4
* Copyright (c) 2003 Fabrice Bellard
5
* Copyright (c) 2005-2007 CodeSourcery
6
* Copyright (c) 2007 OpenedHand, Ltd.
8
* This library is free software; you can redistribute it and/or
9
* modify it under the terms of the GNU Lesser General Public
10
* License as published by the Free Software Foundation; either
11
* version 2 of the License, or (at your option) any later version.
13
* This library is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
* Lesser General Public License for more details.
18
* You should have received a copy of the GNU Lesser General Public
19
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
28
#include "disas/disas.h"
31
#include "qemu/bitops.h"
37
#define ENABLE_ARCH_4T arm_feature(env, ARM_FEATURE_V4T)
38
#define ENABLE_ARCH_5 arm_feature(env, ARM_FEATURE_V5)
39
/* currently all emulated v5 cores are also v5TE, so don't bother */
40
#define ENABLE_ARCH_5TE arm_feature(env, ARM_FEATURE_V5)
41
#define ENABLE_ARCH_5J 0
42
#define ENABLE_ARCH_6 arm_feature(env, ARM_FEATURE_V6)
43
#define ENABLE_ARCH_6K arm_feature(env, ARM_FEATURE_V6K)
44
#define ENABLE_ARCH_6T2 arm_feature(env, ARM_FEATURE_THUMB2)
45
#define ENABLE_ARCH_7 arm_feature(env, ARM_FEATURE_V7)
46
#define ENABLE_ARCH_8 arm_feature(env, ARM_FEATURE_V8)
48
#define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
50
#include "translate.h"
51
static uint32_t gen_opc_condexec_bits[OPC_BUF_SIZE];
53
#if defined(CONFIG_USER_ONLY)
56
#define IS_USER(s) (s->user)
59
/* These instructions trap after executing, so defer them until after the
60
conditional execution state has been updated. */
66
/* We reuse the same 64-bit temporaries for efficiency. */
67
static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
68
static TCGv_i32 cpu_R[16];
69
static TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
70
static TCGv_i32 cpu_exclusive_addr;
71
static TCGv_i32 cpu_exclusive_val;
72
static TCGv_i32 cpu_exclusive_high;
73
#ifdef CONFIG_USER_ONLY
74
static TCGv_i32 cpu_exclusive_test;
75
static TCGv_i32 cpu_exclusive_info;
78
/* FIXME: These should be removed. */
79
static TCGv_i32 cpu_F0s, cpu_F1s;
80
static TCGv_i64 cpu_F0d, cpu_F1d;
82
#include "exec/gen-icount.h"
84
static const char *regnames[] =
85
{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
86
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
88
/* initialize TCG globals. */
89
void arm_translate_init(void)
93
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
95
for (i = 0; i < 16; i++) {
96
cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
97
offsetof(CPUARMState, regs[i]),
100
cpu_CF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, CF), "CF");
101
cpu_NF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, NF), "NF");
102
cpu_VF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, VF), "VF");
103
cpu_ZF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, ZF), "ZF");
105
cpu_exclusive_addr = tcg_global_mem_new_i32(TCG_AREG0,
106
offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
107
cpu_exclusive_val = tcg_global_mem_new_i32(TCG_AREG0,
108
offsetof(CPUARMState, exclusive_val), "exclusive_val");
109
cpu_exclusive_high = tcg_global_mem_new_i32(TCG_AREG0,
110
offsetof(CPUARMState, exclusive_high), "exclusive_high");
111
#ifdef CONFIG_USER_ONLY
112
cpu_exclusive_test = tcg_global_mem_new_i32(TCG_AREG0,
113
offsetof(CPUARMState, exclusive_test), "exclusive_test");
114
cpu_exclusive_info = tcg_global_mem_new_i32(TCG_AREG0,
115
offsetof(CPUARMState, exclusive_info), "exclusive_info");
118
a64_translate_init();
121
static inline TCGv_i32 load_cpu_offset(int offset)
123
TCGv_i32 tmp = tcg_temp_new_i32();
124
tcg_gen_ld_i32(tmp, cpu_env, offset);
128
#define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
130
static inline void store_cpu_offset(TCGv_i32 var, int offset)
132
tcg_gen_st_i32(var, cpu_env, offset);
133
tcg_temp_free_i32(var);
136
#define store_cpu_field(var, name) \
137
store_cpu_offset(var, offsetof(CPUARMState, name))
139
/* Set a variable to the value of a CPU register. */
140
static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
144
/* normally, since we updated PC, we need only to add one insn */
146
addr = (long)s->pc + 2;
148
addr = (long)s->pc + 4;
149
tcg_gen_movi_i32(var, addr);
151
tcg_gen_mov_i32(var, cpu_R[reg]);
155
/* Create a new temporary and set it to the value of a CPU register. */
156
static inline TCGv_i32 load_reg(DisasContext *s, int reg)
158
TCGv_i32 tmp = tcg_temp_new_i32();
159
load_reg_var(s, tmp, reg);
163
/* Set a CPU register. The source must be a temporary and will be
165
static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
168
tcg_gen_andi_i32(var, var, ~1);
169
s->is_jmp = DISAS_JUMP;
171
tcg_gen_mov_i32(cpu_R[reg], var);
172
tcg_temp_free_i32(var);
175
/* Value extensions. */
176
#define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
177
#define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
178
#define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
179
#define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
181
#define gen_sxtb16(var) gen_helper_sxtb16(var, var)
182
#define gen_uxtb16(var) gen_helper_uxtb16(var, var)
185
static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
187
TCGv_i32 tmp_mask = tcg_const_i32(mask);
188
gen_helper_cpsr_write(cpu_env, var, tmp_mask);
189
tcg_temp_free_i32(tmp_mask);
191
/* Set NZCV flags from the high 4 bits of var. */
192
#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
194
static void gen_exception(int excp)
196
TCGv_i32 tmp = tcg_temp_new_i32();
197
tcg_gen_movi_i32(tmp, excp);
198
gen_helper_exception(cpu_env, tmp);
199
tcg_temp_free_i32(tmp);
202
static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
204
TCGv_i32 tmp1 = tcg_temp_new_i32();
205
TCGv_i32 tmp2 = tcg_temp_new_i32();
206
tcg_gen_ext16s_i32(tmp1, a);
207
tcg_gen_ext16s_i32(tmp2, b);
208
tcg_gen_mul_i32(tmp1, tmp1, tmp2);
209
tcg_temp_free_i32(tmp2);
210
tcg_gen_sari_i32(a, a, 16);
211
tcg_gen_sari_i32(b, b, 16);
212
tcg_gen_mul_i32(b, b, a);
213
tcg_gen_mov_i32(a, tmp1);
214
tcg_temp_free_i32(tmp1);
217
/* Byteswap each halfword. */
218
static void gen_rev16(TCGv_i32 var)
220
TCGv_i32 tmp = tcg_temp_new_i32();
221
tcg_gen_shri_i32(tmp, var, 8);
222
tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
223
tcg_gen_shli_i32(var, var, 8);
224
tcg_gen_andi_i32(var, var, 0xff00ff00);
225
tcg_gen_or_i32(var, var, tmp);
226
tcg_temp_free_i32(tmp);
229
/* Byteswap low halfword and sign extend. */
230
static void gen_revsh(TCGv_i32 var)
232
tcg_gen_ext16u_i32(var, var);
233
tcg_gen_bswap16_i32(var, var);
234
tcg_gen_ext16s_i32(var, var);
237
/* Unsigned bitfield extract. */
238
static void gen_ubfx(TCGv_i32 var, int shift, uint32_t mask)
241
tcg_gen_shri_i32(var, var, shift);
242
tcg_gen_andi_i32(var, var, mask);
245
/* Signed bitfield extract. */
246
static void gen_sbfx(TCGv_i32 var, int shift, int width)
251
tcg_gen_sari_i32(var, var, shift);
252
if (shift + width < 32) {
253
signbit = 1u << (width - 1);
254
tcg_gen_andi_i32(var, var, (1u << width) - 1);
255
tcg_gen_xori_i32(var, var, signbit);
256
tcg_gen_subi_i32(var, var, signbit);
260
/* Return (b << 32) + a. Mark inputs as dead */
261
static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
263
TCGv_i64 tmp64 = tcg_temp_new_i64();
265
tcg_gen_extu_i32_i64(tmp64, b);
266
tcg_temp_free_i32(b);
267
tcg_gen_shli_i64(tmp64, tmp64, 32);
268
tcg_gen_add_i64(a, tmp64, a);
270
tcg_temp_free_i64(tmp64);
274
/* Return (b << 32) - a. Mark inputs as dead. */
275
static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
277
TCGv_i64 tmp64 = tcg_temp_new_i64();
279
tcg_gen_extu_i32_i64(tmp64, b);
280
tcg_temp_free_i32(b);
281
tcg_gen_shli_i64(tmp64, tmp64, 32);
282
tcg_gen_sub_i64(a, tmp64, a);
284
tcg_temp_free_i64(tmp64);
288
/* 32x32->64 multiply. Marks inputs as dead. */
289
static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
291
TCGv_i32 lo = tcg_temp_new_i32();
292
TCGv_i32 hi = tcg_temp_new_i32();
295
tcg_gen_mulu2_i32(lo, hi, a, b);
296
tcg_temp_free_i32(a);
297
tcg_temp_free_i32(b);
299
ret = tcg_temp_new_i64();
300
tcg_gen_concat_i32_i64(ret, lo, hi);
301
tcg_temp_free_i32(lo);
302
tcg_temp_free_i32(hi);
307
static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
309
TCGv_i32 lo = tcg_temp_new_i32();
310
TCGv_i32 hi = tcg_temp_new_i32();
313
tcg_gen_muls2_i32(lo, hi, a, b);
314
tcg_temp_free_i32(a);
315
tcg_temp_free_i32(b);
317
ret = tcg_temp_new_i64();
318
tcg_gen_concat_i32_i64(ret, lo, hi);
319
tcg_temp_free_i32(lo);
320
tcg_temp_free_i32(hi);
325
/* Swap low and high halfwords. */
326
static void gen_swap_half(TCGv_i32 var)
328
TCGv_i32 tmp = tcg_temp_new_i32();
329
tcg_gen_shri_i32(tmp, var, 16);
330
tcg_gen_shli_i32(var, var, 16);
331
tcg_gen_or_i32(var, var, tmp);
332
tcg_temp_free_i32(tmp);
335
/* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
336
tmp = (t0 ^ t1) & 0x8000;
339
t0 = (t0 + t1) ^ tmp;
342
static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
344
TCGv_i32 tmp = tcg_temp_new_i32();
345
tcg_gen_xor_i32(tmp, t0, t1);
346
tcg_gen_andi_i32(tmp, tmp, 0x8000);
347
tcg_gen_andi_i32(t0, t0, ~0x8000);
348
tcg_gen_andi_i32(t1, t1, ~0x8000);
349
tcg_gen_add_i32(t0, t0, t1);
350
tcg_gen_xor_i32(t0, t0, tmp);
351
tcg_temp_free_i32(tmp);
352
tcg_temp_free_i32(t1);
355
/* Set CF to the top bit of var. */
356
static void gen_set_CF_bit31(TCGv_i32 var)
358
tcg_gen_shri_i32(cpu_CF, var, 31);
361
/* Set N and Z flags from var. */
362
static inline void gen_logic_CC(TCGv_i32 var)
364
tcg_gen_mov_i32(cpu_NF, var);
365
tcg_gen_mov_i32(cpu_ZF, var);
369
static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
371
tcg_gen_add_i32(t0, t0, t1);
372
tcg_gen_add_i32(t0, t0, cpu_CF);
375
/* dest = T0 + T1 + CF. */
376
static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
378
tcg_gen_add_i32(dest, t0, t1);
379
tcg_gen_add_i32(dest, dest, cpu_CF);
382
/* dest = T0 - T1 + CF - 1. */
383
static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
385
tcg_gen_sub_i32(dest, t0, t1);
386
tcg_gen_add_i32(dest, dest, cpu_CF);
387
tcg_gen_subi_i32(dest, dest, 1);
390
/* dest = T0 + T1. Compute C, N, V and Z flags */
391
static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
393
TCGv_i32 tmp = tcg_temp_new_i32();
394
tcg_gen_movi_i32(tmp, 0);
395
tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
396
tcg_gen_mov_i32(cpu_ZF, cpu_NF);
397
tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
398
tcg_gen_xor_i32(tmp, t0, t1);
399
tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
400
tcg_temp_free_i32(tmp);
401
tcg_gen_mov_i32(dest, cpu_NF);
404
/* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
405
static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
407
TCGv_i32 tmp = tcg_temp_new_i32();
408
if (TCG_TARGET_HAS_add2_i32) {
409
tcg_gen_movi_i32(tmp, 0);
410
tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
411
tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
413
TCGv_i64 q0 = tcg_temp_new_i64();
414
TCGv_i64 q1 = tcg_temp_new_i64();
415
tcg_gen_extu_i32_i64(q0, t0);
416
tcg_gen_extu_i32_i64(q1, t1);
417
tcg_gen_add_i64(q0, q0, q1);
418
tcg_gen_extu_i32_i64(q1, cpu_CF);
419
tcg_gen_add_i64(q0, q0, q1);
420
tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
421
tcg_temp_free_i64(q0);
422
tcg_temp_free_i64(q1);
424
tcg_gen_mov_i32(cpu_ZF, cpu_NF);
425
tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
426
tcg_gen_xor_i32(tmp, t0, t1);
427
tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
428
tcg_temp_free_i32(tmp);
429
tcg_gen_mov_i32(dest, cpu_NF);
432
/* dest = T0 - T1. Compute C, N, V and Z flags */
433
static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
436
tcg_gen_sub_i32(cpu_NF, t0, t1);
437
tcg_gen_mov_i32(cpu_ZF, cpu_NF);
438
tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
439
tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
440
tmp = tcg_temp_new_i32();
441
tcg_gen_xor_i32(tmp, t0, t1);
442
tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
443
tcg_temp_free_i32(tmp);
444
tcg_gen_mov_i32(dest, cpu_NF);
447
/* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
448
static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
450
TCGv_i32 tmp = tcg_temp_new_i32();
451
tcg_gen_not_i32(tmp, t1);
452
gen_adc_CC(dest, t0, tmp);
453
tcg_temp_free_i32(tmp);
456
#define GEN_SHIFT(name) \
457
static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
459
TCGv_i32 tmp1, tmp2, tmp3; \
460
tmp1 = tcg_temp_new_i32(); \
461
tcg_gen_andi_i32(tmp1, t1, 0xff); \
462
tmp2 = tcg_const_i32(0); \
463
tmp3 = tcg_const_i32(0x1f); \
464
tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
465
tcg_temp_free_i32(tmp3); \
466
tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
467
tcg_gen_##name##_i32(dest, tmp2, tmp1); \
468
tcg_temp_free_i32(tmp2); \
469
tcg_temp_free_i32(tmp1); \
475
static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
478
tmp1 = tcg_temp_new_i32();
479
tcg_gen_andi_i32(tmp1, t1, 0xff);
480
tmp2 = tcg_const_i32(0x1f);
481
tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
482
tcg_temp_free_i32(tmp2);
483
tcg_gen_sar_i32(dest, t0, tmp1);
484
tcg_temp_free_i32(tmp1);
487
static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
489
TCGv_i32 c0 = tcg_const_i32(0);
490
TCGv_i32 tmp = tcg_temp_new_i32();
491
tcg_gen_neg_i32(tmp, src);
492
tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
493
tcg_temp_free_i32(c0);
494
tcg_temp_free_i32(tmp);
497
static void shifter_out_im(TCGv_i32 var, int shift)
500
tcg_gen_andi_i32(cpu_CF, var, 1);
502
tcg_gen_shri_i32(cpu_CF, var, shift);
504
tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
509
/* Shift by immediate. Includes special handling for shift == 0. */
510
static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
511
int shift, int flags)
517
shifter_out_im(var, 32 - shift);
518
tcg_gen_shli_i32(var, var, shift);
524
tcg_gen_shri_i32(cpu_CF, var, 31);
526
tcg_gen_movi_i32(var, 0);
529
shifter_out_im(var, shift - 1);
530
tcg_gen_shri_i32(var, var, shift);
537
shifter_out_im(var, shift - 1);
540
tcg_gen_sari_i32(var, var, shift);
542
case 3: /* ROR/RRX */
545
shifter_out_im(var, shift - 1);
546
tcg_gen_rotri_i32(var, var, shift); break;
548
TCGv_i32 tmp = tcg_temp_new_i32();
549
tcg_gen_shli_i32(tmp, cpu_CF, 31);
551
shifter_out_im(var, 0);
552
tcg_gen_shri_i32(var, var, 1);
553
tcg_gen_or_i32(var, var, tmp);
554
tcg_temp_free_i32(tmp);
559
static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
560
TCGv_i32 shift, int flags)
564
case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
565
case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
566
case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
567
case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
572
gen_shl(var, var, shift);
575
gen_shr(var, var, shift);
578
gen_sar(var, var, shift);
580
case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
581
tcg_gen_rotr_i32(var, var, shift); break;
584
tcg_temp_free_i32(shift);
587
#define PAS_OP(pfx) \
589
case 0: gen_pas_helper(glue(pfx,add16)); break; \
590
case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
591
case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
592
case 3: gen_pas_helper(glue(pfx,sub16)); break; \
593
case 4: gen_pas_helper(glue(pfx,add8)); break; \
594
case 7: gen_pas_helper(glue(pfx,sub8)); break; \
596
static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
601
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
603
tmp = tcg_temp_new_ptr();
604
tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
606
tcg_temp_free_ptr(tmp);
609
tmp = tcg_temp_new_ptr();
610
tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
612
tcg_temp_free_ptr(tmp);
614
#undef gen_pas_helper
615
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
628
#undef gen_pas_helper
633
/* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
634
#define PAS_OP(pfx) \
636
case 0: gen_pas_helper(glue(pfx,add8)); break; \
637
case 1: gen_pas_helper(glue(pfx,add16)); break; \
638
case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
639
case 4: gen_pas_helper(glue(pfx,sub8)); break; \
640
case 5: gen_pas_helper(glue(pfx,sub16)); break; \
641
case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
643
static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
648
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
650
tmp = tcg_temp_new_ptr();
651
tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
653
tcg_temp_free_ptr(tmp);
656
tmp = tcg_temp_new_ptr();
657
tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
659
tcg_temp_free_ptr(tmp);
661
#undef gen_pas_helper
662
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
675
#undef gen_pas_helper
680
static void gen_test_cc(int cc, int label)
687
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
690
tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label);
693
tcg_gen_brcondi_i32(TCG_COND_NE, cpu_CF, 0, label);
696
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label);
699
tcg_gen_brcondi_i32(TCG_COND_LT, cpu_NF, 0, label);
702
tcg_gen_brcondi_i32(TCG_COND_GE, cpu_NF, 0, label);
705
tcg_gen_brcondi_i32(TCG_COND_LT, cpu_VF, 0, label);
708
tcg_gen_brcondi_i32(TCG_COND_GE, cpu_VF, 0, label);
710
case 8: /* hi: C && !Z */
711
inv = gen_new_label();
712
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, inv);
713
tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label);
716
case 9: /* ls: !C || Z */
717
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label);
718
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
720
case 10: /* ge: N == V -> N ^ V == 0 */
721
tmp = tcg_temp_new_i32();
722
tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
723
tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
724
tcg_temp_free_i32(tmp);
726
case 11: /* lt: N != V -> N ^ V != 0 */
727
tmp = tcg_temp_new_i32();
728
tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
729
tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
730
tcg_temp_free_i32(tmp);
732
case 12: /* gt: !Z && N == V */
733
inv = gen_new_label();
734
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, inv);
735
tmp = tcg_temp_new_i32();
736
tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
737
tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
738
tcg_temp_free_i32(tmp);
741
case 13: /* le: Z || N != V */
742
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
743
tmp = tcg_temp_new_i32();
744
tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
745
tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
746
tcg_temp_free_i32(tmp);
749
fprintf(stderr, "Bad condition code 0x%x\n", cc);
754
static const uint8_t table_logic_cc[16] = {
773
/* Set PC and Thumb state from an immediate address. */
774
static inline void gen_bx_im(DisasContext *s, uint32_t addr)
778
s->is_jmp = DISAS_UPDATE;
779
if (s->thumb != (addr & 1)) {
780
tmp = tcg_temp_new_i32();
781
tcg_gen_movi_i32(tmp, addr & 1);
782
tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
783
tcg_temp_free_i32(tmp);
785
tcg_gen_movi_i32(cpu_R[15], addr & ~1);
788
/* Set PC and Thumb state from var. var is marked as dead. */
789
static inline void gen_bx(DisasContext *s, TCGv_i32 var)
791
s->is_jmp = DISAS_UPDATE;
792
tcg_gen_andi_i32(cpu_R[15], var, ~1);
793
tcg_gen_andi_i32(var, var, 1);
794
store_cpu_field(var, thumb);
797
/* Variant of store_reg which uses branch&exchange logic when storing
798
to r15 in ARM architecture v7 and above. The source must be a temporary
799
and will be marked as dead. */
800
static inline void store_reg_bx(CPUARMState *env, DisasContext *s,
801
int reg, TCGv_i32 var)
803
if (reg == 15 && ENABLE_ARCH_7) {
806
store_reg(s, reg, var);
810
/* Variant of store_reg which uses branch&exchange logic when storing
811
* to r15 in ARM architecture v5T and above. This is used for storing
812
* the results of a LDR/LDM/POP into r15, and corresponds to the cases
813
* in the ARM ARM which use the LoadWritePC() pseudocode function. */
814
static inline void store_reg_from_load(CPUARMState *env, DisasContext *s,
815
int reg, TCGv_i32 var)
817
if (reg == 15 && ENABLE_ARCH_5) {
820
store_reg(s, reg, var);
824
/* Abstractions of "generate code to do a guest load/store for
825
* AArch32", where a vaddr is always 32 bits (and is zero
826
* extended if we're a 64 bit core) and data is also
827
* 32 bits unless specifically doing a 64 bit access.
828
* These functions work like tcg_gen_qemu_{ld,st}* except
829
* that their arguments are TCGv_i32 rather than TCGv.
831
#if TARGET_LONG_BITS == 32
833
#define DO_GEN_LD(OP) \
834
static inline void gen_aa32_##OP(TCGv_i32 val, TCGv_i32 addr, int index) \
836
tcg_gen_qemu_##OP(val, addr, index); \
839
#define DO_GEN_ST(OP) \
840
static inline void gen_aa32_##OP(TCGv_i32 val, TCGv_i32 addr, int index) \
842
tcg_gen_qemu_##OP(val, addr, index); \
845
static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
847
tcg_gen_qemu_ld64(val, addr, index);
850
static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
852
tcg_gen_qemu_st64(val, addr, index);
857
#define DO_GEN_LD(OP) \
858
static inline void gen_aa32_##OP(TCGv_i32 val, TCGv_i32 addr, int index) \
860
TCGv addr64 = tcg_temp_new(); \
861
TCGv val64 = tcg_temp_new(); \
862
tcg_gen_extu_i32_i64(addr64, addr); \
863
tcg_gen_qemu_##OP(val64, addr64, index); \
864
tcg_temp_free(addr64); \
865
tcg_gen_trunc_i64_i32(val, val64); \
866
tcg_temp_free(val64); \
869
#define DO_GEN_ST(OP) \
870
static inline void gen_aa32_##OP(TCGv_i32 val, TCGv_i32 addr, int index) \
872
TCGv addr64 = tcg_temp_new(); \
873
TCGv val64 = tcg_temp_new(); \
874
tcg_gen_extu_i32_i64(addr64, addr); \
875
tcg_gen_extu_i32_i64(val64, val); \
876
tcg_gen_qemu_##OP(val64, addr64, index); \
877
tcg_temp_free(addr64); \
878
tcg_temp_free(val64); \
881
static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
883
TCGv addr64 = tcg_temp_new();
884
tcg_gen_extu_i32_i64(addr64, addr);
885
tcg_gen_qemu_ld64(val, addr64, index);
886
tcg_temp_free(addr64);
889
static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
891
TCGv addr64 = tcg_temp_new();
892
tcg_gen_extu_i32_i64(addr64, addr);
893
tcg_gen_qemu_st64(val, addr64, index);
894
tcg_temp_free(addr64);
908
static inline void gen_smc(CPUARMState *env, DisasContext *s)
910
tcg_gen_movi_i32(cpu_R[15], s->pc);
911
s->is_jmp = DISAS_SMC;
914
static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
917
gen_a64_set_pc_im(val);
919
tcg_gen_movi_i32(cpu_R[15], val);
923
/* Force a TB lookup after an instruction that changes the CPU state. */
924
static inline void gen_lookup_tb(DisasContext *s)
926
tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
927
s->is_jmp = DISAS_UPDATE;
930
static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
933
int val, rm, shift, shiftop;
936
if (!(insn & (1 << 25))) {
939
if (!(insn & (1 << 23)))
942
tcg_gen_addi_i32(var, var, val);
946
shift = (insn >> 7) & 0x1f;
947
shiftop = (insn >> 5) & 3;
948
offset = load_reg(s, rm);
949
gen_arm_shift_im(offset, shiftop, shift, 0);
950
if (!(insn & (1 << 23)))
951
tcg_gen_sub_i32(var, var, offset);
953
tcg_gen_add_i32(var, var, offset);
954
tcg_temp_free_i32(offset);
958
static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
959
int extra, TCGv_i32 var)
964
if (insn & (1 << 22)) {
966
val = (insn & 0xf) | ((insn >> 4) & 0xf0);
967
if (!(insn & (1 << 23)))
971
tcg_gen_addi_i32(var, var, val);
975
tcg_gen_addi_i32(var, var, extra);
977
offset = load_reg(s, rm);
978
if (!(insn & (1 << 23)))
979
tcg_gen_sub_i32(var, var, offset);
981
tcg_gen_add_i32(var, var, offset);
982
tcg_temp_free_i32(offset);
986
static TCGv_ptr get_fpstatus_ptr(int neon)
988
TCGv_ptr statusptr = tcg_temp_new_ptr();
991
offset = offsetof(CPUARMState, vfp.standard_fp_status);
993
offset = offsetof(CPUARMState, vfp.fp_status);
995
tcg_gen_addi_ptr(statusptr, cpu_env, offset);
999
#define VFP_OP2(name) \
1000
static inline void gen_vfp_##name(int dp) \
1002
TCGv_ptr fpst = get_fpstatus_ptr(0); \
1004
gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1006
gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1008
tcg_temp_free_ptr(fpst); \
1018
static inline void gen_vfp_F1_mul(int dp)
1020
/* Like gen_vfp_mul() but put result in F1 */
1021
TCGv_ptr fpst = get_fpstatus_ptr(0);
1023
gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1025
gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1027
tcg_temp_free_ptr(fpst);
1030
static inline void gen_vfp_F1_neg(int dp)
1032
/* Like gen_vfp_neg() but put result in F1 */
1034
gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1036
gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1040
static inline void gen_vfp_abs(int dp)
1043
gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1045
gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1048
static inline void gen_vfp_neg(int dp)
1051
gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1053
gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1056
static inline void gen_vfp_sqrt(int dp)
1059
gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1061
gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1064
static inline void gen_vfp_cmp(int dp)
1067
gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1069
gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1072
static inline void gen_vfp_cmpe(int dp)
1075
gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1077
gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1080
static inline void gen_vfp_F1_ld0(int dp)
1083
tcg_gen_movi_i64(cpu_F1d, 0);
1085
tcg_gen_movi_i32(cpu_F1s, 0);
1088
#define VFP_GEN_ITOF(name) \
1089
static inline void gen_vfp_##name(int dp, int neon) \
1091
TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1093
gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1095
gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1097
tcg_temp_free_ptr(statusptr); \
1104
#define VFP_GEN_FTOI(name) \
1105
static inline void gen_vfp_##name(int dp, int neon) \
1107
TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1109
gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1111
gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1113
tcg_temp_free_ptr(statusptr); \
1122
#define VFP_GEN_FIX(name) \
1123
static inline void gen_vfp_##name(int dp, int shift, int neon) \
1125
TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1126
TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1128
gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, statusptr); \
1130
gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, statusptr); \
1132
tcg_temp_free_i32(tmp_shift); \
1133
tcg_temp_free_ptr(statusptr); \
1145
static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1148
gen_aa32_ld64(cpu_F0d, addr, IS_USER(s));
1150
gen_aa32_ld32u(cpu_F0s, addr, IS_USER(s));
1154
static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1157
gen_aa32_st64(cpu_F0d, addr, IS_USER(s));
1159
gen_aa32_st32(cpu_F0s, addr, IS_USER(s));
1164
vfp_reg_offset (int dp, int reg)
1167
return offsetof(CPUARMState, vfp.regs[reg]);
1169
return offsetof(CPUARMState, vfp.regs[reg >> 1])
1170
+ offsetof(CPU_DoubleU, l.upper);
1172
return offsetof(CPUARMState, vfp.regs[reg >> 1])
1173
+ offsetof(CPU_DoubleU, l.lower);
1177
/* Return the offset of a 32-bit piece of a NEON register.
1178
zero is the least significant end of the register. */
1180
neon_reg_offset (int reg, int n)
1184
return vfp_reg_offset(0, sreg);
1187
static TCGv_i32 neon_load_reg(int reg, int pass)
1189
TCGv_i32 tmp = tcg_temp_new_i32();
1190
tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1194
static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1196
tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1197
tcg_temp_free_i32(var);
1200
static inline void neon_load_reg64(TCGv_i64 var, int reg)
1202
tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1205
static inline void neon_store_reg64(TCGv_i64 var, int reg)
1207
tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1210
#define tcg_gen_ld_f32 tcg_gen_ld_i32
1211
#define tcg_gen_ld_f64 tcg_gen_ld_i64
1212
#define tcg_gen_st_f32 tcg_gen_st_i32
1213
#define tcg_gen_st_f64 tcg_gen_st_i64
1215
static inline void gen_mov_F0_vreg(int dp, int reg)
1218
tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1220
tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1223
static inline void gen_mov_F1_vreg(int dp, int reg)
1226
tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1228
tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1231
static inline void gen_mov_vreg_F0(int dp, int reg)
1234
tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1236
tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1239
#define ARM_CP_RW_BIT (1 << 20)
1241
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1243
tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1246
static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1248
tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1251
static inline TCGv_i32 iwmmxt_load_creg(int reg)
1253
TCGv_i32 var = tcg_temp_new_i32();
1254
tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1258
static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1260
tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1261
tcg_temp_free_i32(var);
1264
static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1266
iwmmxt_store_reg(cpu_M0, rn);
1269
static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1271
iwmmxt_load_reg(cpu_M0, rn);
1274
static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1276
iwmmxt_load_reg(cpu_V1, rn);
1277
tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1280
static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1282
iwmmxt_load_reg(cpu_V1, rn);
1283
tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1286
static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1288
iwmmxt_load_reg(cpu_V1, rn);
1289
tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1292
#define IWMMXT_OP(name) \
1293
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1295
iwmmxt_load_reg(cpu_V1, rn); \
1296
gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1299
#define IWMMXT_OP_ENV(name) \
1300
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1302
iwmmxt_load_reg(cpu_V1, rn); \
1303
gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1306
#define IWMMXT_OP_ENV_SIZE(name) \
1307
IWMMXT_OP_ENV(name##b) \
1308
IWMMXT_OP_ENV(name##w) \
1309
IWMMXT_OP_ENV(name##l)
1311
#define IWMMXT_OP_ENV1(name) \
1312
static inline void gen_op_iwmmxt_##name##_M0(void) \
1314
gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1328
IWMMXT_OP_ENV_SIZE(unpackl)
1329
IWMMXT_OP_ENV_SIZE(unpackh)
1331
IWMMXT_OP_ENV1(unpacklub)
1332
IWMMXT_OP_ENV1(unpackluw)
1333
IWMMXT_OP_ENV1(unpacklul)
1334
IWMMXT_OP_ENV1(unpackhub)
1335
IWMMXT_OP_ENV1(unpackhuw)
1336
IWMMXT_OP_ENV1(unpackhul)
1337
IWMMXT_OP_ENV1(unpacklsb)
1338
IWMMXT_OP_ENV1(unpacklsw)
1339
IWMMXT_OP_ENV1(unpacklsl)
1340
IWMMXT_OP_ENV1(unpackhsb)
1341
IWMMXT_OP_ENV1(unpackhsw)
1342
IWMMXT_OP_ENV1(unpackhsl)
1344
IWMMXT_OP_ENV_SIZE(cmpeq)
1345
IWMMXT_OP_ENV_SIZE(cmpgtu)
1346
IWMMXT_OP_ENV_SIZE(cmpgts)
1348
IWMMXT_OP_ENV_SIZE(mins)
1349
IWMMXT_OP_ENV_SIZE(minu)
1350
IWMMXT_OP_ENV_SIZE(maxs)
1351
IWMMXT_OP_ENV_SIZE(maxu)
1353
IWMMXT_OP_ENV_SIZE(subn)
1354
IWMMXT_OP_ENV_SIZE(addn)
1355
IWMMXT_OP_ENV_SIZE(subu)
1356
IWMMXT_OP_ENV_SIZE(addu)
1357
IWMMXT_OP_ENV_SIZE(subs)
1358
IWMMXT_OP_ENV_SIZE(adds)
1360
IWMMXT_OP_ENV(avgb0)
1361
IWMMXT_OP_ENV(avgb1)
1362
IWMMXT_OP_ENV(avgw0)
1363
IWMMXT_OP_ENV(avgw1)
1367
IWMMXT_OP_ENV(packuw)
1368
IWMMXT_OP_ENV(packul)
1369
IWMMXT_OP_ENV(packuq)
1370
IWMMXT_OP_ENV(packsw)
1371
IWMMXT_OP_ENV(packsl)
1372
IWMMXT_OP_ENV(packsq)
1374
static void gen_op_iwmmxt_set_mup(void)
1377
tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1378
tcg_gen_ori_i32(tmp, tmp, 2);
1379
store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1382
static void gen_op_iwmmxt_set_cup(void)
1385
tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1386
tcg_gen_ori_i32(tmp, tmp, 1);
1387
store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1390
static void gen_op_iwmmxt_setpsr_nz(void)
1392
TCGv_i32 tmp = tcg_temp_new_i32();
1393
gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1394
store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1397
static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1399
iwmmxt_load_reg(cpu_V1, rn);
1400
tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1401
tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1404
static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1411
rd = (insn >> 16) & 0xf;
1412
tmp = load_reg(s, rd);
1414
offset = (insn & 0xff) << ((insn >> 7) & 2);
1415
if (insn & (1 << 24)) {
1417
if (insn & (1 << 23))
1418
tcg_gen_addi_i32(tmp, tmp, offset);
1420
tcg_gen_addi_i32(tmp, tmp, -offset);
1421
tcg_gen_mov_i32(dest, tmp);
1422
if (insn & (1 << 21))
1423
store_reg(s, rd, tmp);
1425
tcg_temp_free_i32(tmp);
1426
} else if (insn & (1 << 21)) {
1428
tcg_gen_mov_i32(dest, tmp);
1429
if (insn & (1 << 23))
1430
tcg_gen_addi_i32(tmp, tmp, offset);
1432
tcg_gen_addi_i32(tmp, tmp, -offset);
1433
store_reg(s, rd, tmp);
1434
} else if (!(insn & (1 << 23)))
1439
static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1441
int rd = (insn >> 0) & 0xf;
1444
if (insn & (1 << 8)) {
1445
if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1448
tmp = iwmmxt_load_creg(rd);
1451
tmp = tcg_temp_new_i32();
1452
iwmmxt_load_reg(cpu_V0, rd);
1453
tcg_gen_trunc_i64_i32(tmp, cpu_V0);
1455
tcg_gen_andi_i32(tmp, tmp, mask);
1456
tcg_gen_mov_i32(dest, tmp);
1457
tcg_temp_free_i32(tmp);
1461
/* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1462
(ie. an undefined instruction). */
1463
static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
1466
int rdhi, rdlo, rd0, rd1, i;
1468
TCGv_i32 tmp, tmp2, tmp3;
1470
if ((insn & 0x0e000e00) == 0x0c000000) {
1471
if ((insn & 0x0fe00ff0) == 0x0c400000) {
1473
rdlo = (insn >> 12) & 0xf;
1474
rdhi = (insn >> 16) & 0xf;
1475
if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1476
iwmmxt_load_reg(cpu_V0, wrd);
1477
tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
1478
tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1479
tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
1480
} else { /* TMCRR */
1481
tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1482
iwmmxt_store_reg(cpu_V0, wrd);
1483
gen_op_iwmmxt_set_mup();
1488
wrd = (insn >> 12) & 0xf;
1489
addr = tcg_temp_new_i32();
1490
if (gen_iwmmxt_address(s, insn, addr)) {
1491
tcg_temp_free_i32(addr);
1494
if (insn & ARM_CP_RW_BIT) {
1495
if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1496
tmp = tcg_temp_new_i32();
1497
gen_aa32_ld32u(tmp, addr, IS_USER(s));
1498
iwmmxt_store_creg(wrd, tmp);
1501
if (insn & (1 << 8)) {
1502
if (insn & (1 << 22)) { /* WLDRD */
1503
gen_aa32_ld64(cpu_M0, addr, IS_USER(s));
1505
} else { /* WLDRW wRd */
1506
tmp = tcg_temp_new_i32();
1507
gen_aa32_ld32u(tmp, addr, IS_USER(s));
1510
tmp = tcg_temp_new_i32();
1511
if (insn & (1 << 22)) { /* WLDRH */
1512
gen_aa32_ld16u(tmp, addr, IS_USER(s));
1513
} else { /* WLDRB */
1514
gen_aa32_ld8u(tmp, addr, IS_USER(s));
1518
tcg_gen_extu_i32_i64(cpu_M0, tmp);
1519
tcg_temp_free_i32(tmp);
1521
gen_op_iwmmxt_movq_wRn_M0(wrd);
1524
if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1525
tmp = iwmmxt_load_creg(wrd);
1526
gen_aa32_st32(tmp, addr, IS_USER(s));
1528
gen_op_iwmmxt_movq_M0_wRn(wrd);
1529
tmp = tcg_temp_new_i32();
1530
if (insn & (1 << 8)) {
1531
if (insn & (1 << 22)) { /* WSTRD */
1532
gen_aa32_st64(cpu_M0, addr, IS_USER(s));
1533
} else { /* WSTRW wRd */
1534
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1535
gen_aa32_st32(tmp, addr, IS_USER(s));
1538
if (insn & (1 << 22)) { /* WSTRH */
1539
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1540
gen_aa32_st16(tmp, addr, IS_USER(s));
1541
} else { /* WSTRB */
1542
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1543
gen_aa32_st8(tmp, addr, IS_USER(s));
1547
tcg_temp_free_i32(tmp);
1549
tcg_temp_free_i32(addr);
1553
if ((insn & 0x0f000000) != 0x0e000000)
1556
switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1557
case 0x000: /* WOR */
1558
wrd = (insn >> 12) & 0xf;
1559
rd0 = (insn >> 0) & 0xf;
1560
rd1 = (insn >> 16) & 0xf;
1561
gen_op_iwmmxt_movq_M0_wRn(rd0);
1562
gen_op_iwmmxt_orq_M0_wRn(rd1);
1563
gen_op_iwmmxt_setpsr_nz();
1564
gen_op_iwmmxt_movq_wRn_M0(wrd);
1565
gen_op_iwmmxt_set_mup();
1566
gen_op_iwmmxt_set_cup();
1568
case 0x011: /* TMCR */
1571
rd = (insn >> 12) & 0xf;
1572
wrd = (insn >> 16) & 0xf;
1574
case ARM_IWMMXT_wCID:
1575
case ARM_IWMMXT_wCASF:
1577
case ARM_IWMMXT_wCon:
1578
gen_op_iwmmxt_set_cup();
1580
case ARM_IWMMXT_wCSSF:
1581
tmp = iwmmxt_load_creg(wrd);
1582
tmp2 = load_reg(s, rd);
1583
tcg_gen_andc_i32(tmp, tmp, tmp2);
1584
tcg_temp_free_i32(tmp2);
1585
iwmmxt_store_creg(wrd, tmp);
1587
case ARM_IWMMXT_wCGR0:
1588
case ARM_IWMMXT_wCGR1:
1589
case ARM_IWMMXT_wCGR2:
1590
case ARM_IWMMXT_wCGR3:
1591
gen_op_iwmmxt_set_cup();
1592
tmp = load_reg(s, rd);
1593
iwmmxt_store_creg(wrd, tmp);
1599
case 0x100: /* WXOR */
1600
wrd = (insn >> 12) & 0xf;
1601
rd0 = (insn >> 0) & 0xf;
1602
rd1 = (insn >> 16) & 0xf;
1603
gen_op_iwmmxt_movq_M0_wRn(rd0);
1604
gen_op_iwmmxt_xorq_M0_wRn(rd1);
1605
gen_op_iwmmxt_setpsr_nz();
1606
gen_op_iwmmxt_movq_wRn_M0(wrd);
1607
gen_op_iwmmxt_set_mup();
1608
gen_op_iwmmxt_set_cup();
1610
case 0x111: /* TMRC */
1613
rd = (insn >> 12) & 0xf;
1614
wrd = (insn >> 16) & 0xf;
1615
tmp = iwmmxt_load_creg(wrd);
1616
store_reg(s, rd, tmp);
1618
case 0x300: /* WANDN */
1619
wrd = (insn >> 12) & 0xf;
1620
rd0 = (insn >> 0) & 0xf;
1621
rd1 = (insn >> 16) & 0xf;
1622
gen_op_iwmmxt_movq_M0_wRn(rd0);
1623
tcg_gen_neg_i64(cpu_M0, cpu_M0);
1624
gen_op_iwmmxt_andq_M0_wRn(rd1);
1625
gen_op_iwmmxt_setpsr_nz();
1626
gen_op_iwmmxt_movq_wRn_M0(wrd);
1627
gen_op_iwmmxt_set_mup();
1628
gen_op_iwmmxt_set_cup();
1630
case 0x200: /* WAND */
1631
wrd = (insn >> 12) & 0xf;
1632
rd0 = (insn >> 0) & 0xf;
1633
rd1 = (insn >> 16) & 0xf;
1634
gen_op_iwmmxt_movq_M0_wRn(rd0);
1635
gen_op_iwmmxt_andq_M0_wRn(rd1);
1636
gen_op_iwmmxt_setpsr_nz();
1637
gen_op_iwmmxt_movq_wRn_M0(wrd);
1638
gen_op_iwmmxt_set_mup();
1639
gen_op_iwmmxt_set_cup();
1641
case 0x810: case 0xa10: /* WMADD */
1642
wrd = (insn >> 12) & 0xf;
1643
rd0 = (insn >> 0) & 0xf;
1644
rd1 = (insn >> 16) & 0xf;
1645
gen_op_iwmmxt_movq_M0_wRn(rd0);
1646
if (insn & (1 << 21))
1647
gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1649
gen_op_iwmmxt_madduq_M0_wRn(rd1);
1650
gen_op_iwmmxt_movq_wRn_M0(wrd);
1651
gen_op_iwmmxt_set_mup();
1653
case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1654
wrd = (insn >> 12) & 0xf;
1655
rd0 = (insn >> 16) & 0xf;
1656
rd1 = (insn >> 0) & 0xf;
1657
gen_op_iwmmxt_movq_M0_wRn(rd0);
1658
switch ((insn >> 22) & 3) {
1660
gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1663
gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1666
gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1671
gen_op_iwmmxt_movq_wRn_M0(wrd);
1672
gen_op_iwmmxt_set_mup();
1673
gen_op_iwmmxt_set_cup();
1675
case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1676
wrd = (insn >> 12) & 0xf;
1677
rd0 = (insn >> 16) & 0xf;
1678
rd1 = (insn >> 0) & 0xf;
1679
gen_op_iwmmxt_movq_M0_wRn(rd0);
1680
switch ((insn >> 22) & 3) {
1682
gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1685
gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1688
gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1693
gen_op_iwmmxt_movq_wRn_M0(wrd);
1694
gen_op_iwmmxt_set_mup();
1695
gen_op_iwmmxt_set_cup();
1697
case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1698
wrd = (insn >> 12) & 0xf;
1699
rd0 = (insn >> 16) & 0xf;
1700
rd1 = (insn >> 0) & 0xf;
1701
gen_op_iwmmxt_movq_M0_wRn(rd0);
1702
if (insn & (1 << 22))
1703
gen_op_iwmmxt_sadw_M0_wRn(rd1);
1705
gen_op_iwmmxt_sadb_M0_wRn(rd1);
1706
if (!(insn & (1 << 20)))
1707
gen_op_iwmmxt_addl_M0_wRn(wrd);
1708
gen_op_iwmmxt_movq_wRn_M0(wrd);
1709
gen_op_iwmmxt_set_mup();
1711
case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1712
wrd = (insn >> 12) & 0xf;
1713
rd0 = (insn >> 16) & 0xf;
1714
rd1 = (insn >> 0) & 0xf;
1715
gen_op_iwmmxt_movq_M0_wRn(rd0);
1716
if (insn & (1 << 21)) {
1717
if (insn & (1 << 20))
1718
gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1720
gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1722
if (insn & (1 << 20))
1723
gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1725
gen_op_iwmmxt_mululw_M0_wRn(rd1);
1727
gen_op_iwmmxt_movq_wRn_M0(wrd);
1728
gen_op_iwmmxt_set_mup();
1730
case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1731
wrd = (insn >> 12) & 0xf;
1732
rd0 = (insn >> 16) & 0xf;
1733
rd1 = (insn >> 0) & 0xf;
1734
gen_op_iwmmxt_movq_M0_wRn(rd0);
1735
if (insn & (1 << 21))
1736
gen_op_iwmmxt_macsw_M0_wRn(rd1);
1738
gen_op_iwmmxt_macuw_M0_wRn(rd1);
1739
if (!(insn & (1 << 20))) {
1740
iwmmxt_load_reg(cpu_V1, wrd);
1741
tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1743
gen_op_iwmmxt_movq_wRn_M0(wrd);
1744
gen_op_iwmmxt_set_mup();
1746
case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1747
wrd = (insn >> 12) & 0xf;
1748
rd0 = (insn >> 16) & 0xf;
1749
rd1 = (insn >> 0) & 0xf;
1750
gen_op_iwmmxt_movq_M0_wRn(rd0);
1751
switch ((insn >> 22) & 3) {
1753
gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1756
gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1759
gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1764
gen_op_iwmmxt_movq_wRn_M0(wrd);
1765
gen_op_iwmmxt_set_mup();
1766
gen_op_iwmmxt_set_cup();
1768
case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1769
wrd = (insn >> 12) & 0xf;
1770
rd0 = (insn >> 16) & 0xf;
1771
rd1 = (insn >> 0) & 0xf;
1772
gen_op_iwmmxt_movq_M0_wRn(rd0);
1773
if (insn & (1 << 22)) {
1774
if (insn & (1 << 20))
1775
gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1777
gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1779
if (insn & (1 << 20))
1780
gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1782
gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1784
gen_op_iwmmxt_movq_wRn_M0(wrd);
1785
gen_op_iwmmxt_set_mup();
1786
gen_op_iwmmxt_set_cup();
1788
case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1789
wrd = (insn >> 12) & 0xf;
1790
rd0 = (insn >> 16) & 0xf;
1791
rd1 = (insn >> 0) & 0xf;
1792
gen_op_iwmmxt_movq_M0_wRn(rd0);
1793
tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1794
tcg_gen_andi_i32(tmp, tmp, 7);
1795
iwmmxt_load_reg(cpu_V1, rd1);
1796
gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
1797
tcg_temp_free_i32(tmp);
1798
gen_op_iwmmxt_movq_wRn_M0(wrd);
1799
gen_op_iwmmxt_set_mup();
1801
case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1802
if (((insn >> 6) & 3) == 3)
1804
rd = (insn >> 12) & 0xf;
1805
wrd = (insn >> 16) & 0xf;
1806
tmp = load_reg(s, rd);
1807
gen_op_iwmmxt_movq_M0_wRn(wrd);
1808
switch ((insn >> 6) & 3) {
1810
tmp2 = tcg_const_i32(0xff);
1811
tmp3 = tcg_const_i32((insn & 7) << 3);
1814
tmp2 = tcg_const_i32(0xffff);
1815
tmp3 = tcg_const_i32((insn & 3) << 4);
1818
tmp2 = tcg_const_i32(0xffffffff);
1819
tmp3 = tcg_const_i32((insn & 1) << 5);
1822
TCGV_UNUSED_I32(tmp2);
1823
TCGV_UNUSED_I32(tmp3);
1825
gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
1826
tcg_temp_free_i32(tmp3);
1827
tcg_temp_free_i32(tmp2);
1828
tcg_temp_free_i32(tmp);
1829
gen_op_iwmmxt_movq_wRn_M0(wrd);
1830
gen_op_iwmmxt_set_mup();
1832
case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1833
rd = (insn >> 12) & 0xf;
1834
wrd = (insn >> 16) & 0xf;
1835
if (rd == 15 || ((insn >> 22) & 3) == 3)
1837
gen_op_iwmmxt_movq_M0_wRn(wrd);
1838
tmp = tcg_temp_new_i32();
1839
switch ((insn >> 22) & 3) {
1841
tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
1842
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1844
tcg_gen_ext8s_i32(tmp, tmp);
1846
tcg_gen_andi_i32(tmp, tmp, 0xff);
1850
tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
1851
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1853
tcg_gen_ext16s_i32(tmp, tmp);
1855
tcg_gen_andi_i32(tmp, tmp, 0xffff);
1859
tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
1860
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1863
store_reg(s, rd, tmp);
1865
case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1866
if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1868
tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1869
switch ((insn >> 22) & 3) {
1871
tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
1874
tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
1877
tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
1880
tcg_gen_shli_i32(tmp, tmp, 28);
1882
tcg_temp_free_i32(tmp);
1884
case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1885
if (((insn >> 6) & 3) == 3)
1887
rd = (insn >> 12) & 0xf;
1888
wrd = (insn >> 16) & 0xf;
1889
tmp = load_reg(s, rd);
1890
switch ((insn >> 6) & 3) {
1892
gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
1895
gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
1898
gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
1901
tcg_temp_free_i32(tmp);
1902
gen_op_iwmmxt_movq_wRn_M0(wrd);
1903
gen_op_iwmmxt_set_mup();
1905
case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1906
if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1908
tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1909
tmp2 = tcg_temp_new_i32();
1910
tcg_gen_mov_i32(tmp2, tmp);
1911
switch ((insn >> 22) & 3) {
1913
for (i = 0; i < 7; i ++) {
1914
tcg_gen_shli_i32(tmp2, tmp2, 4);
1915
tcg_gen_and_i32(tmp, tmp, tmp2);
1919
for (i = 0; i < 3; i ++) {
1920
tcg_gen_shli_i32(tmp2, tmp2, 8);
1921
tcg_gen_and_i32(tmp, tmp, tmp2);
1925
tcg_gen_shli_i32(tmp2, tmp2, 16);
1926
tcg_gen_and_i32(tmp, tmp, tmp2);
1930
tcg_temp_free_i32(tmp2);
1931
tcg_temp_free_i32(tmp);
1933
case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1934
wrd = (insn >> 12) & 0xf;
1935
rd0 = (insn >> 16) & 0xf;
1936
gen_op_iwmmxt_movq_M0_wRn(rd0);
1937
switch ((insn >> 22) & 3) {
1939
gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
1942
gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
1945
gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
1950
gen_op_iwmmxt_movq_wRn_M0(wrd);
1951
gen_op_iwmmxt_set_mup();
1953
case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1954
if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1956
tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1957
tmp2 = tcg_temp_new_i32();
1958
tcg_gen_mov_i32(tmp2, tmp);
1959
switch ((insn >> 22) & 3) {
1961
for (i = 0; i < 7; i ++) {
1962
tcg_gen_shli_i32(tmp2, tmp2, 4);
1963
tcg_gen_or_i32(tmp, tmp, tmp2);
1967
for (i = 0; i < 3; i ++) {
1968
tcg_gen_shli_i32(tmp2, tmp2, 8);
1969
tcg_gen_or_i32(tmp, tmp, tmp2);
1973
tcg_gen_shli_i32(tmp2, tmp2, 16);
1974
tcg_gen_or_i32(tmp, tmp, tmp2);
1978
tcg_temp_free_i32(tmp2);
1979
tcg_temp_free_i32(tmp);
1981
case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1982
rd = (insn >> 12) & 0xf;
1983
rd0 = (insn >> 16) & 0xf;
1984
if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
1986
gen_op_iwmmxt_movq_M0_wRn(rd0);
1987
tmp = tcg_temp_new_i32();
1988
switch ((insn >> 22) & 3) {
1990
gen_helper_iwmmxt_msbb(tmp, cpu_M0);
1993
gen_helper_iwmmxt_msbw(tmp, cpu_M0);
1996
gen_helper_iwmmxt_msbl(tmp, cpu_M0);
1999
store_reg(s, rd, tmp);
2001
case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2002
case 0x906: case 0xb06: case 0xd06: case 0xf06:
2003
wrd = (insn >> 12) & 0xf;
2004
rd0 = (insn >> 16) & 0xf;
2005
rd1 = (insn >> 0) & 0xf;
2006
gen_op_iwmmxt_movq_M0_wRn(rd0);
2007
switch ((insn >> 22) & 3) {
2009
if (insn & (1 << 21))
2010
gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2012
gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2015
if (insn & (1 << 21))
2016
gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2018
gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2021
if (insn & (1 << 21))
2022
gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2024
gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2029
gen_op_iwmmxt_movq_wRn_M0(wrd);
2030
gen_op_iwmmxt_set_mup();
2031
gen_op_iwmmxt_set_cup();
2033
case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2034
case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2035
wrd = (insn >> 12) & 0xf;
2036
rd0 = (insn >> 16) & 0xf;
2037
gen_op_iwmmxt_movq_M0_wRn(rd0);
2038
switch ((insn >> 22) & 3) {
2040
if (insn & (1 << 21))
2041
gen_op_iwmmxt_unpacklsb_M0();
2043
gen_op_iwmmxt_unpacklub_M0();
2046
if (insn & (1 << 21))
2047
gen_op_iwmmxt_unpacklsw_M0();
2049
gen_op_iwmmxt_unpackluw_M0();
2052
if (insn & (1 << 21))
2053
gen_op_iwmmxt_unpacklsl_M0();
2055
gen_op_iwmmxt_unpacklul_M0();
2060
gen_op_iwmmxt_movq_wRn_M0(wrd);
2061
gen_op_iwmmxt_set_mup();
2062
gen_op_iwmmxt_set_cup();
2064
case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2065
case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2066
wrd = (insn >> 12) & 0xf;
2067
rd0 = (insn >> 16) & 0xf;
2068
gen_op_iwmmxt_movq_M0_wRn(rd0);
2069
switch ((insn >> 22) & 3) {
2071
if (insn & (1 << 21))
2072
gen_op_iwmmxt_unpackhsb_M0();
2074
gen_op_iwmmxt_unpackhub_M0();
2077
if (insn & (1 << 21))
2078
gen_op_iwmmxt_unpackhsw_M0();
2080
gen_op_iwmmxt_unpackhuw_M0();
2083
if (insn & (1 << 21))
2084
gen_op_iwmmxt_unpackhsl_M0();
2086
gen_op_iwmmxt_unpackhul_M0();
2091
gen_op_iwmmxt_movq_wRn_M0(wrd);
2092
gen_op_iwmmxt_set_mup();
2093
gen_op_iwmmxt_set_cup();
2095
case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2096
case 0x214: case 0x614: case 0xa14: case 0xe14:
2097
if (((insn >> 22) & 3) == 0)
2099
wrd = (insn >> 12) & 0xf;
2100
rd0 = (insn >> 16) & 0xf;
2101
gen_op_iwmmxt_movq_M0_wRn(rd0);
2102
tmp = tcg_temp_new_i32();
2103
if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2104
tcg_temp_free_i32(tmp);
2107
switch ((insn >> 22) & 3) {
2109
gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2112
gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2115
gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2118
tcg_temp_free_i32(tmp);
2119
gen_op_iwmmxt_movq_wRn_M0(wrd);
2120
gen_op_iwmmxt_set_mup();
2121
gen_op_iwmmxt_set_cup();
2123
case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2124
case 0x014: case 0x414: case 0x814: case 0xc14:
2125
if (((insn >> 22) & 3) == 0)
2127
wrd = (insn >> 12) & 0xf;
2128
rd0 = (insn >> 16) & 0xf;
2129
gen_op_iwmmxt_movq_M0_wRn(rd0);
2130
tmp = tcg_temp_new_i32();
2131
if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2132
tcg_temp_free_i32(tmp);
2135
switch ((insn >> 22) & 3) {
2137
gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2140
gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2143
gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2146
tcg_temp_free_i32(tmp);
2147
gen_op_iwmmxt_movq_wRn_M0(wrd);
2148
gen_op_iwmmxt_set_mup();
2149
gen_op_iwmmxt_set_cup();
2151
case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2152
case 0x114: case 0x514: case 0x914: case 0xd14:
2153
if (((insn >> 22) & 3) == 0)
2155
wrd = (insn >> 12) & 0xf;
2156
rd0 = (insn >> 16) & 0xf;
2157
gen_op_iwmmxt_movq_M0_wRn(rd0);
2158
tmp = tcg_temp_new_i32();
2159
if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2160
tcg_temp_free_i32(tmp);
2163
switch ((insn >> 22) & 3) {
2165
gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2168
gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2171
gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2174
tcg_temp_free_i32(tmp);
2175
gen_op_iwmmxt_movq_wRn_M0(wrd);
2176
gen_op_iwmmxt_set_mup();
2177
gen_op_iwmmxt_set_cup();
2179
case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2180
case 0x314: case 0x714: case 0xb14: case 0xf14:
2181
if (((insn >> 22) & 3) == 0)
2183
wrd = (insn >> 12) & 0xf;
2184
rd0 = (insn >> 16) & 0xf;
2185
gen_op_iwmmxt_movq_M0_wRn(rd0);
2186
tmp = tcg_temp_new_i32();
2187
switch ((insn >> 22) & 3) {
2189
if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2190
tcg_temp_free_i32(tmp);
2193
gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2196
if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2197
tcg_temp_free_i32(tmp);
2200
gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2203
if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2204
tcg_temp_free_i32(tmp);
2207
gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2210
tcg_temp_free_i32(tmp);
2211
gen_op_iwmmxt_movq_wRn_M0(wrd);
2212
gen_op_iwmmxt_set_mup();
2213
gen_op_iwmmxt_set_cup();
2215
case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2216
case 0x916: case 0xb16: case 0xd16: case 0xf16:
2217
wrd = (insn >> 12) & 0xf;
2218
rd0 = (insn >> 16) & 0xf;
2219
rd1 = (insn >> 0) & 0xf;
2220
gen_op_iwmmxt_movq_M0_wRn(rd0);
2221
switch ((insn >> 22) & 3) {
2223
if (insn & (1 << 21))
2224
gen_op_iwmmxt_minsb_M0_wRn(rd1);
2226
gen_op_iwmmxt_minub_M0_wRn(rd1);
2229
if (insn & (1 << 21))
2230
gen_op_iwmmxt_minsw_M0_wRn(rd1);
2232
gen_op_iwmmxt_minuw_M0_wRn(rd1);
2235
if (insn & (1 << 21))
2236
gen_op_iwmmxt_minsl_M0_wRn(rd1);
2238
gen_op_iwmmxt_minul_M0_wRn(rd1);
2243
gen_op_iwmmxt_movq_wRn_M0(wrd);
2244
gen_op_iwmmxt_set_mup();
2246
case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2247
case 0x816: case 0xa16: case 0xc16: case 0xe16:
2248
wrd = (insn >> 12) & 0xf;
2249
rd0 = (insn >> 16) & 0xf;
2250
rd1 = (insn >> 0) & 0xf;
2251
gen_op_iwmmxt_movq_M0_wRn(rd0);
2252
switch ((insn >> 22) & 3) {
2254
if (insn & (1 << 21))
2255
gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2257
gen_op_iwmmxt_maxub_M0_wRn(rd1);
2260
if (insn & (1 << 21))
2261
gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2263
gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2266
if (insn & (1 << 21))
2267
gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2269
gen_op_iwmmxt_maxul_M0_wRn(rd1);
2274
gen_op_iwmmxt_movq_wRn_M0(wrd);
2275
gen_op_iwmmxt_set_mup();
2277
case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2278
case 0x402: case 0x502: case 0x602: case 0x702:
2279
wrd = (insn >> 12) & 0xf;
2280
rd0 = (insn >> 16) & 0xf;
2281
rd1 = (insn >> 0) & 0xf;
2282
gen_op_iwmmxt_movq_M0_wRn(rd0);
2283
tmp = tcg_const_i32((insn >> 20) & 3);
2284
iwmmxt_load_reg(cpu_V1, rd1);
2285
gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2286
tcg_temp_free_i32(tmp);
2287
gen_op_iwmmxt_movq_wRn_M0(wrd);
2288
gen_op_iwmmxt_set_mup();
2290
case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2291
case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2292
case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2293
case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2294
wrd = (insn >> 12) & 0xf;
2295
rd0 = (insn >> 16) & 0xf;
2296
rd1 = (insn >> 0) & 0xf;
2297
gen_op_iwmmxt_movq_M0_wRn(rd0);
2298
switch ((insn >> 20) & 0xf) {
2300
gen_op_iwmmxt_subnb_M0_wRn(rd1);
2303
gen_op_iwmmxt_subub_M0_wRn(rd1);
2306
gen_op_iwmmxt_subsb_M0_wRn(rd1);
2309
gen_op_iwmmxt_subnw_M0_wRn(rd1);
2312
gen_op_iwmmxt_subuw_M0_wRn(rd1);
2315
gen_op_iwmmxt_subsw_M0_wRn(rd1);
2318
gen_op_iwmmxt_subnl_M0_wRn(rd1);
2321
gen_op_iwmmxt_subul_M0_wRn(rd1);
2324
gen_op_iwmmxt_subsl_M0_wRn(rd1);
2329
gen_op_iwmmxt_movq_wRn_M0(wrd);
2330
gen_op_iwmmxt_set_mup();
2331
gen_op_iwmmxt_set_cup();
2333
case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2334
case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2335
case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2336
case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2337
wrd = (insn >> 12) & 0xf;
2338
rd0 = (insn >> 16) & 0xf;
2339
gen_op_iwmmxt_movq_M0_wRn(rd0);
2340
tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2341
gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2342
tcg_temp_free_i32(tmp);
2343
gen_op_iwmmxt_movq_wRn_M0(wrd);
2344
gen_op_iwmmxt_set_mup();
2345
gen_op_iwmmxt_set_cup();
2347
case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2348
case 0x418: case 0x518: case 0x618: case 0x718:
2349
case 0x818: case 0x918: case 0xa18: case 0xb18:
2350
case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2351
wrd = (insn >> 12) & 0xf;
2352
rd0 = (insn >> 16) & 0xf;
2353
rd1 = (insn >> 0) & 0xf;
2354
gen_op_iwmmxt_movq_M0_wRn(rd0);
2355
switch ((insn >> 20) & 0xf) {
2357
gen_op_iwmmxt_addnb_M0_wRn(rd1);
2360
gen_op_iwmmxt_addub_M0_wRn(rd1);
2363
gen_op_iwmmxt_addsb_M0_wRn(rd1);
2366
gen_op_iwmmxt_addnw_M0_wRn(rd1);
2369
gen_op_iwmmxt_adduw_M0_wRn(rd1);
2372
gen_op_iwmmxt_addsw_M0_wRn(rd1);
2375
gen_op_iwmmxt_addnl_M0_wRn(rd1);
2378
gen_op_iwmmxt_addul_M0_wRn(rd1);
2381
gen_op_iwmmxt_addsl_M0_wRn(rd1);
2386
gen_op_iwmmxt_movq_wRn_M0(wrd);
2387
gen_op_iwmmxt_set_mup();
2388
gen_op_iwmmxt_set_cup();
2390
case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2391
case 0x408: case 0x508: case 0x608: case 0x708:
2392
case 0x808: case 0x908: case 0xa08: case 0xb08:
2393
case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2394
if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2396
wrd = (insn >> 12) & 0xf;
2397
rd0 = (insn >> 16) & 0xf;
2398
rd1 = (insn >> 0) & 0xf;
2399
gen_op_iwmmxt_movq_M0_wRn(rd0);
2400
switch ((insn >> 22) & 3) {
2402
if (insn & (1 << 21))
2403
gen_op_iwmmxt_packsw_M0_wRn(rd1);
2405
gen_op_iwmmxt_packuw_M0_wRn(rd1);
2408
if (insn & (1 << 21))
2409
gen_op_iwmmxt_packsl_M0_wRn(rd1);
2411
gen_op_iwmmxt_packul_M0_wRn(rd1);
2414
if (insn & (1 << 21))
2415
gen_op_iwmmxt_packsq_M0_wRn(rd1);
2417
gen_op_iwmmxt_packuq_M0_wRn(rd1);
2420
gen_op_iwmmxt_movq_wRn_M0(wrd);
2421
gen_op_iwmmxt_set_mup();
2422
gen_op_iwmmxt_set_cup();
2424
case 0x201: case 0x203: case 0x205: case 0x207:
2425
case 0x209: case 0x20b: case 0x20d: case 0x20f:
2426
case 0x211: case 0x213: case 0x215: case 0x217:
2427
case 0x219: case 0x21b: case 0x21d: case 0x21f:
2428
wrd = (insn >> 5) & 0xf;
2429
rd0 = (insn >> 12) & 0xf;
2430
rd1 = (insn >> 0) & 0xf;
2431
if (rd0 == 0xf || rd1 == 0xf)
2433
gen_op_iwmmxt_movq_M0_wRn(wrd);
2434
tmp = load_reg(s, rd0);
2435
tmp2 = load_reg(s, rd1);
2436
switch ((insn >> 16) & 0xf) {
2437
case 0x0: /* TMIA */
2438
gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2440
case 0x8: /* TMIAPH */
2441
gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2443
case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2444
if (insn & (1 << 16))
2445
tcg_gen_shri_i32(tmp, tmp, 16);
2446
if (insn & (1 << 17))
2447
tcg_gen_shri_i32(tmp2, tmp2, 16);
2448
gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2451
tcg_temp_free_i32(tmp2);
2452
tcg_temp_free_i32(tmp);
2455
tcg_temp_free_i32(tmp2);
2456
tcg_temp_free_i32(tmp);
2457
gen_op_iwmmxt_movq_wRn_M0(wrd);
2458
gen_op_iwmmxt_set_mup();
2467
/* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2468
(ie. an undefined instruction). */
2469
static int disas_dsp_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
2471
int acc, rd0, rd1, rdhi, rdlo;
2474
if ((insn & 0x0ff00f10) == 0x0e200010) {
2475
/* Multiply with Internal Accumulate Format */
2476
rd0 = (insn >> 12) & 0xf;
2478
acc = (insn >> 5) & 7;
2483
tmp = load_reg(s, rd0);
2484
tmp2 = load_reg(s, rd1);
2485
switch ((insn >> 16) & 0xf) {
2487
gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2489
case 0x8: /* MIAPH */
2490
gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2492
case 0xc: /* MIABB */
2493
case 0xd: /* MIABT */
2494
case 0xe: /* MIATB */
2495
case 0xf: /* MIATT */
2496
if (insn & (1 << 16))
2497
tcg_gen_shri_i32(tmp, tmp, 16);
2498
if (insn & (1 << 17))
2499
tcg_gen_shri_i32(tmp2, tmp2, 16);
2500
gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2505
tcg_temp_free_i32(tmp2);
2506
tcg_temp_free_i32(tmp);
2508
gen_op_iwmmxt_movq_wRn_M0(acc);
2512
if ((insn & 0x0fe00ff8) == 0x0c400000) {
2513
/* Internal Accumulator Access Format */
2514
rdhi = (insn >> 16) & 0xf;
2515
rdlo = (insn >> 12) & 0xf;
2521
if (insn & ARM_CP_RW_BIT) { /* MRA */
2522
iwmmxt_load_reg(cpu_V0, acc);
2523
tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
2524
tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2525
tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
2526
tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2528
tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2529
iwmmxt_store_reg(cpu_V0, acc);
2537
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2538
#define VFP_SREG(insn, bigbit, smallbit) \
2539
((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2540
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2541
if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2542
reg = (((insn) >> (bigbit)) & 0x0f) \
2543
| (((insn) >> ((smallbit) - 4)) & 0x10); \
2545
if (insn & (1 << (smallbit))) \
2547
reg = ((insn) >> (bigbit)) & 0x0f; \
2550
#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2551
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2552
#define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2553
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2554
#define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2555
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2557
/* Move between integer and VFP cores. */
2558
static TCGv_i32 gen_vfp_mrs(void)
2560
TCGv_i32 tmp = tcg_temp_new_i32();
2561
tcg_gen_mov_i32(tmp, cpu_F0s);
2565
static void gen_vfp_msr(TCGv_i32 tmp)
2567
tcg_gen_mov_i32(cpu_F0s, tmp);
2568
tcg_temp_free_i32(tmp);
2571
static void gen_neon_dup_u8(TCGv_i32 var, int shift)
2573
TCGv_i32 tmp = tcg_temp_new_i32();
2575
tcg_gen_shri_i32(var, var, shift);
2576
tcg_gen_ext8u_i32(var, var);
2577
tcg_gen_shli_i32(tmp, var, 8);
2578
tcg_gen_or_i32(var, var, tmp);
2579
tcg_gen_shli_i32(tmp, var, 16);
2580
tcg_gen_or_i32(var, var, tmp);
2581
tcg_temp_free_i32(tmp);
2584
static void gen_neon_dup_low16(TCGv_i32 var)
2586
TCGv_i32 tmp = tcg_temp_new_i32();
2587
tcg_gen_ext16u_i32(var, var);
2588
tcg_gen_shli_i32(tmp, var, 16);
2589
tcg_gen_or_i32(var, var, tmp);
2590
tcg_temp_free_i32(tmp);
2593
static void gen_neon_dup_high16(TCGv_i32 var)
2595
TCGv_i32 tmp = tcg_temp_new_i32();
2596
tcg_gen_andi_i32(var, var, 0xffff0000);
2597
tcg_gen_shri_i32(tmp, var, 16);
2598
tcg_gen_or_i32(var, var, tmp);
2599
tcg_temp_free_i32(tmp);
2602
static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
2604
/* Load a single Neon element and replicate into a 32 bit TCG reg */
2605
TCGv_i32 tmp = tcg_temp_new_i32();
2608
gen_aa32_ld8u(tmp, addr, IS_USER(s));
2609
gen_neon_dup_u8(tmp, 0);
2612
gen_aa32_ld16u(tmp, addr, IS_USER(s));
2613
gen_neon_dup_low16(tmp);
2616
gen_aa32_ld32u(tmp, addr, IS_USER(s));
2618
default: /* Avoid compiler warnings. */
2624
/* Disassemble a VFP instruction. Returns nonzero if an error occurred
2625
(ie. an undefined instruction). */
2626
static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
2628
uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2634
if (!arm_feature(env, ARM_FEATURE_VFP))
2637
if (!s->vfp_enabled) {
2638
/* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2639
if ((insn & 0x0fe00fff) != 0x0ee00a10)
2641
rn = (insn >> 16) & 0xf;
2642
if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2643
&& rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2647
if (extract32(insn, 28, 4) == 0xf) {
2648
/* Encodings with T=1 (Thumb) or unconditional (ARM):
2649
* only used in v8 and above.
2654
dp = ((insn & 0xf00) == 0xb00);
2655
switch ((insn >> 24) & 0xf) {
2657
if (insn & (1 << 4)) {
2658
/* single register transfer */
2659
rd = (insn >> 12) & 0xf;
2664
VFP_DREG_N(rn, insn);
2667
if (insn & 0x00c00060
2668
&& !arm_feature(env, ARM_FEATURE_NEON))
2671
pass = (insn >> 21) & 1;
2672
if (insn & (1 << 22)) {
2674
offset = ((insn >> 5) & 3) * 8;
2675
} else if (insn & (1 << 5)) {
2677
offset = (insn & (1 << 6)) ? 16 : 0;
2682
if (insn & ARM_CP_RW_BIT) {
2684
tmp = neon_load_reg(rn, pass);
2688
tcg_gen_shri_i32(tmp, tmp, offset);
2689
if (insn & (1 << 23))
2695
if (insn & (1 << 23)) {
2697
tcg_gen_shri_i32(tmp, tmp, 16);
2703
tcg_gen_sari_i32(tmp, tmp, 16);
2712
store_reg(s, rd, tmp);
2715
tmp = load_reg(s, rd);
2716
if (insn & (1 << 23)) {
2719
gen_neon_dup_u8(tmp, 0);
2720
} else if (size == 1) {
2721
gen_neon_dup_low16(tmp);
2723
for (n = 0; n <= pass * 2; n++) {
2724
tmp2 = tcg_temp_new_i32();
2725
tcg_gen_mov_i32(tmp2, tmp);
2726
neon_store_reg(rn, n, tmp2);
2728
neon_store_reg(rn, n, tmp);
2733
tmp2 = neon_load_reg(rn, pass);
2734
tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
2735
tcg_temp_free_i32(tmp2);
2738
tmp2 = neon_load_reg(rn, pass);
2739
tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
2740
tcg_temp_free_i32(tmp2);
2745
neon_store_reg(rn, pass, tmp);
2749
if ((insn & 0x6f) != 0x00)
2751
rn = VFP_SREG_N(insn);
2752
if (insn & ARM_CP_RW_BIT) {
2754
if (insn & (1 << 21)) {
2755
/* system register */
2760
/* VFP2 allows access to FSID from userspace.
2761
VFP3 restricts all id registers to privileged
2764
&& arm_feature(env, ARM_FEATURE_VFP3))
2766
tmp = load_cpu_field(vfp.xregs[rn]);
2771
tmp = load_cpu_field(vfp.xregs[rn]);
2773
case ARM_VFP_FPINST:
2774
case ARM_VFP_FPINST2:
2775
/* Not present in VFP3. */
2777
|| arm_feature(env, ARM_FEATURE_VFP3))
2779
tmp = load_cpu_field(vfp.xregs[rn]);
2783
tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
2784
tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
2786
tmp = tcg_temp_new_i32();
2787
gen_helper_vfp_get_fpscr(tmp, cpu_env);
2793
|| !arm_feature(env, ARM_FEATURE_MVFR))
2795
tmp = load_cpu_field(vfp.xregs[rn]);
2801
gen_mov_F0_vreg(0, rn);
2802
tmp = gen_vfp_mrs();
2805
/* Set the 4 flag bits in the CPSR. */
2807
tcg_temp_free_i32(tmp);
2809
store_reg(s, rd, tmp);
2813
if (insn & (1 << 21)) {
2815
/* system register */
2820
/* Writes are ignored. */
2823
tmp = load_reg(s, rd);
2824
gen_helper_vfp_set_fpscr(cpu_env, tmp);
2825
tcg_temp_free_i32(tmp);
2831
/* TODO: VFP subarchitecture support.
2832
* For now, keep the EN bit only */
2833
tmp = load_reg(s, rd);
2834
tcg_gen_andi_i32(tmp, tmp, 1 << 30);
2835
store_cpu_field(tmp, vfp.xregs[rn]);
2838
case ARM_VFP_FPINST:
2839
case ARM_VFP_FPINST2:
2840
tmp = load_reg(s, rd);
2841
store_cpu_field(tmp, vfp.xregs[rn]);
2847
tmp = load_reg(s, rd);
2849
gen_mov_vreg_F0(0, rn);
2854
/* data processing */
2855
/* The opcode is in bits 23, 21, 20 and 6. */
2856
op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
2860
rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
2862
/* rn is register number */
2863
VFP_DREG_N(rn, insn);
2866
if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18))) {
2867
/* Integer or single precision destination. */
2868
rd = VFP_SREG_D(insn);
2870
VFP_DREG_D(rd, insn);
2873
(((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14))) {
2874
/* VCVT from int is always from S reg regardless of dp bit.
2875
* VCVT with immediate frac_bits has same format as SREG_M
2877
rm = VFP_SREG_M(insn);
2879
VFP_DREG_M(rm, insn);
2882
rn = VFP_SREG_N(insn);
2883
if (op == 15 && rn == 15) {
2884
/* Double precision destination. */
2885
VFP_DREG_D(rd, insn);
2887
rd = VFP_SREG_D(insn);
2889
/* NB that we implicitly rely on the encoding for the frac_bits
2890
* in VCVT of fixed to float being the same as that of an SREG_M
2892
rm = VFP_SREG_M(insn);
2895
veclen = s->vec_len;
2896
if (op == 15 && rn > 3)
2899
/* Shut up compiler warnings. */
2910
/* Figure out what type of vector operation this is. */
2911
if ((rd & bank_mask) == 0) {
2916
delta_d = (s->vec_stride >> 1) + 1;
2918
delta_d = s->vec_stride + 1;
2920
if ((rm & bank_mask) == 0) {
2921
/* mixed scalar/vector */
2930
/* Load the initial operands. */
2935
/* Integer source */
2936
gen_mov_F0_vreg(0, rm);
2941
gen_mov_F0_vreg(dp, rd);
2942
gen_mov_F1_vreg(dp, rm);
2946
/* Compare with zero */
2947
gen_mov_F0_vreg(dp, rd);
2958
/* Source and destination the same. */
2959
gen_mov_F0_vreg(dp, rd);
2965
/* VCVTB, VCVTT: only present with the halfprec extension,
2966
* UNPREDICTABLE if bit 8 is set (we choose to UNDEF)
2968
if (dp || !arm_feature(env, ARM_FEATURE_VFP_FP16)) {
2971
/* Otherwise fall through */
2973
/* One source operand. */
2974
gen_mov_F0_vreg(dp, rm);
2978
/* Two source operands. */
2979
gen_mov_F0_vreg(dp, rn);
2980
gen_mov_F1_vreg(dp, rm);
2984
/* Perform the calculation. */
2986
case 0: /* VMLA: fd + (fn * fm) */
2987
/* Note that order of inputs to the add matters for NaNs */
2989
gen_mov_F0_vreg(dp, rd);
2992
case 1: /* VMLS: fd + -(fn * fm) */
2995
gen_mov_F0_vreg(dp, rd);
2998
case 2: /* VNMLS: -fd + (fn * fm) */
2999
/* Note that it isn't valid to replace (-A + B) with (B - A)
3000
* or similar plausible looking simplifications
3001
* because this will give wrong results for NaNs.
3004
gen_mov_F0_vreg(dp, rd);
3008
case 3: /* VNMLA: -fd + -(fn * fm) */
3011
gen_mov_F0_vreg(dp, rd);
3015
case 4: /* mul: fn * fm */
3018
case 5: /* nmul: -(fn * fm) */
3022
case 6: /* add: fn + fm */
3025
case 7: /* sub: fn - fm */
3028
case 8: /* div: fn / fm */
3031
case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3032
case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3033
case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3034
case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3035
/* These are fused multiply-add, and must be done as one
3036
* floating point operation with no rounding between the
3037
* multiplication and addition steps.
3038
* NB that doing the negations here as separate steps is
3039
* correct : an input NaN should come out with its sign bit
3040
* flipped if it is a negated-input.
3042
if (!arm_feature(env, ARM_FEATURE_VFP4)) {
3050
gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3052
frd = tcg_temp_new_i64();
3053
tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3056
gen_helper_vfp_negd(frd, frd);
3058
fpst = get_fpstatus_ptr(0);
3059
gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3060
cpu_F1d, frd, fpst);
3061
tcg_temp_free_ptr(fpst);
3062
tcg_temp_free_i64(frd);
3068
gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3070
frd = tcg_temp_new_i32();
3071
tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3073
gen_helper_vfp_negs(frd, frd);
3075
fpst = get_fpstatus_ptr(0);
3076
gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3077
cpu_F1s, frd, fpst);
3078
tcg_temp_free_ptr(fpst);
3079
tcg_temp_free_i32(frd);
3082
case 14: /* fconst */
3083
if (!arm_feature(env, ARM_FEATURE_VFP3))
3086
n = (insn << 12) & 0x80000000;
3087
i = ((insn >> 12) & 0x70) | (insn & 0xf);
3094
tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3101
tcg_gen_movi_i32(cpu_F0s, n);
3104
case 15: /* extension space */
3118
case 4: /* vcvtb.f32.f16 */
3119
tmp = gen_vfp_mrs();
3120
tcg_gen_ext16u_i32(tmp, tmp);
3121
gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3122
tcg_temp_free_i32(tmp);
3124
case 5: /* vcvtt.f32.f16 */
3125
tmp = gen_vfp_mrs();
3126
tcg_gen_shri_i32(tmp, tmp, 16);
3127
gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3128
tcg_temp_free_i32(tmp);
3130
case 6: /* vcvtb.f16.f32 */
3131
tmp = tcg_temp_new_i32();
3132
gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3133
gen_mov_F0_vreg(0, rd);
3134
tmp2 = gen_vfp_mrs();
3135
tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3136
tcg_gen_or_i32(tmp, tmp, tmp2);
3137
tcg_temp_free_i32(tmp2);
3140
case 7: /* vcvtt.f16.f32 */
3141
tmp = tcg_temp_new_i32();
3142
gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3143
tcg_gen_shli_i32(tmp, tmp, 16);
3144
gen_mov_F0_vreg(0, rd);
3145
tmp2 = gen_vfp_mrs();
3146
tcg_gen_ext16u_i32(tmp2, tmp2);
3147
tcg_gen_or_i32(tmp, tmp, tmp2);
3148
tcg_temp_free_i32(tmp2);
3160
case 11: /* cmpez */
3164
case 15: /* single<->double conversion */
3166
gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3168
gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3170
case 16: /* fuito */
3171
gen_vfp_uito(dp, 0);
3173
case 17: /* fsito */
3174
gen_vfp_sito(dp, 0);
3176
case 20: /* fshto */
3177
if (!arm_feature(env, ARM_FEATURE_VFP3))
3179
gen_vfp_shto(dp, 16 - rm, 0);
3181
case 21: /* fslto */
3182
if (!arm_feature(env, ARM_FEATURE_VFP3))
3184
gen_vfp_slto(dp, 32 - rm, 0);
3186
case 22: /* fuhto */
3187
if (!arm_feature(env, ARM_FEATURE_VFP3))
3189
gen_vfp_uhto(dp, 16 - rm, 0);
3191
case 23: /* fulto */
3192
if (!arm_feature(env, ARM_FEATURE_VFP3))
3194
gen_vfp_ulto(dp, 32 - rm, 0);
3196
case 24: /* ftoui */
3197
gen_vfp_toui(dp, 0);
3199
case 25: /* ftouiz */
3200
gen_vfp_touiz(dp, 0);
3202
case 26: /* ftosi */
3203
gen_vfp_tosi(dp, 0);
3205
case 27: /* ftosiz */
3206
gen_vfp_tosiz(dp, 0);
3208
case 28: /* ftosh */
3209
if (!arm_feature(env, ARM_FEATURE_VFP3))
3211
gen_vfp_tosh(dp, 16 - rm, 0);
3213
case 29: /* ftosl */
3214
if (!arm_feature(env, ARM_FEATURE_VFP3))
3216
gen_vfp_tosl(dp, 32 - rm, 0);
3218
case 30: /* ftouh */
3219
if (!arm_feature(env, ARM_FEATURE_VFP3))
3221
gen_vfp_touh(dp, 16 - rm, 0);
3223
case 31: /* ftoul */
3224
if (!arm_feature(env, ARM_FEATURE_VFP3))
3226
gen_vfp_toul(dp, 32 - rm, 0);
3228
default: /* undefined */
3232
default: /* undefined */
3236
/* Write back the result. */
3237
if (op == 15 && (rn >= 8 && rn <= 11))
3238
; /* Comparison, do nothing. */
3239
else if (op == 15 && dp && ((rn & 0x1c) == 0x18))
3240
/* VCVT double to int: always integer result. */
3241
gen_mov_vreg_F0(0, rd);
3242
else if (op == 15 && rn == 15)
3244
gen_mov_vreg_F0(!dp, rd);
3246
gen_mov_vreg_F0(dp, rd);
3248
/* break out of the loop if we have finished */
3252
if (op == 15 && delta_m == 0) {
3253
/* single source one-many */
3255
rd = ((rd + delta_d) & (bank_mask - 1))
3257
gen_mov_vreg_F0(dp, rd);
3261
/* Setup the next operands. */
3263
rd = ((rd + delta_d) & (bank_mask - 1))
3267
/* One source operand. */
3268
rm = ((rm + delta_m) & (bank_mask - 1))
3270
gen_mov_F0_vreg(dp, rm);
3272
/* Two source operands. */
3273
rn = ((rn + delta_d) & (bank_mask - 1))
3275
gen_mov_F0_vreg(dp, rn);
3277
rm = ((rm + delta_m) & (bank_mask - 1))
3279
gen_mov_F1_vreg(dp, rm);
3287
if ((insn & 0x03e00000) == 0x00400000) {
3288
/* two-register transfer */
3289
rn = (insn >> 16) & 0xf;
3290
rd = (insn >> 12) & 0xf;
3292
VFP_DREG_M(rm, insn);
3294
rm = VFP_SREG_M(insn);
3297
if (insn & ARM_CP_RW_BIT) {
3300
gen_mov_F0_vreg(0, rm * 2);
3301
tmp = gen_vfp_mrs();
3302
store_reg(s, rd, tmp);
3303
gen_mov_F0_vreg(0, rm * 2 + 1);
3304
tmp = gen_vfp_mrs();
3305
store_reg(s, rn, tmp);
3307
gen_mov_F0_vreg(0, rm);
3308
tmp = gen_vfp_mrs();
3309
store_reg(s, rd, tmp);
3310
gen_mov_F0_vreg(0, rm + 1);
3311
tmp = gen_vfp_mrs();
3312
store_reg(s, rn, tmp);
3317
tmp = load_reg(s, rd);
3319
gen_mov_vreg_F0(0, rm * 2);
3320
tmp = load_reg(s, rn);
3322
gen_mov_vreg_F0(0, rm * 2 + 1);
3324
tmp = load_reg(s, rd);
3326
gen_mov_vreg_F0(0, rm);
3327
tmp = load_reg(s, rn);
3329
gen_mov_vreg_F0(0, rm + 1);
3334
rn = (insn >> 16) & 0xf;
3336
VFP_DREG_D(rd, insn);
3338
rd = VFP_SREG_D(insn);
3339
if ((insn & 0x01200000) == 0x01000000) {
3340
/* Single load/store */
3341
offset = (insn & 0xff) << 2;
3342
if ((insn & (1 << 23)) == 0)
3344
if (s->thumb && rn == 15) {
3345
/* This is actually UNPREDICTABLE */
3346
addr = tcg_temp_new_i32();
3347
tcg_gen_movi_i32(addr, s->pc & ~2);
3349
addr = load_reg(s, rn);
3351
tcg_gen_addi_i32(addr, addr, offset);
3352
if (insn & (1 << 20)) {
3353
gen_vfp_ld(s, dp, addr);
3354
gen_mov_vreg_F0(dp, rd);
3356
gen_mov_F0_vreg(dp, rd);
3357
gen_vfp_st(s, dp, addr);
3359
tcg_temp_free_i32(addr);
3361
/* load/store multiple */
3362
int w = insn & (1 << 21);
3364
n = (insn >> 1) & 0x7f;
3368
if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
3369
/* P == U , W == 1 => UNDEF */
3372
if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
3373
/* UNPREDICTABLE cases for bad immediates: we choose to
3374
* UNDEF to avoid generating huge numbers of TCG ops
3378
if (rn == 15 && w) {
3379
/* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3383
if (s->thumb && rn == 15) {
3384
/* This is actually UNPREDICTABLE */
3385
addr = tcg_temp_new_i32();
3386
tcg_gen_movi_i32(addr, s->pc & ~2);
3388
addr = load_reg(s, rn);
3390
if (insn & (1 << 24)) /* pre-decrement */
3391
tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3397
for (i = 0; i < n; i++) {
3398
if (insn & ARM_CP_RW_BIT) {
3400
gen_vfp_ld(s, dp, addr);
3401
gen_mov_vreg_F0(dp, rd + i);
3404
gen_mov_F0_vreg(dp, rd + i);
3405
gen_vfp_st(s, dp, addr);
3407
tcg_gen_addi_i32(addr, addr, offset);
3411
if (insn & (1 << 24))
3412
offset = -offset * n;
3413
else if (dp && (insn & 1))
3419
tcg_gen_addi_i32(addr, addr, offset);
3420
store_reg(s, rn, addr);
3422
tcg_temp_free_i32(addr);
3428
/* Should never happen. */
3434
static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
3436
TranslationBlock *tb;
3439
if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3441
gen_set_pc_im(s, dest);
3442
tcg_gen_exit_tb((uintptr_t)tb + n);
3444
gen_set_pc_im(s, dest);
3449
static inline void gen_jmp (DisasContext *s, uint32_t dest)
3451
if (unlikely(s->singlestep_enabled)) {
3452
/* An indirect jump so that we still trigger the debug exception. */
3457
gen_goto_tb(s, 0, dest);
3458
s->is_jmp = DISAS_TB_JUMP;
3462
static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
3465
tcg_gen_sari_i32(t0, t0, 16);
3469
tcg_gen_sari_i32(t1, t1, 16);
3472
tcg_gen_mul_i32(t0, t0, t1);
3475
/* Return the mask of PSR bits set by a MSR instruction. */
3476
static uint32_t msr_mask(CPUARMState *env, DisasContext *s, int flags, int spsr) {
3480
if (flags & (1 << 0))
3482
if (flags & (1 << 1))
3484
if (flags & (1 << 2))
3486
if (flags & (1 << 3))
3489
/* Mask out undefined bits. */
3490
mask &= ~CPSR_RESERVED;
3491
if (!arm_feature(env, ARM_FEATURE_V4T))
3493
if (!arm_feature(env, ARM_FEATURE_V5))
3494
mask &= ~CPSR_Q; /* V5TE in reality*/
3495
if (!arm_feature(env, ARM_FEATURE_V6))
3496
mask &= ~(CPSR_E | CPSR_GE);
3497
if (!arm_feature(env, ARM_FEATURE_THUMB2))
3499
/* Mask out execution state bits. */
3502
/* Mask out privileged bits. */
3508
/* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3509
static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
3513
/* ??? This is also undefined in system mode. */
3517
tmp = load_cpu_field(spsr);
3518
tcg_gen_andi_i32(tmp, tmp, ~mask);
3519
tcg_gen_andi_i32(t0, t0, mask);
3520
tcg_gen_or_i32(tmp, tmp, t0);
3521
store_cpu_field(tmp, spsr);
3523
gen_set_cpsr(t0, mask);
3525
tcg_temp_free_i32(t0);
3530
/* Returns nonzero if access to the PSR is not permitted. */
3531
static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3534
tmp = tcg_temp_new_i32();
3535
tcg_gen_movi_i32(tmp, val);
3536
return gen_set_psr(s, mask, spsr, tmp);
3539
/* Generate an old-style exception return. Marks pc as dead. */
3540
static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
3543
store_reg(s, 15, pc);
3544
tmp = load_cpu_field(spsr);
3545
gen_set_cpsr(tmp, 0xffffffff);
3546
tcg_temp_free_i32(tmp);
3547
s->is_jmp = DISAS_UPDATE;
3550
/* Generate a v6 exception return. Marks both values as dead. */
3551
static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
3553
gen_set_cpsr(cpsr, 0xffffffff);
3554
tcg_temp_free_i32(cpsr);
3555
store_reg(s, 15, pc);
3556
s->is_jmp = DISAS_UPDATE;
3560
gen_set_condexec (DisasContext *s)
3562
if (s->condexec_mask) {
3563
uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3564
TCGv_i32 tmp = tcg_temp_new_i32();
3565
tcg_gen_movi_i32(tmp, val);
3566
store_cpu_field(tmp, condexec_bits);
3570
static void gen_exception_insn(DisasContext *s, int offset, int excp)
3572
gen_set_condexec(s);
3573
gen_set_pc_im(s, s->pc - offset);
3574
gen_exception(excp);
3575
s->is_jmp = DISAS_JUMP;
3578
static void gen_nop_hint(DisasContext *s, int val)
3582
gen_set_pc_im(s, s->pc);
3583
s->is_jmp = DISAS_WFI;
3588
/* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3594
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3596
static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
3599
case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3600
case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3601
case 2: tcg_gen_add_i32(t0, t0, t1); break;
3606
static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
3609
case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3610
case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3611
case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3616
/* 32-bit pairwise ops end up the same as the elementwise versions. */
3617
#define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3618
#define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3619
#define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3620
#define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3622
#define GEN_NEON_INTEGER_OP_ENV(name) do { \
3623
switch ((size << 1) | u) { \
3625
gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3628
gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3631
gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3634
gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3637
gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3640
gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3642
default: return 1; \
3645
#define GEN_NEON_INTEGER_OP(name) do { \
3646
switch ((size << 1) | u) { \
3648
gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3651
gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3654
gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3657
gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3660
gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3663
gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3665
default: return 1; \
3668
static TCGv_i32 neon_load_scratch(int scratch)
3670
TCGv_i32 tmp = tcg_temp_new_i32();
3671
tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3675
static void neon_store_scratch(int scratch, TCGv_i32 var)
3677
tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3678
tcg_temp_free_i32(var);
3681
static inline TCGv_i32 neon_get_scalar(int size, int reg)
3685
tmp = neon_load_reg(reg & 7, reg >> 4);
3687
gen_neon_dup_high16(tmp);
3689
gen_neon_dup_low16(tmp);
3692
tmp = neon_load_reg(reg & 15, reg >> 4);
3697
static int gen_neon_unzip(int rd, int rm, int size, int q)
3700
if (!q && size == 2) {
3703
tmp = tcg_const_i32(rd);
3704
tmp2 = tcg_const_i32(rm);
3708
gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
3711
gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
3714
gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
3722
gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
3725
gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
3731
tcg_temp_free_i32(tmp);
3732
tcg_temp_free_i32(tmp2);
3736
static int gen_neon_zip(int rd, int rm, int size, int q)
3739
if (!q && size == 2) {
3742
tmp = tcg_const_i32(rd);
3743
tmp2 = tcg_const_i32(rm);
3747
gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
3750
gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
3753
gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
3761
gen_helper_neon_zip8(cpu_env, tmp, tmp2);
3764
gen_helper_neon_zip16(cpu_env, tmp, tmp2);
3770
tcg_temp_free_i32(tmp);
3771
tcg_temp_free_i32(tmp2);
3775
static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
3779
rd = tcg_temp_new_i32();
3780
tmp = tcg_temp_new_i32();
3782
tcg_gen_shli_i32(rd, t0, 8);
3783
tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3784
tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3785
tcg_gen_or_i32(rd, rd, tmp);
3787
tcg_gen_shri_i32(t1, t1, 8);
3788
tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3789
tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3790
tcg_gen_or_i32(t1, t1, tmp);
3791
tcg_gen_mov_i32(t0, rd);
3793
tcg_temp_free_i32(tmp);
3794
tcg_temp_free_i32(rd);
3797
static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
3801
rd = tcg_temp_new_i32();
3802
tmp = tcg_temp_new_i32();
3804
tcg_gen_shli_i32(rd, t0, 16);
3805
tcg_gen_andi_i32(tmp, t1, 0xffff);
3806
tcg_gen_or_i32(rd, rd, tmp);
3807
tcg_gen_shri_i32(t1, t1, 16);
3808
tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3809
tcg_gen_or_i32(t1, t1, tmp);
3810
tcg_gen_mov_i32(t0, rd);
3812
tcg_temp_free_i32(tmp);
3813
tcg_temp_free_i32(rd);
3821
} neon_ls_element_type[11] = {
3835
/* Translate a NEON load/store element instruction. Return nonzero if the
3836
instruction is invalid. */
3837
static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
3856
if (!s->vfp_enabled)
3858
VFP_DREG_D(rd, insn);
3859
rn = (insn >> 16) & 0xf;
3861
load = (insn & (1 << 21)) != 0;
3862
if ((insn & (1 << 23)) == 0) {
3863
/* Load store all elements. */
3864
op = (insn >> 8) & 0xf;
3865
size = (insn >> 6) & 3;
3868
/* Catch UNDEF cases for bad values of align field */
3871
if (((insn >> 5) & 1) == 1) {
3876
if (((insn >> 4) & 3) == 3) {
3883
nregs = neon_ls_element_type[op].nregs;
3884
interleave = neon_ls_element_type[op].interleave;
3885
spacing = neon_ls_element_type[op].spacing;
3886
if (size == 3 && (interleave | spacing) != 1)
3888
addr = tcg_temp_new_i32();
3889
load_reg_var(s, addr, rn);
3890
stride = (1 << size) * interleave;
3891
for (reg = 0; reg < nregs; reg++) {
3892
if (interleave > 2 || (interleave == 2 && nregs == 2)) {
3893
load_reg_var(s, addr, rn);
3894
tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
3895
} else if (interleave == 2 && nregs == 4 && reg == 2) {
3896
load_reg_var(s, addr, rn);
3897
tcg_gen_addi_i32(addr, addr, 1 << size);
3900
tmp64 = tcg_temp_new_i64();
3902
gen_aa32_ld64(tmp64, addr, IS_USER(s));
3903
neon_store_reg64(tmp64, rd);
3905
neon_load_reg64(tmp64, rd);
3906
gen_aa32_st64(tmp64, addr, IS_USER(s));
3908
tcg_temp_free_i64(tmp64);
3909
tcg_gen_addi_i32(addr, addr, stride);
3911
for (pass = 0; pass < 2; pass++) {
3914
tmp = tcg_temp_new_i32();
3915
gen_aa32_ld32u(tmp, addr, IS_USER(s));
3916
neon_store_reg(rd, pass, tmp);
3918
tmp = neon_load_reg(rd, pass);
3919
gen_aa32_st32(tmp, addr, IS_USER(s));
3920
tcg_temp_free_i32(tmp);
3922
tcg_gen_addi_i32(addr, addr, stride);
3923
} else if (size == 1) {
3925
tmp = tcg_temp_new_i32();
3926
gen_aa32_ld16u(tmp, addr, IS_USER(s));
3927
tcg_gen_addi_i32(addr, addr, stride);
3928
tmp2 = tcg_temp_new_i32();
3929
gen_aa32_ld16u(tmp2, addr, IS_USER(s));
3930
tcg_gen_addi_i32(addr, addr, stride);
3931
tcg_gen_shli_i32(tmp2, tmp2, 16);
3932
tcg_gen_or_i32(tmp, tmp, tmp2);
3933
tcg_temp_free_i32(tmp2);
3934
neon_store_reg(rd, pass, tmp);
3936
tmp = neon_load_reg(rd, pass);
3937
tmp2 = tcg_temp_new_i32();
3938
tcg_gen_shri_i32(tmp2, tmp, 16);
3939
gen_aa32_st16(tmp, addr, IS_USER(s));
3940
tcg_temp_free_i32(tmp);
3941
tcg_gen_addi_i32(addr, addr, stride);
3942
gen_aa32_st16(tmp2, addr, IS_USER(s));
3943
tcg_temp_free_i32(tmp2);
3944
tcg_gen_addi_i32(addr, addr, stride);
3946
} else /* size == 0 */ {
3948
TCGV_UNUSED_I32(tmp2);
3949
for (n = 0; n < 4; n++) {
3950
tmp = tcg_temp_new_i32();
3951
gen_aa32_ld8u(tmp, addr, IS_USER(s));
3952
tcg_gen_addi_i32(addr, addr, stride);
3956
tcg_gen_shli_i32(tmp, tmp, n * 8);
3957
tcg_gen_or_i32(tmp2, tmp2, tmp);
3958
tcg_temp_free_i32(tmp);
3961
neon_store_reg(rd, pass, tmp2);
3963
tmp2 = neon_load_reg(rd, pass);
3964
for (n = 0; n < 4; n++) {
3965
tmp = tcg_temp_new_i32();
3967
tcg_gen_mov_i32(tmp, tmp2);
3969
tcg_gen_shri_i32(tmp, tmp2, n * 8);
3971
gen_aa32_st8(tmp, addr, IS_USER(s));
3972
tcg_temp_free_i32(tmp);
3973
tcg_gen_addi_i32(addr, addr, stride);
3975
tcg_temp_free_i32(tmp2);
3982
tcg_temp_free_i32(addr);
3985
size = (insn >> 10) & 3;
3987
/* Load single element to all lanes. */
3988
int a = (insn >> 4) & 1;
3992
size = (insn >> 6) & 3;
3993
nregs = ((insn >> 8) & 3) + 1;
3996
if (nregs != 4 || a == 0) {
3999
/* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4002
if (nregs == 1 && a == 1 && size == 0) {
4005
if (nregs == 3 && a == 1) {
4008
addr = tcg_temp_new_i32();
4009
load_reg_var(s, addr, rn);
4011
/* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4012
tmp = gen_load_and_replicate(s, addr, size);
4013
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4014
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4015
if (insn & (1 << 5)) {
4016
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
4017
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
4019
tcg_temp_free_i32(tmp);
4021
/* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4022
stride = (insn & (1 << 5)) ? 2 : 1;
4023
for (reg = 0; reg < nregs; reg++) {
4024
tmp = gen_load_and_replicate(s, addr, size);
4025
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4026
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4027
tcg_temp_free_i32(tmp);
4028
tcg_gen_addi_i32(addr, addr, 1 << size);
4032
tcg_temp_free_i32(addr);
4033
stride = (1 << size) * nregs;
4035
/* Single element. */
4036
int idx = (insn >> 4) & 0xf;
4037
pass = (insn >> 7) & 1;
4040
shift = ((insn >> 5) & 3) * 8;
4044
shift = ((insn >> 6) & 1) * 16;
4045
stride = (insn & (1 << 5)) ? 2 : 1;
4049
stride = (insn & (1 << 6)) ? 2 : 1;
4054
nregs = ((insn >> 8) & 3) + 1;
4055
/* Catch the UNDEF cases. This is unavoidably a bit messy. */
4058
if (((idx & (1 << size)) != 0) ||
4059
(size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4064
if ((idx & 1) != 0) {
4069
if (size == 2 && (idx & 2) != 0) {
4074
if ((size == 2) && ((idx & 3) == 3)) {
4081
if ((rd + stride * (nregs - 1)) > 31) {
4082
/* Attempts to write off the end of the register file
4083
* are UNPREDICTABLE; we choose to UNDEF because otherwise
4084
* the neon_load_reg() would write off the end of the array.
4088
addr = tcg_temp_new_i32();
4089
load_reg_var(s, addr, rn);
4090
for (reg = 0; reg < nregs; reg++) {
4092
tmp = tcg_temp_new_i32();
4095
gen_aa32_ld8u(tmp, addr, IS_USER(s));
4098
gen_aa32_ld16u(tmp, addr, IS_USER(s));
4101
gen_aa32_ld32u(tmp, addr, IS_USER(s));
4103
default: /* Avoid compiler warnings. */
4107
tmp2 = neon_load_reg(rd, pass);
4108
tcg_gen_deposit_i32(tmp, tmp2, tmp,
4109
shift, size ? 16 : 8);
4110
tcg_temp_free_i32(tmp2);
4112
neon_store_reg(rd, pass, tmp);
4113
} else { /* Store */
4114
tmp = neon_load_reg(rd, pass);
4116
tcg_gen_shri_i32(tmp, tmp, shift);
4119
gen_aa32_st8(tmp, addr, IS_USER(s));
4122
gen_aa32_st16(tmp, addr, IS_USER(s));
4125
gen_aa32_st32(tmp, addr, IS_USER(s));
4128
tcg_temp_free_i32(tmp);
4131
tcg_gen_addi_i32(addr, addr, 1 << size);
4133
tcg_temp_free_i32(addr);
4134
stride = nregs * (1 << size);
4140
base = load_reg(s, rn);
4142
tcg_gen_addi_i32(base, base, stride);
4145
index = load_reg(s, rm);
4146
tcg_gen_add_i32(base, base, index);
4147
tcg_temp_free_i32(index);
4149
store_reg(s, rn, base);
4154
/* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4155
static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
4157
tcg_gen_and_i32(t, t, c);
4158
tcg_gen_andc_i32(f, f, c);
4159
tcg_gen_or_i32(dest, t, f);
4162
static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
4165
case 0: gen_helper_neon_narrow_u8(dest, src); break;
4166
case 1: gen_helper_neon_narrow_u16(dest, src); break;
4167
case 2: tcg_gen_trunc_i64_i32(dest, src); break;
4172
static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4175
case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4176
case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4177
case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4182
static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
4185
case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4186
case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4187
case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4192
static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4195
case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4196
case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4197
case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4202
static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
4208
case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4209
case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4214
case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4215
case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4222
case 1: gen_helper_neon_shl_u16(var, var, shift); break;
4223
case 2: gen_helper_neon_shl_u32(var, var, shift); break;
4228
case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4229
case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4236
static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
4240
case 0: gen_helper_neon_widen_u8(dest, src); break;
4241
case 1: gen_helper_neon_widen_u16(dest, src); break;
4242
case 2: tcg_gen_extu_i32_i64(dest, src); break;
4247
case 0: gen_helper_neon_widen_s8(dest, src); break;
4248
case 1: gen_helper_neon_widen_s16(dest, src); break;
4249
case 2: tcg_gen_ext_i32_i64(dest, src); break;
4253
tcg_temp_free_i32(src);
4256
static inline void gen_neon_addl(int size)
4259
case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4260
case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4261
case 2: tcg_gen_add_i64(CPU_V001); break;
4266
static inline void gen_neon_subl(int size)
4269
case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4270
case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4271
case 2: tcg_gen_sub_i64(CPU_V001); break;
4276
static inline void gen_neon_negl(TCGv_i64 var, int size)
4279
case 0: gen_helper_neon_negl_u16(var, var); break;
4280
case 1: gen_helper_neon_negl_u32(var, var); break;
4282
tcg_gen_neg_i64(var, var);
4288
static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4291
case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4292
case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4297
static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
4302
switch ((size << 1) | u) {
4303
case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4304
case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4305
case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4306
case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4308
tmp = gen_muls_i64_i32(a, b);
4309
tcg_gen_mov_i64(dest, tmp);
4310
tcg_temp_free_i64(tmp);
4313
tmp = gen_mulu_i64_i32(a, b);
4314
tcg_gen_mov_i64(dest, tmp);
4315
tcg_temp_free_i64(tmp);
4320
/* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4321
Don't forget to clean them now. */
4323
tcg_temp_free_i32(a);
4324
tcg_temp_free_i32(b);
4328
static void gen_neon_narrow_op(int op, int u, int size,
4329
TCGv_i32 dest, TCGv_i64 src)
4333
gen_neon_unarrow_sats(size, dest, src);
4335
gen_neon_narrow(size, dest, src);
4339
gen_neon_narrow_satu(size, dest, src);
4341
gen_neon_narrow_sats(size, dest, src);
4346
/* Symbolic constants for op fields for Neon 3-register same-length.
4347
* The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4350
#define NEON_3R_VHADD 0
4351
#define NEON_3R_VQADD 1
4352
#define NEON_3R_VRHADD 2
4353
#define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4354
#define NEON_3R_VHSUB 4
4355
#define NEON_3R_VQSUB 5
4356
#define NEON_3R_VCGT 6
4357
#define NEON_3R_VCGE 7
4358
#define NEON_3R_VSHL 8
4359
#define NEON_3R_VQSHL 9
4360
#define NEON_3R_VRSHL 10
4361
#define NEON_3R_VQRSHL 11
4362
#define NEON_3R_VMAX 12
4363
#define NEON_3R_VMIN 13
4364
#define NEON_3R_VABD 14
4365
#define NEON_3R_VABA 15
4366
#define NEON_3R_VADD_VSUB 16
4367
#define NEON_3R_VTST_VCEQ 17
4368
#define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4369
#define NEON_3R_VMUL 19
4370
#define NEON_3R_VPMAX 20
4371
#define NEON_3R_VPMIN 21
4372
#define NEON_3R_VQDMULH_VQRDMULH 22
4373
#define NEON_3R_VPADD 23
4374
#define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4375
#define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4376
#define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4377
#define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4378
#define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4379
#define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4380
#define NEON_3R_VRECPS_VRSQRTS 31 /* float VRECPS, VRSQRTS */
4382
static const uint8_t neon_3r_sizes[] = {
4383
[NEON_3R_VHADD] = 0x7,
4384
[NEON_3R_VQADD] = 0xf,
4385
[NEON_3R_VRHADD] = 0x7,
4386
[NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
4387
[NEON_3R_VHSUB] = 0x7,
4388
[NEON_3R_VQSUB] = 0xf,
4389
[NEON_3R_VCGT] = 0x7,
4390
[NEON_3R_VCGE] = 0x7,
4391
[NEON_3R_VSHL] = 0xf,
4392
[NEON_3R_VQSHL] = 0xf,
4393
[NEON_3R_VRSHL] = 0xf,
4394
[NEON_3R_VQRSHL] = 0xf,
4395
[NEON_3R_VMAX] = 0x7,
4396
[NEON_3R_VMIN] = 0x7,
4397
[NEON_3R_VABD] = 0x7,
4398
[NEON_3R_VABA] = 0x7,
4399
[NEON_3R_VADD_VSUB] = 0xf,
4400
[NEON_3R_VTST_VCEQ] = 0x7,
4401
[NEON_3R_VML] = 0x7,
4402
[NEON_3R_VMUL] = 0x7,
4403
[NEON_3R_VPMAX] = 0x7,
4404
[NEON_3R_VPMIN] = 0x7,
4405
[NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4406
[NEON_3R_VPADD] = 0x7,
4407
[NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
4408
[NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4409
[NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4410
[NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4411
[NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4412
[NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4413
[NEON_3R_VRECPS_VRSQRTS] = 0x5, /* size bit 1 encodes op */
4416
/* Symbolic constants for op fields for Neon 2-register miscellaneous.
4417
* The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4420
#define NEON_2RM_VREV64 0
4421
#define NEON_2RM_VREV32 1
4422
#define NEON_2RM_VREV16 2
4423
#define NEON_2RM_VPADDL 4
4424
#define NEON_2RM_VPADDL_U 5
4425
#define NEON_2RM_VCLS 8
4426
#define NEON_2RM_VCLZ 9
4427
#define NEON_2RM_VCNT 10
4428
#define NEON_2RM_VMVN 11
4429
#define NEON_2RM_VPADAL 12
4430
#define NEON_2RM_VPADAL_U 13
4431
#define NEON_2RM_VQABS 14
4432
#define NEON_2RM_VQNEG 15
4433
#define NEON_2RM_VCGT0 16
4434
#define NEON_2RM_VCGE0 17
4435
#define NEON_2RM_VCEQ0 18
4436
#define NEON_2RM_VCLE0 19
4437
#define NEON_2RM_VCLT0 20
4438
#define NEON_2RM_VABS 22
4439
#define NEON_2RM_VNEG 23
4440
#define NEON_2RM_VCGT0_F 24
4441
#define NEON_2RM_VCGE0_F 25
4442
#define NEON_2RM_VCEQ0_F 26
4443
#define NEON_2RM_VCLE0_F 27
4444
#define NEON_2RM_VCLT0_F 28
4445
#define NEON_2RM_VABS_F 30
4446
#define NEON_2RM_VNEG_F 31
4447
#define NEON_2RM_VSWP 32
4448
#define NEON_2RM_VTRN 33
4449
#define NEON_2RM_VUZP 34
4450
#define NEON_2RM_VZIP 35
4451
#define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4452
#define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4453
#define NEON_2RM_VSHLL 38
4454
#define NEON_2RM_VCVT_F16_F32 44
4455
#define NEON_2RM_VCVT_F32_F16 46
4456
#define NEON_2RM_VRECPE 56
4457
#define NEON_2RM_VRSQRTE 57
4458
#define NEON_2RM_VRECPE_F 58
4459
#define NEON_2RM_VRSQRTE_F 59
4460
#define NEON_2RM_VCVT_FS 60
4461
#define NEON_2RM_VCVT_FU 61
4462
#define NEON_2RM_VCVT_SF 62
4463
#define NEON_2RM_VCVT_UF 63
4465
static int neon_2rm_is_float_op(int op)
4467
/* Return true if this neon 2reg-misc op is float-to-float */
4468
return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
4469
op >= NEON_2RM_VRECPE_F);
4472
/* Each entry in this array has bit n set if the insn allows
4473
* size value n (otherwise it will UNDEF). Since unallocated
4474
* op values will have no bits set they always UNDEF.
4476
static const uint8_t neon_2rm_sizes[] = {
4477
[NEON_2RM_VREV64] = 0x7,
4478
[NEON_2RM_VREV32] = 0x3,
4479
[NEON_2RM_VREV16] = 0x1,
4480
[NEON_2RM_VPADDL] = 0x7,
4481
[NEON_2RM_VPADDL_U] = 0x7,
4482
[NEON_2RM_VCLS] = 0x7,
4483
[NEON_2RM_VCLZ] = 0x7,
4484
[NEON_2RM_VCNT] = 0x1,
4485
[NEON_2RM_VMVN] = 0x1,
4486
[NEON_2RM_VPADAL] = 0x7,
4487
[NEON_2RM_VPADAL_U] = 0x7,
4488
[NEON_2RM_VQABS] = 0x7,
4489
[NEON_2RM_VQNEG] = 0x7,
4490
[NEON_2RM_VCGT0] = 0x7,
4491
[NEON_2RM_VCGE0] = 0x7,
4492
[NEON_2RM_VCEQ0] = 0x7,
4493
[NEON_2RM_VCLE0] = 0x7,
4494
[NEON_2RM_VCLT0] = 0x7,
4495
[NEON_2RM_VABS] = 0x7,
4496
[NEON_2RM_VNEG] = 0x7,
4497
[NEON_2RM_VCGT0_F] = 0x4,
4498
[NEON_2RM_VCGE0_F] = 0x4,
4499
[NEON_2RM_VCEQ0_F] = 0x4,
4500
[NEON_2RM_VCLE0_F] = 0x4,
4501
[NEON_2RM_VCLT0_F] = 0x4,
4502
[NEON_2RM_VABS_F] = 0x4,
4503
[NEON_2RM_VNEG_F] = 0x4,
4504
[NEON_2RM_VSWP] = 0x1,
4505
[NEON_2RM_VTRN] = 0x7,
4506
[NEON_2RM_VUZP] = 0x7,
4507
[NEON_2RM_VZIP] = 0x7,
4508
[NEON_2RM_VMOVN] = 0x7,
4509
[NEON_2RM_VQMOVN] = 0x7,
4510
[NEON_2RM_VSHLL] = 0x7,
4511
[NEON_2RM_VCVT_F16_F32] = 0x2,
4512
[NEON_2RM_VCVT_F32_F16] = 0x2,
4513
[NEON_2RM_VRECPE] = 0x4,
4514
[NEON_2RM_VRSQRTE] = 0x4,
4515
[NEON_2RM_VRECPE_F] = 0x4,
4516
[NEON_2RM_VRSQRTE_F] = 0x4,
4517
[NEON_2RM_VCVT_FS] = 0x4,
4518
[NEON_2RM_VCVT_FU] = 0x4,
4519
[NEON_2RM_VCVT_SF] = 0x4,
4520
[NEON_2RM_VCVT_UF] = 0x4,
4523
/* Translate a NEON data processing instruction. Return nonzero if the
4524
instruction is invalid.
4525
We process data in a mixture of 32-bit and 64-bit chunks.
4526
Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4528
static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4540
TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
4543
if (!s->vfp_enabled)
4545
q = (insn & (1 << 6)) != 0;
4546
u = (insn >> 24) & 1;
4547
VFP_DREG_D(rd, insn);
4548
VFP_DREG_N(rn, insn);
4549
VFP_DREG_M(rm, insn);
4550
size = (insn >> 20) & 3;
4551
if ((insn & (1 << 23)) == 0) {
4552
/* Three register same length. */
4553
op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4554
/* Catch invalid op and bad size combinations: UNDEF */
4555
if ((neon_3r_sizes[op] & (1 << size)) == 0) {
4558
/* All insns of this form UNDEF for either this condition or the
4559
* superset of cases "Q==1"; we catch the latter later.
4561
if (q && ((rd | rn | rm) & 1)) {
4564
if (size == 3 && op != NEON_3R_LOGIC) {
4565
/* 64-bit element instructions. */
4566
for (pass = 0; pass < (q ? 2 : 1); pass++) {
4567
neon_load_reg64(cpu_V0, rn + pass);
4568
neon_load_reg64(cpu_V1, rm + pass);
4572
gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
4575
gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
4581
gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
4584
gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
4590
gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4592
gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4597
gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4600
gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
4606
gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4608
gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4611
case NEON_3R_VQRSHL:
4613
gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4616
gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4620
case NEON_3R_VADD_VSUB:
4622
tcg_gen_sub_i64(CPU_V001);
4624
tcg_gen_add_i64(CPU_V001);
4630
neon_store_reg64(cpu_V0, rd + pass);
4639
case NEON_3R_VQRSHL:
4642
/* Shift instruction operands are reversed. */
4657
case NEON_3R_FLOAT_ARITH:
4658
pairwise = (u && size < 2); /* if VPADD (float) */
4660
case NEON_3R_FLOAT_MINMAX:
4661
pairwise = u; /* if VPMIN/VPMAX (float) */
4663
case NEON_3R_FLOAT_CMP:
4665
/* no encoding for U=0 C=1x */
4669
case NEON_3R_FLOAT_ACMP:
4674
case NEON_3R_VRECPS_VRSQRTS:
4680
if (u && (size != 0)) {
4681
/* UNDEF on invalid size for polynomial subcase */
4686
if (!arm_feature(env, ARM_FEATURE_VFP4) || u) {
4694
if (pairwise && q) {
4695
/* All the pairwise insns UNDEF if Q is set */
4699
for (pass = 0; pass < (q ? 4 : 2); pass++) {
4704
tmp = neon_load_reg(rn, 0);
4705
tmp2 = neon_load_reg(rn, 1);
4707
tmp = neon_load_reg(rm, 0);
4708
tmp2 = neon_load_reg(rm, 1);
4712
tmp = neon_load_reg(rn, pass);
4713
tmp2 = neon_load_reg(rm, pass);
4717
GEN_NEON_INTEGER_OP(hadd);
4720
GEN_NEON_INTEGER_OP_ENV(qadd);
4722
case NEON_3R_VRHADD:
4723
GEN_NEON_INTEGER_OP(rhadd);
4725
case NEON_3R_LOGIC: /* Logic ops. */
4726
switch ((u << 2) | size) {
4728
tcg_gen_and_i32(tmp, tmp, tmp2);
4731
tcg_gen_andc_i32(tmp, tmp, tmp2);
4734
tcg_gen_or_i32(tmp, tmp, tmp2);
4737
tcg_gen_orc_i32(tmp, tmp, tmp2);
4740
tcg_gen_xor_i32(tmp, tmp, tmp2);
4743
tmp3 = neon_load_reg(rd, pass);
4744
gen_neon_bsl(tmp, tmp, tmp2, tmp3);
4745
tcg_temp_free_i32(tmp3);
4748
tmp3 = neon_load_reg(rd, pass);
4749
gen_neon_bsl(tmp, tmp, tmp3, tmp2);
4750
tcg_temp_free_i32(tmp3);
4753
tmp3 = neon_load_reg(rd, pass);
4754
gen_neon_bsl(tmp, tmp3, tmp, tmp2);
4755
tcg_temp_free_i32(tmp3);
4760
GEN_NEON_INTEGER_OP(hsub);
4763
GEN_NEON_INTEGER_OP_ENV(qsub);
4766
GEN_NEON_INTEGER_OP(cgt);
4769
GEN_NEON_INTEGER_OP(cge);
4772
GEN_NEON_INTEGER_OP(shl);
4775
GEN_NEON_INTEGER_OP_ENV(qshl);
4778
GEN_NEON_INTEGER_OP(rshl);
4780
case NEON_3R_VQRSHL:
4781
GEN_NEON_INTEGER_OP_ENV(qrshl);
4784
GEN_NEON_INTEGER_OP(max);
4787
GEN_NEON_INTEGER_OP(min);
4790
GEN_NEON_INTEGER_OP(abd);
4793
GEN_NEON_INTEGER_OP(abd);
4794
tcg_temp_free_i32(tmp2);
4795
tmp2 = neon_load_reg(rd, pass);
4796
gen_neon_add(size, tmp, tmp2);
4798
case NEON_3R_VADD_VSUB:
4799
if (!u) { /* VADD */
4800
gen_neon_add(size, tmp, tmp2);
4803
case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
4804
case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
4805
case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
4810
case NEON_3R_VTST_VCEQ:
4811
if (!u) { /* VTST */
4813
case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
4814
case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
4815
case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
4820
case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
4821
case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
4822
case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
4827
case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
4829
case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
4830
case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
4831
case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
4834
tcg_temp_free_i32(tmp2);
4835
tmp2 = neon_load_reg(rd, pass);
4837
gen_neon_rsb(size, tmp, tmp2);
4839
gen_neon_add(size, tmp, tmp2);
4843
if (u) { /* polynomial */
4844
gen_helper_neon_mul_p8(tmp, tmp, tmp2);
4845
} else { /* Integer */
4847
case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
4848
case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
4849
case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
4855
GEN_NEON_INTEGER_OP(pmax);
4858
GEN_NEON_INTEGER_OP(pmin);
4860
case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
4861
if (!u) { /* VQDMULH */
4864
gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
4867
gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
4871
} else { /* VQRDMULH */
4874
gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
4877
gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
4885
case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
4886
case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
4887
case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
4891
case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
4893
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4894
switch ((u << 2) | size) {
4897
gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
4900
gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
4903
gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
4908
tcg_temp_free_ptr(fpstatus);
4911
case NEON_3R_FLOAT_MULTIPLY:
4913
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4914
gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
4916
tcg_temp_free_i32(tmp2);
4917
tmp2 = neon_load_reg(rd, pass);
4919
gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
4921
gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
4924
tcg_temp_free_ptr(fpstatus);
4927
case NEON_3R_FLOAT_CMP:
4929
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4931
gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
4934
gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
4936
gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
4939
tcg_temp_free_ptr(fpstatus);
4942
case NEON_3R_FLOAT_ACMP:
4944
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4946
gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
4948
gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
4950
tcg_temp_free_ptr(fpstatus);
4953
case NEON_3R_FLOAT_MINMAX:
4955
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4957
gen_helper_neon_max_f32(tmp, tmp, tmp2, fpstatus);
4959
gen_helper_neon_min_f32(tmp, tmp, tmp2, fpstatus);
4961
tcg_temp_free_ptr(fpstatus);
4964
case NEON_3R_VRECPS_VRSQRTS:
4966
gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
4968
gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
4972
/* VFMA, VFMS: fused multiply-add */
4973
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4974
TCGv_i32 tmp3 = neon_load_reg(rd, pass);
4977
gen_helper_vfp_negs(tmp, tmp);
4979
gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
4980
tcg_temp_free_i32(tmp3);
4981
tcg_temp_free_ptr(fpstatus);
4987
tcg_temp_free_i32(tmp2);
4989
/* Save the result. For elementwise operations we can put it
4990
straight into the destination register. For pairwise operations
4991
we have to be careful to avoid clobbering the source operands. */
4992
if (pairwise && rd == rm) {
4993
neon_store_scratch(pass, tmp);
4995
neon_store_reg(rd, pass, tmp);
4999
if (pairwise && rd == rm) {
5000
for (pass = 0; pass < (q ? 4 : 2); pass++) {
5001
tmp = neon_load_scratch(pass);
5002
neon_store_reg(rd, pass, tmp);
5005
/* End of 3 register same size operations. */
5006
} else if (insn & (1 << 4)) {
5007
if ((insn & 0x00380080) != 0) {
5008
/* Two registers and shift. */
5009
op = (insn >> 8) & 0xf;
5010
if (insn & (1 << 7)) {
5018
while ((insn & (1 << (size + 19))) == 0)
5021
shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5022
/* To avoid excessive duplication of ops we implement shift
5023
by immediate using the variable shift operations. */
5025
/* Shift by immediate:
5026
VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5027
if (q && ((rd | rm) & 1)) {
5030
if (!u && (op == 4 || op == 6)) {
5033
/* Right shifts are encoded as N - shift, where N is the
5034
element size in bits. */
5036
shift = shift - (1 << (size + 3));
5044
imm = (uint8_t) shift;
5049
imm = (uint16_t) shift;
5060
for (pass = 0; pass < count; pass++) {
5062
neon_load_reg64(cpu_V0, rm + pass);
5063
tcg_gen_movi_i64(cpu_V1, imm);
5068
gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5070
gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
5075
gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5077
gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5080
case 5: /* VSHL, VSLI */
5081
gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5083
case 6: /* VQSHLU */
5084
gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5089
gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5092
gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5097
if (op == 1 || op == 3) {
5099
neon_load_reg64(cpu_V1, rd + pass);
5100
tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5101
} else if (op == 4 || (op == 5 && u)) {
5103
neon_load_reg64(cpu_V1, rd + pass);
5105
if (shift < -63 || shift > 63) {
5109
mask = 0xffffffffffffffffull >> -shift;
5111
mask = 0xffffffffffffffffull << shift;
5114
tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
5115
tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5117
neon_store_reg64(cpu_V0, rd + pass);
5118
} else { /* size < 3 */
5119
/* Operands in T0 and T1. */
5120
tmp = neon_load_reg(rm, pass);
5121
tmp2 = tcg_temp_new_i32();
5122
tcg_gen_movi_i32(tmp2, imm);
5126
GEN_NEON_INTEGER_OP(shl);
5130
GEN_NEON_INTEGER_OP(rshl);
5133
case 5: /* VSHL, VSLI */
5135
case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
5136
case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
5137
case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
5141
case 6: /* VQSHLU */
5144
gen_helper_neon_qshlu_s8(tmp, cpu_env,
5148
gen_helper_neon_qshlu_s16(tmp, cpu_env,
5152
gen_helper_neon_qshlu_s32(tmp, cpu_env,
5160
GEN_NEON_INTEGER_OP_ENV(qshl);
5163
tcg_temp_free_i32(tmp2);
5165
if (op == 1 || op == 3) {
5167
tmp2 = neon_load_reg(rd, pass);
5168
gen_neon_add(size, tmp, tmp2);
5169
tcg_temp_free_i32(tmp2);
5170
} else if (op == 4 || (op == 5 && u)) {
5175
mask = 0xff >> -shift;
5177
mask = (uint8_t)(0xff << shift);
5183
mask = 0xffff >> -shift;
5185
mask = (uint16_t)(0xffff << shift);
5189
if (shift < -31 || shift > 31) {
5193
mask = 0xffffffffu >> -shift;
5195
mask = 0xffffffffu << shift;
5201
tmp2 = neon_load_reg(rd, pass);
5202
tcg_gen_andi_i32(tmp, tmp, mask);
5203
tcg_gen_andi_i32(tmp2, tmp2, ~mask);
5204
tcg_gen_or_i32(tmp, tmp, tmp2);
5205
tcg_temp_free_i32(tmp2);
5207
neon_store_reg(rd, pass, tmp);
5210
} else if (op < 10) {
5211
/* Shift by immediate and narrow:
5212
VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5213
int input_unsigned = (op == 8) ? !u : u;
5217
shift = shift - (1 << (size + 3));
5220
tmp64 = tcg_const_i64(shift);
5221
neon_load_reg64(cpu_V0, rm);
5222
neon_load_reg64(cpu_V1, rm + 1);
5223
for (pass = 0; pass < 2; pass++) {
5231
if (input_unsigned) {
5232
gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5234
gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5237
if (input_unsigned) {
5238
gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5240
gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5243
tmp = tcg_temp_new_i32();
5244
gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5245
neon_store_reg(rd, pass, tmp);
5247
tcg_temp_free_i64(tmp64);
5250
imm = (uint16_t)shift;
5254
imm = (uint32_t)shift;
5256
tmp2 = tcg_const_i32(imm);
5257
tmp4 = neon_load_reg(rm + 1, 0);
5258
tmp5 = neon_load_reg(rm + 1, 1);
5259
for (pass = 0; pass < 2; pass++) {
5261
tmp = neon_load_reg(rm, 0);
5265
gen_neon_shift_narrow(size, tmp, tmp2, q,
5268
tmp3 = neon_load_reg(rm, 1);
5272
gen_neon_shift_narrow(size, tmp3, tmp2, q,
5274
tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5275
tcg_temp_free_i32(tmp);
5276
tcg_temp_free_i32(tmp3);
5277
tmp = tcg_temp_new_i32();
5278
gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5279
neon_store_reg(rd, pass, tmp);
5281
tcg_temp_free_i32(tmp2);
5283
} else if (op == 10) {
5285
if (q || (rd & 1)) {
5288
tmp = neon_load_reg(rm, 0);
5289
tmp2 = neon_load_reg(rm, 1);
5290
for (pass = 0; pass < 2; pass++) {
5294
gen_neon_widen(cpu_V0, tmp, size, u);
5297
/* The shift is less than the width of the source
5298
type, so we can just shift the whole register. */
5299
tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5300
/* Widen the result of shift: we need to clear
5301
* the potential overflow bits resulting from
5302
* left bits of the narrow input appearing as
5303
* right bits of left the neighbour narrow
5305
if (size < 2 || !u) {
5308
imm = (0xffu >> (8 - shift));
5310
} else if (size == 1) {
5311
imm = 0xffff >> (16 - shift);
5314
imm = 0xffffffff >> (32 - shift);
5317
imm64 = imm | (((uint64_t)imm) << 32);
5321
tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5324
neon_store_reg64(cpu_V0, rd + pass);
5326
} else if (op >= 14) {
5327
/* VCVT fixed-point. */
5328
if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5331
/* We have already masked out the must-be-1 top bit of imm6,
5332
* hence this 32-shift where the ARM ARM has 64-imm6.
5335
for (pass = 0; pass < (q ? 4 : 2); pass++) {
5336
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
5339
gen_vfp_ulto(0, shift, 1);
5341
gen_vfp_slto(0, shift, 1);
5344
gen_vfp_toul(0, shift, 1);
5346
gen_vfp_tosl(0, shift, 1);
5348
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
5353
} else { /* (insn & 0x00380080) == 0 */
5355
if (q && (rd & 1)) {
5359
op = (insn >> 8) & 0xf;
5360
/* One register and immediate. */
5361
imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5362
invert = (insn & (1 << 5)) != 0;
5363
/* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5364
* We choose to not special-case this and will behave as if a
5365
* valid constant encoding of 0 had been given.
5384
imm = (imm << 8) | (imm << 24);
5387
imm = (imm << 8) | 0xff;
5390
imm = (imm << 16) | 0xffff;
5393
imm |= (imm << 8) | (imm << 16) | (imm << 24);
5401
imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5402
| ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5408
for (pass = 0; pass < (q ? 4 : 2); pass++) {
5409
if (op & 1 && op < 12) {
5410
tmp = neon_load_reg(rd, pass);
5412
/* The immediate value has already been inverted, so
5414
tcg_gen_andi_i32(tmp, tmp, imm);
5416
tcg_gen_ori_i32(tmp, tmp, imm);
5420
tmp = tcg_temp_new_i32();
5421
if (op == 14 && invert) {
5425
for (n = 0; n < 4; n++) {
5426
if (imm & (1 << (n + (pass & 1) * 4)))
5427
val |= 0xff << (n * 8);
5429
tcg_gen_movi_i32(tmp, val);
5431
tcg_gen_movi_i32(tmp, imm);
5434
neon_store_reg(rd, pass, tmp);
5437
} else { /* (insn & 0x00800010 == 0x00800000) */
5439
op = (insn >> 8) & 0xf;
5440
if ((insn & (1 << 6)) == 0) {
5441
/* Three registers of different lengths. */
5445
/* undefreq: bit 0 : UNDEF if size != 0
5446
* bit 1 : UNDEF if size == 0
5447
* bit 2 : UNDEF if U == 1
5448
* Note that [1:0] set implies 'always UNDEF'
5451
/* prewiden, src1_wide, src2_wide, undefreq */
5452
static const int neon_3reg_wide[16][4] = {
5453
{1, 0, 0, 0}, /* VADDL */
5454
{1, 1, 0, 0}, /* VADDW */
5455
{1, 0, 0, 0}, /* VSUBL */
5456
{1, 1, 0, 0}, /* VSUBW */
5457
{0, 1, 1, 0}, /* VADDHN */
5458
{0, 0, 0, 0}, /* VABAL */
5459
{0, 1, 1, 0}, /* VSUBHN */
5460
{0, 0, 0, 0}, /* VABDL */
5461
{0, 0, 0, 0}, /* VMLAL */
5462
{0, 0, 0, 6}, /* VQDMLAL */
5463
{0, 0, 0, 0}, /* VMLSL */
5464
{0, 0, 0, 6}, /* VQDMLSL */
5465
{0, 0, 0, 0}, /* Integer VMULL */
5466
{0, 0, 0, 2}, /* VQDMULL */
5467
{0, 0, 0, 5}, /* Polynomial VMULL */
5468
{0, 0, 0, 3}, /* Reserved: always UNDEF */
5471
prewiden = neon_3reg_wide[op][0];
5472
src1_wide = neon_3reg_wide[op][1];
5473
src2_wide = neon_3reg_wide[op][2];
5474
undefreq = neon_3reg_wide[op][3];
5476
if (((undefreq & 1) && (size != 0)) ||
5477
((undefreq & 2) && (size == 0)) ||
5478
((undefreq & 4) && u)) {
5481
if ((src1_wide && (rn & 1)) ||
5482
(src2_wide && (rm & 1)) ||
5483
(!src2_wide && (rd & 1))) {
5487
/* Avoid overlapping operands. Wide source operands are
5488
always aligned so will never overlap with wide
5489
destinations in problematic ways. */
5490
if (rd == rm && !src2_wide) {
5491
tmp = neon_load_reg(rm, 1);
5492
neon_store_scratch(2, tmp);
5493
} else if (rd == rn && !src1_wide) {
5494
tmp = neon_load_reg(rn, 1);
5495
neon_store_scratch(2, tmp);
5497
TCGV_UNUSED_I32(tmp3);
5498
for (pass = 0; pass < 2; pass++) {
5500
neon_load_reg64(cpu_V0, rn + pass);
5501
TCGV_UNUSED_I32(tmp);
5503
if (pass == 1 && rd == rn) {
5504
tmp = neon_load_scratch(2);
5506
tmp = neon_load_reg(rn, pass);
5509
gen_neon_widen(cpu_V0, tmp, size, u);
5513
neon_load_reg64(cpu_V1, rm + pass);
5514
TCGV_UNUSED_I32(tmp2);
5516
if (pass == 1 && rd == rm) {
5517
tmp2 = neon_load_scratch(2);
5519
tmp2 = neon_load_reg(rm, pass);
5522
gen_neon_widen(cpu_V1, tmp2, size, u);
5526
case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5527
gen_neon_addl(size);
5529
case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5530
gen_neon_subl(size);
5532
case 5: case 7: /* VABAL, VABDL */
5533
switch ((size << 1) | u) {
5535
gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5538
gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5541
gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5544
gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5547
gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5550
gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5554
tcg_temp_free_i32(tmp2);
5555
tcg_temp_free_i32(tmp);
5557
case 8: case 9: case 10: case 11: case 12: case 13:
5558
/* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5559
gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5561
case 14: /* Polynomial VMULL */
5562
gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
5563
tcg_temp_free_i32(tmp2);
5564
tcg_temp_free_i32(tmp);
5566
default: /* 15 is RESERVED: caught earlier */
5571
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5572
neon_store_reg64(cpu_V0, rd + pass);
5573
} else if (op == 5 || (op >= 8 && op <= 11)) {
5575
neon_load_reg64(cpu_V1, rd + pass);
5577
case 10: /* VMLSL */
5578
gen_neon_negl(cpu_V0, size);
5580
case 5: case 8: /* VABAL, VMLAL */
5581
gen_neon_addl(size);
5583
case 9: case 11: /* VQDMLAL, VQDMLSL */
5584
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5586
gen_neon_negl(cpu_V0, size);
5588
gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5593
neon_store_reg64(cpu_V0, rd + pass);
5594
} else if (op == 4 || op == 6) {
5595
/* Narrowing operation. */
5596
tmp = tcg_temp_new_i32();
5600
gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
5603
gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
5606
tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5607
tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5614
gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
5617
gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
5620
tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
5621
tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5622
tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5630
neon_store_reg(rd, 0, tmp3);
5631
neon_store_reg(rd, 1, tmp);
5634
/* Write back the result. */
5635
neon_store_reg64(cpu_V0, rd + pass);
5639
/* Two registers and a scalar. NB that for ops of this form
5640
* the ARM ARM labels bit 24 as Q, but it is in our variable
5647
case 1: /* Float VMLA scalar */
5648
case 5: /* Floating point VMLS scalar */
5649
case 9: /* Floating point VMUL scalar */
5654
case 0: /* Integer VMLA scalar */
5655
case 4: /* Integer VMLS scalar */
5656
case 8: /* Integer VMUL scalar */
5657
case 12: /* VQDMULH scalar */
5658
case 13: /* VQRDMULH scalar */
5659
if (u && ((rd | rn) & 1)) {
5662
tmp = neon_get_scalar(size, rm);
5663
neon_store_scratch(0, tmp);
5664
for (pass = 0; pass < (u ? 4 : 2); pass++) {
5665
tmp = neon_load_scratch(0);
5666
tmp2 = neon_load_reg(rn, pass);
5669
gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5671
gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5673
} else if (op == 13) {
5675
gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5677
gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5679
} else if (op & 1) {
5680
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5681
gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5682
tcg_temp_free_ptr(fpstatus);
5685
case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5686
case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5687
case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5691
tcg_temp_free_i32(tmp2);
5694
tmp2 = neon_load_reg(rd, pass);
5697
gen_neon_add(size, tmp, tmp2);
5701
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5702
gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5703
tcg_temp_free_ptr(fpstatus);
5707
gen_neon_rsb(size, tmp, tmp2);
5711
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5712
gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5713
tcg_temp_free_ptr(fpstatus);
5719
tcg_temp_free_i32(tmp2);
5721
neon_store_reg(rd, pass, tmp);
5724
case 3: /* VQDMLAL scalar */
5725
case 7: /* VQDMLSL scalar */
5726
case 11: /* VQDMULL scalar */
5731
case 2: /* VMLAL sclar */
5732
case 6: /* VMLSL scalar */
5733
case 10: /* VMULL scalar */
5737
tmp2 = neon_get_scalar(size, rm);
5738
/* We need a copy of tmp2 because gen_neon_mull
5739
* deletes it during pass 0. */
5740
tmp4 = tcg_temp_new_i32();
5741
tcg_gen_mov_i32(tmp4, tmp2);
5742
tmp3 = neon_load_reg(rn, 1);
5744
for (pass = 0; pass < 2; pass++) {
5746
tmp = neon_load_reg(rn, 0);
5751
gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5753
neon_load_reg64(cpu_V1, rd + pass);
5757
gen_neon_negl(cpu_V0, size);
5760
gen_neon_addl(size);
5763
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5765
gen_neon_negl(cpu_V0, size);
5767
gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5773
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5778
neon_store_reg64(cpu_V0, rd + pass);
5783
default: /* 14 and 15 are RESERVED */
5787
} else { /* size == 3 */
5790
imm = (insn >> 8) & 0xf;
5795
if (q && ((rd | rn | rm) & 1)) {
5800
neon_load_reg64(cpu_V0, rn);
5802
neon_load_reg64(cpu_V1, rn + 1);
5804
} else if (imm == 8) {
5805
neon_load_reg64(cpu_V0, rn + 1);
5807
neon_load_reg64(cpu_V1, rm);
5810
tmp64 = tcg_temp_new_i64();
5812
neon_load_reg64(cpu_V0, rn);
5813
neon_load_reg64(tmp64, rn + 1);
5815
neon_load_reg64(cpu_V0, rn + 1);
5816
neon_load_reg64(tmp64, rm);
5818
tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
5819
tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
5820
tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5822
neon_load_reg64(cpu_V1, rm);
5824
neon_load_reg64(cpu_V1, rm + 1);
5827
tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5828
tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
5829
tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
5830
tcg_temp_free_i64(tmp64);
5833
neon_load_reg64(cpu_V0, rn);
5834
tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
5835
neon_load_reg64(cpu_V1, rm);
5836
tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5837
tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5839
neon_store_reg64(cpu_V0, rd);
5841
neon_store_reg64(cpu_V1, rd + 1);
5843
} else if ((insn & (1 << 11)) == 0) {
5844
/* Two register misc. */
5845
op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
5846
size = (insn >> 18) & 3;
5847
/* UNDEF for unknown op values and bad op-size combinations */
5848
if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
5851
if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
5852
q && ((rm | rd) & 1)) {
5856
case NEON_2RM_VREV64:
5857
for (pass = 0; pass < (q ? 2 : 1); pass++) {
5858
tmp = neon_load_reg(rm, pass * 2);
5859
tmp2 = neon_load_reg(rm, pass * 2 + 1);
5861
case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
5862
case 1: gen_swap_half(tmp); break;
5863
case 2: /* no-op */ break;
5866
neon_store_reg(rd, pass * 2 + 1, tmp);
5868
neon_store_reg(rd, pass * 2, tmp2);
5871
case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
5872
case 1: gen_swap_half(tmp2); break;
5875
neon_store_reg(rd, pass * 2, tmp2);
5879
case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
5880
case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
5881
for (pass = 0; pass < q + 1; pass++) {
5882
tmp = neon_load_reg(rm, pass * 2);
5883
gen_neon_widen(cpu_V0, tmp, size, op & 1);
5884
tmp = neon_load_reg(rm, pass * 2 + 1);
5885
gen_neon_widen(cpu_V1, tmp, size, op & 1);
5887
case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
5888
case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
5889
case 2: tcg_gen_add_i64(CPU_V001); break;
5892
if (op >= NEON_2RM_VPADAL) {
5894
neon_load_reg64(cpu_V1, rd + pass);
5895
gen_neon_addl(size);
5897
neon_store_reg64(cpu_V0, rd + pass);
5903
for (n = 0; n < (q ? 4 : 2); n += 2) {
5904
tmp = neon_load_reg(rm, n);
5905
tmp2 = neon_load_reg(rd, n + 1);
5906
neon_store_reg(rm, n, tmp2);
5907
neon_store_reg(rd, n + 1, tmp);
5914
if (gen_neon_unzip(rd, rm, size, q)) {
5919
if (gen_neon_zip(rd, rm, size, q)) {
5923
case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
5924
/* also VQMOVUN; op field and mnemonics don't line up */
5928
TCGV_UNUSED_I32(tmp2);
5929
for (pass = 0; pass < 2; pass++) {
5930
neon_load_reg64(cpu_V0, rm + pass);
5931
tmp = tcg_temp_new_i32();
5932
gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
5937
neon_store_reg(rd, 0, tmp2);
5938
neon_store_reg(rd, 1, tmp);
5942
case NEON_2RM_VSHLL:
5943
if (q || (rd & 1)) {
5946
tmp = neon_load_reg(rm, 0);
5947
tmp2 = neon_load_reg(rm, 1);
5948
for (pass = 0; pass < 2; pass++) {
5951
gen_neon_widen(cpu_V0, tmp, size, 1);
5952
tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
5953
neon_store_reg64(cpu_V0, rd + pass);
5956
case NEON_2RM_VCVT_F16_F32:
5957
if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
5961
tmp = tcg_temp_new_i32();
5962
tmp2 = tcg_temp_new_i32();
5963
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
5964
gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
5965
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
5966
gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
5967
tcg_gen_shli_i32(tmp2, tmp2, 16);
5968
tcg_gen_or_i32(tmp2, tmp2, tmp);
5969
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
5970
gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
5971
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
5972
neon_store_reg(rd, 0, tmp2);
5973
tmp2 = tcg_temp_new_i32();
5974
gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
5975
tcg_gen_shli_i32(tmp2, tmp2, 16);
5976
tcg_gen_or_i32(tmp2, tmp2, tmp);
5977
neon_store_reg(rd, 1, tmp2);
5978
tcg_temp_free_i32(tmp);
5980
case NEON_2RM_VCVT_F32_F16:
5981
if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
5985
tmp3 = tcg_temp_new_i32();
5986
tmp = neon_load_reg(rm, 0);
5987
tmp2 = neon_load_reg(rm, 1);
5988
tcg_gen_ext16u_i32(tmp3, tmp);
5989
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5990
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
5991
tcg_gen_shri_i32(tmp3, tmp, 16);
5992
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5993
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
5994
tcg_temp_free_i32(tmp);
5995
tcg_gen_ext16u_i32(tmp3, tmp2);
5996
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5997
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
5998
tcg_gen_shri_i32(tmp3, tmp2, 16);
5999
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6000
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
6001
tcg_temp_free_i32(tmp2);
6002
tcg_temp_free_i32(tmp3);
6006
for (pass = 0; pass < (q ? 4 : 2); pass++) {
6007
if (neon_2rm_is_float_op(op)) {
6008
tcg_gen_ld_f32(cpu_F0s, cpu_env,
6009
neon_reg_offset(rm, pass));
6010
TCGV_UNUSED_I32(tmp);
6012
tmp = neon_load_reg(rm, pass);
6015
case NEON_2RM_VREV32:
6017
case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6018
case 1: gen_swap_half(tmp); break;
6022
case NEON_2RM_VREV16:
6027
case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6028
case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6029
case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6035
case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6036
case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6037
case 2: gen_helper_clz(tmp, tmp); break;
6042
gen_helper_neon_cnt_u8(tmp, tmp);
6045
tcg_gen_not_i32(tmp, tmp);
6047
case NEON_2RM_VQABS:
6050
gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6053
gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6056
gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6061
case NEON_2RM_VQNEG:
6064
gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6067
gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6070
gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6075
case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6076
tmp2 = tcg_const_i32(0);
6078
case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6079
case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6080
case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6083
tcg_temp_free_i32(tmp2);
6084
if (op == NEON_2RM_VCLE0) {
6085
tcg_gen_not_i32(tmp, tmp);
6088
case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6089
tmp2 = tcg_const_i32(0);
6091
case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6092
case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6093
case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6096
tcg_temp_free_i32(tmp2);
6097
if (op == NEON_2RM_VCLT0) {
6098
tcg_gen_not_i32(tmp, tmp);
6101
case NEON_2RM_VCEQ0:
6102
tmp2 = tcg_const_i32(0);
6104
case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6105
case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6106
case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6109
tcg_temp_free_i32(tmp2);
6113
case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
6114
case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
6115
case 2: tcg_gen_abs_i32(tmp, tmp); break;
6120
tmp2 = tcg_const_i32(0);
6121
gen_neon_rsb(size, tmp, tmp2);
6122
tcg_temp_free_i32(tmp2);
6124
case NEON_2RM_VCGT0_F:
6126
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6127
tmp2 = tcg_const_i32(0);
6128
gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6129
tcg_temp_free_i32(tmp2);
6130
tcg_temp_free_ptr(fpstatus);
6133
case NEON_2RM_VCGE0_F:
6135
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6136
tmp2 = tcg_const_i32(0);
6137
gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6138
tcg_temp_free_i32(tmp2);
6139
tcg_temp_free_ptr(fpstatus);
6142
case NEON_2RM_VCEQ0_F:
6144
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6145
tmp2 = tcg_const_i32(0);
6146
gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6147
tcg_temp_free_i32(tmp2);
6148
tcg_temp_free_ptr(fpstatus);
6151
case NEON_2RM_VCLE0_F:
6153
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6154
tmp2 = tcg_const_i32(0);
6155
gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6156
tcg_temp_free_i32(tmp2);
6157
tcg_temp_free_ptr(fpstatus);
6160
case NEON_2RM_VCLT0_F:
6162
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6163
tmp2 = tcg_const_i32(0);
6164
gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6165
tcg_temp_free_i32(tmp2);
6166
tcg_temp_free_ptr(fpstatus);
6169
case NEON_2RM_VABS_F:
6172
case NEON_2RM_VNEG_F:
6176
tmp2 = neon_load_reg(rd, pass);
6177
neon_store_reg(rm, pass, tmp2);
6180
tmp2 = neon_load_reg(rd, pass);
6182
case 0: gen_neon_trn_u8(tmp, tmp2); break;
6183
case 1: gen_neon_trn_u16(tmp, tmp2); break;
6186
neon_store_reg(rm, pass, tmp2);
6188
case NEON_2RM_VRECPE:
6189
gen_helper_recpe_u32(tmp, tmp, cpu_env);
6191
case NEON_2RM_VRSQRTE:
6192
gen_helper_rsqrte_u32(tmp, tmp, cpu_env);
6194
case NEON_2RM_VRECPE_F:
6195
gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
6197
case NEON_2RM_VRSQRTE_F:
6198
gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
6200
case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6203
case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6206
case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6207
gen_vfp_tosiz(0, 1);
6209
case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6210
gen_vfp_touiz(0, 1);
6213
/* Reserved op values were caught by the
6214
* neon_2rm_sizes[] check earlier.
6218
if (neon_2rm_is_float_op(op)) {
6219
tcg_gen_st_f32(cpu_F0s, cpu_env,
6220
neon_reg_offset(rd, pass));
6222
neon_store_reg(rd, pass, tmp);
6227
} else if ((insn & (1 << 10)) == 0) {
6229
int n = ((insn >> 8) & 3) + 1;
6230
if ((rn + n) > 32) {
6231
/* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6232
* helper function running off the end of the register file.
6237
if (insn & (1 << 6)) {
6238
tmp = neon_load_reg(rd, 0);
6240
tmp = tcg_temp_new_i32();
6241
tcg_gen_movi_i32(tmp, 0);
6243
tmp2 = neon_load_reg(rm, 0);
6244
tmp4 = tcg_const_i32(rn);
6245
tmp5 = tcg_const_i32(n);
6246
gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
6247
tcg_temp_free_i32(tmp);
6248
if (insn & (1 << 6)) {
6249
tmp = neon_load_reg(rd, 1);
6251
tmp = tcg_temp_new_i32();
6252
tcg_gen_movi_i32(tmp, 0);
6254
tmp3 = neon_load_reg(rm, 1);
6255
gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
6256
tcg_temp_free_i32(tmp5);
6257
tcg_temp_free_i32(tmp4);
6258
neon_store_reg(rd, 0, tmp2);
6259
neon_store_reg(rd, 1, tmp3);
6260
tcg_temp_free_i32(tmp);
6261
} else if ((insn & 0x380) == 0) {
6263
if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
6266
if (insn & (1 << 19)) {
6267
tmp = neon_load_reg(rm, 1);
6269
tmp = neon_load_reg(rm, 0);
6271
if (insn & (1 << 16)) {
6272
gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
6273
} else if (insn & (1 << 17)) {
6274
if ((insn >> 18) & 1)
6275
gen_neon_dup_high16(tmp);
6277
gen_neon_dup_low16(tmp);
6279
for (pass = 0; pass < (q ? 4 : 2); pass++) {
6280
tmp2 = tcg_temp_new_i32();
6281
tcg_gen_mov_i32(tmp2, tmp);
6282
neon_store_reg(rd, pass, tmp2);
6284
tcg_temp_free_i32(tmp);
6293
static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
6295
int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
6296
const ARMCPRegInfo *ri;
6297
ARMCPU *cpu = arm_env_get_cpu(env);
6299
cpnum = (insn >> 8) & 0xf;
6300
if (arm_feature(env, ARM_FEATURE_XSCALE)
6301
&& ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
6304
/* First check for coprocessor space used for actual instructions */
6308
if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6309
return disas_iwmmxt_insn(env, s, insn);
6310
} else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
6311
return disas_dsp_insn(env, s, insn);
6318
/* Otherwise treat as a generic register access */
6319
is64 = (insn & (1 << 25)) == 0;
6320
if (!is64 && ((insn & (1 << 4)) == 0)) {
6328
opc1 = (insn >> 4) & 0xf;
6330
rt2 = (insn >> 16) & 0xf;
6332
crn = (insn >> 16) & 0xf;
6333
opc1 = (insn >> 21) & 7;
6334
opc2 = (insn >> 5) & 7;
6337
isread = (insn >> 20) & 1;
6338
rt = (insn >> 12) & 0xf;
6340
ri = get_arm_cp_reginfo(cpu,
6341
ENCODE_CP_REG(cpnum, is64, crn, crm, opc1, opc2));
6343
/* Check access permissions */
6344
if (!cp_access_ok(env, ri, isread)) {
6348
/* Handle special cases first */
6349
switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
6356
gen_set_pc_im(s, s->pc);
6357
s->is_jmp = DISAS_WFI;
6363
if (use_icount && (ri->type & ARM_CP_IO)) {
6372
if (ri->type & ARM_CP_CONST) {
6373
tmp64 = tcg_const_i64(ri->resetvalue);
6374
} else if (ri->readfn) {
6376
gen_set_pc_im(s, s->pc);
6377
tmp64 = tcg_temp_new_i64();
6378
tmpptr = tcg_const_ptr(ri);
6379
gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
6380
tcg_temp_free_ptr(tmpptr);
6382
tmp64 = tcg_temp_new_i64();
6383
tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
6385
tmp = tcg_temp_new_i32();
6386
tcg_gen_trunc_i64_i32(tmp, tmp64);
6387
store_reg(s, rt, tmp);
6388
tcg_gen_shri_i64(tmp64, tmp64, 32);
6389
tmp = tcg_temp_new_i32();
6390
tcg_gen_trunc_i64_i32(tmp, tmp64);
6391
tcg_temp_free_i64(tmp64);
6392
store_reg(s, rt2, tmp);
6395
if (ri->type & ARM_CP_CONST) {
6396
tmp = tcg_const_i32(ri->resetvalue);
6397
} else if (ri->readfn) {
6399
gen_set_pc_im(s, s->pc);
6400
tmp = tcg_temp_new_i32();
6401
tmpptr = tcg_const_ptr(ri);
6402
gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
6403
tcg_temp_free_ptr(tmpptr);
6405
tmp = load_cpu_offset(ri->fieldoffset);
6408
/* Destination register of r15 for 32 bit loads sets
6409
* the condition codes from the high 4 bits of the value
6412
tcg_temp_free_i32(tmp);
6414
store_reg(s, rt, tmp);
6419
if (ri->type & ARM_CP_CONST) {
6420
/* If not forbidden by access permissions, treat as WI */
6425
TCGv_i32 tmplo, tmphi;
6426
TCGv_i64 tmp64 = tcg_temp_new_i64();
6427
tmplo = load_reg(s, rt);
6428
tmphi = load_reg(s, rt2);
6429
tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
6430
tcg_temp_free_i32(tmplo);
6431
tcg_temp_free_i32(tmphi);
6433
TCGv_ptr tmpptr = tcg_const_ptr(ri);
6434
gen_set_pc_im(s, s->pc);
6435
gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
6436
tcg_temp_free_ptr(tmpptr);
6438
tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
6440
tcg_temp_free_i64(tmp64);
6445
gen_set_pc_im(s, s->pc);
6446
tmp = load_reg(s, rt);
6447
tmpptr = tcg_const_ptr(ri);
6448
gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
6449
tcg_temp_free_ptr(tmpptr);
6450
tcg_temp_free_i32(tmp);
6452
TCGv_i32 tmp = load_reg(s, rt);
6453
store_cpu_offset(tmp, ri->fieldoffset);
6458
if (use_icount && (ri->type & ARM_CP_IO)) {
6459
/* I/O operations must end the TB here (whether read or write) */
6462
} else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
6463
/* We default to ending the TB on a coprocessor register write,
6464
* but allow this to be suppressed by the register definition
6465
* (usually only necessary to work around guest bugs).
6477
/* Store a 64-bit value to a register pair. Clobbers val. */
6478
static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
6481
tmp = tcg_temp_new_i32();
6482
tcg_gen_trunc_i64_i32(tmp, val);
6483
store_reg(s, rlow, tmp);
6484
tmp = tcg_temp_new_i32();
6485
tcg_gen_shri_i64(val, val, 32);
6486
tcg_gen_trunc_i64_i32(tmp, val);
6487
store_reg(s, rhigh, tmp);
6490
/* load a 32-bit value from a register and perform a 64-bit accumulate. */
6491
static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
6496
/* Load value and extend to 64 bits. */
6497
tmp = tcg_temp_new_i64();
6498
tmp2 = load_reg(s, rlow);
6499
tcg_gen_extu_i32_i64(tmp, tmp2);
6500
tcg_temp_free_i32(tmp2);
6501
tcg_gen_add_i64(val, val, tmp);
6502
tcg_temp_free_i64(tmp);
6505
/* load and add a 64-bit value from a register pair. */
6506
static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
6512
/* Load 64-bit value rd:rn. */
6513
tmpl = load_reg(s, rlow);
6514
tmph = load_reg(s, rhigh);
6515
tmp = tcg_temp_new_i64();
6516
tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
6517
tcg_temp_free_i32(tmpl);
6518
tcg_temp_free_i32(tmph);
6519
tcg_gen_add_i64(val, val, tmp);
6520
tcg_temp_free_i64(tmp);
6523
/* Set N and Z flags from hi|lo. */
6524
static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
6526
tcg_gen_mov_i32(cpu_NF, hi);
6527
tcg_gen_or_i32(cpu_ZF, lo, hi);
6530
/* Load/Store exclusive instructions are implemented by remembering
6531
the value/address loaded, and seeing if these are the same
6532
when the store is performed. This should be sufficient to implement
6533
the architecturally mandated semantics, and avoids having to monitor
6536
In system emulation mode only one CPU will be running at once, so
6537
this sequence is effectively atomic. In user emulation mode we
6538
throw an exception and handle the atomic operation elsewhere. */
6539
static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
6540
TCGv_i32 addr, int size)
6542
TCGv_i32 tmp = tcg_temp_new_i32();
6546
gen_aa32_ld8u(tmp, addr, IS_USER(s));
6549
gen_aa32_ld16u(tmp, addr, IS_USER(s));
6553
gen_aa32_ld32u(tmp, addr, IS_USER(s));
6558
tcg_gen_mov_i32(cpu_exclusive_val, tmp);
6559
store_reg(s, rt, tmp);
6561
TCGv_i32 tmp2 = tcg_temp_new_i32();
6562
tcg_gen_addi_i32(tmp2, addr, 4);
6563
tmp = tcg_temp_new_i32();
6564
gen_aa32_ld32u(tmp, tmp2, IS_USER(s));
6565
tcg_temp_free_i32(tmp2);
6566
tcg_gen_mov_i32(cpu_exclusive_high, tmp);
6567
store_reg(s, rt2, tmp);
6569
tcg_gen_mov_i32(cpu_exclusive_addr, addr);
6572
static void gen_clrex(DisasContext *s)
6574
tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6577
#ifdef CONFIG_USER_ONLY
6578
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6579
TCGv_i32 addr, int size)
6581
tcg_gen_mov_i32(cpu_exclusive_test, addr);
6582
tcg_gen_movi_i32(cpu_exclusive_info,
6583
size | (rd << 4) | (rt << 8) | (rt2 << 12));
6584
gen_exception_insn(s, 4, EXCP_STREX);
6587
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6588
TCGv_i32 addr, int size)
6594
/* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6600
fail_label = gen_new_label();
6601
done_label = gen_new_label();
6602
tcg_gen_brcond_i32(TCG_COND_NE, addr, cpu_exclusive_addr, fail_label);
6603
tmp = tcg_temp_new_i32();
6606
gen_aa32_ld8u(tmp, addr, IS_USER(s));
6609
gen_aa32_ld16u(tmp, addr, IS_USER(s));
6613
gen_aa32_ld32u(tmp, addr, IS_USER(s));
6618
tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_val, fail_label);
6619
tcg_temp_free_i32(tmp);
6621
TCGv_i32 tmp2 = tcg_temp_new_i32();
6622
tcg_gen_addi_i32(tmp2, addr, 4);
6623
tmp = tcg_temp_new_i32();
6624
gen_aa32_ld32u(tmp, tmp2, IS_USER(s));
6625
tcg_temp_free_i32(tmp2);
6626
tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_high, fail_label);
6627
tcg_temp_free_i32(tmp);
6629
tmp = load_reg(s, rt);
6632
gen_aa32_st8(tmp, addr, IS_USER(s));
6635
gen_aa32_st16(tmp, addr, IS_USER(s));
6639
gen_aa32_st32(tmp, addr, IS_USER(s));
6644
tcg_temp_free_i32(tmp);
6646
tcg_gen_addi_i32(addr, addr, 4);
6647
tmp = load_reg(s, rt2);
6648
gen_aa32_st32(tmp, addr, IS_USER(s));
6649
tcg_temp_free_i32(tmp);
6651
tcg_gen_movi_i32(cpu_R[rd], 0);
6652
tcg_gen_br(done_label);
6653
gen_set_label(fail_label);
6654
tcg_gen_movi_i32(cpu_R[rd], 1);
6655
gen_set_label(done_label);
6656
tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6663
* @mode: mode field from insn (which stack to store to)
6664
* @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
6665
* @writeback: true if writeback bit set
6667
* Generate code for the SRS (Store Return State) insn.
6669
static void gen_srs(DisasContext *s,
6670
uint32_t mode, uint32_t amode, bool writeback)
6673
TCGv_i32 addr = tcg_temp_new_i32();
6674
TCGv_i32 tmp = tcg_const_i32(mode);
6675
gen_helper_get_r13_banked(addr, cpu_env, tmp);
6676
tcg_temp_free_i32(tmp);
6693
tcg_gen_addi_i32(addr, addr, offset);
6694
tmp = load_reg(s, 14);
6695
gen_aa32_st32(tmp, addr, 0);
6696
tcg_temp_free_i32(tmp);
6697
tmp = load_cpu_field(spsr);
6698
tcg_gen_addi_i32(addr, addr, 4);
6699
gen_aa32_st32(tmp, addr, 0);
6700
tcg_temp_free_i32(tmp);
6718
tcg_gen_addi_i32(addr, addr, offset);
6719
tmp = tcg_const_i32(mode);
6720
gen_helper_set_r13_banked(cpu_env, tmp, addr);
6721
tcg_temp_free_i32(tmp);
6723
tcg_temp_free_i32(addr);
6726
static void disas_arm_insn(CPUARMState * env, DisasContext *s)
6728
unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
6735
insn = arm_ldl_code(env, s->pc, s->bswap_code);
6738
/* M variants do not implement ARM mode. */
6743
/* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
6744
* choose to UNDEF. In ARMv5 and above the space is used
6745
* for miscellaneous unconditional instructions.
6749
/* Unconditional instructions. */
6750
if (((insn >> 25) & 7) == 1) {
6751
/* NEON Data processing. */
6752
if (!arm_feature(env, ARM_FEATURE_NEON))
6755
if (disas_neon_data_insn(env, s, insn))
6759
if ((insn & 0x0f100000) == 0x04000000) {
6760
/* NEON load/store. */
6761
if (!arm_feature(env, ARM_FEATURE_NEON))
6764
if (disas_neon_ls_insn(env, s, insn))
6768
if ((insn & 0x0f000e10) == 0x0e000a00) {
6770
if (disas_vfp_insn(env, s, insn)) {
6775
if (((insn & 0x0f30f000) == 0x0510f000) ||
6776
((insn & 0x0f30f010) == 0x0710f000)) {
6777
if ((insn & (1 << 22)) == 0) {
6779
if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6783
/* Otherwise PLD; v5TE+ */
6787
if (((insn & 0x0f70f000) == 0x0450f000) ||
6788
((insn & 0x0f70f010) == 0x0650f000)) {
6790
return; /* PLI; V7 */
6792
if (((insn & 0x0f700000) == 0x04100000) ||
6793
((insn & 0x0f700010) == 0x06100000)) {
6794
if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6797
return; /* v7MP: Unallocated memory hint: must NOP */
6800
if ((insn & 0x0ffffdff) == 0x01010000) {
6803
if (((insn >> 9) & 1) != s->bswap_code) {
6804
/* Dynamic endianness switching not implemented. */
6805
qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
6809
} else if ((insn & 0x0fffff00) == 0x057ff000) {
6810
switch ((insn >> 4) & 0xf) {
6819
/* We don't emulate caches so these are a no-op. */
6824
} else if ((insn & 0x0e5fffe0) == 0x084d0500) {
6830
gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
6832
} else if ((insn & 0x0e50ffe0) == 0x08100a00) {
6838
rn = (insn >> 16) & 0xf;
6839
addr = load_reg(s, rn);
6840
i = (insn >> 23) & 3;
6842
case 0: offset = -4; break; /* DA */
6843
case 1: offset = 0; break; /* IA */
6844
case 2: offset = -8; break; /* DB */
6845
case 3: offset = 4; break; /* IB */
6849
tcg_gen_addi_i32(addr, addr, offset);
6850
/* Load PC into tmp and CPSR into tmp2. */
6851
tmp = tcg_temp_new_i32();
6852
gen_aa32_ld32u(tmp, addr, 0);
6853
tcg_gen_addi_i32(addr, addr, 4);
6854
tmp2 = tcg_temp_new_i32();
6855
gen_aa32_ld32u(tmp2, addr, 0);
6856
if (insn & (1 << 21)) {
6857
/* Base writeback. */
6859
case 0: offset = -8; break;
6860
case 1: offset = 4; break;
6861
case 2: offset = -4; break;
6862
case 3: offset = 0; break;
6866
tcg_gen_addi_i32(addr, addr, offset);
6867
store_reg(s, rn, addr);
6869
tcg_temp_free_i32(addr);
6871
gen_rfe(s, tmp, tmp2);
6873
} else if ((insn & 0x0e000000) == 0x0a000000) {
6874
/* branch link and change to thumb (blx <offset>) */
6877
val = (uint32_t)s->pc;
6878
tmp = tcg_temp_new_i32();
6879
tcg_gen_movi_i32(tmp, val);
6880
store_reg(s, 14, tmp);
6881
/* Sign-extend the 24-bit offset */
6882
offset = (((int32_t)insn) << 8) >> 8;
6883
/* offset * 4 + bit24 * 2 + (thumb bit) */
6884
val += (offset << 2) | ((insn >> 23) & 2) | 1;
6885
/* pipeline offset */
6887
/* protected by ARCH(5); above, near the start of uncond block */
6890
} else if ((insn & 0x0e000f00) == 0x0c000100) {
6891
if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6892
/* iWMMXt register transfer. */
6893
if (env->cp15.c15_cpar & (1 << 1))
6894
if (!disas_iwmmxt_insn(env, s, insn))
6897
} else if ((insn & 0x0fe00000) == 0x0c400000) {
6898
/* Coprocessor double register transfer. */
6900
/* XXX doesn't belong in the trustzone patch: should just UNDEF? */
6901
cpu_abort(env, "unsupported coprocessor double register transfer\n");
6902
} else if ((insn & 0x0f000010) == 0x0e000010) {
6903
/* Additional coprocessor register transfer. */
6904
if (!disas_coproc_insn(env, s, insn)) {
6907
} else if ((insn & 0x0ff10020) == 0x01000000) {
6910
/* cps (privileged) */
6914
if (insn & (1 << 19)) {
6915
if (insn & (1 << 8))
6917
if (insn & (1 << 7))
6919
if (insn & (1 << 6))
6921
if (insn & (1 << 18))
6924
if (insn & (1 << 17)) {
6926
val |= (insn & 0x1f);
6929
gen_set_psr_im(s, mask, 0, val);
6936
/* if not always execute, we generate a conditional jump to
6938
s->condlabel = gen_new_label();
6939
gen_test_cc(cond ^ 1, s->condlabel);
6942
if ((insn & 0x0f900000) == 0x03000000) {
6943
if ((insn & (1 << 21)) == 0) {
6945
rd = (insn >> 12) & 0xf;
6946
val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
6947
if ((insn & (1 << 22)) == 0) {
6949
tmp = tcg_temp_new_i32();
6950
tcg_gen_movi_i32(tmp, val);
6953
tmp = load_reg(s, rd);
6954
tcg_gen_ext16u_i32(tmp, tmp);
6955
tcg_gen_ori_i32(tmp, tmp, val << 16);
6957
store_reg(s, rd, tmp);
6959
if (((insn >> 12) & 0xf) != 0xf)
6961
if (((insn >> 16) & 0xf) == 0) {
6962
gen_nop_hint(s, insn & 0xff);
6964
/* CPSR = immediate */
6966
shift = ((insn >> 8) & 0xf) * 2;
6968
val = (val >> shift) | (val << (32 - shift));
6969
i = ((insn & (1 << 22)) != 0);
6970
if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val))
6974
} else if ((insn & 0x0f900000) == 0x01000000
6975
&& (insn & 0x00000090) != 0x00000090) {
6976
/* miscellaneous instructions */
6977
op1 = (insn >> 21) & 3;
6978
sh = (insn >> 4) & 0xf;
6981
case 0x0: /* move program status register */
6984
tmp = load_reg(s, rm);
6985
i = ((op1 & 2) != 0);
6986
if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp))
6990
rd = (insn >> 12) & 0xf;
6994
tmp = load_cpu_field(spsr);
6996
tmp = tcg_temp_new_i32();
6997
gen_helper_cpsr_read(tmp, cpu_env);
6999
store_reg(s, rd, tmp);
7004
/* branch/exchange thumb (bx). */
7006
tmp = load_reg(s, rm);
7008
} else if (op1 == 3) {
7011
rd = (insn >> 12) & 0xf;
7012
tmp = load_reg(s, rm);
7013
gen_helper_clz(tmp, tmp);
7014
store_reg(s, rd, tmp);
7022
/* Trivial implementation equivalent to bx. */
7023
tmp = load_reg(s, rm);
7034
/* branch link/exchange thumb (blx) */
7035
tmp = load_reg(s, rm);
7036
tmp2 = tcg_temp_new_i32();
7037
tcg_gen_movi_i32(tmp2, s->pc);
7038
store_reg(s, 14, tmp2);
7041
case 0x5: /* saturating add/subtract */
7043
rd = (insn >> 12) & 0xf;
7044
rn = (insn >> 16) & 0xf;
7045
tmp = load_reg(s, rm);
7046
tmp2 = load_reg(s, rn);
7048
gen_helper_double_saturate(tmp2, cpu_env, tmp2);
7050
gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
7052
gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
7053
tcg_temp_free_i32(tmp2);
7054
store_reg(s, rd, tmp);
7060
gen_exception_insn(s, 4, EXCP_BKPT);
7061
} else if (op1 == 3) {
7063
if (!arm_feature(env, ARM_FEATURE_TRUSTZONE) || IS_USER(s)) {
7071
case 0x8: /* signed multiply */
7076
rs = (insn >> 8) & 0xf;
7077
rn = (insn >> 12) & 0xf;
7078
rd = (insn >> 16) & 0xf;
7080
/* (32 * 16) >> 16 */
7081
tmp = load_reg(s, rm);
7082
tmp2 = load_reg(s, rs);
7084
tcg_gen_sari_i32(tmp2, tmp2, 16);
7087
tmp64 = gen_muls_i64_i32(tmp, tmp2);
7088
tcg_gen_shri_i64(tmp64, tmp64, 16);
7089
tmp = tcg_temp_new_i32();
7090
tcg_gen_trunc_i64_i32(tmp, tmp64);
7091
tcg_temp_free_i64(tmp64);
7092
if ((sh & 2) == 0) {
7093
tmp2 = load_reg(s, rn);
7094
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7095
tcg_temp_free_i32(tmp2);
7097
store_reg(s, rd, tmp);
7100
tmp = load_reg(s, rm);
7101
tmp2 = load_reg(s, rs);
7102
gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
7103
tcg_temp_free_i32(tmp2);
7105
tmp64 = tcg_temp_new_i64();
7106
tcg_gen_ext_i32_i64(tmp64, tmp);
7107
tcg_temp_free_i32(tmp);
7108
gen_addq(s, tmp64, rn, rd);
7109
gen_storeq_reg(s, rn, rd, tmp64);
7110
tcg_temp_free_i64(tmp64);
7113
tmp2 = load_reg(s, rn);
7114
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7115
tcg_temp_free_i32(tmp2);
7117
store_reg(s, rd, tmp);
7124
} else if (((insn & 0x0e000000) == 0 &&
7125
(insn & 0x00000090) != 0x90) ||
7126
((insn & 0x0e000000) == (1 << 25))) {
7127
int set_cc, logic_cc, shiftop;
7129
op1 = (insn >> 21) & 0xf;
7130
set_cc = (insn >> 20) & 1;
7131
logic_cc = table_logic_cc[op1] & set_cc;
7133
/* data processing instruction */
7134
if (insn & (1 << 25)) {
7135
/* immediate operand */
7137
shift = ((insn >> 8) & 0xf) * 2;
7139
val = (val >> shift) | (val << (32 - shift));
7141
tmp2 = tcg_temp_new_i32();
7142
tcg_gen_movi_i32(tmp2, val);
7143
if (logic_cc && shift) {
7144
gen_set_CF_bit31(tmp2);
7149
tmp2 = load_reg(s, rm);
7150
shiftop = (insn >> 5) & 3;
7151
if (!(insn & (1 << 4))) {
7152
shift = (insn >> 7) & 0x1f;
7153
gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
7155
rs = (insn >> 8) & 0xf;
7156
tmp = load_reg(s, rs);
7157
gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
7160
if (op1 != 0x0f && op1 != 0x0d) {
7161
rn = (insn >> 16) & 0xf;
7162
tmp = load_reg(s, rn);
7164
TCGV_UNUSED_I32(tmp);
7166
rd = (insn >> 12) & 0xf;
7169
tcg_gen_and_i32(tmp, tmp, tmp2);
7173
store_reg_bx(env, s, rd, tmp);
7176
tcg_gen_xor_i32(tmp, tmp, tmp2);
7180
store_reg_bx(env, s, rd, tmp);
7183
if (set_cc && rd == 15) {
7184
/* SUBS r15, ... is used for exception return. */
7188
gen_sub_CC(tmp, tmp, tmp2);
7189
gen_exception_return(s, tmp);
7192
gen_sub_CC(tmp, tmp, tmp2);
7194
tcg_gen_sub_i32(tmp, tmp, tmp2);
7196
store_reg_bx(env, s, rd, tmp);
7201
gen_sub_CC(tmp, tmp2, tmp);
7203
tcg_gen_sub_i32(tmp, tmp2, tmp);
7205
store_reg_bx(env, s, rd, tmp);
7209
gen_add_CC(tmp, tmp, tmp2);
7211
tcg_gen_add_i32(tmp, tmp, tmp2);
7213
store_reg_bx(env, s, rd, tmp);
7217
gen_adc_CC(tmp, tmp, tmp2);
7219
gen_add_carry(tmp, tmp, tmp2);
7221
store_reg_bx(env, s, rd, tmp);
7225
gen_sbc_CC(tmp, tmp, tmp2);
7227
gen_sub_carry(tmp, tmp, tmp2);
7229
store_reg_bx(env, s, rd, tmp);
7233
gen_sbc_CC(tmp, tmp2, tmp);
7235
gen_sub_carry(tmp, tmp2, tmp);
7237
store_reg_bx(env, s, rd, tmp);
7241
tcg_gen_and_i32(tmp, tmp, tmp2);
7244
tcg_temp_free_i32(tmp);
7248
tcg_gen_xor_i32(tmp, tmp, tmp2);
7251
tcg_temp_free_i32(tmp);
7255
gen_sub_CC(tmp, tmp, tmp2);
7257
tcg_temp_free_i32(tmp);
7261
gen_add_CC(tmp, tmp, tmp2);
7263
tcg_temp_free_i32(tmp);
7266
tcg_gen_or_i32(tmp, tmp, tmp2);
7270
store_reg_bx(env, s, rd, tmp);
7273
if (logic_cc && rd == 15) {
7274
/* MOVS r15, ... is used for exception return. */
7278
gen_exception_return(s, tmp2);
7283
store_reg_bx(env, s, rd, tmp2);
7287
tcg_gen_andc_i32(tmp, tmp, tmp2);
7291
store_reg_bx(env, s, rd, tmp);
7295
tcg_gen_not_i32(tmp2, tmp2);
7299
store_reg_bx(env, s, rd, tmp2);
7302
if (op1 != 0x0f && op1 != 0x0d) {
7303
tcg_temp_free_i32(tmp2);
7306
/* other instructions */
7307
op1 = (insn >> 24) & 0xf;
7311
/* multiplies, extra load/stores */
7312
sh = (insn >> 5) & 3;
7315
rd = (insn >> 16) & 0xf;
7316
rn = (insn >> 12) & 0xf;
7317
rs = (insn >> 8) & 0xf;
7319
op1 = (insn >> 20) & 0xf;
7321
case 0: case 1: case 2: case 3: case 6:
7323
tmp = load_reg(s, rs);
7324
tmp2 = load_reg(s, rm);
7325
tcg_gen_mul_i32(tmp, tmp, tmp2);
7326
tcg_temp_free_i32(tmp2);
7327
if (insn & (1 << 22)) {
7328
/* Subtract (mls) */
7330
tmp2 = load_reg(s, rn);
7331
tcg_gen_sub_i32(tmp, tmp2, tmp);
7332
tcg_temp_free_i32(tmp2);
7333
} else if (insn & (1 << 21)) {
7335
tmp2 = load_reg(s, rn);
7336
tcg_gen_add_i32(tmp, tmp, tmp2);
7337
tcg_temp_free_i32(tmp2);
7339
if (insn & (1 << 20))
7341
store_reg(s, rd, tmp);
7344
/* 64 bit mul double accumulate (UMAAL) */
7346
tmp = load_reg(s, rs);
7347
tmp2 = load_reg(s, rm);
7348
tmp64 = gen_mulu_i64_i32(tmp, tmp2);
7349
gen_addq_lo(s, tmp64, rn);
7350
gen_addq_lo(s, tmp64, rd);
7351
gen_storeq_reg(s, rn, rd, tmp64);
7352
tcg_temp_free_i64(tmp64);
7354
case 8: case 9: case 10: case 11:
7355
case 12: case 13: case 14: case 15:
7356
/* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7357
tmp = load_reg(s, rs);
7358
tmp2 = load_reg(s, rm);
7359
if (insn & (1 << 22)) {
7360
tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
7362
tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
7364
if (insn & (1 << 21)) { /* mult accumulate */
7365
TCGv_i32 al = load_reg(s, rn);
7366
TCGv_i32 ah = load_reg(s, rd);
7367
tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
7368
tcg_temp_free_i32(al);
7369
tcg_temp_free_i32(ah);
7371
if (insn & (1 << 20)) {
7372
gen_logicq_cc(tmp, tmp2);
7374
store_reg(s, rn, tmp);
7375
store_reg(s, rd, tmp2);
7381
rn = (insn >> 16) & 0xf;
7382
rd = (insn >> 12) & 0xf;
7383
if (insn & (1 << 23)) {
7384
/* load/store exclusive */
7385
int op2 = (insn >> 8) & 3;
7386
op1 = (insn >> 21) & 0x3;
7389
case 0: /* lda/stl */
7395
case 1: /* reserved */
7397
case 2: /* ldaex/stlex */
7400
case 3: /* ldrex/strex */
7409
addr = tcg_temp_local_new_i32();
7410
load_reg_var(s, addr, rn);
7412
/* Since the emulation does not have barriers,
7413
the acquire/release semantics need no special
7416
if (insn & (1 << 20)) {
7417
tmp = tcg_temp_new_i32();
7420
gen_aa32_ld32u(tmp, addr, IS_USER(s));
7423
gen_aa32_ld8u(tmp, addr, IS_USER(s));
7426
gen_aa32_ld16u(tmp, addr, IS_USER(s));
7431
store_reg(s, rd, tmp);
7434
tmp = load_reg(s, rm);
7437
gen_aa32_st32(tmp, addr, IS_USER(s));
7440
gen_aa32_st8(tmp, addr, IS_USER(s));
7443
gen_aa32_st16(tmp, addr, IS_USER(s));
7448
tcg_temp_free_i32(tmp);
7450
} else if (insn & (1 << 20)) {
7453
gen_load_exclusive(s, rd, 15, addr, 2);
7455
case 1: /* ldrexd */
7456
gen_load_exclusive(s, rd, rd + 1, addr, 3);
7458
case 2: /* ldrexb */
7459
gen_load_exclusive(s, rd, 15, addr, 0);
7461
case 3: /* ldrexh */
7462
gen_load_exclusive(s, rd, 15, addr, 1);
7471
gen_store_exclusive(s, rd, rm, 15, addr, 2);
7473
case 1: /* strexd */
7474
gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
7476
case 2: /* strexb */
7477
gen_store_exclusive(s, rd, rm, 15, addr, 0);
7479
case 3: /* strexh */
7480
gen_store_exclusive(s, rd, rm, 15, addr, 1);
7486
tcg_temp_free_i32(addr);
7488
/* SWP instruction */
7491
/* ??? This is not really atomic. However we know
7492
we never have multiple CPUs running in parallel,
7493
so it is good enough. */
7494
addr = load_reg(s, rn);
7495
tmp = load_reg(s, rm);
7496
tmp2 = tcg_temp_new_i32();
7497
if (insn & (1 << 22)) {
7498
gen_aa32_ld8u(tmp2, addr, IS_USER(s));
7499
gen_aa32_st8(tmp, addr, IS_USER(s));
7501
gen_aa32_ld32u(tmp2, addr, IS_USER(s));
7502
gen_aa32_st32(tmp, addr, IS_USER(s));
7504
tcg_temp_free_i32(tmp);
7505
tcg_temp_free_i32(addr);
7506
store_reg(s, rd, tmp2);
7512
/* Misc load/store */
7513
rn = (insn >> 16) & 0xf;
7514
rd = (insn >> 12) & 0xf;
7515
addr = load_reg(s, rn);
7516
if (insn & (1 << 24))
7517
gen_add_datah_offset(s, insn, 0, addr);
7519
if (insn & (1 << 20)) {
7521
tmp = tcg_temp_new_i32();
7524
gen_aa32_ld16u(tmp, addr, IS_USER(s));
7527
gen_aa32_ld8s(tmp, addr, IS_USER(s));
7531
gen_aa32_ld16s(tmp, addr, IS_USER(s));
7535
} else if (sh & 2) {
7540
tmp = load_reg(s, rd);
7541
gen_aa32_st32(tmp, addr, IS_USER(s));
7542
tcg_temp_free_i32(tmp);
7543
tcg_gen_addi_i32(addr, addr, 4);
7544
tmp = load_reg(s, rd + 1);
7545
gen_aa32_st32(tmp, addr, IS_USER(s));
7546
tcg_temp_free_i32(tmp);
7550
tmp = tcg_temp_new_i32();
7551
gen_aa32_ld32u(tmp, addr, IS_USER(s));
7552
store_reg(s, rd, tmp);
7553
tcg_gen_addi_i32(addr, addr, 4);
7554
tmp = tcg_temp_new_i32();
7555
gen_aa32_ld32u(tmp, addr, IS_USER(s));
7559
address_offset = -4;
7562
tmp = load_reg(s, rd);
7563
gen_aa32_st16(tmp, addr, IS_USER(s));
7564
tcg_temp_free_i32(tmp);
7567
/* Perform base writeback before the loaded value to
7568
ensure correct behavior with overlapping index registers.
7569
ldrd with base writeback is is undefined if the
7570
destination and index registers overlap. */
7571
if (!(insn & (1 << 24))) {
7572
gen_add_datah_offset(s, insn, address_offset, addr);
7573
store_reg(s, rn, addr);
7574
} else if (insn & (1 << 21)) {
7576
tcg_gen_addi_i32(addr, addr, address_offset);
7577
store_reg(s, rn, addr);
7579
tcg_temp_free_i32(addr);
7582
/* Complete the load. */
7583
store_reg(s, rd, tmp);
7592
if (insn & (1 << 4)) {
7594
/* Armv6 Media instructions. */
7596
rn = (insn >> 16) & 0xf;
7597
rd = (insn >> 12) & 0xf;
7598
rs = (insn >> 8) & 0xf;
7599
switch ((insn >> 23) & 3) {
7600
case 0: /* Parallel add/subtract. */
7601
op1 = (insn >> 20) & 7;
7602
tmp = load_reg(s, rn);
7603
tmp2 = load_reg(s, rm);
7604
sh = (insn >> 5) & 7;
7605
if ((op1 & 3) == 0 || sh == 5 || sh == 6)
7607
gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
7608
tcg_temp_free_i32(tmp2);
7609
store_reg(s, rd, tmp);
7612
if ((insn & 0x00700020) == 0) {
7613
/* Halfword pack. */
7614
tmp = load_reg(s, rn);
7615
tmp2 = load_reg(s, rm);
7616
shift = (insn >> 7) & 0x1f;
7617
if (insn & (1 << 6)) {
7621
tcg_gen_sari_i32(tmp2, tmp2, shift);
7622
tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
7623
tcg_gen_ext16u_i32(tmp2, tmp2);
7627
tcg_gen_shli_i32(tmp2, tmp2, shift);
7628
tcg_gen_ext16u_i32(tmp, tmp);
7629
tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
7631
tcg_gen_or_i32(tmp, tmp, tmp2);
7632
tcg_temp_free_i32(tmp2);
7633
store_reg(s, rd, tmp);
7634
} else if ((insn & 0x00200020) == 0x00200000) {
7636
tmp = load_reg(s, rm);
7637
shift = (insn >> 7) & 0x1f;
7638
if (insn & (1 << 6)) {
7641
tcg_gen_sari_i32(tmp, tmp, shift);
7643
tcg_gen_shli_i32(tmp, tmp, shift);
7645
sh = (insn >> 16) & 0x1f;
7646
tmp2 = tcg_const_i32(sh);
7647
if (insn & (1 << 22))
7648
gen_helper_usat(tmp, cpu_env, tmp, tmp2);
7650
gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
7651
tcg_temp_free_i32(tmp2);
7652
store_reg(s, rd, tmp);
7653
} else if ((insn & 0x00300fe0) == 0x00200f20) {
7655
tmp = load_reg(s, rm);
7656
sh = (insn >> 16) & 0x1f;
7657
tmp2 = tcg_const_i32(sh);
7658
if (insn & (1 << 22))
7659
gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
7661
gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
7662
tcg_temp_free_i32(tmp2);
7663
store_reg(s, rd, tmp);
7664
} else if ((insn & 0x00700fe0) == 0x00000fa0) {
7666
tmp = load_reg(s, rn);
7667
tmp2 = load_reg(s, rm);
7668
tmp3 = tcg_temp_new_i32();
7669
tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
7670
gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7671
tcg_temp_free_i32(tmp3);
7672
tcg_temp_free_i32(tmp2);
7673
store_reg(s, rd, tmp);
7674
} else if ((insn & 0x000003e0) == 0x00000060) {
7675
tmp = load_reg(s, rm);
7676
shift = (insn >> 10) & 3;
7677
/* ??? In many cases it's not necessary to do a
7678
rotate, a shift is sufficient. */
7680
tcg_gen_rotri_i32(tmp, tmp, shift * 8);
7681
op1 = (insn >> 20) & 7;
7683
case 0: gen_sxtb16(tmp); break;
7684
case 2: gen_sxtb(tmp); break;
7685
case 3: gen_sxth(tmp); break;
7686
case 4: gen_uxtb16(tmp); break;
7687
case 6: gen_uxtb(tmp); break;
7688
case 7: gen_uxth(tmp); break;
7689
default: goto illegal_op;
7692
tmp2 = load_reg(s, rn);
7693
if ((op1 & 3) == 0) {
7694
gen_add16(tmp, tmp2);
7696
tcg_gen_add_i32(tmp, tmp, tmp2);
7697
tcg_temp_free_i32(tmp2);
7700
store_reg(s, rd, tmp);
7701
} else if ((insn & 0x003f0f60) == 0x003f0f20) {
7703
tmp = load_reg(s, rm);
7704
if (insn & (1 << 22)) {
7705
if (insn & (1 << 7)) {
7709
gen_helper_rbit(tmp, tmp);
7712
if (insn & (1 << 7))
7715
tcg_gen_bswap32_i32(tmp, tmp);
7717
store_reg(s, rd, tmp);
7722
case 2: /* Multiplies (Type 3). */
7723
switch ((insn >> 20) & 0x7) {
7725
if (((insn >> 6) ^ (insn >> 7)) & 1) {
7726
/* op2 not 00x or 11x : UNDEF */
7729
/* Signed multiply most significant [accumulate].
7730
(SMMUL, SMMLA, SMMLS) */
7731
tmp = load_reg(s, rm);
7732
tmp2 = load_reg(s, rs);
7733
tmp64 = gen_muls_i64_i32(tmp, tmp2);
7736
tmp = load_reg(s, rd);
7737
if (insn & (1 << 6)) {
7738
tmp64 = gen_subq_msw(tmp64, tmp);
7740
tmp64 = gen_addq_msw(tmp64, tmp);
7743
if (insn & (1 << 5)) {
7744
tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
7746
tcg_gen_shri_i64(tmp64, tmp64, 32);
7747
tmp = tcg_temp_new_i32();
7748
tcg_gen_trunc_i64_i32(tmp, tmp64);
7749
tcg_temp_free_i64(tmp64);
7750
store_reg(s, rn, tmp);
7754
/* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
7755
if (insn & (1 << 7)) {
7758
tmp = load_reg(s, rm);
7759
tmp2 = load_reg(s, rs);
7760
if (insn & (1 << 5))
7761
gen_swap_half(tmp2);
7762
gen_smul_dual(tmp, tmp2);
7763
if (insn & (1 << 6)) {
7764
/* This subtraction cannot overflow. */
7765
tcg_gen_sub_i32(tmp, tmp, tmp2);
7767
/* This addition cannot overflow 32 bits;
7768
* however it may overflow considered as a signed
7769
* operation, in which case we must set the Q flag.
7771
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7773
tcg_temp_free_i32(tmp2);
7774
if (insn & (1 << 22)) {
7775
/* smlald, smlsld */
7776
tmp64 = tcg_temp_new_i64();
7777
tcg_gen_ext_i32_i64(tmp64, tmp);
7778
tcg_temp_free_i32(tmp);
7779
gen_addq(s, tmp64, rd, rn);
7780
gen_storeq_reg(s, rd, rn, tmp64);
7781
tcg_temp_free_i64(tmp64);
7783
/* smuad, smusd, smlad, smlsd */
7786
tmp2 = load_reg(s, rd);
7787
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7788
tcg_temp_free_i32(tmp2);
7790
store_reg(s, rn, tmp);
7796
if (!arm_feature(env, ARM_FEATURE_ARM_DIV)) {
7799
if (((insn >> 5) & 7) || (rd != 15)) {
7802
tmp = load_reg(s, rm);
7803
tmp2 = load_reg(s, rs);
7804
if (insn & (1 << 21)) {
7805
gen_helper_udiv(tmp, tmp, tmp2);
7807
gen_helper_sdiv(tmp, tmp, tmp2);
7809
tcg_temp_free_i32(tmp2);
7810
store_reg(s, rn, tmp);
7817
op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
7819
case 0: /* Unsigned sum of absolute differences. */
7821
tmp = load_reg(s, rm);
7822
tmp2 = load_reg(s, rs);
7823
gen_helper_usad8(tmp, tmp, tmp2);
7824
tcg_temp_free_i32(tmp2);
7826
tmp2 = load_reg(s, rd);
7827
tcg_gen_add_i32(tmp, tmp, tmp2);
7828
tcg_temp_free_i32(tmp2);
7830
store_reg(s, rn, tmp);
7832
case 0x20: case 0x24: case 0x28: case 0x2c:
7833
/* Bitfield insert/clear. */
7835
shift = (insn >> 7) & 0x1f;
7836
i = (insn >> 16) & 0x1f;
7839
tmp = tcg_temp_new_i32();
7840
tcg_gen_movi_i32(tmp, 0);
7842
tmp = load_reg(s, rm);
7845
tmp2 = load_reg(s, rd);
7846
tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
7847
tcg_temp_free_i32(tmp2);
7849
store_reg(s, rd, tmp);
7851
case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
7852
case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
7854
tmp = load_reg(s, rm);
7855
shift = (insn >> 7) & 0x1f;
7856
i = ((insn >> 16) & 0x1f) + 1;
7861
gen_ubfx(tmp, shift, (1u << i) - 1);
7863
gen_sbfx(tmp, shift, i);
7866
store_reg(s, rd, tmp);
7876
/* Check for undefined extension instructions
7877
* per the ARM Bible IE:
7878
* xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
7880
sh = (0xf << 20) | (0xf << 4);
7881
if (op1 == 0x7 && ((insn & sh) == sh))
7885
/* load/store byte/word */
7886
rn = (insn >> 16) & 0xf;
7887
rd = (insn >> 12) & 0xf;
7888
tmp2 = load_reg(s, rn);
7889
i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
7890
if (insn & (1 << 24))
7891
gen_add_data_offset(s, insn, tmp2);
7892
if (insn & (1 << 20)) {
7894
tmp = tcg_temp_new_i32();
7895
if (insn & (1 << 22)) {
7896
gen_aa32_ld8u(tmp, tmp2, i);
7898
gen_aa32_ld32u(tmp, tmp2, i);
7902
tmp = load_reg(s, rd);
7903
if (insn & (1 << 22)) {
7904
gen_aa32_st8(tmp, tmp2, i);
7906
gen_aa32_st32(tmp, tmp2, i);
7908
tcg_temp_free_i32(tmp);
7910
if (!(insn & (1 << 24))) {
7911
gen_add_data_offset(s, insn, tmp2);
7912
store_reg(s, rn, tmp2);
7913
} else if (insn & (1 << 21)) {
7914
store_reg(s, rn, tmp2);
7916
tcg_temp_free_i32(tmp2);
7918
if (insn & (1 << 20)) {
7919
/* Complete the load. */
7920
store_reg_from_load(env, s, rd, tmp);
7926
int j, n, user, loaded_base;
7927
TCGv_i32 loaded_var;
7928
/* load/store multiple words */
7929
/* XXX: store correct base if write back */
7931
if (insn & (1 << 22)) {
7933
goto illegal_op; /* only usable in supervisor mode */
7935
if ((insn & (1 << 15)) == 0)
7938
rn = (insn >> 16) & 0xf;
7939
addr = load_reg(s, rn);
7941
/* compute total size */
7943
TCGV_UNUSED_I32(loaded_var);
7946
if (insn & (1 << i))
7949
/* XXX: test invalid n == 0 case ? */
7950
if (insn & (1 << 23)) {
7951
if (insn & (1 << 24)) {
7953
tcg_gen_addi_i32(addr, addr, 4);
7955
/* post increment */
7958
if (insn & (1 << 24)) {
7960
tcg_gen_addi_i32(addr, addr, -(n * 4));
7962
/* post decrement */
7964
tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
7969
if (insn & (1 << i)) {
7970
if (insn & (1 << 20)) {
7972
tmp = tcg_temp_new_i32();
7973
gen_aa32_ld32u(tmp, addr, IS_USER(s));
7975
tmp2 = tcg_const_i32(i);
7976
gen_helper_set_user_reg(cpu_env, tmp2, tmp);
7977
tcg_temp_free_i32(tmp2);
7978
tcg_temp_free_i32(tmp);
7979
} else if (i == rn) {
7983
store_reg_from_load(env, s, i, tmp);
7988
/* special case: r15 = PC + 8 */
7989
val = (long)s->pc + 4;
7990
tmp = tcg_temp_new_i32();
7991
tcg_gen_movi_i32(tmp, val);
7993
tmp = tcg_temp_new_i32();
7994
tmp2 = tcg_const_i32(i);
7995
gen_helper_get_user_reg(tmp, cpu_env, tmp2);
7996
tcg_temp_free_i32(tmp2);
7998
tmp = load_reg(s, i);
8000
gen_aa32_st32(tmp, addr, IS_USER(s));
8001
tcg_temp_free_i32(tmp);
8004
/* no need to add after the last transfer */
8006
tcg_gen_addi_i32(addr, addr, 4);
8009
if (insn & (1 << 21)) {
8011
if (insn & (1 << 23)) {
8012
if (insn & (1 << 24)) {
8015
/* post increment */
8016
tcg_gen_addi_i32(addr, addr, 4);
8019
if (insn & (1 << 24)) {
8022
tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8024
/* post decrement */
8025
tcg_gen_addi_i32(addr, addr, -(n * 4));
8028
store_reg(s, rn, addr);
8030
tcg_temp_free_i32(addr);
8033
store_reg(s, rn, loaded_var);
8035
if ((insn & (1 << 22)) && !user) {
8036
/* Restore CPSR from SPSR. */
8037
tmp = load_cpu_field(spsr);
8038
gen_set_cpsr(tmp, 0xffffffff);
8039
tcg_temp_free_i32(tmp);
8040
s->is_jmp = DISAS_UPDATE;
8049
/* branch (and link) */
8050
val = (int32_t)s->pc;
8051
if (insn & (1 << 24)) {
8052
tmp = tcg_temp_new_i32();
8053
tcg_gen_movi_i32(tmp, val);
8054
store_reg(s, 14, tmp);
8056
offset = sextract32(insn << 2, 0, 26);
8064
if (((insn >> 8) & 0xe) == 10) {
8066
if (disas_vfp_insn(env, s, insn)) {
8069
} else if (disas_coproc_insn(env, s, insn)) {
8076
gen_set_pc_im(s, s->pc);
8077
s->is_jmp = DISAS_SWI;
8081
gen_exception_insn(s, 4, EXCP_UDEF);
8087
/* Return true if this is a Thumb-2 logical op. */
8089
thumb2_logic_op(int op)
8094
/* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
8095
then set condition code flags based on the result of the operation.
8096
If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8097
to the high bit of T1.
8098
Returns zero if the opcode is valid. */
8101
gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
8102
TCGv_i32 t0, TCGv_i32 t1)
8109
tcg_gen_and_i32(t0, t0, t1);
8113
tcg_gen_andc_i32(t0, t0, t1);
8117
tcg_gen_or_i32(t0, t0, t1);
8121
tcg_gen_orc_i32(t0, t0, t1);
8125
tcg_gen_xor_i32(t0, t0, t1);
8130
gen_add_CC(t0, t0, t1);
8132
tcg_gen_add_i32(t0, t0, t1);
8136
gen_adc_CC(t0, t0, t1);
8142
gen_sbc_CC(t0, t0, t1);
8144
gen_sub_carry(t0, t0, t1);
8149
gen_sub_CC(t0, t0, t1);
8151
tcg_gen_sub_i32(t0, t0, t1);
8155
gen_sub_CC(t0, t1, t0);
8157
tcg_gen_sub_i32(t0, t1, t0);
8159
default: /* 5, 6, 7, 9, 12, 15. */
8165
gen_set_CF_bit31(t1);
8170
/* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
8172
static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
8174
uint32_t insn, imm, shift, offset;
8175
uint32_t rd, rn, rm, rs;
8186
if (!(arm_feature(env, ARM_FEATURE_THUMB2)
8187
|| arm_feature (env, ARM_FEATURE_M))) {
8188
/* Thumb-1 cores may need to treat bl and blx as a pair of
8189
16-bit instructions to get correct prefetch abort behavior. */
8191
if ((insn & (1 << 12)) == 0) {
8193
/* Second half of blx. */
8194
offset = ((insn & 0x7ff) << 1);
8195
tmp = load_reg(s, 14);
8196
tcg_gen_addi_i32(tmp, tmp, offset);
8197
tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
8199
tmp2 = tcg_temp_new_i32();
8200
tcg_gen_movi_i32(tmp2, s->pc | 1);
8201
store_reg(s, 14, tmp2);
8205
if (insn & (1 << 11)) {
8206
/* Second half of bl. */
8207
offset = ((insn & 0x7ff) << 1) | 1;
8208
tmp = load_reg(s, 14);
8209
tcg_gen_addi_i32(tmp, tmp, offset);
8211
tmp2 = tcg_temp_new_i32();
8212
tcg_gen_movi_i32(tmp2, s->pc | 1);
8213
store_reg(s, 14, tmp2);
8217
if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
8218
/* Instruction spans a page boundary. Implement it as two
8219
16-bit instructions in case the second half causes an
8221
offset = ((int32_t)insn << 21) >> 9;
8222
tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
8225
/* Fall through to 32-bit decode. */
8228
insn = arm_lduw_code(env, s->pc, s->bswap_code);
8230
insn |= (uint32_t)insn_hw1 << 16;
8232
if ((insn & 0xf800e800) != 0xf000e800) {
8236
rn = (insn >> 16) & 0xf;
8237
rs = (insn >> 12) & 0xf;
8238
rd = (insn >> 8) & 0xf;
8240
switch ((insn >> 25) & 0xf) {
8241
case 0: case 1: case 2: case 3:
8242
/* 16-bit instructions. Should never happen. */
8245
if (insn & (1 << 22)) {
8246
/* Other load/store, table branch. */
8247
if (insn & 0x01200000) {
8248
/* Load/store doubleword. */
8250
addr = tcg_temp_new_i32();
8251
tcg_gen_movi_i32(addr, s->pc & ~3);
8253
addr = load_reg(s, rn);
8255
offset = (insn & 0xff) * 4;
8256
if ((insn & (1 << 23)) == 0)
8258
if (insn & (1 << 24)) {
8259
tcg_gen_addi_i32(addr, addr, offset);
8262
if (insn & (1 << 20)) {
8264
tmp = tcg_temp_new_i32();
8265
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8266
store_reg(s, rs, tmp);
8267
tcg_gen_addi_i32(addr, addr, 4);
8268
tmp = tcg_temp_new_i32();
8269
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8270
store_reg(s, rd, tmp);
8273
tmp = load_reg(s, rs);
8274
gen_aa32_st32(tmp, addr, IS_USER(s));
8275
tcg_temp_free_i32(tmp);
8276
tcg_gen_addi_i32(addr, addr, 4);
8277
tmp = load_reg(s, rd);
8278
gen_aa32_st32(tmp, addr, IS_USER(s));
8279
tcg_temp_free_i32(tmp);
8281
if (insn & (1 << 21)) {
8282
/* Base writeback. */
8285
tcg_gen_addi_i32(addr, addr, offset - 4);
8286
store_reg(s, rn, addr);
8288
tcg_temp_free_i32(addr);
8290
} else if ((insn & (1 << 23)) == 0) {
8291
/* Load/store exclusive word. */
8292
addr = tcg_temp_local_new_i32();
8293
load_reg_var(s, addr, rn);
8294
tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
8295
if (insn & (1 << 20)) {
8296
gen_load_exclusive(s, rs, 15, addr, 2);
8298
gen_store_exclusive(s, rd, rs, 15, addr, 2);
8300
tcg_temp_free_i32(addr);
8301
} else if ((insn & (7 << 5)) == 0) {
8304
addr = tcg_temp_new_i32();
8305
tcg_gen_movi_i32(addr, s->pc);
8307
addr = load_reg(s, rn);
8309
tmp = load_reg(s, rm);
8310
tcg_gen_add_i32(addr, addr, tmp);
8311
if (insn & (1 << 4)) {
8313
tcg_gen_add_i32(addr, addr, tmp);
8314
tcg_temp_free_i32(tmp);
8315
tmp = tcg_temp_new_i32();
8316
gen_aa32_ld16u(tmp, addr, IS_USER(s));
8318
tcg_temp_free_i32(tmp);
8319
tmp = tcg_temp_new_i32();
8320
gen_aa32_ld8u(tmp, addr, IS_USER(s));
8322
tcg_temp_free_i32(addr);
8323
tcg_gen_shli_i32(tmp, tmp, 1);
8324
tcg_gen_addi_i32(tmp, tmp, s->pc);
8325
store_reg(s, 15, tmp);
8327
int op2 = (insn >> 6) & 0x3;
8328
op = (insn >> 4) & 0x3;
8333
/* Load/store exclusive byte/halfword/doubleword */
8340
/* Load-acquire/store-release */
8346
/* Load-acquire/store-release exclusive */
8350
addr = tcg_temp_local_new_i32();
8351
load_reg_var(s, addr, rn);
8353
if (insn & (1 << 20)) {
8354
tmp = tcg_temp_new_i32();
8357
gen_aa32_ld8u(tmp, addr, IS_USER(s));
8360
gen_aa32_ld16u(tmp, addr, IS_USER(s));
8363
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8368
store_reg(s, rs, tmp);
8370
tmp = load_reg(s, rs);
8373
gen_aa32_st8(tmp, addr, IS_USER(s));
8376
gen_aa32_st16(tmp, addr, IS_USER(s));
8379
gen_aa32_st32(tmp, addr, IS_USER(s));
8384
tcg_temp_free_i32(tmp);
8386
} else if (insn & (1 << 20)) {
8387
gen_load_exclusive(s, rs, rd, addr, op);
8389
gen_store_exclusive(s, rm, rs, rd, addr, op);
8391
tcg_temp_free_i32(addr);
8394
/* Load/store multiple, RFE, SRS. */
8395
if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
8396
/* RFE, SRS: not available in user mode or on M profile */
8397
if (IS_USER(s) || IS_M(env)) {
8400
if (insn & (1 << 20)) {
8402
addr = load_reg(s, rn);
8403
if ((insn & (1 << 24)) == 0)
8404
tcg_gen_addi_i32(addr, addr, -8);
8405
/* Load PC into tmp and CPSR into tmp2. */
8406
tmp = tcg_temp_new_i32();
8407
gen_aa32_ld32u(tmp, addr, 0);
8408
tcg_gen_addi_i32(addr, addr, 4);
8409
tmp2 = tcg_temp_new_i32();
8410
gen_aa32_ld32u(tmp2, addr, 0);
8411
if (insn & (1 << 21)) {
8412
/* Base writeback. */
8413
if (insn & (1 << 24)) {
8414
tcg_gen_addi_i32(addr, addr, 4);
8416
tcg_gen_addi_i32(addr, addr, -4);
8418
store_reg(s, rn, addr);
8420
tcg_temp_free_i32(addr);
8422
gen_rfe(s, tmp, tmp2);
8425
gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
8429
int i, loaded_base = 0;
8430
TCGv_i32 loaded_var;
8431
/* Load/store multiple. */
8432
addr = load_reg(s, rn);
8434
for (i = 0; i < 16; i++) {
8435
if (insn & (1 << i))
8438
if (insn & (1 << 24)) {
8439
tcg_gen_addi_i32(addr, addr, -offset);
8442
TCGV_UNUSED_I32(loaded_var);
8443
for (i = 0; i < 16; i++) {
8444
if ((insn & (1 << i)) == 0)
8446
if (insn & (1 << 20)) {
8448
tmp = tcg_temp_new_i32();
8449
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8452
} else if (i == rn) {
8456
store_reg(s, i, tmp);
8460
tmp = load_reg(s, i);
8461
gen_aa32_st32(tmp, addr, IS_USER(s));
8462
tcg_temp_free_i32(tmp);
8464
tcg_gen_addi_i32(addr, addr, 4);
8467
store_reg(s, rn, loaded_var);
8469
if (insn & (1 << 21)) {
8470
/* Base register writeback. */
8471
if (insn & (1 << 24)) {
8472
tcg_gen_addi_i32(addr, addr, -offset);
8474
/* Fault if writeback register is in register list. */
8475
if (insn & (1 << rn))
8477
store_reg(s, rn, addr);
8479
tcg_temp_free_i32(addr);
8486
op = (insn >> 21) & 0xf;
8488
/* Halfword pack. */
8489
tmp = load_reg(s, rn);
8490
tmp2 = load_reg(s, rm);
8491
shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
8492
if (insn & (1 << 5)) {
8496
tcg_gen_sari_i32(tmp2, tmp2, shift);
8497
tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8498
tcg_gen_ext16u_i32(tmp2, tmp2);
8502
tcg_gen_shli_i32(tmp2, tmp2, shift);
8503
tcg_gen_ext16u_i32(tmp, tmp);
8504
tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8506
tcg_gen_or_i32(tmp, tmp, tmp2);
8507
tcg_temp_free_i32(tmp2);
8508
store_reg(s, rd, tmp);
8510
/* Data processing register constant shift. */
8512
tmp = tcg_temp_new_i32();
8513
tcg_gen_movi_i32(tmp, 0);
8515
tmp = load_reg(s, rn);
8517
tmp2 = load_reg(s, rm);
8519
shiftop = (insn >> 4) & 3;
8520
shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
8521
conds = (insn & (1 << 20)) != 0;
8522
logic_cc = (conds && thumb2_logic_op(op));
8523
gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8524
if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
8526
tcg_temp_free_i32(tmp2);
8528
store_reg(s, rd, tmp);
8530
tcg_temp_free_i32(tmp);
8534
case 13: /* Misc data processing. */
8535
op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
8536
if (op < 4 && (insn & 0xf000) != 0xf000)
8539
case 0: /* Register controlled shift. */
8540
tmp = load_reg(s, rn);
8541
tmp2 = load_reg(s, rm);
8542
if ((insn & 0x70) != 0)
8544
op = (insn >> 21) & 3;
8545
logic_cc = (insn & (1 << 20)) != 0;
8546
gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
8549
store_reg_bx(env, s, rd, tmp);
8551
case 1: /* Sign/zero extend. */
8552
tmp = load_reg(s, rm);
8553
shift = (insn >> 4) & 3;
8554
/* ??? In many cases it's not necessary to do a
8555
rotate, a shift is sufficient. */
8557
tcg_gen_rotri_i32(tmp, tmp, shift * 8);
8558
op = (insn >> 20) & 7;
8560
case 0: gen_sxth(tmp); break;
8561
case 1: gen_uxth(tmp); break;
8562
case 2: gen_sxtb16(tmp); break;
8563
case 3: gen_uxtb16(tmp); break;
8564
case 4: gen_sxtb(tmp); break;
8565
case 5: gen_uxtb(tmp); break;
8566
default: goto illegal_op;
8569
tmp2 = load_reg(s, rn);
8570
if ((op >> 1) == 1) {
8571
gen_add16(tmp, tmp2);
8573
tcg_gen_add_i32(tmp, tmp, tmp2);
8574
tcg_temp_free_i32(tmp2);
8577
store_reg(s, rd, tmp);
8579
case 2: /* SIMD add/subtract. */
8580
op = (insn >> 20) & 7;
8581
shift = (insn >> 4) & 7;
8582
if ((op & 3) == 3 || (shift & 3) == 3)
8584
tmp = load_reg(s, rn);
8585
tmp2 = load_reg(s, rm);
8586
gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
8587
tcg_temp_free_i32(tmp2);
8588
store_reg(s, rd, tmp);
8590
case 3: /* Other data processing. */
8591
op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
8593
/* Saturating add/subtract. */
8594
tmp = load_reg(s, rn);
8595
tmp2 = load_reg(s, rm);
8597
gen_helper_double_saturate(tmp, cpu_env, tmp);
8599
gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
8601
gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8602
tcg_temp_free_i32(tmp2);
8604
tmp = load_reg(s, rn);
8606
case 0x0a: /* rbit */
8607
gen_helper_rbit(tmp, tmp);
8609
case 0x08: /* rev */
8610
tcg_gen_bswap32_i32(tmp, tmp);
8612
case 0x09: /* rev16 */
8615
case 0x0b: /* revsh */
8618
case 0x10: /* sel */
8619
tmp2 = load_reg(s, rm);
8620
tmp3 = tcg_temp_new_i32();
8621
tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
8622
gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
8623
tcg_temp_free_i32(tmp3);
8624
tcg_temp_free_i32(tmp2);
8626
case 0x18: /* clz */
8627
gen_helper_clz(tmp, tmp);
8633
store_reg(s, rd, tmp);
8635
case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
8636
op = (insn >> 4) & 0xf;
8637
tmp = load_reg(s, rn);
8638
tmp2 = load_reg(s, rm);
8639
switch ((insn >> 20) & 7) {
8640
case 0: /* 32 x 32 -> 32 */
8641
tcg_gen_mul_i32(tmp, tmp, tmp2);
8642
tcg_temp_free_i32(tmp2);
8644
tmp2 = load_reg(s, rs);
8646
tcg_gen_sub_i32(tmp, tmp2, tmp);
8648
tcg_gen_add_i32(tmp, tmp, tmp2);
8649
tcg_temp_free_i32(tmp2);
8652
case 1: /* 16 x 16 -> 32 */
8653
gen_mulxy(tmp, tmp2, op & 2, op & 1);
8654
tcg_temp_free_i32(tmp2);
8656
tmp2 = load_reg(s, rs);
8657
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8658
tcg_temp_free_i32(tmp2);
8661
case 2: /* Dual multiply add. */
8662
case 4: /* Dual multiply subtract. */
8664
gen_swap_half(tmp2);
8665
gen_smul_dual(tmp, tmp2);
8666
if (insn & (1 << 22)) {
8667
/* This subtraction cannot overflow. */
8668
tcg_gen_sub_i32(tmp, tmp, tmp2);
8670
/* This addition cannot overflow 32 bits;
8671
* however it may overflow considered as a signed
8672
* operation, in which case we must set the Q flag.
8674
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8676
tcg_temp_free_i32(tmp2);
8679
tmp2 = load_reg(s, rs);
8680
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8681
tcg_temp_free_i32(tmp2);
8684
case 3: /* 32 * 16 -> 32msb */
8686
tcg_gen_sari_i32(tmp2, tmp2, 16);
8689
tmp64 = gen_muls_i64_i32(tmp, tmp2);
8690
tcg_gen_shri_i64(tmp64, tmp64, 16);
8691
tmp = tcg_temp_new_i32();
8692
tcg_gen_trunc_i64_i32(tmp, tmp64);
8693
tcg_temp_free_i64(tmp64);
8696
tmp2 = load_reg(s, rs);
8697
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8698
tcg_temp_free_i32(tmp2);
8701
case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
8702
tmp64 = gen_muls_i64_i32(tmp, tmp2);
8704
tmp = load_reg(s, rs);
8705
if (insn & (1 << 20)) {
8706
tmp64 = gen_addq_msw(tmp64, tmp);
8708
tmp64 = gen_subq_msw(tmp64, tmp);
8711
if (insn & (1 << 4)) {
8712
tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
8714
tcg_gen_shri_i64(tmp64, tmp64, 32);
8715
tmp = tcg_temp_new_i32();
8716
tcg_gen_trunc_i64_i32(tmp, tmp64);
8717
tcg_temp_free_i64(tmp64);
8719
case 7: /* Unsigned sum of absolute differences. */
8720
gen_helper_usad8(tmp, tmp, tmp2);
8721
tcg_temp_free_i32(tmp2);
8723
tmp2 = load_reg(s, rs);
8724
tcg_gen_add_i32(tmp, tmp, tmp2);
8725
tcg_temp_free_i32(tmp2);
8729
store_reg(s, rd, tmp);
8731
case 6: case 7: /* 64-bit multiply, Divide. */
8732
op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
8733
tmp = load_reg(s, rn);
8734
tmp2 = load_reg(s, rm);
8735
if ((op & 0x50) == 0x10) {
8737
if (!arm_feature(env, ARM_FEATURE_THUMB_DIV)) {
8741
gen_helper_udiv(tmp, tmp, tmp2);
8743
gen_helper_sdiv(tmp, tmp, tmp2);
8744
tcg_temp_free_i32(tmp2);
8745
store_reg(s, rd, tmp);
8746
} else if ((op & 0xe) == 0xc) {
8747
/* Dual multiply accumulate long. */
8749
gen_swap_half(tmp2);
8750
gen_smul_dual(tmp, tmp2);
8752
tcg_gen_sub_i32(tmp, tmp, tmp2);
8754
tcg_gen_add_i32(tmp, tmp, tmp2);
8756
tcg_temp_free_i32(tmp2);
8758
tmp64 = tcg_temp_new_i64();
8759
tcg_gen_ext_i32_i64(tmp64, tmp);
8760
tcg_temp_free_i32(tmp);
8761
gen_addq(s, tmp64, rs, rd);
8762
gen_storeq_reg(s, rs, rd, tmp64);
8763
tcg_temp_free_i64(tmp64);
8766
/* Unsigned 64-bit multiply */
8767
tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8771
gen_mulxy(tmp, tmp2, op & 2, op & 1);
8772
tcg_temp_free_i32(tmp2);
8773
tmp64 = tcg_temp_new_i64();
8774
tcg_gen_ext_i32_i64(tmp64, tmp);
8775
tcg_temp_free_i32(tmp);
8777
/* Signed 64-bit multiply */
8778
tmp64 = gen_muls_i64_i32(tmp, tmp2);
8783
gen_addq_lo(s, tmp64, rs);
8784
gen_addq_lo(s, tmp64, rd);
8785
} else if (op & 0x40) {
8786
/* 64-bit accumulate. */
8787
gen_addq(s, tmp64, rs, rd);
8789
gen_storeq_reg(s, rs, rd, tmp64);
8790
tcg_temp_free_i64(tmp64);
8795
case 6: case 7: case 14: case 15:
8797
if (((insn >> 24) & 3) == 3) {
8798
/* Translate into the equivalent ARM encoding. */
8799
insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
8800
if (disas_neon_data_insn(env, s, insn))
8802
} else if (((insn >> 8) & 0xe) == 10) {
8803
if (disas_vfp_insn(env, s, insn)) {
8807
if (insn & (1 << 28))
8809
if (disas_coproc_insn (env, s, insn))
8813
case 8: case 9: case 10: case 11:
8814
if (insn & (1 << 15)) {
8815
/* Branches, misc control. */
8816
if (insn & 0x5000) {
8817
/* Unconditional branch. */
8818
/* signextend(hw1[10:0]) -> offset[:12]. */
8819
offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
8820
/* hw1[10:0] -> offset[11:1]. */
8821
offset |= (insn & 0x7ff) << 1;
8822
/* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
8823
offset[24:22] already have the same value because of the
8824
sign extension above. */
8825
offset ^= ((~insn) & (1 << 13)) << 10;
8826
offset ^= ((~insn) & (1 << 11)) << 11;
8828
if (insn & (1 << 14)) {
8829
/* Branch and link. */
8830
tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
8834
if (insn & (1 << 12)) {
8839
offset &= ~(uint32_t)2;
8840
/* thumb2 bx, no need to check */
8841
gen_bx_im(s, offset);
8843
} else if (((insn >> 23) & 7) == 7) {
8845
if (insn & (1 << 13))
8848
if (insn & (1 << 26)) {
8849
/* Secure monitor call / smc (v6Z) */
8850
if (!arm_feature(env, ARM_FEATURE_TRUSTZONE)
8856
op = (insn >> 20) & 7;
8858
case 0: /* msr cpsr. */
8860
tmp = load_reg(s, rn);
8861
addr = tcg_const_i32(insn & 0xff);
8862
gen_helper_v7m_msr(cpu_env, addr, tmp);
8863
tcg_temp_free_i32(addr);
8864
tcg_temp_free_i32(tmp);
8869
case 1: /* msr spsr. */
8872
tmp = load_reg(s, rn);
8874
msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
8878
case 2: /* cps, nop-hint. */
8879
if (((insn >> 8) & 7) == 0) {
8880
gen_nop_hint(s, insn & 0xff);
8882
/* Implemented as NOP in user mode. */
8887
if (insn & (1 << 10)) {
8888
if (insn & (1 << 7))
8890
if (insn & (1 << 6))
8892
if (insn & (1 << 5))
8894
if (insn & (1 << 9))
8895
imm = CPSR_A | CPSR_I | CPSR_F;
8897
if (insn & (1 << 8)) {
8899
imm |= (insn & 0x1f);
8902
gen_set_psr_im(s, offset, 0, imm);
8905
case 3: /* Special control operations. */
8907
op = (insn >> 4) & 0xf;
8915
/* These execute as NOPs. */
8922
/* Trivial implementation equivalent to bx. */
8923
tmp = load_reg(s, rn);
8926
case 5: /* Exception return. */
8930
if (rn != 14 || rd != 15) {
8933
tmp = load_reg(s, rn);
8934
tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
8935
gen_exception_return(s, tmp);
8937
case 6: /* mrs cpsr. */
8938
tmp = tcg_temp_new_i32();
8940
addr = tcg_const_i32(insn & 0xff);
8941
gen_helper_v7m_mrs(tmp, cpu_env, addr);
8942
tcg_temp_free_i32(addr);
8944
gen_helper_cpsr_read(tmp, cpu_env);
8946
store_reg(s, rd, tmp);
8948
case 7: /* mrs spsr. */
8949
/* Not accessible in user mode. */
8950
if (IS_USER(s) || IS_M(env))
8952
tmp = load_cpu_field(spsr);
8953
store_reg(s, rd, tmp);
8958
/* Conditional branch. */
8959
op = (insn >> 22) & 0xf;
8960
/* Generate a conditional jump to next instruction. */
8961
s->condlabel = gen_new_label();
8962
gen_test_cc(op ^ 1, s->condlabel);
8965
/* offset[11:1] = insn[10:0] */
8966
offset = (insn & 0x7ff) << 1;
8967
/* offset[17:12] = insn[21:16]. */
8968
offset |= (insn & 0x003f0000) >> 4;
8969
/* offset[31:20] = insn[26]. */
8970
offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
8971
/* offset[18] = insn[13]. */
8972
offset |= (insn & (1 << 13)) << 5;
8973
/* offset[19] = insn[11]. */
8974
offset |= (insn & (1 << 11)) << 8;
8976
/* jump to the offset */
8977
gen_jmp(s, s->pc + offset);
8980
/* Data processing immediate. */
8981
if (insn & (1 << 25)) {
8982
if (insn & (1 << 24)) {
8983
if (insn & (1 << 20))
8985
/* Bitfield/Saturate. */
8986
op = (insn >> 21) & 7;
8988
shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
8990
tmp = tcg_temp_new_i32();
8991
tcg_gen_movi_i32(tmp, 0);
8993
tmp = load_reg(s, rn);
8996
case 2: /* Signed bitfield extract. */
8998
if (shift + imm > 32)
9001
gen_sbfx(tmp, shift, imm);
9003
case 6: /* Unsigned bitfield extract. */
9005
if (shift + imm > 32)
9008
gen_ubfx(tmp, shift, (1u << imm) - 1);
9010
case 3: /* Bitfield insert/clear. */
9013
imm = imm + 1 - shift;
9015
tmp2 = load_reg(s, rd);
9016
tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
9017
tcg_temp_free_i32(tmp2);
9022
default: /* Saturate. */
9025
tcg_gen_sari_i32(tmp, tmp, shift);
9027
tcg_gen_shli_i32(tmp, tmp, shift);
9029
tmp2 = tcg_const_i32(imm);
9032
if ((op & 1) && shift == 0)
9033
gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9035
gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9038
if ((op & 1) && shift == 0)
9039
gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9041
gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9043
tcg_temp_free_i32(tmp2);
9046
store_reg(s, rd, tmp);
9048
imm = ((insn & 0x04000000) >> 15)
9049
| ((insn & 0x7000) >> 4) | (insn & 0xff);
9050
if (insn & (1 << 22)) {
9051
/* 16-bit immediate. */
9052
imm |= (insn >> 4) & 0xf000;
9053
if (insn & (1 << 23)) {
9055
tmp = load_reg(s, rd);
9056
tcg_gen_ext16u_i32(tmp, tmp);
9057
tcg_gen_ori_i32(tmp, tmp, imm << 16);
9060
tmp = tcg_temp_new_i32();
9061
tcg_gen_movi_i32(tmp, imm);
9064
/* Add/sub 12-bit immediate. */
9066
offset = s->pc & ~(uint32_t)3;
9067
if (insn & (1 << 23))
9071
tmp = tcg_temp_new_i32();
9072
tcg_gen_movi_i32(tmp, offset);
9074
tmp = load_reg(s, rn);
9075
if (insn & (1 << 23))
9076
tcg_gen_subi_i32(tmp, tmp, imm);
9078
tcg_gen_addi_i32(tmp, tmp, imm);
9081
store_reg(s, rd, tmp);
9084
int shifter_out = 0;
9085
/* modified 12-bit immediate. */
9086
shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
9087
imm = (insn & 0xff);
9090
/* Nothing to do. */
9092
case 1: /* 00XY00XY */
9095
case 2: /* XY00XY00 */
9099
case 3: /* XYXYXYXY */
9103
default: /* Rotated constant. */
9104
shift = (shift << 1) | (imm >> 7);
9106
imm = imm << (32 - shift);
9110
tmp2 = tcg_temp_new_i32();
9111
tcg_gen_movi_i32(tmp2, imm);
9112
rn = (insn >> 16) & 0xf;
9114
tmp = tcg_temp_new_i32();
9115
tcg_gen_movi_i32(tmp, 0);
9117
tmp = load_reg(s, rn);
9119
op = (insn >> 21) & 0xf;
9120
if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
9121
shifter_out, tmp, tmp2))
9123
tcg_temp_free_i32(tmp2);
9124
rd = (insn >> 8) & 0xf;
9126
store_reg(s, rd, tmp);
9128
tcg_temp_free_i32(tmp);
9133
case 12: /* Load/store single data item. */
9138
if ((insn & 0x01100000) == 0x01000000) {
9139
if (disas_neon_ls_insn(env, s, insn))
9143
op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
9145
if (!(insn & (1 << 20))) {
9149
/* Byte or halfword load space with dest == r15 : memory hints.
9150
* Catch them early so we don't emit pointless addressing code.
9151
* This space is a mix of:
9152
* PLD/PLDW/PLI, which we implement as NOPs (note that unlike
9153
* the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
9155
* unallocated hints, which must be treated as NOPs
9156
* UNPREDICTABLE space, which we NOP or UNDEF depending on
9157
* which is easiest for the decoding logic
9158
* Some space which must UNDEF
9160
int op1 = (insn >> 23) & 3;
9161
int op2 = (insn >> 6) & 0x3f;
9166
/* UNPREDICTABLE, unallocated hint or
9167
* PLD/PLDW/PLI (literal)
9172
return 0; /* PLD/PLDW/PLI or unallocated hint */
9174
if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
9175
return 0; /* PLD/PLDW/PLI or unallocated hint */
9177
/* UNDEF space, or an UNPREDICTABLE */
9183
addr = tcg_temp_new_i32();
9185
/* s->pc has already been incremented by 4. */
9186
imm = s->pc & 0xfffffffc;
9187
if (insn & (1 << 23))
9188
imm += insn & 0xfff;
9190
imm -= insn & 0xfff;
9191
tcg_gen_movi_i32(addr, imm);
9193
addr = load_reg(s, rn);
9194
if (insn & (1 << 23)) {
9195
/* Positive offset. */
9197
tcg_gen_addi_i32(addr, addr, imm);
9200
switch ((insn >> 8) & 0xf) {
9201
case 0x0: /* Shifted Register. */
9202
shift = (insn >> 4) & 0xf;
9204
tcg_temp_free_i32(addr);
9207
tmp = load_reg(s, rm);
9209
tcg_gen_shli_i32(tmp, tmp, shift);
9210
tcg_gen_add_i32(addr, addr, tmp);
9211
tcg_temp_free_i32(tmp);
9213
case 0xc: /* Negative offset. */
9214
tcg_gen_addi_i32(addr, addr, -imm);
9216
case 0xe: /* User privilege. */
9217
tcg_gen_addi_i32(addr, addr, imm);
9220
case 0x9: /* Post-decrement. */
9223
case 0xb: /* Post-increment. */
9227
case 0xd: /* Pre-decrement. */
9230
case 0xf: /* Pre-increment. */
9231
tcg_gen_addi_i32(addr, addr, imm);
9235
tcg_temp_free_i32(addr);
9240
if (insn & (1 << 20)) {
9242
tmp = tcg_temp_new_i32();
9245
gen_aa32_ld8u(tmp, addr, user);
9248
gen_aa32_ld8s(tmp, addr, user);
9251
gen_aa32_ld16u(tmp, addr, user);
9254
gen_aa32_ld16s(tmp, addr, user);
9257
gen_aa32_ld32u(tmp, addr, user);
9260
tcg_temp_free_i32(tmp);
9261
tcg_temp_free_i32(addr);
9267
store_reg(s, rs, tmp);
9271
tmp = load_reg(s, rs);
9274
gen_aa32_st8(tmp, addr, user);
9277
gen_aa32_st16(tmp, addr, user);
9280
gen_aa32_st32(tmp, addr, user);
9283
tcg_temp_free_i32(tmp);
9284
tcg_temp_free_i32(addr);
9287
tcg_temp_free_i32(tmp);
9290
tcg_gen_addi_i32(addr, addr, imm);
9292
store_reg(s, rn, addr);
9294
tcg_temp_free_i32(addr);
9306
static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
9308
uint32_t val, insn, op, rm, rn, rd, shift, cond;
9315
if (s->condexec_mask) {
9316
cond = s->condexec_cond;
9317
if (cond != 0x0e) { /* Skip conditional when condition is AL. */
9318
s->condlabel = gen_new_label();
9319
gen_test_cc(cond ^ 1, s->condlabel);
9324
insn = arm_lduw_code(env, s->pc, s->bswap_code);
9327
switch (insn >> 12) {
9331
op = (insn >> 11) & 3;
9334
rn = (insn >> 3) & 7;
9335
tmp = load_reg(s, rn);
9336
if (insn & (1 << 10)) {
9338
tmp2 = tcg_temp_new_i32();
9339
tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
9342
rm = (insn >> 6) & 7;
9343
tmp2 = load_reg(s, rm);
9345
if (insn & (1 << 9)) {
9346
if (s->condexec_mask)
9347
tcg_gen_sub_i32(tmp, tmp, tmp2);
9349
gen_sub_CC(tmp, tmp, tmp2);
9351
if (s->condexec_mask)
9352
tcg_gen_add_i32(tmp, tmp, tmp2);
9354
gen_add_CC(tmp, tmp, tmp2);
9356
tcg_temp_free_i32(tmp2);
9357
store_reg(s, rd, tmp);
9359
/* shift immediate */
9360
rm = (insn >> 3) & 7;
9361
shift = (insn >> 6) & 0x1f;
9362
tmp = load_reg(s, rm);
9363
gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
9364
if (!s->condexec_mask)
9366
store_reg(s, rd, tmp);
9370
/* arithmetic large immediate */
9371
op = (insn >> 11) & 3;
9372
rd = (insn >> 8) & 0x7;
9373
if (op == 0) { /* mov */
9374
tmp = tcg_temp_new_i32();
9375
tcg_gen_movi_i32(tmp, insn & 0xff);
9376
if (!s->condexec_mask)
9378
store_reg(s, rd, tmp);
9380
tmp = load_reg(s, rd);
9381
tmp2 = tcg_temp_new_i32();
9382
tcg_gen_movi_i32(tmp2, insn & 0xff);
9385
gen_sub_CC(tmp, tmp, tmp2);
9386
tcg_temp_free_i32(tmp);
9387
tcg_temp_free_i32(tmp2);
9390
if (s->condexec_mask)
9391
tcg_gen_add_i32(tmp, tmp, tmp2);
9393
gen_add_CC(tmp, tmp, tmp2);
9394
tcg_temp_free_i32(tmp2);
9395
store_reg(s, rd, tmp);
9398
if (s->condexec_mask)
9399
tcg_gen_sub_i32(tmp, tmp, tmp2);
9401
gen_sub_CC(tmp, tmp, tmp2);
9402
tcg_temp_free_i32(tmp2);
9403
store_reg(s, rd, tmp);
9409
if (insn & (1 << 11)) {
9410
rd = (insn >> 8) & 7;
9411
/* load pc-relative. Bit 1 of PC is ignored. */
9412
val = s->pc + 2 + ((insn & 0xff) * 4);
9413
val &= ~(uint32_t)2;
9414
addr = tcg_temp_new_i32();
9415
tcg_gen_movi_i32(addr, val);
9416
tmp = tcg_temp_new_i32();
9417
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9418
tcg_temp_free_i32(addr);
9419
store_reg(s, rd, tmp);
9422
if (insn & (1 << 10)) {
9423
/* data processing extended or blx */
9424
rd = (insn & 7) | ((insn >> 4) & 8);
9425
rm = (insn >> 3) & 0xf;
9426
op = (insn >> 8) & 3;
9429
tmp = load_reg(s, rd);
9430
tmp2 = load_reg(s, rm);
9431
tcg_gen_add_i32(tmp, tmp, tmp2);
9432
tcg_temp_free_i32(tmp2);
9433
store_reg(s, rd, tmp);
9436
tmp = load_reg(s, rd);
9437
tmp2 = load_reg(s, rm);
9438
gen_sub_CC(tmp, tmp, tmp2);
9439
tcg_temp_free_i32(tmp2);
9440
tcg_temp_free_i32(tmp);
9442
case 2: /* mov/cpy */
9443
tmp = load_reg(s, rm);
9444
store_reg(s, rd, tmp);
9446
case 3:/* branch [and link] exchange thumb register */
9447
tmp = load_reg(s, rm);
9448
if (insn & (1 << 7)) {
9450
val = (uint32_t)s->pc | 1;
9451
tmp2 = tcg_temp_new_i32();
9452
tcg_gen_movi_i32(tmp2, val);
9453
store_reg(s, 14, tmp2);
9455
/* already thumb, no need to check */
9462
/* data processing register */
9464
rm = (insn >> 3) & 7;
9465
op = (insn >> 6) & 0xf;
9466
if (op == 2 || op == 3 || op == 4 || op == 7) {
9467
/* the shift/rotate ops want the operands backwards */
9476
if (op == 9) { /* neg */
9477
tmp = tcg_temp_new_i32();
9478
tcg_gen_movi_i32(tmp, 0);
9479
} else if (op != 0xf) { /* mvn doesn't read its first operand */
9480
tmp = load_reg(s, rd);
9482
TCGV_UNUSED_I32(tmp);
9485
tmp2 = load_reg(s, rm);
9488
tcg_gen_and_i32(tmp, tmp, tmp2);
9489
if (!s->condexec_mask)
9493
tcg_gen_xor_i32(tmp, tmp, tmp2);
9494
if (!s->condexec_mask)
9498
if (s->condexec_mask) {
9499
gen_shl(tmp2, tmp2, tmp);
9501
gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
9506
if (s->condexec_mask) {
9507
gen_shr(tmp2, tmp2, tmp);
9509
gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
9514
if (s->condexec_mask) {
9515
gen_sar(tmp2, tmp2, tmp);
9517
gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
9522
if (s->condexec_mask) {
9525
gen_adc_CC(tmp, tmp, tmp2);
9529
if (s->condexec_mask) {
9530
gen_sub_carry(tmp, tmp, tmp2);
9532
gen_sbc_CC(tmp, tmp, tmp2);
9536
if (s->condexec_mask) {
9537
tcg_gen_andi_i32(tmp, tmp, 0x1f);
9538
tcg_gen_rotr_i32(tmp2, tmp2, tmp);
9540
gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
9545
tcg_gen_and_i32(tmp, tmp, tmp2);
9550
if (s->condexec_mask)
9551
tcg_gen_neg_i32(tmp, tmp2);
9553
gen_sub_CC(tmp, tmp, tmp2);
9556
gen_sub_CC(tmp, tmp, tmp2);
9560
gen_add_CC(tmp, tmp, tmp2);
9564
tcg_gen_or_i32(tmp, tmp, tmp2);
9565
if (!s->condexec_mask)
9569
tcg_gen_mul_i32(tmp, tmp, tmp2);
9570
if (!s->condexec_mask)
9574
tcg_gen_andc_i32(tmp, tmp, tmp2);
9575
if (!s->condexec_mask)
9579
tcg_gen_not_i32(tmp2, tmp2);
9580
if (!s->condexec_mask)
9588
store_reg(s, rm, tmp2);
9590
tcg_temp_free_i32(tmp);
9592
store_reg(s, rd, tmp);
9593
tcg_temp_free_i32(tmp2);
9596
tcg_temp_free_i32(tmp);
9597
tcg_temp_free_i32(tmp2);
9602
/* load/store register offset. */
9604
rn = (insn >> 3) & 7;
9605
rm = (insn >> 6) & 7;
9606
op = (insn >> 9) & 7;
9607
addr = load_reg(s, rn);
9608
tmp = load_reg(s, rm);
9609
tcg_gen_add_i32(addr, addr, tmp);
9610
tcg_temp_free_i32(tmp);
9612
if (op < 3) { /* store */
9613
tmp = load_reg(s, rd);
9615
tmp = tcg_temp_new_i32();
9620
gen_aa32_st32(tmp, addr, IS_USER(s));
9623
gen_aa32_st16(tmp, addr, IS_USER(s));
9626
gen_aa32_st8(tmp, addr, IS_USER(s));
9629
gen_aa32_ld8s(tmp, addr, IS_USER(s));
9632
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9635
gen_aa32_ld16u(tmp, addr, IS_USER(s));
9638
gen_aa32_ld8u(tmp, addr, IS_USER(s));
9641
gen_aa32_ld16s(tmp, addr, IS_USER(s));
9644
if (op >= 3) { /* load */
9645
store_reg(s, rd, tmp);
9647
tcg_temp_free_i32(tmp);
9649
tcg_temp_free_i32(addr);
9653
/* load/store word immediate offset */
9655
rn = (insn >> 3) & 7;
9656
addr = load_reg(s, rn);
9657
val = (insn >> 4) & 0x7c;
9658
tcg_gen_addi_i32(addr, addr, val);
9660
if (insn & (1 << 11)) {
9662
tmp = tcg_temp_new_i32();
9663
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9664
store_reg(s, rd, tmp);
9667
tmp = load_reg(s, rd);
9668
gen_aa32_st32(tmp, addr, IS_USER(s));
9669
tcg_temp_free_i32(tmp);
9671
tcg_temp_free_i32(addr);
9675
/* load/store byte immediate offset */
9677
rn = (insn >> 3) & 7;
9678
addr = load_reg(s, rn);
9679
val = (insn >> 6) & 0x1f;
9680
tcg_gen_addi_i32(addr, addr, val);
9682
if (insn & (1 << 11)) {
9684
tmp = tcg_temp_new_i32();
9685
gen_aa32_ld8u(tmp, addr, IS_USER(s));
9686
store_reg(s, rd, tmp);
9689
tmp = load_reg(s, rd);
9690
gen_aa32_st8(tmp, addr, IS_USER(s));
9691
tcg_temp_free_i32(tmp);
9693
tcg_temp_free_i32(addr);
9697
/* load/store halfword immediate offset */
9699
rn = (insn >> 3) & 7;
9700
addr = load_reg(s, rn);
9701
val = (insn >> 5) & 0x3e;
9702
tcg_gen_addi_i32(addr, addr, val);
9704
if (insn & (1 << 11)) {
9706
tmp = tcg_temp_new_i32();
9707
gen_aa32_ld16u(tmp, addr, IS_USER(s));
9708
store_reg(s, rd, tmp);
9711
tmp = load_reg(s, rd);
9712
gen_aa32_st16(tmp, addr, IS_USER(s));
9713
tcg_temp_free_i32(tmp);
9715
tcg_temp_free_i32(addr);
9719
/* load/store from stack */
9720
rd = (insn >> 8) & 7;
9721
addr = load_reg(s, 13);
9722
val = (insn & 0xff) * 4;
9723
tcg_gen_addi_i32(addr, addr, val);
9725
if (insn & (1 << 11)) {
9727
tmp = tcg_temp_new_i32();
9728
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9729
store_reg(s, rd, tmp);
9732
tmp = load_reg(s, rd);
9733
gen_aa32_st32(tmp, addr, IS_USER(s));
9734
tcg_temp_free_i32(tmp);
9736
tcg_temp_free_i32(addr);
9740
/* add to high reg */
9741
rd = (insn >> 8) & 7;
9742
if (insn & (1 << 11)) {
9744
tmp = load_reg(s, 13);
9746
/* PC. bit 1 is ignored. */
9747
tmp = tcg_temp_new_i32();
9748
tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
9750
val = (insn & 0xff) * 4;
9751
tcg_gen_addi_i32(tmp, tmp, val);
9752
store_reg(s, rd, tmp);
9757
op = (insn >> 8) & 0xf;
9760
/* adjust stack pointer */
9761
tmp = load_reg(s, 13);
9762
val = (insn & 0x7f) * 4;
9763
if (insn & (1 << 7))
9764
val = -(int32_t)val;
9765
tcg_gen_addi_i32(tmp, tmp, val);
9766
store_reg(s, 13, tmp);
9769
case 2: /* sign/zero extend. */
9772
rm = (insn >> 3) & 7;
9773
tmp = load_reg(s, rm);
9774
switch ((insn >> 6) & 3) {
9775
case 0: gen_sxth(tmp); break;
9776
case 1: gen_sxtb(tmp); break;
9777
case 2: gen_uxth(tmp); break;
9778
case 3: gen_uxtb(tmp); break;
9780
store_reg(s, rd, tmp);
9782
case 4: case 5: case 0xc: case 0xd:
9784
addr = load_reg(s, 13);
9785
if (insn & (1 << 8))
9789
for (i = 0; i < 8; i++) {
9790
if (insn & (1 << i))
9793
if ((insn & (1 << 11)) == 0) {
9794
tcg_gen_addi_i32(addr, addr, -offset);
9796
for (i = 0; i < 8; i++) {
9797
if (insn & (1 << i)) {
9798
if (insn & (1 << 11)) {
9800
tmp = tcg_temp_new_i32();
9801
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9802
store_reg(s, i, tmp);
9805
tmp = load_reg(s, i);
9806
gen_aa32_st32(tmp, addr, IS_USER(s));
9807
tcg_temp_free_i32(tmp);
9809
/* advance to the next address. */
9810
tcg_gen_addi_i32(addr, addr, 4);
9813
TCGV_UNUSED_I32(tmp);
9814
if (insn & (1 << 8)) {
9815
if (insn & (1 << 11)) {
9817
tmp = tcg_temp_new_i32();
9818
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9819
/* don't set the pc until the rest of the instruction
9823
tmp = load_reg(s, 14);
9824
gen_aa32_st32(tmp, addr, IS_USER(s));
9825
tcg_temp_free_i32(tmp);
9827
tcg_gen_addi_i32(addr, addr, 4);
9829
if ((insn & (1 << 11)) == 0) {
9830
tcg_gen_addi_i32(addr, addr, -offset);
9832
/* write back the new stack pointer */
9833
store_reg(s, 13, addr);
9834
/* set the new PC value */
9835
if ((insn & 0x0900) == 0x0900) {
9836
store_reg_from_load(env, s, 15, tmp);
9840
case 1: case 3: case 9: case 11: /* czb */
9842
tmp = load_reg(s, rm);
9843
s->condlabel = gen_new_label();
9845
if (insn & (1 << 11))
9846
tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
9848
tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
9849
tcg_temp_free_i32(tmp);
9850
offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
9851
val = (uint32_t)s->pc + 2;
9856
case 15: /* IT, nop-hint. */
9857
if ((insn & 0xf) == 0) {
9858
gen_nop_hint(s, (insn >> 4) & 0xf);
9862
s->condexec_cond = (insn >> 4) & 0xe;
9863
s->condexec_mask = insn & 0x1f;
9864
/* No actual code generated for this insn, just setup state. */
9867
case 0xe: /* bkpt */
9869
gen_exception_insn(s, 2, EXCP_BKPT);
9874
rn = (insn >> 3) & 0x7;
9876
tmp = load_reg(s, rn);
9877
switch ((insn >> 6) & 3) {
9878
case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
9879
case 1: gen_rev16(tmp); break;
9880
case 3: gen_revsh(tmp); break;
9881
default: goto illegal_op;
9883
store_reg(s, rd, tmp);
9887
switch ((insn >> 5) & 7) {
9891
if (((insn >> 3) & 1) != s->bswap_code) {
9892
/* Dynamic endianness switching not implemented. */
9893
qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
9904
tmp = tcg_const_i32((insn & (1 << 4)) != 0);
9907
addr = tcg_const_i32(19);
9908
gen_helper_v7m_msr(cpu_env, addr, tmp);
9909
tcg_temp_free_i32(addr);
9913
addr = tcg_const_i32(16);
9914
gen_helper_v7m_msr(cpu_env, addr, tmp);
9915
tcg_temp_free_i32(addr);
9917
tcg_temp_free_i32(tmp);
9920
if (insn & (1 << 4)) {
9921
shift = CPSR_A | CPSR_I | CPSR_F;
9925
gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
9940
/* load/store multiple */
9941
TCGv_i32 loaded_var;
9942
TCGV_UNUSED_I32(loaded_var);
9943
rn = (insn >> 8) & 0x7;
9944
addr = load_reg(s, rn);
9945
for (i = 0; i < 8; i++) {
9946
if (insn & (1 << i)) {
9947
if (insn & (1 << 11)) {
9949
tmp = tcg_temp_new_i32();
9950
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9954
store_reg(s, i, tmp);
9958
tmp = load_reg(s, i);
9959
gen_aa32_st32(tmp, addr, IS_USER(s));
9960
tcg_temp_free_i32(tmp);
9962
/* advance to the next address */
9963
tcg_gen_addi_i32(addr, addr, 4);
9966
if ((insn & (1 << rn)) == 0) {
9967
/* base reg not in list: base register writeback */
9968
store_reg(s, rn, addr);
9970
/* base reg in list: if load, complete it now */
9971
if (insn & (1 << 11)) {
9972
store_reg(s, rn, loaded_var);
9974
tcg_temp_free_i32(addr);
9979
/* conditional branch or swi */
9980
cond = (insn >> 8) & 0xf;
9986
gen_set_pc_im(s, s->pc);
9987
s->is_jmp = DISAS_SWI;
9990
/* generate a conditional jump to next instruction */
9991
s->condlabel = gen_new_label();
9992
gen_test_cc(cond ^ 1, s->condlabel);
9995
/* jump to the offset */
9996
val = (uint32_t)s->pc + 2;
9997
offset = ((int32_t)insn << 24) >> 24;
10003
if (insn & (1 << 11)) {
10004
if (disas_thumb2_insn(env, s, insn))
10008
/* unconditional branch */
10009
val = (uint32_t)s->pc;
10010
offset = ((int32_t)insn << 21) >> 21;
10011
val += (offset << 1) + 2;
10016
if (disas_thumb2_insn(env, s, insn))
10022
gen_exception_insn(s, 4, EXCP_UDEF);
10026
gen_exception_insn(s, 2, EXCP_UDEF);
10029
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
10030
basic block 'tb'. If search_pc is TRUE, also generate PC
10031
information for each intermediate instruction. */
10032
static inline void gen_intermediate_code_internal(ARMCPU *cpu,
10033
TranslationBlock *tb,
10036
CPUState *cs = CPU(cpu);
10037
CPUARMState *env = &cpu->env;
10038
DisasContext dc1, *dc = &dc1;
10040
uint16_t *gen_opc_end;
10042
target_ulong pc_start;
10043
target_ulong next_page_start;
10047
/* generate intermediate code */
10052
gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
10054
dc->is_jmp = DISAS_NEXT;
10056
dc->singlestep_enabled = cs->singlestep_enabled;
10059
if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
10062
dc->bswap_code = 0;
10063
dc->condexec_mask = 0;
10064
dc->condexec_cond = 0;
10065
#if !defined(CONFIG_USER_ONLY)
10068
dc->vfp_enabled = 0;
10070
dc->vec_stride = 0;
10073
dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
10074
dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags);
10075
dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
10076
dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
10077
#if !defined(CONFIG_USER_ONLY)
10078
dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
10080
dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
10081
dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
10082
dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
10084
cpu_F0s = tcg_temp_new_i32();
10085
cpu_F1s = tcg_temp_new_i32();
10086
cpu_F0d = tcg_temp_new_i64();
10087
cpu_F1d = tcg_temp_new_i64();
10090
/* FIXME: cpu_M0 can probably be the same as cpu_V0. */
10091
cpu_M0 = tcg_temp_new_i64();
10092
next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
10095
max_insns = tb->cflags & CF_COUNT_MASK;
10096
if (max_insns == 0)
10097
max_insns = CF_COUNT_MASK;
10101
tcg_clear_temp_count();
10103
/* A note on handling of the condexec (IT) bits:
10105
* We want to avoid the overhead of having to write the updated condexec
10106
* bits back to the CPUARMState for every instruction in an IT block. So:
10107
* (1) if the condexec bits are not already zero then we write
10108
* zero back into the CPUARMState now. This avoids complications trying
10109
* to do it at the end of the block. (For example if we don't do this
10110
* it's hard to identify whether we can safely skip writing condexec
10111
* at the end of the TB, which we definitely want to do for the case
10112
* where a TB doesn't do anything with the IT state at all.)
10113
* (2) if we are going to leave the TB then we call gen_set_condexec()
10114
* which will write the correct value into CPUARMState if zero is wrong.
10115
* This is done both for leaving the TB at the end, and for leaving
10116
* it because of an exception we know will happen, which is done in
10117
* gen_exception_insn(). The latter is necessary because we need to
10118
* leave the TB with the PC/IT state just prior to execution of the
10119
* instruction which caused the exception.
10120
* (3) if we leave the TB unexpectedly (eg a data abort on a load)
10121
* then the CPUARMState will be wrong and we need to reset it.
10122
* This is handled in the same way as restoration of the
10123
* PC in these situations: we will be called again with search_pc=1
10124
* and generate a mapping of the condexec bits for each PC in
10125
* gen_opc_condexec_bits[]. restore_state_to_opc() then uses
10126
* this to restore the condexec bits.
10128
* Note that there are no instructions which can read the condexec
10129
* bits, and none which can write non-static values to them, so
10130
* we don't need to care about whether CPUARMState is correct in the
10134
/* Reset the conditional execution bits immediately. This avoids
10135
complications trying to do it at the end of the block. */
10136
if (dc->condexec_mask || dc->condexec_cond)
10138
TCGv_i32 tmp = tcg_temp_new_i32();
10139
tcg_gen_movi_i32(tmp, 0);
10140
store_cpu_field(tmp, condexec_bits);
10143
#ifdef CONFIG_USER_ONLY
10144
/* Intercept jump to the magic kernel page. */
10145
if (!dc->aarch64 && dc->pc >= 0xffff0000) {
10146
/* We always get here via a jump, so know we are not in a
10147
conditional execution block. */
10148
gen_exception(EXCP_KERNEL_TRAP);
10149
dc->is_jmp = DISAS_UPDATE;
10153
if (dc->pc >= 0xfffffff0 && IS_M(env)) {
10154
/* We always get here via a jump, so know we are not in a
10155
conditional execution block. */
10156
gen_exception(EXCP_EXCEPTION_EXIT);
10157
dc->is_jmp = DISAS_UPDATE;
10162
if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
10163
QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
10164
if (bp->pc == dc->pc) {
10165
gen_exception_insn(dc, 0, EXCP_DEBUG);
10166
/* Advance PC so that clearing the breakpoint will
10167
invalidate this TB. */
10169
goto done_generating;
10174
j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10178
tcg_ctx.gen_opc_instr_start[lj++] = 0;
10180
tcg_ctx.gen_opc_pc[lj] = dc->pc;
10181
gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
10182
tcg_ctx.gen_opc_instr_start[lj] = 1;
10183
tcg_ctx.gen_opc_icount[lj] = num_insns;
10186
if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
10189
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
10190
tcg_gen_debug_insn_start(dc->pc);
10194
disas_a64_insn(env, dc);
10195
} else if (dc->thumb) {
10196
disas_thumb_insn(env, dc);
10197
if (dc->condexec_mask) {
10198
dc->condexec_cond = (dc->condexec_cond & 0xe)
10199
| ((dc->condexec_mask >> 4) & 1);
10200
dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
10201
if (dc->condexec_mask == 0) {
10202
dc->condexec_cond = 0;
10206
disas_arm_insn(env, dc);
10209
if (dc->condjmp && !dc->is_jmp) {
10210
gen_set_label(dc->condlabel);
10214
if (tcg_check_temp_count()) {
10215
fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
10219
/* Translation stops when a conditional branch is encountered.
10220
* Otherwise the subsequent code could get translated several times.
10221
* Also stop translation when a page boundary is reached. This
10222
* ensures prefetch aborts occur at the right place. */
10224
} while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
10225
!cs->singlestep_enabled &&
10227
dc->pc < next_page_start &&
10228
num_insns < max_insns);
10230
if (tb->cflags & CF_LAST_IO) {
10232
/* FIXME: This can theoretically happen with self-modifying
10234
cpu_abort(env, "IO on conditional branch instruction");
10239
/* At this stage dc->condjmp will only be set when the skipped
10240
instruction was a conditional branch or trap, and the PC has
10241
already been written. */
10242
if (unlikely(cs->singlestep_enabled)) {
10243
/* Make sure the pc is updated, and raise a debug exception. */
10245
gen_set_condexec(dc);
10246
if (dc->is_jmp == DISAS_SWI) {
10247
gen_exception(EXCP_SWI);
10248
} else if (dc->is_jmp == DISAS_SMC) {
10249
gen_exception(EXCP_SMC);
10251
gen_exception(EXCP_DEBUG);
10253
gen_set_label(dc->condlabel);
10255
if (dc->condjmp || !dc->is_jmp) {
10256
gen_set_pc_im(dc, dc->pc);
10259
gen_set_condexec(dc);
10260
if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
10261
gen_exception(EXCP_SWI);
10262
} else if (dc->is_jmp == DISAS_SMC && !dc->condjmp) {
10263
gen_exception(EXCP_SMC);
10265
/* FIXME: Single stepping a WFI insn will not halt
10267
gen_exception(EXCP_DEBUG);
10270
/* While branches must always occur at the end of an IT block,
10271
there are a few other things that can cause us to terminate
10272
the TB in the middle of an IT block:
10273
- Exception generating instructions (bkpt, swi, undefined).
10275
- Hardware watchpoints.
10276
Hardware breakpoints have already been handled and skip this code.
10278
gen_set_condexec(dc);
10279
switch(dc->is_jmp) {
10281
gen_goto_tb(dc, 1, dc->pc);
10286
/* indicate that the hash table must be used to find the next TB */
10287
tcg_gen_exit_tb(0);
10289
case DISAS_TB_JUMP:
10290
/* nothing more to generate */
10293
gen_helper_wfi(cpu_env);
10296
gen_exception(EXCP_SWI);
10299
gen_exception(EXCP_SMC);
10303
gen_set_label(dc->condlabel);
10304
gen_set_condexec(dc);
10305
gen_goto_tb(dc, 1, dc->pc);
10311
gen_tb_end(tb, num_insns);
10312
*tcg_ctx.gen_opc_ptr = INDEX_op_end;
10315
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
10316
qemu_log("----------------\n");
10317
qemu_log("IN: %s\n", lookup_symbol(pc_start));
10318
log_target_disas(env, pc_start, dc->pc - pc_start,
10319
dc->thumb | (dc->bswap_code << 1));
10324
j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10327
tcg_ctx.gen_opc_instr_start[lj++] = 0;
10329
tb->size = dc->pc - pc_start;
10330
tb->icount = num_insns;
10334
void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
10336
gen_intermediate_code_internal(arm_env_get_cpu(env), tb, false);
10339
void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb)
10341
gen_intermediate_code_internal(arm_env_get_cpu(env), tb, true);
10344
static const char *cpu_mode_names[16] = {
10345
"usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
10346
"???", "???", "???", "und", "???", "???", "???", "sys"
10349
void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
10352
ARMCPU *cpu = ARM_CPU(cs);
10353
CPUARMState *env = &cpu->env;
10357
for(i=0;i<16;i++) {
10358
cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
10360
cpu_fprintf(f, "\n");
10362
cpu_fprintf(f, " ");
10364
psr = cpsr_read(env);
10365
cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
10367
psr & (1 << 31) ? 'N' : '-',
10368
psr & (1 << 30) ? 'Z' : '-',
10369
psr & (1 << 29) ? 'C' : '-',
10370
psr & (1 << 28) ? 'V' : '-',
10371
psr & CPSR_T ? 'T' : 'A',
10372
cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
10374
if (flags & CPU_DUMP_FPU) {
10375
int numvfpregs = 0;
10376
if (arm_feature(env, ARM_FEATURE_VFP)) {
10379
if (arm_feature(env, ARM_FEATURE_VFP3)) {
10382
for (i = 0; i < numvfpregs; i++) {
10383
uint64_t v = float64_val(env->vfp.regs[i]);
10384
cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
10385
i * 2, (uint32_t)v,
10386
i * 2 + 1, (uint32_t)(v >> 32),
10389
cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
10393
void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos)
10396
env->pc = tcg_ctx.gen_opc_pc[pc_pos];
10398
env->regs[15] = tcg_ctx.gen_opc_pc[pc_pos];
10400
env->condexec_bits = gen_opc_condexec_bits[pc_pos];