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 the address argument is TCGv_i32 rather than TCGv.
831
#if TARGET_LONG_BITS == 32
833
#define DO_GEN_LD(SUFF, OPC) \
834
static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
836
tcg_gen_qemu_ld_i32(val, addr, index, OPC); \
839
#define DO_GEN_ST(SUFF, OPC) \
840
static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
842
tcg_gen_qemu_st_i32(val, addr, index, OPC); \
845
static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
847
tcg_gen_qemu_ld_i64(val, addr, index, MO_TEQ);
850
static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
852
tcg_gen_qemu_st_i64(val, addr, index, MO_TEQ);
857
#define DO_GEN_LD(SUFF, OPC) \
858
static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
860
TCGv addr64 = tcg_temp_new(); \
861
tcg_gen_extu_i32_i64(addr64, addr); \
862
tcg_gen_qemu_ld_i32(val, addr64, index, OPC); \
863
tcg_temp_free(addr64); \
866
#define DO_GEN_ST(SUFF, OPC) \
867
static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
869
TCGv addr64 = tcg_temp_new(); \
870
tcg_gen_extu_i32_i64(addr64, addr); \
871
tcg_gen_qemu_st_i32(val, addr64, index, OPC); \
872
tcg_temp_free(addr64); \
875
static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
877
TCGv addr64 = tcg_temp_new();
878
tcg_gen_extu_i32_i64(addr64, addr);
879
tcg_gen_qemu_ld_i64(val, addr64, index, MO_TEQ);
880
tcg_temp_free(addr64);
883
static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
885
TCGv addr64 = tcg_temp_new();
886
tcg_gen_extu_i32_i64(addr64, addr);
887
tcg_gen_qemu_st_i64(val, addr64, index, MO_TEQ);
888
tcg_temp_free(addr64);
895
DO_GEN_LD(16s, MO_TESW)
896
DO_GEN_LD(16u, MO_TEUW)
897
DO_GEN_LD(32u, MO_TEUL)
899
DO_GEN_ST(16, MO_TEUW)
900
DO_GEN_ST(32, MO_TEUL)
902
static inline void gen_smc(CPUARMState *env, DisasContext *s)
904
tcg_gen_movi_i32(cpu_R[15], s->pc);
905
s->is_jmp = DISAS_SMC;
908
static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
911
gen_a64_set_pc_im(val);
913
tcg_gen_movi_i32(cpu_R[15], val);
917
/* Force a TB lookup after an instruction that changes the CPU state. */
918
static inline void gen_lookup_tb(DisasContext *s)
920
tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
921
s->is_jmp = DISAS_UPDATE;
924
static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
927
int val, rm, shift, shiftop;
930
if (!(insn & (1 << 25))) {
933
if (!(insn & (1 << 23)))
936
tcg_gen_addi_i32(var, var, val);
940
shift = (insn >> 7) & 0x1f;
941
shiftop = (insn >> 5) & 3;
942
offset = load_reg(s, rm);
943
gen_arm_shift_im(offset, shiftop, shift, 0);
944
if (!(insn & (1 << 23)))
945
tcg_gen_sub_i32(var, var, offset);
947
tcg_gen_add_i32(var, var, offset);
948
tcg_temp_free_i32(offset);
952
static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
953
int extra, TCGv_i32 var)
958
if (insn & (1 << 22)) {
960
val = (insn & 0xf) | ((insn >> 4) & 0xf0);
961
if (!(insn & (1 << 23)))
965
tcg_gen_addi_i32(var, var, val);
969
tcg_gen_addi_i32(var, var, extra);
971
offset = load_reg(s, rm);
972
if (!(insn & (1 << 23)))
973
tcg_gen_sub_i32(var, var, offset);
975
tcg_gen_add_i32(var, var, offset);
976
tcg_temp_free_i32(offset);
980
static TCGv_ptr get_fpstatus_ptr(int neon)
982
TCGv_ptr statusptr = tcg_temp_new_ptr();
985
offset = offsetof(CPUARMState, vfp.standard_fp_status);
987
offset = offsetof(CPUARMState, vfp.fp_status);
989
tcg_gen_addi_ptr(statusptr, cpu_env, offset);
993
#define VFP_OP2(name) \
994
static inline void gen_vfp_##name(int dp) \
996
TCGv_ptr fpst = get_fpstatus_ptr(0); \
998
gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1000
gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1002
tcg_temp_free_ptr(fpst); \
1012
static inline void gen_vfp_F1_mul(int dp)
1014
/* Like gen_vfp_mul() but put result in F1 */
1015
TCGv_ptr fpst = get_fpstatus_ptr(0);
1017
gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1019
gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1021
tcg_temp_free_ptr(fpst);
1024
static inline void gen_vfp_F1_neg(int dp)
1026
/* Like gen_vfp_neg() but put result in F1 */
1028
gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1030
gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1034
static inline void gen_vfp_abs(int dp)
1037
gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1039
gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1042
static inline void gen_vfp_neg(int dp)
1045
gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1047
gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1050
static inline void gen_vfp_sqrt(int dp)
1053
gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1055
gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1058
static inline void gen_vfp_cmp(int dp)
1061
gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1063
gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1066
static inline void gen_vfp_cmpe(int dp)
1069
gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1071
gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1074
static inline void gen_vfp_F1_ld0(int dp)
1077
tcg_gen_movi_i64(cpu_F1d, 0);
1079
tcg_gen_movi_i32(cpu_F1s, 0);
1082
#define VFP_GEN_ITOF(name) \
1083
static inline void gen_vfp_##name(int dp, int neon) \
1085
TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1087
gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1089
gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1091
tcg_temp_free_ptr(statusptr); \
1098
#define VFP_GEN_FTOI(name) \
1099
static inline void gen_vfp_##name(int dp, int neon) \
1101
TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1103
gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1105
gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1107
tcg_temp_free_ptr(statusptr); \
1116
#define VFP_GEN_FIX(name) \
1117
static inline void gen_vfp_##name(int dp, int shift, int neon) \
1119
TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1120
TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1122
gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, statusptr); \
1124
gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, statusptr); \
1126
tcg_temp_free_i32(tmp_shift); \
1127
tcg_temp_free_ptr(statusptr); \
1139
static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1142
gen_aa32_ld64(cpu_F0d, addr, IS_USER(s));
1144
gen_aa32_ld32u(cpu_F0s, addr, IS_USER(s));
1148
static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1151
gen_aa32_st64(cpu_F0d, addr, IS_USER(s));
1153
gen_aa32_st32(cpu_F0s, addr, IS_USER(s));
1158
vfp_reg_offset (int dp, int reg)
1161
return offsetof(CPUARMState, vfp.regs[reg]);
1163
return offsetof(CPUARMState, vfp.regs[reg >> 1])
1164
+ offsetof(CPU_DoubleU, l.upper);
1166
return offsetof(CPUARMState, vfp.regs[reg >> 1])
1167
+ offsetof(CPU_DoubleU, l.lower);
1171
/* Return the offset of a 32-bit piece of a NEON register.
1172
zero is the least significant end of the register. */
1174
neon_reg_offset (int reg, int n)
1178
return vfp_reg_offset(0, sreg);
1181
static TCGv_i32 neon_load_reg(int reg, int pass)
1183
TCGv_i32 tmp = tcg_temp_new_i32();
1184
tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1188
static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1190
tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1191
tcg_temp_free_i32(var);
1194
static inline void neon_load_reg64(TCGv_i64 var, int reg)
1196
tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1199
static inline void neon_store_reg64(TCGv_i64 var, int reg)
1201
tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1204
#define tcg_gen_ld_f32 tcg_gen_ld_i32
1205
#define tcg_gen_ld_f64 tcg_gen_ld_i64
1206
#define tcg_gen_st_f32 tcg_gen_st_i32
1207
#define tcg_gen_st_f64 tcg_gen_st_i64
1209
static inline void gen_mov_F0_vreg(int dp, int reg)
1212
tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1214
tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1217
static inline void gen_mov_F1_vreg(int dp, int reg)
1220
tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1222
tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1225
static inline void gen_mov_vreg_F0(int dp, int reg)
1228
tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1230
tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1233
#define ARM_CP_RW_BIT (1 << 20)
1235
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1237
tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1240
static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1242
tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1245
static inline TCGv_i32 iwmmxt_load_creg(int reg)
1247
TCGv_i32 var = tcg_temp_new_i32();
1248
tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1252
static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1254
tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1255
tcg_temp_free_i32(var);
1258
static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1260
iwmmxt_store_reg(cpu_M0, rn);
1263
static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1265
iwmmxt_load_reg(cpu_M0, rn);
1268
static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1270
iwmmxt_load_reg(cpu_V1, rn);
1271
tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1274
static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1276
iwmmxt_load_reg(cpu_V1, rn);
1277
tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1280
static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1282
iwmmxt_load_reg(cpu_V1, rn);
1283
tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1286
#define IWMMXT_OP(name) \
1287
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1289
iwmmxt_load_reg(cpu_V1, rn); \
1290
gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1293
#define IWMMXT_OP_ENV(name) \
1294
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1296
iwmmxt_load_reg(cpu_V1, rn); \
1297
gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1300
#define IWMMXT_OP_ENV_SIZE(name) \
1301
IWMMXT_OP_ENV(name##b) \
1302
IWMMXT_OP_ENV(name##w) \
1303
IWMMXT_OP_ENV(name##l)
1305
#define IWMMXT_OP_ENV1(name) \
1306
static inline void gen_op_iwmmxt_##name##_M0(void) \
1308
gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1322
IWMMXT_OP_ENV_SIZE(unpackl)
1323
IWMMXT_OP_ENV_SIZE(unpackh)
1325
IWMMXT_OP_ENV1(unpacklub)
1326
IWMMXT_OP_ENV1(unpackluw)
1327
IWMMXT_OP_ENV1(unpacklul)
1328
IWMMXT_OP_ENV1(unpackhub)
1329
IWMMXT_OP_ENV1(unpackhuw)
1330
IWMMXT_OP_ENV1(unpackhul)
1331
IWMMXT_OP_ENV1(unpacklsb)
1332
IWMMXT_OP_ENV1(unpacklsw)
1333
IWMMXT_OP_ENV1(unpacklsl)
1334
IWMMXT_OP_ENV1(unpackhsb)
1335
IWMMXT_OP_ENV1(unpackhsw)
1336
IWMMXT_OP_ENV1(unpackhsl)
1338
IWMMXT_OP_ENV_SIZE(cmpeq)
1339
IWMMXT_OP_ENV_SIZE(cmpgtu)
1340
IWMMXT_OP_ENV_SIZE(cmpgts)
1342
IWMMXT_OP_ENV_SIZE(mins)
1343
IWMMXT_OP_ENV_SIZE(minu)
1344
IWMMXT_OP_ENV_SIZE(maxs)
1345
IWMMXT_OP_ENV_SIZE(maxu)
1347
IWMMXT_OP_ENV_SIZE(subn)
1348
IWMMXT_OP_ENV_SIZE(addn)
1349
IWMMXT_OP_ENV_SIZE(subu)
1350
IWMMXT_OP_ENV_SIZE(addu)
1351
IWMMXT_OP_ENV_SIZE(subs)
1352
IWMMXT_OP_ENV_SIZE(adds)
1354
IWMMXT_OP_ENV(avgb0)
1355
IWMMXT_OP_ENV(avgb1)
1356
IWMMXT_OP_ENV(avgw0)
1357
IWMMXT_OP_ENV(avgw1)
1361
IWMMXT_OP_ENV(packuw)
1362
IWMMXT_OP_ENV(packul)
1363
IWMMXT_OP_ENV(packuq)
1364
IWMMXT_OP_ENV(packsw)
1365
IWMMXT_OP_ENV(packsl)
1366
IWMMXT_OP_ENV(packsq)
1368
static void gen_op_iwmmxt_set_mup(void)
1371
tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1372
tcg_gen_ori_i32(tmp, tmp, 2);
1373
store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1376
static void gen_op_iwmmxt_set_cup(void)
1379
tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1380
tcg_gen_ori_i32(tmp, tmp, 1);
1381
store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1384
static void gen_op_iwmmxt_setpsr_nz(void)
1386
TCGv_i32 tmp = tcg_temp_new_i32();
1387
gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1388
store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1391
static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1393
iwmmxt_load_reg(cpu_V1, rn);
1394
tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1395
tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1398
static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1405
rd = (insn >> 16) & 0xf;
1406
tmp = load_reg(s, rd);
1408
offset = (insn & 0xff) << ((insn >> 7) & 2);
1409
if (insn & (1 << 24)) {
1411
if (insn & (1 << 23))
1412
tcg_gen_addi_i32(tmp, tmp, offset);
1414
tcg_gen_addi_i32(tmp, tmp, -offset);
1415
tcg_gen_mov_i32(dest, tmp);
1416
if (insn & (1 << 21))
1417
store_reg(s, rd, tmp);
1419
tcg_temp_free_i32(tmp);
1420
} else if (insn & (1 << 21)) {
1422
tcg_gen_mov_i32(dest, tmp);
1423
if (insn & (1 << 23))
1424
tcg_gen_addi_i32(tmp, tmp, offset);
1426
tcg_gen_addi_i32(tmp, tmp, -offset);
1427
store_reg(s, rd, tmp);
1428
} else if (!(insn & (1 << 23)))
1433
static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1435
int rd = (insn >> 0) & 0xf;
1438
if (insn & (1 << 8)) {
1439
if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1442
tmp = iwmmxt_load_creg(rd);
1445
tmp = tcg_temp_new_i32();
1446
iwmmxt_load_reg(cpu_V0, rd);
1447
tcg_gen_trunc_i64_i32(tmp, cpu_V0);
1449
tcg_gen_andi_i32(tmp, tmp, mask);
1450
tcg_gen_mov_i32(dest, tmp);
1451
tcg_temp_free_i32(tmp);
1455
/* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1456
(ie. an undefined instruction). */
1457
static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
1460
int rdhi, rdlo, rd0, rd1, i;
1462
TCGv_i32 tmp, tmp2, tmp3;
1464
if ((insn & 0x0e000e00) == 0x0c000000) {
1465
if ((insn & 0x0fe00ff0) == 0x0c400000) {
1467
rdlo = (insn >> 12) & 0xf;
1468
rdhi = (insn >> 16) & 0xf;
1469
if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1470
iwmmxt_load_reg(cpu_V0, wrd);
1471
tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
1472
tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1473
tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
1474
} else { /* TMCRR */
1475
tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1476
iwmmxt_store_reg(cpu_V0, wrd);
1477
gen_op_iwmmxt_set_mup();
1482
wrd = (insn >> 12) & 0xf;
1483
addr = tcg_temp_new_i32();
1484
if (gen_iwmmxt_address(s, insn, addr)) {
1485
tcg_temp_free_i32(addr);
1488
if (insn & ARM_CP_RW_BIT) {
1489
if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1490
tmp = tcg_temp_new_i32();
1491
gen_aa32_ld32u(tmp, addr, IS_USER(s));
1492
iwmmxt_store_creg(wrd, tmp);
1495
if (insn & (1 << 8)) {
1496
if (insn & (1 << 22)) { /* WLDRD */
1497
gen_aa32_ld64(cpu_M0, addr, IS_USER(s));
1499
} else { /* WLDRW wRd */
1500
tmp = tcg_temp_new_i32();
1501
gen_aa32_ld32u(tmp, addr, IS_USER(s));
1504
tmp = tcg_temp_new_i32();
1505
if (insn & (1 << 22)) { /* WLDRH */
1506
gen_aa32_ld16u(tmp, addr, IS_USER(s));
1507
} else { /* WLDRB */
1508
gen_aa32_ld8u(tmp, addr, IS_USER(s));
1512
tcg_gen_extu_i32_i64(cpu_M0, tmp);
1513
tcg_temp_free_i32(tmp);
1515
gen_op_iwmmxt_movq_wRn_M0(wrd);
1518
if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1519
tmp = iwmmxt_load_creg(wrd);
1520
gen_aa32_st32(tmp, addr, IS_USER(s));
1522
gen_op_iwmmxt_movq_M0_wRn(wrd);
1523
tmp = tcg_temp_new_i32();
1524
if (insn & (1 << 8)) {
1525
if (insn & (1 << 22)) { /* WSTRD */
1526
gen_aa32_st64(cpu_M0, addr, IS_USER(s));
1527
} else { /* WSTRW wRd */
1528
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1529
gen_aa32_st32(tmp, addr, IS_USER(s));
1532
if (insn & (1 << 22)) { /* WSTRH */
1533
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1534
gen_aa32_st16(tmp, addr, IS_USER(s));
1535
} else { /* WSTRB */
1536
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1537
gen_aa32_st8(tmp, addr, IS_USER(s));
1541
tcg_temp_free_i32(tmp);
1543
tcg_temp_free_i32(addr);
1547
if ((insn & 0x0f000000) != 0x0e000000)
1550
switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1551
case 0x000: /* WOR */
1552
wrd = (insn >> 12) & 0xf;
1553
rd0 = (insn >> 0) & 0xf;
1554
rd1 = (insn >> 16) & 0xf;
1555
gen_op_iwmmxt_movq_M0_wRn(rd0);
1556
gen_op_iwmmxt_orq_M0_wRn(rd1);
1557
gen_op_iwmmxt_setpsr_nz();
1558
gen_op_iwmmxt_movq_wRn_M0(wrd);
1559
gen_op_iwmmxt_set_mup();
1560
gen_op_iwmmxt_set_cup();
1562
case 0x011: /* TMCR */
1565
rd = (insn >> 12) & 0xf;
1566
wrd = (insn >> 16) & 0xf;
1568
case ARM_IWMMXT_wCID:
1569
case ARM_IWMMXT_wCASF:
1571
case ARM_IWMMXT_wCon:
1572
gen_op_iwmmxt_set_cup();
1574
case ARM_IWMMXT_wCSSF:
1575
tmp = iwmmxt_load_creg(wrd);
1576
tmp2 = load_reg(s, rd);
1577
tcg_gen_andc_i32(tmp, tmp, tmp2);
1578
tcg_temp_free_i32(tmp2);
1579
iwmmxt_store_creg(wrd, tmp);
1581
case ARM_IWMMXT_wCGR0:
1582
case ARM_IWMMXT_wCGR1:
1583
case ARM_IWMMXT_wCGR2:
1584
case ARM_IWMMXT_wCGR3:
1585
gen_op_iwmmxt_set_cup();
1586
tmp = load_reg(s, rd);
1587
iwmmxt_store_creg(wrd, tmp);
1593
case 0x100: /* WXOR */
1594
wrd = (insn >> 12) & 0xf;
1595
rd0 = (insn >> 0) & 0xf;
1596
rd1 = (insn >> 16) & 0xf;
1597
gen_op_iwmmxt_movq_M0_wRn(rd0);
1598
gen_op_iwmmxt_xorq_M0_wRn(rd1);
1599
gen_op_iwmmxt_setpsr_nz();
1600
gen_op_iwmmxt_movq_wRn_M0(wrd);
1601
gen_op_iwmmxt_set_mup();
1602
gen_op_iwmmxt_set_cup();
1604
case 0x111: /* TMRC */
1607
rd = (insn >> 12) & 0xf;
1608
wrd = (insn >> 16) & 0xf;
1609
tmp = iwmmxt_load_creg(wrd);
1610
store_reg(s, rd, tmp);
1612
case 0x300: /* WANDN */
1613
wrd = (insn >> 12) & 0xf;
1614
rd0 = (insn >> 0) & 0xf;
1615
rd1 = (insn >> 16) & 0xf;
1616
gen_op_iwmmxt_movq_M0_wRn(rd0);
1617
tcg_gen_neg_i64(cpu_M0, cpu_M0);
1618
gen_op_iwmmxt_andq_M0_wRn(rd1);
1619
gen_op_iwmmxt_setpsr_nz();
1620
gen_op_iwmmxt_movq_wRn_M0(wrd);
1621
gen_op_iwmmxt_set_mup();
1622
gen_op_iwmmxt_set_cup();
1624
case 0x200: /* WAND */
1625
wrd = (insn >> 12) & 0xf;
1626
rd0 = (insn >> 0) & 0xf;
1627
rd1 = (insn >> 16) & 0xf;
1628
gen_op_iwmmxt_movq_M0_wRn(rd0);
1629
gen_op_iwmmxt_andq_M0_wRn(rd1);
1630
gen_op_iwmmxt_setpsr_nz();
1631
gen_op_iwmmxt_movq_wRn_M0(wrd);
1632
gen_op_iwmmxt_set_mup();
1633
gen_op_iwmmxt_set_cup();
1635
case 0x810: case 0xa10: /* WMADD */
1636
wrd = (insn >> 12) & 0xf;
1637
rd0 = (insn >> 0) & 0xf;
1638
rd1 = (insn >> 16) & 0xf;
1639
gen_op_iwmmxt_movq_M0_wRn(rd0);
1640
if (insn & (1 << 21))
1641
gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1643
gen_op_iwmmxt_madduq_M0_wRn(rd1);
1644
gen_op_iwmmxt_movq_wRn_M0(wrd);
1645
gen_op_iwmmxt_set_mup();
1647
case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1648
wrd = (insn >> 12) & 0xf;
1649
rd0 = (insn >> 16) & 0xf;
1650
rd1 = (insn >> 0) & 0xf;
1651
gen_op_iwmmxt_movq_M0_wRn(rd0);
1652
switch ((insn >> 22) & 3) {
1654
gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1657
gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1660
gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1665
gen_op_iwmmxt_movq_wRn_M0(wrd);
1666
gen_op_iwmmxt_set_mup();
1667
gen_op_iwmmxt_set_cup();
1669
case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1670
wrd = (insn >> 12) & 0xf;
1671
rd0 = (insn >> 16) & 0xf;
1672
rd1 = (insn >> 0) & 0xf;
1673
gen_op_iwmmxt_movq_M0_wRn(rd0);
1674
switch ((insn >> 22) & 3) {
1676
gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1679
gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1682
gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1687
gen_op_iwmmxt_movq_wRn_M0(wrd);
1688
gen_op_iwmmxt_set_mup();
1689
gen_op_iwmmxt_set_cup();
1691
case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1692
wrd = (insn >> 12) & 0xf;
1693
rd0 = (insn >> 16) & 0xf;
1694
rd1 = (insn >> 0) & 0xf;
1695
gen_op_iwmmxt_movq_M0_wRn(rd0);
1696
if (insn & (1 << 22))
1697
gen_op_iwmmxt_sadw_M0_wRn(rd1);
1699
gen_op_iwmmxt_sadb_M0_wRn(rd1);
1700
if (!(insn & (1 << 20)))
1701
gen_op_iwmmxt_addl_M0_wRn(wrd);
1702
gen_op_iwmmxt_movq_wRn_M0(wrd);
1703
gen_op_iwmmxt_set_mup();
1705
case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1706
wrd = (insn >> 12) & 0xf;
1707
rd0 = (insn >> 16) & 0xf;
1708
rd1 = (insn >> 0) & 0xf;
1709
gen_op_iwmmxt_movq_M0_wRn(rd0);
1710
if (insn & (1 << 21)) {
1711
if (insn & (1 << 20))
1712
gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1714
gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1716
if (insn & (1 << 20))
1717
gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1719
gen_op_iwmmxt_mululw_M0_wRn(rd1);
1721
gen_op_iwmmxt_movq_wRn_M0(wrd);
1722
gen_op_iwmmxt_set_mup();
1724
case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1725
wrd = (insn >> 12) & 0xf;
1726
rd0 = (insn >> 16) & 0xf;
1727
rd1 = (insn >> 0) & 0xf;
1728
gen_op_iwmmxt_movq_M0_wRn(rd0);
1729
if (insn & (1 << 21))
1730
gen_op_iwmmxt_macsw_M0_wRn(rd1);
1732
gen_op_iwmmxt_macuw_M0_wRn(rd1);
1733
if (!(insn & (1 << 20))) {
1734
iwmmxt_load_reg(cpu_V1, wrd);
1735
tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1737
gen_op_iwmmxt_movq_wRn_M0(wrd);
1738
gen_op_iwmmxt_set_mup();
1740
case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1741
wrd = (insn >> 12) & 0xf;
1742
rd0 = (insn >> 16) & 0xf;
1743
rd1 = (insn >> 0) & 0xf;
1744
gen_op_iwmmxt_movq_M0_wRn(rd0);
1745
switch ((insn >> 22) & 3) {
1747
gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1750
gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1753
gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1758
gen_op_iwmmxt_movq_wRn_M0(wrd);
1759
gen_op_iwmmxt_set_mup();
1760
gen_op_iwmmxt_set_cup();
1762
case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1763
wrd = (insn >> 12) & 0xf;
1764
rd0 = (insn >> 16) & 0xf;
1765
rd1 = (insn >> 0) & 0xf;
1766
gen_op_iwmmxt_movq_M0_wRn(rd0);
1767
if (insn & (1 << 22)) {
1768
if (insn & (1 << 20))
1769
gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1771
gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1773
if (insn & (1 << 20))
1774
gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1776
gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1778
gen_op_iwmmxt_movq_wRn_M0(wrd);
1779
gen_op_iwmmxt_set_mup();
1780
gen_op_iwmmxt_set_cup();
1782
case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1783
wrd = (insn >> 12) & 0xf;
1784
rd0 = (insn >> 16) & 0xf;
1785
rd1 = (insn >> 0) & 0xf;
1786
gen_op_iwmmxt_movq_M0_wRn(rd0);
1787
tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1788
tcg_gen_andi_i32(tmp, tmp, 7);
1789
iwmmxt_load_reg(cpu_V1, rd1);
1790
gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
1791
tcg_temp_free_i32(tmp);
1792
gen_op_iwmmxt_movq_wRn_M0(wrd);
1793
gen_op_iwmmxt_set_mup();
1795
case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1796
if (((insn >> 6) & 3) == 3)
1798
rd = (insn >> 12) & 0xf;
1799
wrd = (insn >> 16) & 0xf;
1800
tmp = load_reg(s, rd);
1801
gen_op_iwmmxt_movq_M0_wRn(wrd);
1802
switch ((insn >> 6) & 3) {
1804
tmp2 = tcg_const_i32(0xff);
1805
tmp3 = tcg_const_i32((insn & 7) << 3);
1808
tmp2 = tcg_const_i32(0xffff);
1809
tmp3 = tcg_const_i32((insn & 3) << 4);
1812
tmp2 = tcg_const_i32(0xffffffff);
1813
tmp3 = tcg_const_i32((insn & 1) << 5);
1816
TCGV_UNUSED_I32(tmp2);
1817
TCGV_UNUSED_I32(tmp3);
1819
gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
1820
tcg_temp_free_i32(tmp3);
1821
tcg_temp_free_i32(tmp2);
1822
tcg_temp_free_i32(tmp);
1823
gen_op_iwmmxt_movq_wRn_M0(wrd);
1824
gen_op_iwmmxt_set_mup();
1826
case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1827
rd = (insn >> 12) & 0xf;
1828
wrd = (insn >> 16) & 0xf;
1829
if (rd == 15 || ((insn >> 22) & 3) == 3)
1831
gen_op_iwmmxt_movq_M0_wRn(wrd);
1832
tmp = tcg_temp_new_i32();
1833
switch ((insn >> 22) & 3) {
1835
tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
1836
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1838
tcg_gen_ext8s_i32(tmp, tmp);
1840
tcg_gen_andi_i32(tmp, tmp, 0xff);
1844
tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
1845
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1847
tcg_gen_ext16s_i32(tmp, tmp);
1849
tcg_gen_andi_i32(tmp, tmp, 0xffff);
1853
tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
1854
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1857
store_reg(s, rd, tmp);
1859
case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1860
if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1862
tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1863
switch ((insn >> 22) & 3) {
1865
tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
1868
tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
1871
tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
1874
tcg_gen_shli_i32(tmp, tmp, 28);
1876
tcg_temp_free_i32(tmp);
1878
case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1879
if (((insn >> 6) & 3) == 3)
1881
rd = (insn >> 12) & 0xf;
1882
wrd = (insn >> 16) & 0xf;
1883
tmp = load_reg(s, rd);
1884
switch ((insn >> 6) & 3) {
1886
gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
1889
gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
1892
gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
1895
tcg_temp_free_i32(tmp);
1896
gen_op_iwmmxt_movq_wRn_M0(wrd);
1897
gen_op_iwmmxt_set_mup();
1899
case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1900
if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1902
tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1903
tmp2 = tcg_temp_new_i32();
1904
tcg_gen_mov_i32(tmp2, tmp);
1905
switch ((insn >> 22) & 3) {
1907
for (i = 0; i < 7; i ++) {
1908
tcg_gen_shli_i32(tmp2, tmp2, 4);
1909
tcg_gen_and_i32(tmp, tmp, tmp2);
1913
for (i = 0; i < 3; i ++) {
1914
tcg_gen_shli_i32(tmp2, tmp2, 8);
1915
tcg_gen_and_i32(tmp, tmp, tmp2);
1919
tcg_gen_shli_i32(tmp2, tmp2, 16);
1920
tcg_gen_and_i32(tmp, tmp, tmp2);
1924
tcg_temp_free_i32(tmp2);
1925
tcg_temp_free_i32(tmp);
1927
case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1928
wrd = (insn >> 12) & 0xf;
1929
rd0 = (insn >> 16) & 0xf;
1930
gen_op_iwmmxt_movq_M0_wRn(rd0);
1931
switch ((insn >> 22) & 3) {
1933
gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
1936
gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
1939
gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
1944
gen_op_iwmmxt_movq_wRn_M0(wrd);
1945
gen_op_iwmmxt_set_mup();
1947
case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1948
if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1950
tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1951
tmp2 = tcg_temp_new_i32();
1952
tcg_gen_mov_i32(tmp2, tmp);
1953
switch ((insn >> 22) & 3) {
1955
for (i = 0; i < 7; i ++) {
1956
tcg_gen_shli_i32(tmp2, tmp2, 4);
1957
tcg_gen_or_i32(tmp, tmp, tmp2);
1961
for (i = 0; i < 3; i ++) {
1962
tcg_gen_shli_i32(tmp2, tmp2, 8);
1963
tcg_gen_or_i32(tmp, tmp, tmp2);
1967
tcg_gen_shli_i32(tmp2, tmp2, 16);
1968
tcg_gen_or_i32(tmp, tmp, tmp2);
1972
tcg_temp_free_i32(tmp2);
1973
tcg_temp_free_i32(tmp);
1975
case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1976
rd = (insn >> 12) & 0xf;
1977
rd0 = (insn >> 16) & 0xf;
1978
if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
1980
gen_op_iwmmxt_movq_M0_wRn(rd0);
1981
tmp = tcg_temp_new_i32();
1982
switch ((insn >> 22) & 3) {
1984
gen_helper_iwmmxt_msbb(tmp, cpu_M0);
1987
gen_helper_iwmmxt_msbw(tmp, cpu_M0);
1990
gen_helper_iwmmxt_msbl(tmp, cpu_M0);
1993
store_reg(s, rd, tmp);
1995
case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
1996
case 0x906: case 0xb06: case 0xd06: case 0xf06:
1997
wrd = (insn >> 12) & 0xf;
1998
rd0 = (insn >> 16) & 0xf;
1999
rd1 = (insn >> 0) & 0xf;
2000
gen_op_iwmmxt_movq_M0_wRn(rd0);
2001
switch ((insn >> 22) & 3) {
2003
if (insn & (1 << 21))
2004
gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2006
gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2009
if (insn & (1 << 21))
2010
gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2012
gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2015
if (insn & (1 << 21))
2016
gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2018
gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2023
gen_op_iwmmxt_movq_wRn_M0(wrd);
2024
gen_op_iwmmxt_set_mup();
2025
gen_op_iwmmxt_set_cup();
2027
case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2028
case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2029
wrd = (insn >> 12) & 0xf;
2030
rd0 = (insn >> 16) & 0xf;
2031
gen_op_iwmmxt_movq_M0_wRn(rd0);
2032
switch ((insn >> 22) & 3) {
2034
if (insn & (1 << 21))
2035
gen_op_iwmmxt_unpacklsb_M0();
2037
gen_op_iwmmxt_unpacklub_M0();
2040
if (insn & (1 << 21))
2041
gen_op_iwmmxt_unpacklsw_M0();
2043
gen_op_iwmmxt_unpackluw_M0();
2046
if (insn & (1 << 21))
2047
gen_op_iwmmxt_unpacklsl_M0();
2049
gen_op_iwmmxt_unpacklul_M0();
2054
gen_op_iwmmxt_movq_wRn_M0(wrd);
2055
gen_op_iwmmxt_set_mup();
2056
gen_op_iwmmxt_set_cup();
2058
case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2059
case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2060
wrd = (insn >> 12) & 0xf;
2061
rd0 = (insn >> 16) & 0xf;
2062
gen_op_iwmmxt_movq_M0_wRn(rd0);
2063
switch ((insn >> 22) & 3) {
2065
if (insn & (1 << 21))
2066
gen_op_iwmmxt_unpackhsb_M0();
2068
gen_op_iwmmxt_unpackhub_M0();
2071
if (insn & (1 << 21))
2072
gen_op_iwmmxt_unpackhsw_M0();
2074
gen_op_iwmmxt_unpackhuw_M0();
2077
if (insn & (1 << 21))
2078
gen_op_iwmmxt_unpackhsl_M0();
2080
gen_op_iwmmxt_unpackhul_M0();
2085
gen_op_iwmmxt_movq_wRn_M0(wrd);
2086
gen_op_iwmmxt_set_mup();
2087
gen_op_iwmmxt_set_cup();
2089
case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2090
case 0x214: case 0x614: case 0xa14: case 0xe14:
2091
if (((insn >> 22) & 3) == 0)
2093
wrd = (insn >> 12) & 0xf;
2094
rd0 = (insn >> 16) & 0xf;
2095
gen_op_iwmmxt_movq_M0_wRn(rd0);
2096
tmp = tcg_temp_new_i32();
2097
if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2098
tcg_temp_free_i32(tmp);
2101
switch ((insn >> 22) & 3) {
2103
gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2106
gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2109
gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2112
tcg_temp_free_i32(tmp);
2113
gen_op_iwmmxt_movq_wRn_M0(wrd);
2114
gen_op_iwmmxt_set_mup();
2115
gen_op_iwmmxt_set_cup();
2117
case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2118
case 0x014: case 0x414: case 0x814: case 0xc14:
2119
if (((insn >> 22) & 3) == 0)
2121
wrd = (insn >> 12) & 0xf;
2122
rd0 = (insn >> 16) & 0xf;
2123
gen_op_iwmmxt_movq_M0_wRn(rd0);
2124
tmp = tcg_temp_new_i32();
2125
if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2126
tcg_temp_free_i32(tmp);
2129
switch ((insn >> 22) & 3) {
2131
gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2134
gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2137
gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2140
tcg_temp_free_i32(tmp);
2141
gen_op_iwmmxt_movq_wRn_M0(wrd);
2142
gen_op_iwmmxt_set_mup();
2143
gen_op_iwmmxt_set_cup();
2145
case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2146
case 0x114: case 0x514: case 0x914: case 0xd14:
2147
if (((insn >> 22) & 3) == 0)
2149
wrd = (insn >> 12) & 0xf;
2150
rd0 = (insn >> 16) & 0xf;
2151
gen_op_iwmmxt_movq_M0_wRn(rd0);
2152
tmp = tcg_temp_new_i32();
2153
if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2154
tcg_temp_free_i32(tmp);
2157
switch ((insn >> 22) & 3) {
2159
gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2162
gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2165
gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2168
tcg_temp_free_i32(tmp);
2169
gen_op_iwmmxt_movq_wRn_M0(wrd);
2170
gen_op_iwmmxt_set_mup();
2171
gen_op_iwmmxt_set_cup();
2173
case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2174
case 0x314: case 0x714: case 0xb14: case 0xf14:
2175
if (((insn >> 22) & 3) == 0)
2177
wrd = (insn >> 12) & 0xf;
2178
rd0 = (insn >> 16) & 0xf;
2179
gen_op_iwmmxt_movq_M0_wRn(rd0);
2180
tmp = tcg_temp_new_i32();
2181
switch ((insn >> 22) & 3) {
2183
if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2184
tcg_temp_free_i32(tmp);
2187
gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2190
if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2191
tcg_temp_free_i32(tmp);
2194
gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2197
if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2198
tcg_temp_free_i32(tmp);
2201
gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2204
tcg_temp_free_i32(tmp);
2205
gen_op_iwmmxt_movq_wRn_M0(wrd);
2206
gen_op_iwmmxt_set_mup();
2207
gen_op_iwmmxt_set_cup();
2209
case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2210
case 0x916: case 0xb16: case 0xd16: case 0xf16:
2211
wrd = (insn >> 12) & 0xf;
2212
rd0 = (insn >> 16) & 0xf;
2213
rd1 = (insn >> 0) & 0xf;
2214
gen_op_iwmmxt_movq_M0_wRn(rd0);
2215
switch ((insn >> 22) & 3) {
2217
if (insn & (1 << 21))
2218
gen_op_iwmmxt_minsb_M0_wRn(rd1);
2220
gen_op_iwmmxt_minub_M0_wRn(rd1);
2223
if (insn & (1 << 21))
2224
gen_op_iwmmxt_minsw_M0_wRn(rd1);
2226
gen_op_iwmmxt_minuw_M0_wRn(rd1);
2229
if (insn & (1 << 21))
2230
gen_op_iwmmxt_minsl_M0_wRn(rd1);
2232
gen_op_iwmmxt_minul_M0_wRn(rd1);
2237
gen_op_iwmmxt_movq_wRn_M0(wrd);
2238
gen_op_iwmmxt_set_mup();
2240
case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2241
case 0x816: case 0xa16: case 0xc16: case 0xe16:
2242
wrd = (insn >> 12) & 0xf;
2243
rd0 = (insn >> 16) & 0xf;
2244
rd1 = (insn >> 0) & 0xf;
2245
gen_op_iwmmxt_movq_M0_wRn(rd0);
2246
switch ((insn >> 22) & 3) {
2248
if (insn & (1 << 21))
2249
gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2251
gen_op_iwmmxt_maxub_M0_wRn(rd1);
2254
if (insn & (1 << 21))
2255
gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2257
gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2260
if (insn & (1 << 21))
2261
gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2263
gen_op_iwmmxt_maxul_M0_wRn(rd1);
2268
gen_op_iwmmxt_movq_wRn_M0(wrd);
2269
gen_op_iwmmxt_set_mup();
2271
case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2272
case 0x402: case 0x502: case 0x602: case 0x702:
2273
wrd = (insn >> 12) & 0xf;
2274
rd0 = (insn >> 16) & 0xf;
2275
rd1 = (insn >> 0) & 0xf;
2276
gen_op_iwmmxt_movq_M0_wRn(rd0);
2277
tmp = tcg_const_i32((insn >> 20) & 3);
2278
iwmmxt_load_reg(cpu_V1, rd1);
2279
gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2280
tcg_temp_free_i32(tmp);
2281
gen_op_iwmmxt_movq_wRn_M0(wrd);
2282
gen_op_iwmmxt_set_mup();
2284
case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2285
case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2286
case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2287
case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2288
wrd = (insn >> 12) & 0xf;
2289
rd0 = (insn >> 16) & 0xf;
2290
rd1 = (insn >> 0) & 0xf;
2291
gen_op_iwmmxt_movq_M0_wRn(rd0);
2292
switch ((insn >> 20) & 0xf) {
2294
gen_op_iwmmxt_subnb_M0_wRn(rd1);
2297
gen_op_iwmmxt_subub_M0_wRn(rd1);
2300
gen_op_iwmmxt_subsb_M0_wRn(rd1);
2303
gen_op_iwmmxt_subnw_M0_wRn(rd1);
2306
gen_op_iwmmxt_subuw_M0_wRn(rd1);
2309
gen_op_iwmmxt_subsw_M0_wRn(rd1);
2312
gen_op_iwmmxt_subnl_M0_wRn(rd1);
2315
gen_op_iwmmxt_subul_M0_wRn(rd1);
2318
gen_op_iwmmxt_subsl_M0_wRn(rd1);
2323
gen_op_iwmmxt_movq_wRn_M0(wrd);
2324
gen_op_iwmmxt_set_mup();
2325
gen_op_iwmmxt_set_cup();
2327
case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2328
case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2329
case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2330
case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2331
wrd = (insn >> 12) & 0xf;
2332
rd0 = (insn >> 16) & 0xf;
2333
gen_op_iwmmxt_movq_M0_wRn(rd0);
2334
tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2335
gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2336
tcg_temp_free_i32(tmp);
2337
gen_op_iwmmxt_movq_wRn_M0(wrd);
2338
gen_op_iwmmxt_set_mup();
2339
gen_op_iwmmxt_set_cup();
2341
case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2342
case 0x418: case 0x518: case 0x618: case 0x718:
2343
case 0x818: case 0x918: case 0xa18: case 0xb18:
2344
case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2345
wrd = (insn >> 12) & 0xf;
2346
rd0 = (insn >> 16) & 0xf;
2347
rd1 = (insn >> 0) & 0xf;
2348
gen_op_iwmmxt_movq_M0_wRn(rd0);
2349
switch ((insn >> 20) & 0xf) {
2351
gen_op_iwmmxt_addnb_M0_wRn(rd1);
2354
gen_op_iwmmxt_addub_M0_wRn(rd1);
2357
gen_op_iwmmxt_addsb_M0_wRn(rd1);
2360
gen_op_iwmmxt_addnw_M0_wRn(rd1);
2363
gen_op_iwmmxt_adduw_M0_wRn(rd1);
2366
gen_op_iwmmxt_addsw_M0_wRn(rd1);
2369
gen_op_iwmmxt_addnl_M0_wRn(rd1);
2372
gen_op_iwmmxt_addul_M0_wRn(rd1);
2375
gen_op_iwmmxt_addsl_M0_wRn(rd1);
2380
gen_op_iwmmxt_movq_wRn_M0(wrd);
2381
gen_op_iwmmxt_set_mup();
2382
gen_op_iwmmxt_set_cup();
2384
case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2385
case 0x408: case 0x508: case 0x608: case 0x708:
2386
case 0x808: case 0x908: case 0xa08: case 0xb08:
2387
case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2388
if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2390
wrd = (insn >> 12) & 0xf;
2391
rd0 = (insn >> 16) & 0xf;
2392
rd1 = (insn >> 0) & 0xf;
2393
gen_op_iwmmxt_movq_M0_wRn(rd0);
2394
switch ((insn >> 22) & 3) {
2396
if (insn & (1 << 21))
2397
gen_op_iwmmxt_packsw_M0_wRn(rd1);
2399
gen_op_iwmmxt_packuw_M0_wRn(rd1);
2402
if (insn & (1 << 21))
2403
gen_op_iwmmxt_packsl_M0_wRn(rd1);
2405
gen_op_iwmmxt_packul_M0_wRn(rd1);
2408
if (insn & (1 << 21))
2409
gen_op_iwmmxt_packsq_M0_wRn(rd1);
2411
gen_op_iwmmxt_packuq_M0_wRn(rd1);
2414
gen_op_iwmmxt_movq_wRn_M0(wrd);
2415
gen_op_iwmmxt_set_mup();
2416
gen_op_iwmmxt_set_cup();
2418
case 0x201: case 0x203: case 0x205: case 0x207:
2419
case 0x209: case 0x20b: case 0x20d: case 0x20f:
2420
case 0x211: case 0x213: case 0x215: case 0x217:
2421
case 0x219: case 0x21b: case 0x21d: case 0x21f:
2422
wrd = (insn >> 5) & 0xf;
2423
rd0 = (insn >> 12) & 0xf;
2424
rd1 = (insn >> 0) & 0xf;
2425
if (rd0 == 0xf || rd1 == 0xf)
2427
gen_op_iwmmxt_movq_M0_wRn(wrd);
2428
tmp = load_reg(s, rd0);
2429
tmp2 = load_reg(s, rd1);
2430
switch ((insn >> 16) & 0xf) {
2431
case 0x0: /* TMIA */
2432
gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2434
case 0x8: /* TMIAPH */
2435
gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2437
case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2438
if (insn & (1 << 16))
2439
tcg_gen_shri_i32(tmp, tmp, 16);
2440
if (insn & (1 << 17))
2441
tcg_gen_shri_i32(tmp2, tmp2, 16);
2442
gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2445
tcg_temp_free_i32(tmp2);
2446
tcg_temp_free_i32(tmp);
2449
tcg_temp_free_i32(tmp2);
2450
tcg_temp_free_i32(tmp);
2451
gen_op_iwmmxt_movq_wRn_M0(wrd);
2452
gen_op_iwmmxt_set_mup();
2461
/* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2462
(ie. an undefined instruction). */
2463
static int disas_dsp_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
2465
int acc, rd0, rd1, rdhi, rdlo;
2468
if ((insn & 0x0ff00f10) == 0x0e200010) {
2469
/* Multiply with Internal Accumulate Format */
2470
rd0 = (insn >> 12) & 0xf;
2472
acc = (insn >> 5) & 7;
2477
tmp = load_reg(s, rd0);
2478
tmp2 = load_reg(s, rd1);
2479
switch ((insn >> 16) & 0xf) {
2481
gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2483
case 0x8: /* MIAPH */
2484
gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2486
case 0xc: /* MIABB */
2487
case 0xd: /* MIABT */
2488
case 0xe: /* MIATB */
2489
case 0xf: /* MIATT */
2490
if (insn & (1 << 16))
2491
tcg_gen_shri_i32(tmp, tmp, 16);
2492
if (insn & (1 << 17))
2493
tcg_gen_shri_i32(tmp2, tmp2, 16);
2494
gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2499
tcg_temp_free_i32(tmp2);
2500
tcg_temp_free_i32(tmp);
2502
gen_op_iwmmxt_movq_wRn_M0(acc);
2506
if ((insn & 0x0fe00ff8) == 0x0c400000) {
2507
/* Internal Accumulator Access Format */
2508
rdhi = (insn >> 16) & 0xf;
2509
rdlo = (insn >> 12) & 0xf;
2515
if (insn & ARM_CP_RW_BIT) { /* MRA */
2516
iwmmxt_load_reg(cpu_V0, acc);
2517
tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
2518
tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2519
tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
2520
tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2522
tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2523
iwmmxt_store_reg(cpu_V0, acc);
2531
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2532
#define VFP_SREG(insn, bigbit, smallbit) \
2533
((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2534
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2535
if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2536
reg = (((insn) >> (bigbit)) & 0x0f) \
2537
| (((insn) >> ((smallbit) - 4)) & 0x10); \
2539
if (insn & (1 << (smallbit))) \
2541
reg = ((insn) >> (bigbit)) & 0x0f; \
2544
#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2545
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2546
#define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2547
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2548
#define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2549
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2551
/* Move between integer and VFP cores. */
2552
static TCGv_i32 gen_vfp_mrs(void)
2554
TCGv_i32 tmp = tcg_temp_new_i32();
2555
tcg_gen_mov_i32(tmp, cpu_F0s);
2559
static void gen_vfp_msr(TCGv_i32 tmp)
2561
tcg_gen_mov_i32(cpu_F0s, tmp);
2562
tcg_temp_free_i32(tmp);
2565
static void gen_neon_dup_u8(TCGv_i32 var, int shift)
2567
TCGv_i32 tmp = tcg_temp_new_i32();
2569
tcg_gen_shri_i32(var, var, shift);
2570
tcg_gen_ext8u_i32(var, var);
2571
tcg_gen_shli_i32(tmp, var, 8);
2572
tcg_gen_or_i32(var, var, tmp);
2573
tcg_gen_shli_i32(tmp, var, 16);
2574
tcg_gen_or_i32(var, var, tmp);
2575
tcg_temp_free_i32(tmp);
2578
static void gen_neon_dup_low16(TCGv_i32 var)
2580
TCGv_i32 tmp = tcg_temp_new_i32();
2581
tcg_gen_ext16u_i32(var, var);
2582
tcg_gen_shli_i32(tmp, var, 16);
2583
tcg_gen_or_i32(var, var, tmp);
2584
tcg_temp_free_i32(tmp);
2587
static void gen_neon_dup_high16(TCGv_i32 var)
2589
TCGv_i32 tmp = tcg_temp_new_i32();
2590
tcg_gen_andi_i32(var, var, 0xffff0000);
2591
tcg_gen_shri_i32(tmp, var, 16);
2592
tcg_gen_or_i32(var, var, tmp);
2593
tcg_temp_free_i32(tmp);
2596
static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
2598
/* Load a single Neon element and replicate into a 32 bit TCG reg */
2599
TCGv_i32 tmp = tcg_temp_new_i32();
2602
gen_aa32_ld8u(tmp, addr, IS_USER(s));
2603
gen_neon_dup_u8(tmp, 0);
2606
gen_aa32_ld16u(tmp, addr, IS_USER(s));
2607
gen_neon_dup_low16(tmp);
2610
gen_aa32_ld32u(tmp, addr, IS_USER(s));
2612
default: /* Avoid compiler warnings. */
2618
static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
2621
uint32_t cc = extract32(insn, 20, 2);
2624
TCGv_i64 frn, frm, dest;
2625
TCGv_i64 tmp, zero, zf, nf, vf;
2627
zero = tcg_const_i64(0);
2629
frn = tcg_temp_new_i64();
2630
frm = tcg_temp_new_i64();
2631
dest = tcg_temp_new_i64();
2633
zf = tcg_temp_new_i64();
2634
nf = tcg_temp_new_i64();
2635
vf = tcg_temp_new_i64();
2637
tcg_gen_extu_i32_i64(zf, cpu_ZF);
2638
tcg_gen_ext_i32_i64(nf, cpu_NF);
2639
tcg_gen_ext_i32_i64(vf, cpu_VF);
2641
tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2642
tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2645
tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
2649
tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
2652
case 2: /* ge: N == V -> N ^ V == 0 */
2653
tmp = tcg_temp_new_i64();
2654
tcg_gen_xor_i64(tmp, vf, nf);
2655
tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2657
tcg_temp_free_i64(tmp);
2659
case 3: /* gt: !Z && N == V */
2660
tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
2662
tmp = tcg_temp_new_i64();
2663
tcg_gen_xor_i64(tmp, vf, nf);
2664
tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2666
tcg_temp_free_i64(tmp);
2669
tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2670
tcg_temp_free_i64(frn);
2671
tcg_temp_free_i64(frm);
2672
tcg_temp_free_i64(dest);
2674
tcg_temp_free_i64(zf);
2675
tcg_temp_free_i64(nf);
2676
tcg_temp_free_i64(vf);
2678
tcg_temp_free_i64(zero);
2680
TCGv_i32 frn, frm, dest;
2683
zero = tcg_const_i32(0);
2685
frn = tcg_temp_new_i32();
2686
frm = tcg_temp_new_i32();
2687
dest = tcg_temp_new_i32();
2688
tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2689
tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2692
tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
2696
tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
2699
case 2: /* ge: N == V -> N ^ V == 0 */
2700
tmp = tcg_temp_new_i32();
2701
tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2702
tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2704
tcg_temp_free_i32(tmp);
2706
case 3: /* gt: !Z && N == V */
2707
tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
2709
tmp = tcg_temp_new_i32();
2710
tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2711
tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2713
tcg_temp_free_i32(tmp);
2716
tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2717
tcg_temp_free_i32(frn);
2718
tcg_temp_free_i32(frm);
2719
tcg_temp_free_i32(dest);
2721
tcg_temp_free_i32(zero);
2727
static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
2728
uint32_t rm, uint32_t dp)
2730
uint32_t vmin = extract32(insn, 6, 1);
2731
TCGv_ptr fpst = get_fpstatus_ptr(0);
2734
TCGv_i64 frn, frm, dest;
2736
frn = tcg_temp_new_i64();
2737
frm = tcg_temp_new_i64();
2738
dest = tcg_temp_new_i64();
2740
tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2741
tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2743
gen_helper_vfp_minnmd(dest, frn, frm, fpst);
2745
gen_helper_vfp_maxnmd(dest, frn, frm, fpst);
2747
tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2748
tcg_temp_free_i64(frn);
2749
tcg_temp_free_i64(frm);
2750
tcg_temp_free_i64(dest);
2752
TCGv_i32 frn, frm, dest;
2754
frn = tcg_temp_new_i32();
2755
frm = tcg_temp_new_i32();
2756
dest = tcg_temp_new_i32();
2758
tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2759
tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2761
gen_helper_vfp_minnms(dest, frn, frm, fpst);
2763
gen_helper_vfp_maxnms(dest, frn, frm, fpst);
2765
tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2766
tcg_temp_free_i32(frn);
2767
tcg_temp_free_i32(frm);
2768
tcg_temp_free_i32(dest);
2771
tcg_temp_free_ptr(fpst);
2775
static int disas_vfp_v8_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
2777
uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
2779
if (!arm_feature(env, ARM_FEATURE_V8)) {
2784
VFP_DREG_D(rd, insn);
2785
VFP_DREG_N(rn, insn);
2786
VFP_DREG_M(rm, insn);
2788
rd = VFP_SREG_D(insn);
2789
rn = VFP_SREG_N(insn);
2790
rm = VFP_SREG_M(insn);
2793
if ((insn & 0x0f800e50) == 0x0e000a00) {
2794
return handle_vsel(insn, rd, rn, rm, dp);
2795
} else if ((insn & 0x0fb00e10) == 0x0e800a00) {
2796
return handle_vminmaxnm(insn, rd, rn, rm, dp);
2801
/* Disassemble a VFP instruction. Returns nonzero if an error occurred
2802
(ie. an undefined instruction). */
2803
static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
2805
uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2811
if (!arm_feature(env, ARM_FEATURE_VFP))
2814
if (!s->vfp_enabled) {
2815
/* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2816
if ((insn & 0x0fe00fff) != 0x0ee00a10)
2818
rn = (insn >> 16) & 0xf;
2819
if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2820
&& rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2824
if (extract32(insn, 28, 4) == 0xf) {
2825
/* Encodings with T=1 (Thumb) or unconditional (ARM):
2826
* only used in v8 and above.
2828
return disas_vfp_v8_insn(env, s, insn);
2831
dp = ((insn & 0xf00) == 0xb00);
2832
switch ((insn >> 24) & 0xf) {
2834
if (insn & (1 << 4)) {
2835
/* single register transfer */
2836
rd = (insn >> 12) & 0xf;
2841
VFP_DREG_N(rn, insn);
2844
if (insn & 0x00c00060
2845
&& !arm_feature(env, ARM_FEATURE_NEON))
2848
pass = (insn >> 21) & 1;
2849
if (insn & (1 << 22)) {
2851
offset = ((insn >> 5) & 3) * 8;
2852
} else if (insn & (1 << 5)) {
2854
offset = (insn & (1 << 6)) ? 16 : 0;
2859
if (insn & ARM_CP_RW_BIT) {
2861
tmp = neon_load_reg(rn, pass);
2865
tcg_gen_shri_i32(tmp, tmp, offset);
2866
if (insn & (1 << 23))
2872
if (insn & (1 << 23)) {
2874
tcg_gen_shri_i32(tmp, tmp, 16);
2880
tcg_gen_sari_i32(tmp, tmp, 16);
2889
store_reg(s, rd, tmp);
2892
tmp = load_reg(s, rd);
2893
if (insn & (1 << 23)) {
2896
gen_neon_dup_u8(tmp, 0);
2897
} else if (size == 1) {
2898
gen_neon_dup_low16(tmp);
2900
for (n = 0; n <= pass * 2; n++) {
2901
tmp2 = tcg_temp_new_i32();
2902
tcg_gen_mov_i32(tmp2, tmp);
2903
neon_store_reg(rn, n, tmp2);
2905
neon_store_reg(rn, n, tmp);
2910
tmp2 = neon_load_reg(rn, pass);
2911
tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
2912
tcg_temp_free_i32(tmp2);
2915
tmp2 = neon_load_reg(rn, pass);
2916
tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
2917
tcg_temp_free_i32(tmp2);
2922
neon_store_reg(rn, pass, tmp);
2926
if ((insn & 0x6f) != 0x00)
2928
rn = VFP_SREG_N(insn);
2929
if (insn & ARM_CP_RW_BIT) {
2931
if (insn & (1 << 21)) {
2932
/* system register */
2937
/* VFP2 allows access to FSID from userspace.
2938
VFP3 restricts all id registers to privileged
2941
&& arm_feature(env, ARM_FEATURE_VFP3))
2943
tmp = load_cpu_field(vfp.xregs[rn]);
2948
tmp = load_cpu_field(vfp.xregs[rn]);
2950
case ARM_VFP_FPINST:
2951
case ARM_VFP_FPINST2:
2952
/* Not present in VFP3. */
2954
|| arm_feature(env, ARM_FEATURE_VFP3))
2956
tmp = load_cpu_field(vfp.xregs[rn]);
2960
tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
2961
tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
2963
tmp = tcg_temp_new_i32();
2964
gen_helper_vfp_get_fpscr(tmp, cpu_env);
2970
|| !arm_feature(env, ARM_FEATURE_MVFR))
2972
tmp = load_cpu_field(vfp.xregs[rn]);
2978
gen_mov_F0_vreg(0, rn);
2979
tmp = gen_vfp_mrs();
2982
/* Set the 4 flag bits in the CPSR. */
2984
tcg_temp_free_i32(tmp);
2986
store_reg(s, rd, tmp);
2990
if (insn & (1 << 21)) {
2992
/* system register */
2997
/* Writes are ignored. */
3000
tmp = load_reg(s, rd);
3001
gen_helper_vfp_set_fpscr(cpu_env, tmp);
3002
tcg_temp_free_i32(tmp);
3008
/* TODO: VFP subarchitecture support.
3009
* For now, keep the EN bit only */
3010
tmp = load_reg(s, rd);
3011
tcg_gen_andi_i32(tmp, tmp, 1 << 30);
3012
store_cpu_field(tmp, vfp.xregs[rn]);
3015
case ARM_VFP_FPINST:
3016
case ARM_VFP_FPINST2:
3017
tmp = load_reg(s, rd);
3018
store_cpu_field(tmp, vfp.xregs[rn]);
3024
tmp = load_reg(s, rd);
3026
gen_mov_vreg_F0(0, rn);
3031
/* data processing */
3032
/* The opcode is in bits 23, 21, 20 and 6. */
3033
op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3037
rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3039
/* rn is register number */
3040
VFP_DREG_N(rn, insn);
3043
if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18))) {
3044
/* Integer or single precision destination. */
3045
rd = VFP_SREG_D(insn);
3047
VFP_DREG_D(rd, insn);
3050
(((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14))) {
3051
/* VCVT from int is always from S reg regardless of dp bit.
3052
* VCVT with immediate frac_bits has same format as SREG_M
3054
rm = VFP_SREG_M(insn);
3056
VFP_DREG_M(rm, insn);
3059
rn = VFP_SREG_N(insn);
3060
if (op == 15 && rn == 15) {
3061
/* Double precision destination. */
3062
VFP_DREG_D(rd, insn);
3064
rd = VFP_SREG_D(insn);
3066
/* NB that we implicitly rely on the encoding for the frac_bits
3067
* in VCVT of fixed to float being the same as that of an SREG_M
3069
rm = VFP_SREG_M(insn);
3072
veclen = s->vec_len;
3073
if (op == 15 && rn > 3)
3076
/* Shut up compiler warnings. */
3087
/* Figure out what type of vector operation this is. */
3088
if ((rd & bank_mask) == 0) {
3093
delta_d = (s->vec_stride >> 1) + 1;
3095
delta_d = s->vec_stride + 1;
3097
if ((rm & bank_mask) == 0) {
3098
/* mixed scalar/vector */
3107
/* Load the initial operands. */
3112
/* Integer source */
3113
gen_mov_F0_vreg(0, rm);
3118
gen_mov_F0_vreg(dp, rd);
3119
gen_mov_F1_vreg(dp, rm);
3123
/* Compare with zero */
3124
gen_mov_F0_vreg(dp, rd);
3135
/* Source and destination the same. */
3136
gen_mov_F0_vreg(dp, rd);
3142
/* VCVTB, VCVTT: only present with the halfprec extension,
3143
* UNPREDICTABLE if bit 8 is set (we choose to UNDEF)
3145
if (dp || !arm_feature(env, ARM_FEATURE_VFP_FP16)) {
3148
/* Otherwise fall through */
3150
/* One source operand. */
3151
gen_mov_F0_vreg(dp, rm);
3155
/* Two source operands. */
3156
gen_mov_F0_vreg(dp, rn);
3157
gen_mov_F1_vreg(dp, rm);
3161
/* Perform the calculation. */
3163
case 0: /* VMLA: fd + (fn * fm) */
3164
/* Note that order of inputs to the add matters for NaNs */
3166
gen_mov_F0_vreg(dp, rd);
3169
case 1: /* VMLS: fd + -(fn * fm) */
3172
gen_mov_F0_vreg(dp, rd);
3175
case 2: /* VNMLS: -fd + (fn * fm) */
3176
/* Note that it isn't valid to replace (-A + B) with (B - A)
3177
* or similar plausible looking simplifications
3178
* because this will give wrong results for NaNs.
3181
gen_mov_F0_vreg(dp, rd);
3185
case 3: /* VNMLA: -fd + -(fn * fm) */
3188
gen_mov_F0_vreg(dp, rd);
3192
case 4: /* mul: fn * fm */
3195
case 5: /* nmul: -(fn * fm) */
3199
case 6: /* add: fn + fm */
3202
case 7: /* sub: fn - fm */
3205
case 8: /* div: fn / fm */
3208
case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3209
case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3210
case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3211
case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3212
/* These are fused multiply-add, and must be done as one
3213
* floating point operation with no rounding between the
3214
* multiplication and addition steps.
3215
* NB that doing the negations here as separate steps is
3216
* correct : an input NaN should come out with its sign bit
3217
* flipped if it is a negated-input.
3219
if (!arm_feature(env, ARM_FEATURE_VFP4)) {
3227
gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3229
frd = tcg_temp_new_i64();
3230
tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3233
gen_helper_vfp_negd(frd, frd);
3235
fpst = get_fpstatus_ptr(0);
3236
gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3237
cpu_F1d, frd, fpst);
3238
tcg_temp_free_ptr(fpst);
3239
tcg_temp_free_i64(frd);
3245
gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3247
frd = tcg_temp_new_i32();
3248
tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3250
gen_helper_vfp_negs(frd, frd);
3252
fpst = get_fpstatus_ptr(0);
3253
gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3254
cpu_F1s, frd, fpst);
3255
tcg_temp_free_ptr(fpst);
3256
tcg_temp_free_i32(frd);
3259
case 14: /* fconst */
3260
if (!arm_feature(env, ARM_FEATURE_VFP3))
3263
n = (insn << 12) & 0x80000000;
3264
i = ((insn >> 12) & 0x70) | (insn & 0xf);
3271
tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3278
tcg_gen_movi_i32(cpu_F0s, n);
3281
case 15: /* extension space */
3295
case 4: /* vcvtb.f32.f16 */
3296
tmp = gen_vfp_mrs();
3297
tcg_gen_ext16u_i32(tmp, tmp);
3298
gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3299
tcg_temp_free_i32(tmp);
3301
case 5: /* vcvtt.f32.f16 */
3302
tmp = gen_vfp_mrs();
3303
tcg_gen_shri_i32(tmp, tmp, 16);
3304
gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3305
tcg_temp_free_i32(tmp);
3307
case 6: /* vcvtb.f16.f32 */
3308
tmp = tcg_temp_new_i32();
3309
gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3310
gen_mov_F0_vreg(0, rd);
3311
tmp2 = gen_vfp_mrs();
3312
tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3313
tcg_gen_or_i32(tmp, tmp, tmp2);
3314
tcg_temp_free_i32(tmp2);
3317
case 7: /* vcvtt.f16.f32 */
3318
tmp = tcg_temp_new_i32();
3319
gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3320
tcg_gen_shli_i32(tmp, tmp, 16);
3321
gen_mov_F0_vreg(0, rd);
3322
tmp2 = gen_vfp_mrs();
3323
tcg_gen_ext16u_i32(tmp2, tmp2);
3324
tcg_gen_or_i32(tmp, tmp, tmp2);
3325
tcg_temp_free_i32(tmp2);
3337
case 11: /* cmpez */
3341
case 15: /* single<->double conversion */
3343
gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3345
gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3347
case 16: /* fuito */
3348
gen_vfp_uito(dp, 0);
3350
case 17: /* fsito */
3351
gen_vfp_sito(dp, 0);
3353
case 20: /* fshto */
3354
if (!arm_feature(env, ARM_FEATURE_VFP3))
3356
gen_vfp_shto(dp, 16 - rm, 0);
3358
case 21: /* fslto */
3359
if (!arm_feature(env, ARM_FEATURE_VFP3))
3361
gen_vfp_slto(dp, 32 - rm, 0);
3363
case 22: /* fuhto */
3364
if (!arm_feature(env, ARM_FEATURE_VFP3))
3366
gen_vfp_uhto(dp, 16 - rm, 0);
3368
case 23: /* fulto */
3369
if (!arm_feature(env, ARM_FEATURE_VFP3))
3371
gen_vfp_ulto(dp, 32 - rm, 0);
3373
case 24: /* ftoui */
3374
gen_vfp_toui(dp, 0);
3376
case 25: /* ftouiz */
3377
gen_vfp_touiz(dp, 0);
3379
case 26: /* ftosi */
3380
gen_vfp_tosi(dp, 0);
3382
case 27: /* ftosiz */
3383
gen_vfp_tosiz(dp, 0);
3385
case 28: /* ftosh */
3386
if (!arm_feature(env, ARM_FEATURE_VFP3))
3388
gen_vfp_tosh(dp, 16 - rm, 0);
3390
case 29: /* ftosl */
3391
if (!arm_feature(env, ARM_FEATURE_VFP3))
3393
gen_vfp_tosl(dp, 32 - rm, 0);
3395
case 30: /* ftouh */
3396
if (!arm_feature(env, ARM_FEATURE_VFP3))
3398
gen_vfp_touh(dp, 16 - rm, 0);
3400
case 31: /* ftoul */
3401
if (!arm_feature(env, ARM_FEATURE_VFP3))
3403
gen_vfp_toul(dp, 32 - rm, 0);
3405
default: /* undefined */
3409
default: /* undefined */
3413
/* Write back the result. */
3414
if (op == 15 && (rn >= 8 && rn <= 11))
3415
; /* Comparison, do nothing. */
3416
else if (op == 15 && dp && ((rn & 0x1c) == 0x18))
3417
/* VCVT double to int: always integer result. */
3418
gen_mov_vreg_F0(0, rd);
3419
else if (op == 15 && rn == 15)
3421
gen_mov_vreg_F0(!dp, rd);
3423
gen_mov_vreg_F0(dp, rd);
3425
/* break out of the loop if we have finished */
3429
if (op == 15 && delta_m == 0) {
3430
/* single source one-many */
3432
rd = ((rd + delta_d) & (bank_mask - 1))
3434
gen_mov_vreg_F0(dp, rd);
3438
/* Setup the next operands. */
3440
rd = ((rd + delta_d) & (bank_mask - 1))
3444
/* One source operand. */
3445
rm = ((rm + delta_m) & (bank_mask - 1))
3447
gen_mov_F0_vreg(dp, rm);
3449
/* Two source operands. */
3450
rn = ((rn + delta_d) & (bank_mask - 1))
3452
gen_mov_F0_vreg(dp, rn);
3454
rm = ((rm + delta_m) & (bank_mask - 1))
3456
gen_mov_F1_vreg(dp, rm);
3464
if ((insn & 0x03e00000) == 0x00400000) {
3465
/* two-register transfer */
3466
rn = (insn >> 16) & 0xf;
3467
rd = (insn >> 12) & 0xf;
3469
VFP_DREG_M(rm, insn);
3471
rm = VFP_SREG_M(insn);
3474
if (insn & ARM_CP_RW_BIT) {
3477
gen_mov_F0_vreg(0, rm * 2);
3478
tmp = gen_vfp_mrs();
3479
store_reg(s, rd, tmp);
3480
gen_mov_F0_vreg(0, rm * 2 + 1);
3481
tmp = gen_vfp_mrs();
3482
store_reg(s, rn, tmp);
3484
gen_mov_F0_vreg(0, rm);
3485
tmp = gen_vfp_mrs();
3486
store_reg(s, rd, tmp);
3487
gen_mov_F0_vreg(0, rm + 1);
3488
tmp = gen_vfp_mrs();
3489
store_reg(s, rn, tmp);
3494
tmp = load_reg(s, rd);
3496
gen_mov_vreg_F0(0, rm * 2);
3497
tmp = load_reg(s, rn);
3499
gen_mov_vreg_F0(0, rm * 2 + 1);
3501
tmp = load_reg(s, rd);
3503
gen_mov_vreg_F0(0, rm);
3504
tmp = load_reg(s, rn);
3506
gen_mov_vreg_F0(0, rm + 1);
3511
rn = (insn >> 16) & 0xf;
3513
VFP_DREG_D(rd, insn);
3515
rd = VFP_SREG_D(insn);
3516
if ((insn & 0x01200000) == 0x01000000) {
3517
/* Single load/store */
3518
offset = (insn & 0xff) << 2;
3519
if ((insn & (1 << 23)) == 0)
3521
if (s->thumb && rn == 15) {
3522
/* This is actually UNPREDICTABLE */
3523
addr = tcg_temp_new_i32();
3524
tcg_gen_movi_i32(addr, s->pc & ~2);
3526
addr = load_reg(s, rn);
3528
tcg_gen_addi_i32(addr, addr, offset);
3529
if (insn & (1 << 20)) {
3530
gen_vfp_ld(s, dp, addr);
3531
gen_mov_vreg_F0(dp, rd);
3533
gen_mov_F0_vreg(dp, rd);
3534
gen_vfp_st(s, dp, addr);
3536
tcg_temp_free_i32(addr);
3538
/* load/store multiple */
3539
int w = insn & (1 << 21);
3541
n = (insn >> 1) & 0x7f;
3545
if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
3546
/* P == U , W == 1 => UNDEF */
3549
if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
3550
/* UNPREDICTABLE cases for bad immediates: we choose to
3551
* UNDEF to avoid generating huge numbers of TCG ops
3555
if (rn == 15 && w) {
3556
/* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3560
if (s->thumb && rn == 15) {
3561
/* This is actually UNPREDICTABLE */
3562
addr = tcg_temp_new_i32();
3563
tcg_gen_movi_i32(addr, s->pc & ~2);
3565
addr = load_reg(s, rn);
3567
if (insn & (1 << 24)) /* pre-decrement */
3568
tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3574
for (i = 0; i < n; i++) {
3575
if (insn & ARM_CP_RW_BIT) {
3577
gen_vfp_ld(s, dp, addr);
3578
gen_mov_vreg_F0(dp, rd + i);
3581
gen_mov_F0_vreg(dp, rd + i);
3582
gen_vfp_st(s, dp, addr);
3584
tcg_gen_addi_i32(addr, addr, offset);
3588
if (insn & (1 << 24))
3589
offset = -offset * n;
3590
else if (dp && (insn & 1))
3596
tcg_gen_addi_i32(addr, addr, offset);
3597
store_reg(s, rn, addr);
3599
tcg_temp_free_i32(addr);
3605
/* Should never happen. */
3611
static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
3613
TranslationBlock *tb;
3616
if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3618
gen_set_pc_im(s, dest);
3619
tcg_gen_exit_tb((uintptr_t)tb + n);
3621
gen_set_pc_im(s, dest);
3626
static inline void gen_jmp (DisasContext *s, uint32_t dest)
3628
if (unlikely(s->singlestep_enabled)) {
3629
/* An indirect jump so that we still trigger the debug exception. */
3634
gen_goto_tb(s, 0, dest);
3635
s->is_jmp = DISAS_TB_JUMP;
3639
static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
3642
tcg_gen_sari_i32(t0, t0, 16);
3646
tcg_gen_sari_i32(t1, t1, 16);
3649
tcg_gen_mul_i32(t0, t0, t1);
3652
/* Return the mask of PSR bits set by a MSR instruction. */
3653
static uint32_t msr_mask(CPUARMState *env, DisasContext *s, int flags, int spsr) {
3657
if (flags & (1 << 0))
3659
if (flags & (1 << 1))
3661
if (flags & (1 << 2))
3663
if (flags & (1 << 3))
3666
/* Mask out undefined bits. */
3667
mask &= ~CPSR_RESERVED;
3668
if (!arm_feature(env, ARM_FEATURE_V4T))
3670
if (!arm_feature(env, ARM_FEATURE_V5))
3671
mask &= ~CPSR_Q; /* V5TE in reality*/
3672
if (!arm_feature(env, ARM_FEATURE_V6))
3673
mask &= ~(CPSR_E | CPSR_GE);
3674
if (!arm_feature(env, ARM_FEATURE_THUMB2))
3676
/* Mask out execution state bits. */
3679
/* Mask out privileged bits. */
3685
/* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3686
static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
3690
/* ??? This is also undefined in system mode. */
3694
tmp = load_cpu_field(spsr);
3695
tcg_gen_andi_i32(tmp, tmp, ~mask);
3696
tcg_gen_andi_i32(t0, t0, mask);
3697
tcg_gen_or_i32(tmp, tmp, t0);
3698
store_cpu_field(tmp, spsr);
3700
gen_set_cpsr(t0, mask);
3702
tcg_temp_free_i32(t0);
3707
/* Returns nonzero if access to the PSR is not permitted. */
3708
static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3711
tmp = tcg_temp_new_i32();
3712
tcg_gen_movi_i32(tmp, val);
3713
return gen_set_psr(s, mask, spsr, tmp);
3716
/* Generate an old-style exception return. Marks pc as dead. */
3717
static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
3720
store_reg(s, 15, pc);
3721
tmp = load_cpu_field(spsr);
3722
gen_set_cpsr(tmp, 0xffffffff);
3723
tcg_temp_free_i32(tmp);
3724
s->is_jmp = DISAS_UPDATE;
3727
/* Generate a v6 exception return. Marks both values as dead. */
3728
static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
3730
gen_set_cpsr(cpsr, 0xffffffff);
3731
tcg_temp_free_i32(cpsr);
3732
store_reg(s, 15, pc);
3733
s->is_jmp = DISAS_UPDATE;
3737
gen_set_condexec (DisasContext *s)
3739
if (s->condexec_mask) {
3740
uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3741
TCGv_i32 tmp = tcg_temp_new_i32();
3742
tcg_gen_movi_i32(tmp, val);
3743
store_cpu_field(tmp, condexec_bits);
3747
static void gen_exception_insn(DisasContext *s, int offset, int excp)
3749
gen_set_condexec(s);
3750
gen_set_pc_im(s, s->pc - offset);
3751
gen_exception(excp);
3752
s->is_jmp = DISAS_JUMP;
3755
static void gen_nop_hint(DisasContext *s, int val)
3759
gen_set_pc_im(s, s->pc);
3760
s->is_jmp = DISAS_WFI;
3765
/* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3771
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3773
static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
3776
case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3777
case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3778
case 2: tcg_gen_add_i32(t0, t0, t1); break;
3783
static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
3786
case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3787
case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3788
case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3793
/* 32-bit pairwise ops end up the same as the elementwise versions. */
3794
#define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3795
#define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3796
#define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3797
#define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3799
#define GEN_NEON_INTEGER_OP_ENV(name) do { \
3800
switch ((size << 1) | u) { \
3802
gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3805
gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3808
gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3811
gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3814
gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3817
gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3819
default: return 1; \
3822
#define GEN_NEON_INTEGER_OP(name) do { \
3823
switch ((size << 1) | u) { \
3825
gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3828
gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3831
gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3834
gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3837
gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3840
gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3842
default: return 1; \
3845
static TCGv_i32 neon_load_scratch(int scratch)
3847
TCGv_i32 tmp = tcg_temp_new_i32();
3848
tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3852
static void neon_store_scratch(int scratch, TCGv_i32 var)
3854
tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3855
tcg_temp_free_i32(var);
3858
static inline TCGv_i32 neon_get_scalar(int size, int reg)
3862
tmp = neon_load_reg(reg & 7, reg >> 4);
3864
gen_neon_dup_high16(tmp);
3866
gen_neon_dup_low16(tmp);
3869
tmp = neon_load_reg(reg & 15, reg >> 4);
3874
static int gen_neon_unzip(int rd, int rm, int size, int q)
3877
if (!q && size == 2) {
3880
tmp = tcg_const_i32(rd);
3881
tmp2 = tcg_const_i32(rm);
3885
gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
3888
gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
3891
gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
3899
gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
3902
gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
3908
tcg_temp_free_i32(tmp);
3909
tcg_temp_free_i32(tmp2);
3913
static int gen_neon_zip(int rd, int rm, int size, int q)
3916
if (!q && size == 2) {
3919
tmp = tcg_const_i32(rd);
3920
tmp2 = tcg_const_i32(rm);
3924
gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
3927
gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
3930
gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
3938
gen_helper_neon_zip8(cpu_env, tmp, tmp2);
3941
gen_helper_neon_zip16(cpu_env, tmp, tmp2);
3947
tcg_temp_free_i32(tmp);
3948
tcg_temp_free_i32(tmp2);
3952
static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
3956
rd = tcg_temp_new_i32();
3957
tmp = tcg_temp_new_i32();
3959
tcg_gen_shli_i32(rd, t0, 8);
3960
tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3961
tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3962
tcg_gen_or_i32(rd, rd, tmp);
3964
tcg_gen_shri_i32(t1, t1, 8);
3965
tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3966
tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3967
tcg_gen_or_i32(t1, t1, tmp);
3968
tcg_gen_mov_i32(t0, rd);
3970
tcg_temp_free_i32(tmp);
3971
tcg_temp_free_i32(rd);
3974
static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
3978
rd = tcg_temp_new_i32();
3979
tmp = tcg_temp_new_i32();
3981
tcg_gen_shli_i32(rd, t0, 16);
3982
tcg_gen_andi_i32(tmp, t1, 0xffff);
3983
tcg_gen_or_i32(rd, rd, tmp);
3984
tcg_gen_shri_i32(t1, t1, 16);
3985
tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3986
tcg_gen_or_i32(t1, t1, tmp);
3987
tcg_gen_mov_i32(t0, rd);
3989
tcg_temp_free_i32(tmp);
3990
tcg_temp_free_i32(rd);
3998
} neon_ls_element_type[11] = {
4012
/* Translate a NEON load/store element instruction. Return nonzero if the
4013
instruction is invalid. */
4014
static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4033
if (!s->vfp_enabled)
4035
VFP_DREG_D(rd, insn);
4036
rn = (insn >> 16) & 0xf;
4038
load = (insn & (1 << 21)) != 0;
4039
if ((insn & (1 << 23)) == 0) {
4040
/* Load store all elements. */
4041
op = (insn >> 8) & 0xf;
4042
size = (insn >> 6) & 3;
4045
/* Catch UNDEF cases for bad values of align field */
4048
if (((insn >> 5) & 1) == 1) {
4053
if (((insn >> 4) & 3) == 3) {
4060
nregs = neon_ls_element_type[op].nregs;
4061
interleave = neon_ls_element_type[op].interleave;
4062
spacing = neon_ls_element_type[op].spacing;
4063
if (size == 3 && (interleave | spacing) != 1)
4065
addr = tcg_temp_new_i32();
4066
load_reg_var(s, addr, rn);
4067
stride = (1 << size) * interleave;
4068
for (reg = 0; reg < nregs; reg++) {
4069
if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4070
load_reg_var(s, addr, rn);
4071
tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
4072
} else if (interleave == 2 && nregs == 4 && reg == 2) {
4073
load_reg_var(s, addr, rn);
4074
tcg_gen_addi_i32(addr, addr, 1 << size);
4077
tmp64 = tcg_temp_new_i64();
4079
gen_aa32_ld64(tmp64, addr, IS_USER(s));
4080
neon_store_reg64(tmp64, rd);
4082
neon_load_reg64(tmp64, rd);
4083
gen_aa32_st64(tmp64, addr, IS_USER(s));
4085
tcg_temp_free_i64(tmp64);
4086
tcg_gen_addi_i32(addr, addr, stride);
4088
for (pass = 0; pass < 2; pass++) {
4091
tmp = tcg_temp_new_i32();
4092
gen_aa32_ld32u(tmp, addr, IS_USER(s));
4093
neon_store_reg(rd, pass, tmp);
4095
tmp = neon_load_reg(rd, pass);
4096
gen_aa32_st32(tmp, addr, IS_USER(s));
4097
tcg_temp_free_i32(tmp);
4099
tcg_gen_addi_i32(addr, addr, stride);
4100
} else if (size == 1) {
4102
tmp = tcg_temp_new_i32();
4103
gen_aa32_ld16u(tmp, addr, IS_USER(s));
4104
tcg_gen_addi_i32(addr, addr, stride);
4105
tmp2 = tcg_temp_new_i32();
4106
gen_aa32_ld16u(tmp2, addr, IS_USER(s));
4107
tcg_gen_addi_i32(addr, addr, stride);
4108
tcg_gen_shli_i32(tmp2, tmp2, 16);
4109
tcg_gen_or_i32(tmp, tmp, tmp2);
4110
tcg_temp_free_i32(tmp2);
4111
neon_store_reg(rd, pass, tmp);
4113
tmp = neon_load_reg(rd, pass);
4114
tmp2 = tcg_temp_new_i32();
4115
tcg_gen_shri_i32(tmp2, tmp, 16);
4116
gen_aa32_st16(tmp, addr, IS_USER(s));
4117
tcg_temp_free_i32(tmp);
4118
tcg_gen_addi_i32(addr, addr, stride);
4119
gen_aa32_st16(tmp2, addr, IS_USER(s));
4120
tcg_temp_free_i32(tmp2);
4121
tcg_gen_addi_i32(addr, addr, stride);
4123
} else /* size == 0 */ {
4125
TCGV_UNUSED_I32(tmp2);
4126
for (n = 0; n < 4; n++) {
4127
tmp = tcg_temp_new_i32();
4128
gen_aa32_ld8u(tmp, addr, IS_USER(s));
4129
tcg_gen_addi_i32(addr, addr, stride);
4133
tcg_gen_shli_i32(tmp, tmp, n * 8);
4134
tcg_gen_or_i32(tmp2, tmp2, tmp);
4135
tcg_temp_free_i32(tmp);
4138
neon_store_reg(rd, pass, tmp2);
4140
tmp2 = neon_load_reg(rd, pass);
4141
for (n = 0; n < 4; n++) {
4142
tmp = tcg_temp_new_i32();
4144
tcg_gen_mov_i32(tmp, tmp2);
4146
tcg_gen_shri_i32(tmp, tmp2, n * 8);
4148
gen_aa32_st8(tmp, addr, IS_USER(s));
4149
tcg_temp_free_i32(tmp);
4150
tcg_gen_addi_i32(addr, addr, stride);
4152
tcg_temp_free_i32(tmp2);
4159
tcg_temp_free_i32(addr);
4162
size = (insn >> 10) & 3;
4164
/* Load single element to all lanes. */
4165
int a = (insn >> 4) & 1;
4169
size = (insn >> 6) & 3;
4170
nregs = ((insn >> 8) & 3) + 1;
4173
if (nregs != 4 || a == 0) {
4176
/* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4179
if (nregs == 1 && a == 1 && size == 0) {
4182
if (nregs == 3 && a == 1) {
4185
addr = tcg_temp_new_i32();
4186
load_reg_var(s, addr, rn);
4188
/* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4189
tmp = gen_load_and_replicate(s, addr, size);
4190
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4191
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4192
if (insn & (1 << 5)) {
4193
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
4194
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
4196
tcg_temp_free_i32(tmp);
4198
/* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4199
stride = (insn & (1 << 5)) ? 2 : 1;
4200
for (reg = 0; reg < nregs; reg++) {
4201
tmp = gen_load_and_replicate(s, addr, size);
4202
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4203
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4204
tcg_temp_free_i32(tmp);
4205
tcg_gen_addi_i32(addr, addr, 1 << size);
4209
tcg_temp_free_i32(addr);
4210
stride = (1 << size) * nregs;
4212
/* Single element. */
4213
int idx = (insn >> 4) & 0xf;
4214
pass = (insn >> 7) & 1;
4217
shift = ((insn >> 5) & 3) * 8;
4221
shift = ((insn >> 6) & 1) * 16;
4222
stride = (insn & (1 << 5)) ? 2 : 1;
4226
stride = (insn & (1 << 6)) ? 2 : 1;
4231
nregs = ((insn >> 8) & 3) + 1;
4232
/* Catch the UNDEF cases. This is unavoidably a bit messy. */
4235
if (((idx & (1 << size)) != 0) ||
4236
(size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4241
if ((idx & 1) != 0) {
4246
if (size == 2 && (idx & 2) != 0) {
4251
if ((size == 2) && ((idx & 3) == 3)) {
4258
if ((rd + stride * (nregs - 1)) > 31) {
4259
/* Attempts to write off the end of the register file
4260
* are UNPREDICTABLE; we choose to UNDEF because otherwise
4261
* the neon_load_reg() would write off the end of the array.
4265
addr = tcg_temp_new_i32();
4266
load_reg_var(s, addr, rn);
4267
for (reg = 0; reg < nregs; reg++) {
4269
tmp = tcg_temp_new_i32();
4272
gen_aa32_ld8u(tmp, addr, IS_USER(s));
4275
gen_aa32_ld16u(tmp, addr, IS_USER(s));
4278
gen_aa32_ld32u(tmp, addr, IS_USER(s));
4280
default: /* Avoid compiler warnings. */
4284
tmp2 = neon_load_reg(rd, pass);
4285
tcg_gen_deposit_i32(tmp, tmp2, tmp,
4286
shift, size ? 16 : 8);
4287
tcg_temp_free_i32(tmp2);
4289
neon_store_reg(rd, pass, tmp);
4290
} else { /* Store */
4291
tmp = neon_load_reg(rd, pass);
4293
tcg_gen_shri_i32(tmp, tmp, shift);
4296
gen_aa32_st8(tmp, addr, IS_USER(s));
4299
gen_aa32_st16(tmp, addr, IS_USER(s));
4302
gen_aa32_st32(tmp, addr, IS_USER(s));
4305
tcg_temp_free_i32(tmp);
4308
tcg_gen_addi_i32(addr, addr, 1 << size);
4310
tcg_temp_free_i32(addr);
4311
stride = nregs * (1 << size);
4317
base = load_reg(s, rn);
4319
tcg_gen_addi_i32(base, base, stride);
4322
index = load_reg(s, rm);
4323
tcg_gen_add_i32(base, base, index);
4324
tcg_temp_free_i32(index);
4326
store_reg(s, rn, base);
4331
/* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4332
static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
4334
tcg_gen_and_i32(t, t, c);
4335
tcg_gen_andc_i32(f, f, c);
4336
tcg_gen_or_i32(dest, t, f);
4339
static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
4342
case 0: gen_helper_neon_narrow_u8(dest, src); break;
4343
case 1: gen_helper_neon_narrow_u16(dest, src); break;
4344
case 2: tcg_gen_trunc_i64_i32(dest, src); break;
4349
static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4352
case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4353
case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4354
case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4359
static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
4362
case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4363
case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4364
case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4369
static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4372
case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4373
case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4374
case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4379
static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
4385
case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4386
case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4391
case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4392
case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4399
case 1: gen_helper_neon_shl_u16(var, var, shift); break;
4400
case 2: gen_helper_neon_shl_u32(var, var, shift); break;
4405
case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4406
case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4413
static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
4417
case 0: gen_helper_neon_widen_u8(dest, src); break;
4418
case 1: gen_helper_neon_widen_u16(dest, src); break;
4419
case 2: tcg_gen_extu_i32_i64(dest, src); break;
4424
case 0: gen_helper_neon_widen_s8(dest, src); break;
4425
case 1: gen_helper_neon_widen_s16(dest, src); break;
4426
case 2: tcg_gen_ext_i32_i64(dest, src); break;
4430
tcg_temp_free_i32(src);
4433
static inline void gen_neon_addl(int size)
4436
case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4437
case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4438
case 2: tcg_gen_add_i64(CPU_V001); break;
4443
static inline void gen_neon_subl(int size)
4446
case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4447
case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4448
case 2: tcg_gen_sub_i64(CPU_V001); break;
4453
static inline void gen_neon_negl(TCGv_i64 var, int size)
4456
case 0: gen_helper_neon_negl_u16(var, var); break;
4457
case 1: gen_helper_neon_negl_u32(var, var); break;
4459
tcg_gen_neg_i64(var, var);
4465
static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4468
case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4469
case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4474
static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
4479
switch ((size << 1) | u) {
4480
case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4481
case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4482
case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4483
case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4485
tmp = gen_muls_i64_i32(a, b);
4486
tcg_gen_mov_i64(dest, tmp);
4487
tcg_temp_free_i64(tmp);
4490
tmp = gen_mulu_i64_i32(a, b);
4491
tcg_gen_mov_i64(dest, tmp);
4492
tcg_temp_free_i64(tmp);
4497
/* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4498
Don't forget to clean them now. */
4500
tcg_temp_free_i32(a);
4501
tcg_temp_free_i32(b);
4505
static void gen_neon_narrow_op(int op, int u, int size,
4506
TCGv_i32 dest, TCGv_i64 src)
4510
gen_neon_unarrow_sats(size, dest, src);
4512
gen_neon_narrow(size, dest, src);
4516
gen_neon_narrow_satu(size, dest, src);
4518
gen_neon_narrow_sats(size, dest, src);
4523
/* Symbolic constants for op fields for Neon 3-register same-length.
4524
* The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4527
#define NEON_3R_VHADD 0
4528
#define NEON_3R_VQADD 1
4529
#define NEON_3R_VRHADD 2
4530
#define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4531
#define NEON_3R_VHSUB 4
4532
#define NEON_3R_VQSUB 5
4533
#define NEON_3R_VCGT 6
4534
#define NEON_3R_VCGE 7
4535
#define NEON_3R_VSHL 8
4536
#define NEON_3R_VQSHL 9
4537
#define NEON_3R_VRSHL 10
4538
#define NEON_3R_VQRSHL 11
4539
#define NEON_3R_VMAX 12
4540
#define NEON_3R_VMIN 13
4541
#define NEON_3R_VABD 14
4542
#define NEON_3R_VABA 15
4543
#define NEON_3R_VADD_VSUB 16
4544
#define NEON_3R_VTST_VCEQ 17
4545
#define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4546
#define NEON_3R_VMUL 19
4547
#define NEON_3R_VPMAX 20
4548
#define NEON_3R_VPMIN 21
4549
#define NEON_3R_VQDMULH_VQRDMULH 22
4550
#define NEON_3R_VPADD 23
4551
#define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4552
#define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4553
#define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4554
#define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4555
#define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4556
#define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4557
#define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4559
static const uint8_t neon_3r_sizes[] = {
4560
[NEON_3R_VHADD] = 0x7,
4561
[NEON_3R_VQADD] = 0xf,
4562
[NEON_3R_VRHADD] = 0x7,
4563
[NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
4564
[NEON_3R_VHSUB] = 0x7,
4565
[NEON_3R_VQSUB] = 0xf,
4566
[NEON_3R_VCGT] = 0x7,
4567
[NEON_3R_VCGE] = 0x7,
4568
[NEON_3R_VSHL] = 0xf,
4569
[NEON_3R_VQSHL] = 0xf,
4570
[NEON_3R_VRSHL] = 0xf,
4571
[NEON_3R_VQRSHL] = 0xf,
4572
[NEON_3R_VMAX] = 0x7,
4573
[NEON_3R_VMIN] = 0x7,
4574
[NEON_3R_VABD] = 0x7,
4575
[NEON_3R_VABA] = 0x7,
4576
[NEON_3R_VADD_VSUB] = 0xf,
4577
[NEON_3R_VTST_VCEQ] = 0x7,
4578
[NEON_3R_VML] = 0x7,
4579
[NEON_3R_VMUL] = 0x7,
4580
[NEON_3R_VPMAX] = 0x7,
4581
[NEON_3R_VPMIN] = 0x7,
4582
[NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4583
[NEON_3R_VPADD] = 0x7,
4584
[NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
4585
[NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4586
[NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4587
[NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4588
[NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4589
[NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4590
[NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
4593
/* Symbolic constants for op fields for Neon 2-register miscellaneous.
4594
* The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4597
#define NEON_2RM_VREV64 0
4598
#define NEON_2RM_VREV32 1
4599
#define NEON_2RM_VREV16 2
4600
#define NEON_2RM_VPADDL 4
4601
#define NEON_2RM_VPADDL_U 5
4602
#define NEON_2RM_VCLS 8
4603
#define NEON_2RM_VCLZ 9
4604
#define NEON_2RM_VCNT 10
4605
#define NEON_2RM_VMVN 11
4606
#define NEON_2RM_VPADAL 12
4607
#define NEON_2RM_VPADAL_U 13
4608
#define NEON_2RM_VQABS 14
4609
#define NEON_2RM_VQNEG 15
4610
#define NEON_2RM_VCGT0 16
4611
#define NEON_2RM_VCGE0 17
4612
#define NEON_2RM_VCEQ0 18
4613
#define NEON_2RM_VCLE0 19
4614
#define NEON_2RM_VCLT0 20
4615
#define NEON_2RM_VABS 22
4616
#define NEON_2RM_VNEG 23
4617
#define NEON_2RM_VCGT0_F 24
4618
#define NEON_2RM_VCGE0_F 25
4619
#define NEON_2RM_VCEQ0_F 26
4620
#define NEON_2RM_VCLE0_F 27
4621
#define NEON_2RM_VCLT0_F 28
4622
#define NEON_2RM_VABS_F 30
4623
#define NEON_2RM_VNEG_F 31
4624
#define NEON_2RM_VSWP 32
4625
#define NEON_2RM_VTRN 33
4626
#define NEON_2RM_VUZP 34
4627
#define NEON_2RM_VZIP 35
4628
#define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4629
#define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4630
#define NEON_2RM_VSHLL 38
4631
#define NEON_2RM_VCVT_F16_F32 44
4632
#define NEON_2RM_VCVT_F32_F16 46
4633
#define NEON_2RM_VRECPE 56
4634
#define NEON_2RM_VRSQRTE 57
4635
#define NEON_2RM_VRECPE_F 58
4636
#define NEON_2RM_VRSQRTE_F 59
4637
#define NEON_2RM_VCVT_FS 60
4638
#define NEON_2RM_VCVT_FU 61
4639
#define NEON_2RM_VCVT_SF 62
4640
#define NEON_2RM_VCVT_UF 63
4642
static int neon_2rm_is_float_op(int op)
4644
/* Return true if this neon 2reg-misc op is float-to-float */
4645
return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
4646
op >= NEON_2RM_VRECPE_F);
4649
/* Each entry in this array has bit n set if the insn allows
4650
* size value n (otherwise it will UNDEF). Since unallocated
4651
* op values will have no bits set they always UNDEF.
4653
static const uint8_t neon_2rm_sizes[] = {
4654
[NEON_2RM_VREV64] = 0x7,
4655
[NEON_2RM_VREV32] = 0x3,
4656
[NEON_2RM_VREV16] = 0x1,
4657
[NEON_2RM_VPADDL] = 0x7,
4658
[NEON_2RM_VPADDL_U] = 0x7,
4659
[NEON_2RM_VCLS] = 0x7,
4660
[NEON_2RM_VCLZ] = 0x7,
4661
[NEON_2RM_VCNT] = 0x1,
4662
[NEON_2RM_VMVN] = 0x1,
4663
[NEON_2RM_VPADAL] = 0x7,
4664
[NEON_2RM_VPADAL_U] = 0x7,
4665
[NEON_2RM_VQABS] = 0x7,
4666
[NEON_2RM_VQNEG] = 0x7,
4667
[NEON_2RM_VCGT0] = 0x7,
4668
[NEON_2RM_VCGE0] = 0x7,
4669
[NEON_2RM_VCEQ0] = 0x7,
4670
[NEON_2RM_VCLE0] = 0x7,
4671
[NEON_2RM_VCLT0] = 0x7,
4672
[NEON_2RM_VABS] = 0x7,
4673
[NEON_2RM_VNEG] = 0x7,
4674
[NEON_2RM_VCGT0_F] = 0x4,
4675
[NEON_2RM_VCGE0_F] = 0x4,
4676
[NEON_2RM_VCEQ0_F] = 0x4,
4677
[NEON_2RM_VCLE0_F] = 0x4,
4678
[NEON_2RM_VCLT0_F] = 0x4,
4679
[NEON_2RM_VABS_F] = 0x4,
4680
[NEON_2RM_VNEG_F] = 0x4,
4681
[NEON_2RM_VSWP] = 0x1,
4682
[NEON_2RM_VTRN] = 0x7,
4683
[NEON_2RM_VUZP] = 0x7,
4684
[NEON_2RM_VZIP] = 0x7,
4685
[NEON_2RM_VMOVN] = 0x7,
4686
[NEON_2RM_VQMOVN] = 0x7,
4687
[NEON_2RM_VSHLL] = 0x7,
4688
[NEON_2RM_VCVT_F16_F32] = 0x2,
4689
[NEON_2RM_VCVT_F32_F16] = 0x2,
4690
[NEON_2RM_VRECPE] = 0x4,
4691
[NEON_2RM_VRSQRTE] = 0x4,
4692
[NEON_2RM_VRECPE_F] = 0x4,
4693
[NEON_2RM_VRSQRTE_F] = 0x4,
4694
[NEON_2RM_VCVT_FS] = 0x4,
4695
[NEON_2RM_VCVT_FU] = 0x4,
4696
[NEON_2RM_VCVT_SF] = 0x4,
4697
[NEON_2RM_VCVT_UF] = 0x4,
4700
/* Translate a NEON data processing instruction. Return nonzero if the
4701
instruction is invalid.
4702
We process data in a mixture of 32-bit and 64-bit chunks.
4703
Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4705
static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4717
TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
4720
if (!s->vfp_enabled)
4722
q = (insn & (1 << 6)) != 0;
4723
u = (insn >> 24) & 1;
4724
VFP_DREG_D(rd, insn);
4725
VFP_DREG_N(rn, insn);
4726
VFP_DREG_M(rm, insn);
4727
size = (insn >> 20) & 3;
4728
if ((insn & (1 << 23)) == 0) {
4729
/* Three register same length. */
4730
op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4731
/* Catch invalid op and bad size combinations: UNDEF */
4732
if ((neon_3r_sizes[op] & (1 << size)) == 0) {
4735
/* All insns of this form UNDEF for either this condition or the
4736
* superset of cases "Q==1"; we catch the latter later.
4738
if (q && ((rd | rn | rm) & 1)) {
4741
if (size == 3 && op != NEON_3R_LOGIC) {
4742
/* 64-bit element instructions. */
4743
for (pass = 0; pass < (q ? 2 : 1); pass++) {
4744
neon_load_reg64(cpu_V0, rn + pass);
4745
neon_load_reg64(cpu_V1, rm + pass);
4749
gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
4752
gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
4758
gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
4761
gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
4767
gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4769
gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4774
gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4777
gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
4783
gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4785
gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4788
case NEON_3R_VQRSHL:
4790
gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4793
gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4797
case NEON_3R_VADD_VSUB:
4799
tcg_gen_sub_i64(CPU_V001);
4801
tcg_gen_add_i64(CPU_V001);
4807
neon_store_reg64(cpu_V0, rd + pass);
4816
case NEON_3R_VQRSHL:
4819
/* Shift instruction operands are reversed. */
4834
case NEON_3R_FLOAT_ARITH:
4835
pairwise = (u && size < 2); /* if VPADD (float) */
4837
case NEON_3R_FLOAT_MINMAX:
4838
pairwise = u; /* if VPMIN/VPMAX (float) */
4840
case NEON_3R_FLOAT_CMP:
4842
/* no encoding for U=0 C=1x */
4846
case NEON_3R_FLOAT_ACMP:
4851
case NEON_3R_FLOAT_MISC:
4852
/* VMAXNM/VMINNM in ARMv8 */
4853
if (u && !arm_feature(env, ARM_FEATURE_V8)) {
4858
if (u && (size != 0)) {
4859
/* UNDEF on invalid size for polynomial subcase */
4864
if (!arm_feature(env, ARM_FEATURE_VFP4) || u) {
4872
if (pairwise && q) {
4873
/* All the pairwise insns UNDEF if Q is set */
4877
for (pass = 0; pass < (q ? 4 : 2); pass++) {
4882
tmp = neon_load_reg(rn, 0);
4883
tmp2 = neon_load_reg(rn, 1);
4885
tmp = neon_load_reg(rm, 0);
4886
tmp2 = neon_load_reg(rm, 1);
4890
tmp = neon_load_reg(rn, pass);
4891
tmp2 = neon_load_reg(rm, pass);
4895
GEN_NEON_INTEGER_OP(hadd);
4898
GEN_NEON_INTEGER_OP_ENV(qadd);
4900
case NEON_3R_VRHADD:
4901
GEN_NEON_INTEGER_OP(rhadd);
4903
case NEON_3R_LOGIC: /* Logic ops. */
4904
switch ((u << 2) | size) {
4906
tcg_gen_and_i32(tmp, tmp, tmp2);
4909
tcg_gen_andc_i32(tmp, tmp, tmp2);
4912
tcg_gen_or_i32(tmp, tmp, tmp2);
4915
tcg_gen_orc_i32(tmp, tmp, tmp2);
4918
tcg_gen_xor_i32(tmp, tmp, tmp2);
4921
tmp3 = neon_load_reg(rd, pass);
4922
gen_neon_bsl(tmp, tmp, tmp2, tmp3);
4923
tcg_temp_free_i32(tmp3);
4926
tmp3 = neon_load_reg(rd, pass);
4927
gen_neon_bsl(tmp, tmp, tmp3, tmp2);
4928
tcg_temp_free_i32(tmp3);
4931
tmp3 = neon_load_reg(rd, pass);
4932
gen_neon_bsl(tmp, tmp3, tmp, tmp2);
4933
tcg_temp_free_i32(tmp3);
4938
GEN_NEON_INTEGER_OP(hsub);
4941
GEN_NEON_INTEGER_OP_ENV(qsub);
4944
GEN_NEON_INTEGER_OP(cgt);
4947
GEN_NEON_INTEGER_OP(cge);
4950
GEN_NEON_INTEGER_OP(shl);
4953
GEN_NEON_INTEGER_OP_ENV(qshl);
4956
GEN_NEON_INTEGER_OP(rshl);
4958
case NEON_3R_VQRSHL:
4959
GEN_NEON_INTEGER_OP_ENV(qrshl);
4962
GEN_NEON_INTEGER_OP(max);
4965
GEN_NEON_INTEGER_OP(min);
4968
GEN_NEON_INTEGER_OP(abd);
4971
GEN_NEON_INTEGER_OP(abd);
4972
tcg_temp_free_i32(tmp2);
4973
tmp2 = neon_load_reg(rd, pass);
4974
gen_neon_add(size, tmp, tmp2);
4976
case NEON_3R_VADD_VSUB:
4977
if (!u) { /* VADD */
4978
gen_neon_add(size, tmp, tmp2);
4981
case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
4982
case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
4983
case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
4988
case NEON_3R_VTST_VCEQ:
4989
if (!u) { /* VTST */
4991
case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
4992
case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
4993
case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
4998
case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
4999
case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
5000
case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
5005
case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
5007
case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5008
case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5009
case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5012
tcg_temp_free_i32(tmp2);
5013
tmp2 = neon_load_reg(rd, pass);
5015
gen_neon_rsb(size, tmp, tmp2);
5017
gen_neon_add(size, tmp, tmp2);
5021
if (u) { /* polynomial */
5022
gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5023
} else { /* Integer */
5025
case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5026
case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5027
case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5033
GEN_NEON_INTEGER_OP(pmax);
5036
GEN_NEON_INTEGER_OP(pmin);
5038
case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5039
if (!u) { /* VQDMULH */
5042
gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5045
gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5049
} else { /* VQRDMULH */
5052
gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5055
gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5063
case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5064
case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5065
case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5069
case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5071
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5072
switch ((u << 2) | size) {
5075
gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5078
gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5081
gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5086
tcg_temp_free_ptr(fpstatus);
5089
case NEON_3R_FLOAT_MULTIPLY:
5091
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5092
gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5094
tcg_temp_free_i32(tmp2);
5095
tmp2 = neon_load_reg(rd, pass);
5097
gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5099
gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5102
tcg_temp_free_ptr(fpstatus);
5105
case NEON_3R_FLOAT_CMP:
5107
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5109
gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5112
gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5114
gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5117
tcg_temp_free_ptr(fpstatus);
5120
case NEON_3R_FLOAT_ACMP:
5122
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5124
gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
5126
gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
5128
tcg_temp_free_ptr(fpstatus);
5131
case NEON_3R_FLOAT_MINMAX:
5133
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5135
gen_helper_neon_max_f32(tmp, tmp, tmp2, fpstatus);
5137
gen_helper_neon_min_f32(tmp, tmp, tmp2, fpstatus);
5139
tcg_temp_free_ptr(fpstatus);
5142
case NEON_3R_FLOAT_MISC:
5145
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5147
gen_helper_vfp_maxnms(tmp, tmp, tmp2, fpstatus);
5149
gen_helper_vfp_minnms(tmp, tmp, tmp2, fpstatus);
5151
tcg_temp_free_ptr(fpstatus);
5154
gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5156
gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
5162
/* VFMA, VFMS: fused multiply-add */
5163
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5164
TCGv_i32 tmp3 = neon_load_reg(rd, pass);
5167
gen_helper_vfp_negs(tmp, tmp);
5169
gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
5170
tcg_temp_free_i32(tmp3);
5171
tcg_temp_free_ptr(fpstatus);
5177
tcg_temp_free_i32(tmp2);
5179
/* Save the result. For elementwise operations we can put it
5180
straight into the destination register. For pairwise operations
5181
we have to be careful to avoid clobbering the source operands. */
5182
if (pairwise && rd == rm) {
5183
neon_store_scratch(pass, tmp);
5185
neon_store_reg(rd, pass, tmp);
5189
if (pairwise && rd == rm) {
5190
for (pass = 0; pass < (q ? 4 : 2); pass++) {
5191
tmp = neon_load_scratch(pass);
5192
neon_store_reg(rd, pass, tmp);
5195
/* End of 3 register same size operations. */
5196
} else if (insn & (1 << 4)) {
5197
if ((insn & 0x00380080) != 0) {
5198
/* Two registers and shift. */
5199
op = (insn >> 8) & 0xf;
5200
if (insn & (1 << 7)) {
5208
while ((insn & (1 << (size + 19))) == 0)
5211
shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5212
/* To avoid excessive duplication of ops we implement shift
5213
by immediate using the variable shift operations. */
5215
/* Shift by immediate:
5216
VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5217
if (q && ((rd | rm) & 1)) {
5220
if (!u && (op == 4 || op == 6)) {
5223
/* Right shifts are encoded as N - shift, where N is the
5224
element size in bits. */
5226
shift = shift - (1 << (size + 3));
5234
imm = (uint8_t) shift;
5239
imm = (uint16_t) shift;
5250
for (pass = 0; pass < count; pass++) {
5252
neon_load_reg64(cpu_V0, rm + pass);
5253
tcg_gen_movi_i64(cpu_V1, imm);
5258
gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5260
gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
5265
gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5267
gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5270
case 5: /* VSHL, VSLI */
5271
gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5273
case 6: /* VQSHLU */
5274
gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5279
gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5282
gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5287
if (op == 1 || op == 3) {
5289
neon_load_reg64(cpu_V1, rd + pass);
5290
tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5291
} else if (op == 4 || (op == 5 && u)) {
5293
neon_load_reg64(cpu_V1, rd + pass);
5295
if (shift < -63 || shift > 63) {
5299
mask = 0xffffffffffffffffull >> -shift;
5301
mask = 0xffffffffffffffffull << shift;
5304
tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
5305
tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5307
neon_store_reg64(cpu_V0, rd + pass);
5308
} else { /* size < 3 */
5309
/* Operands in T0 and T1. */
5310
tmp = neon_load_reg(rm, pass);
5311
tmp2 = tcg_temp_new_i32();
5312
tcg_gen_movi_i32(tmp2, imm);
5316
GEN_NEON_INTEGER_OP(shl);
5320
GEN_NEON_INTEGER_OP(rshl);
5323
case 5: /* VSHL, VSLI */
5325
case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
5326
case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
5327
case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
5331
case 6: /* VQSHLU */
5334
gen_helper_neon_qshlu_s8(tmp, cpu_env,
5338
gen_helper_neon_qshlu_s16(tmp, cpu_env,
5342
gen_helper_neon_qshlu_s32(tmp, cpu_env,
5350
GEN_NEON_INTEGER_OP_ENV(qshl);
5353
tcg_temp_free_i32(tmp2);
5355
if (op == 1 || op == 3) {
5357
tmp2 = neon_load_reg(rd, pass);
5358
gen_neon_add(size, tmp, tmp2);
5359
tcg_temp_free_i32(tmp2);
5360
} else if (op == 4 || (op == 5 && u)) {
5365
mask = 0xff >> -shift;
5367
mask = (uint8_t)(0xff << shift);
5373
mask = 0xffff >> -shift;
5375
mask = (uint16_t)(0xffff << shift);
5379
if (shift < -31 || shift > 31) {
5383
mask = 0xffffffffu >> -shift;
5385
mask = 0xffffffffu << shift;
5391
tmp2 = neon_load_reg(rd, pass);
5392
tcg_gen_andi_i32(tmp, tmp, mask);
5393
tcg_gen_andi_i32(tmp2, tmp2, ~mask);
5394
tcg_gen_or_i32(tmp, tmp, tmp2);
5395
tcg_temp_free_i32(tmp2);
5397
neon_store_reg(rd, pass, tmp);
5400
} else if (op < 10) {
5401
/* Shift by immediate and narrow:
5402
VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5403
int input_unsigned = (op == 8) ? !u : u;
5407
shift = shift - (1 << (size + 3));
5410
tmp64 = tcg_const_i64(shift);
5411
neon_load_reg64(cpu_V0, rm);
5412
neon_load_reg64(cpu_V1, rm + 1);
5413
for (pass = 0; pass < 2; pass++) {
5421
if (input_unsigned) {
5422
gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5424
gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5427
if (input_unsigned) {
5428
gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5430
gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5433
tmp = tcg_temp_new_i32();
5434
gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5435
neon_store_reg(rd, pass, tmp);
5437
tcg_temp_free_i64(tmp64);
5440
imm = (uint16_t)shift;
5444
imm = (uint32_t)shift;
5446
tmp2 = tcg_const_i32(imm);
5447
tmp4 = neon_load_reg(rm + 1, 0);
5448
tmp5 = neon_load_reg(rm + 1, 1);
5449
for (pass = 0; pass < 2; pass++) {
5451
tmp = neon_load_reg(rm, 0);
5455
gen_neon_shift_narrow(size, tmp, tmp2, q,
5458
tmp3 = neon_load_reg(rm, 1);
5462
gen_neon_shift_narrow(size, tmp3, tmp2, q,
5464
tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5465
tcg_temp_free_i32(tmp);
5466
tcg_temp_free_i32(tmp3);
5467
tmp = tcg_temp_new_i32();
5468
gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5469
neon_store_reg(rd, pass, tmp);
5471
tcg_temp_free_i32(tmp2);
5473
} else if (op == 10) {
5475
if (q || (rd & 1)) {
5478
tmp = neon_load_reg(rm, 0);
5479
tmp2 = neon_load_reg(rm, 1);
5480
for (pass = 0; pass < 2; pass++) {
5484
gen_neon_widen(cpu_V0, tmp, size, u);
5487
/* The shift is less than the width of the source
5488
type, so we can just shift the whole register. */
5489
tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5490
/* Widen the result of shift: we need to clear
5491
* the potential overflow bits resulting from
5492
* left bits of the narrow input appearing as
5493
* right bits of left the neighbour narrow
5495
if (size < 2 || !u) {
5498
imm = (0xffu >> (8 - shift));
5500
} else if (size == 1) {
5501
imm = 0xffff >> (16 - shift);
5504
imm = 0xffffffff >> (32 - shift);
5507
imm64 = imm | (((uint64_t)imm) << 32);
5511
tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5514
neon_store_reg64(cpu_V0, rd + pass);
5516
} else if (op >= 14) {
5517
/* VCVT fixed-point. */
5518
if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5521
/* We have already masked out the must-be-1 top bit of imm6,
5522
* hence this 32-shift where the ARM ARM has 64-imm6.
5525
for (pass = 0; pass < (q ? 4 : 2); pass++) {
5526
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
5529
gen_vfp_ulto(0, shift, 1);
5531
gen_vfp_slto(0, shift, 1);
5534
gen_vfp_toul(0, shift, 1);
5536
gen_vfp_tosl(0, shift, 1);
5538
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
5543
} else { /* (insn & 0x00380080) == 0 */
5545
if (q && (rd & 1)) {
5549
op = (insn >> 8) & 0xf;
5550
/* One register and immediate. */
5551
imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5552
invert = (insn & (1 << 5)) != 0;
5553
/* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5554
* We choose to not special-case this and will behave as if a
5555
* valid constant encoding of 0 had been given.
5574
imm = (imm << 8) | (imm << 24);
5577
imm = (imm << 8) | 0xff;
5580
imm = (imm << 16) | 0xffff;
5583
imm |= (imm << 8) | (imm << 16) | (imm << 24);
5591
imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5592
| ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5598
for (pass = 0; pass < (q ? 4 : 2); pass++) {
5599
if (op & 1 && op < 12) {
5600
tmp = neon_load_reg(rd, pass);
5602
/* The immediate value has already been inverted, so
5604
tcg_gen_andi_i32(tmp, tmp, imm);
5606
tcg_gen_ori_i32(tmp, tmp, imm);
5610
tmp = tcg_temp_new_i32();
5611
if (op == 14 && invert) {
5615
for (n = 0; n < 4; n++) {
5616
if (imm & (1 << (n + (pass & 1) * 4)))
5617
val |= 0xff << (n * 8);
5619
tcg_gen_movi_i32(tmp, val);
5621
tcg_gen_movi_i32(tmp, imm);
5624
neon_store_reg(rd, pass, tmp);
5627
} else { /* (insn & 0x00800010 == 0x00800000) */
5629
op = (insn >> 8) & 0xf;
5630
if ((insn & (1 << 6)) == 0) {
5631
/* Three registers of different lengths. */
5635
/* undefreq: bit 0 : UNDEF if size != 0
5636
* bit 1 : UNDEF if size == 0
5637
* bit 2 : UNDEF if U == 1
5638
* Note that [1:0] set implies 'always UNDEF'
5641
/* prewiden, src1_wide, src2_wide, undefreq */
5642
static const int neon_3reg_wide[16][4] = {
5643
{1, 0, 0, 0}, /* VADDL */
5644
{1, 1, 0, 0}, /* VADDW */
5645
{1, 0, 0, 0}, /* VSUBL */
5646
{1, 1, 0, 0}, /* VSUBW */
5647
{0, 1, 1, 0}, /* VADDHN */
5648
{0, 0, 0, 0}, /* VABAL */
5649
{0, 1, 1, 0}, /* VSUBHN */
5650
{0, 0, 0, 0}, /* VABDL */
5651
{0, 0, 0, 0}, /* VMLAL */
5652
{0, 0, 0, 6}, /* VQDMLAL */
5653
{0, 0, 0, 0}, /* VMLSL */
5654
{0, 0, 0, 6}, /* VQDMLSL */
5655
{0, 0, 0, 0}, /* Integer VMULL */
5656
{0, 0, 0, 2}, /* VQDMULL */
5657
{0, 0, 0, 5}, /* Polynomial VMULL */
5658
{0, 0, 0, 3}, /* Reserved: always UNDEF */
5661
prewiden = neon_3reg_wide[op][0];
5662
src1_wide = neon_3reg_wide[op][1];
5663
src2_wide = neon_3reg_wide[op][2];
5664
undefreq = neon_3reg_wide[op][3];
5666
if (((undefreq & 1) && (size != 0)) ||
5667
((undefreq & 2) && (size == 0)) ||
5668
((undefreq & 4) && u)) {
5671
if ((src1_wide && (rn & 1)) ||
5672
(src2_wide && (rm & 1)) ||
5673
(!src2_wide && (rd & 1))) {
5677
/* Avoid overlapping operands. Wide source operands are
5678
always aligned so will never overlap with wide
5679
destinations in problematic ways. */
5680
if (rd == rm && !src2_wide) {
5681
tmp = neon_load_reg(rm, 1);
5682
neon_store_scratch(2, tmp);
5683
} else if (rd == rn && !src1_wide) {
5684
tmp = neon_load_reg(rn, 1);
5685
neon_store_scratch(2, tmp);
5687
TCGV_UNUSED_I32(tmp3);
5688
for (pass = 0; pass < 2; pass++) {
5690
neon_load_reg64(cpu_V0, rn + pass);
5691
TCGV_UNUSED_I32(tmp);
5693
if (pass == 1 && rd == rn) {
5694
tmp = neon_load_scratch(2);
5696
tmp = neon_load_reg(rn, pass);
5699
gen_neon_widen(cpu_V0, tmp, size, u);
5703
neon_load_reg64(cpu_V1, rm + pass);
5704
TCGV_UNUSED_I32(tmp2);
5706
if (pass == 1 && rd == rm) {
5707
tmp2 = neon_load_scratch(2);
5709
tmp2 = neon_load_reg(rm, pass);
5712
gen_neon_widen(cpu_V1, tmp2, size, u);
5716
case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5717
gen_neon_addl(size);
5719
case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5720
gen_neon_subl(size);
5722
case 5: case 7: /* VABAL, VABDL */
5723
switch ((size << 1) | u) {
5725
gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5728
gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5731
gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5734
gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5737
gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5740
gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5744
tcg_temp_free_i32(tmp2);
5745
tcg_temp_free_i32(tmp);
5747
case 8: case 9: case 10: case 11: case 12: case 13:
5748
/* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5749
gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5751
case 14: /* Polynomial VMULL */
5752
gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
5753
tcg_temp_free_i32(tmp2);
5754
tcg_temp_free_i32(tmp);
5756
default: /* 15 is RESERVED: caught earlier */
5761
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5762
neon_store_reg64(cpu_V0, rd + pass);
5763
} else if (op == 5 || (op >= 8 && op <= 11)) {
5765
neon_load_reg64(cpu_V1, rd + pass);
5767
case 10: /* VMLSL */
5768
gen_neon_negl(cpu_V0, size);
5770
case 5: case 8: /* VABAL, VMLAL */
5771
gen_neon_addl(size);
5773
case 9: case 11: /* VQDMLAL, VQDMLSL */
5774
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5776
gen_neon_negl(cpu_V0, size);
5778
gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5783
neon_store_reg64(cpu_V0, rd + pass);
5784
} else if (op == 4 || op == 6) {
5785
/* Narrowing operation. */
5786
tmp = tcg_temp_new_i32();
5790
gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
5793
gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
5796
tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5797
tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5804
gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
5807
gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
5810
tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
5811
tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5812
tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5820
neon_store_reg(rd, 0, tmp3);
5821
neon_store_reg(rd, 1, tmp);
5824
/* Write back the result. */
5825
neon_store_reg64(cpu_V0, rd + pass);
5829
/* Two registers and a scalar. NB that for ops of this form
5830
* the ARM ARM labels bit 24 as Q, but it is in our variable
5837
case 1: /* Float VMLA scalar */
5838
case 5: /* Floating point VMLS scalar */
5839
case 9: /* Floating point VMUL scalar */
5844
case 0: /* Integer VMLA scalar */
5845
case 4: /* Integer VMLS scalar */
5846
case 8: /* Integer VMUL scalar */
5847
case 12: /* VQDMULH scalar */
5848
case 13: /* VQRDMULH scalar */
5849
if (u && ((rd | rn) & 1)) {
5852
tmp = neon_get_scalar(size, rm);
5853
neon_store_scratch(0, tmp);
5854
for (pass = 0; pass < (u ? 4 : 2); pass++) {
5855
tmp = neon_load_scratch(0);
5856
tmp2 = neon_load_reg(rn, pass);
5859
gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5861
gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5863
} else if (op == 13) {
5865
gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5867
gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5869
} else if (op & 1) {
5870
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5871
gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5872
tcg_temp_free_ptr(fpstatus);
5875
case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5876
case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5877
case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5881
tcg_temp_free_i32(tmp2);
5884
tmp2 = neon_load_reg(rd, pass);
5887
gen_neon_add(size, tmp, tmp2);
5891
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5892
gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5893
tcg_temp_free_ptr(fpstatus);
5897
gen_neon_rsb(size, tmp, tmp2);
5901
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5902
gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5903
tcg_temp_free_ptr(fpstatus);
5909
tcg_temp_free_i32(tmp2);
5911
neon_store_reg(rd, pass, tmp);
5914
case 3: /* VQDMLAL scalar */
5915
case 7: /* VQDMLSL scalar */
5916
case 11: /* VQDMULL scalar */
5921
case 2: /* VMLAL sclar */
5922
case 6: /* VMLSL scalar */
5923
case 10: /* VMULL scalar */
5927
tmp2 = neon_get_scalar(size, rm);
5928
/* We need a copy of tmp2 because gen_neon_mull
5929
* deletes it during pass 0. */
5930
tmp4 = tcg_temp_new_i32();
5931
tcg_gen_mov_i32(tmp4, tmp2);
5932
tmp3 = neon_load_reg(rn, 1);
5934
for (pass = 0; pass < 2; pass++) {
5936
tmp = neon_load_reg(rn, 0);
5941
gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5943
neon_load_reg64(cpu_V1, rd + pass);
5947
gen_neon_negl(cpu_V0, size);
5950
gen_neon_addl(size);
5953
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5955
gen_neon_negl(cpu_V0, size);
5957
gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5963
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5968
neon_store_reg64(cpu_V0, rd + pass);
5973
default: /* 14 and 15 are RESERVED */
5977
} else { /* size == 3 */
5980
imm = (insn >> 8) & 0xf;
5985
if (q && ((rd | rn | rm) & 1)) {
5990
neon_load_reg64(cpu_V0, rn);
5992
neon_load_reg64(cpu_V1, rn + 1);
5994
} else if (imm == 8) {
5995
neon_load_reg64(cpu_V0, rn + 1);
5997
neon_load_reg64(cpu_V1, rm);
6000
tmp64 = tcg_temp_new_i64();
6002
neon_load_reg64(cpu_V0, rn);
6003
neon_load_reg64(tmp64, rn + 1);
6005
neon_load_reg64(cpu_V0, rn + 1);
6006
neon_load_reg64(tmp64, rm);
6008
tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6009
tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6010
tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6012
neon_load_reg64(cpu_V1, rm);
6014
neon_load_reg64(cpu_V1, rm + 1);
6017
tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6018
tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6019
tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6020
tcg_temp_free_i64(tmp64);
6023
neon_load_reg64(cpu_V0, rn);
6024
tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6025
neon_load_reg64(cpu_V1, rm);
6026
tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6027
tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6029
neon_store_reg64(cpu_V0, rd);
6031
neon_store_reg64(cpu_V1, rd + 1);
6033
} else if ((insn & (1 << 11)) == 0) {
6034
/* Two register misc. */
6035
op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6036
size = (insn >> 18) & 3;
6037
/* UNDEF for unknown op values and bad op-size combinations */
6038
if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6041
if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6042
q && ((rm | rd) & 1)) {
6046
case NEON_2RM_VREV64:
6047
for (pass = 0; pass < (q ? 2 : 1); pass++) {
6048
tmp = neon_load_reg(rm, pass * 2);
6049
tmp2 = neon_load_reg(rm, pass * 2 + 1);
6051
case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6052
case 1: gen_swap_half(tmp); break;
6053
case 2: /* no-op */ break;
6056
neon_store_reg(rd, pass * 2 + 1, tmp);
6058
neon_store_reg(rd, pass * 2, tmp2);
6061
case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6062
case 1: gen_swap_half(tmp2); break;
6065
neon_store_reg(rd, pass * 2, tmp2);
6069
case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6070
case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6071
for (pass = 0; pass < q + 1; pass++) {
6072
tmp = neon_load_reg(rm, pass * 2);
6073
gen_neon_widen(cpu_V0, tmp, size, op & 1);
6074
tmp = neon_load_reg(rm, pass * 2 + 1);
6075
gen_neon_widen(cpu_V1, tmp, size, op & 1);
6077
case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6078
case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6079
case 2: tcg_gen_add_i64(CPU_V001); break;
6082
if (op >= NEON_2RM_VPADAL) {
6084
neon_load_reg64(cpu_V1, rd + pass);
6085
gen_neon_addl(size);
6087
neon_store_reg64(cpu_V0, rd + pass);
6093
for (n = 0; n < (q ? 4 : 2); n += 2) {
6094
tmp = neon_load_reg(rm, n);
6095
tmp2 = neon_load_reg(rd, n + 1);
6096
neon_store_reg(rm, n, tmp2);
6097
neon_store_reg(rd, n + 1, tmp);
6104
if (gen_neon_unzip(rd, rm, size, q)) {
6109
if (gen_neon_zip(rd, rm, size, q)) {
6113
case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6114
/* also VQMOVUN; op field and mnemonics don't line up */
6118
TCGV_UNUSED_I32(tmp2);
6119
for (pass = 0; pass < 2; pass++) {
6120
neon_load_reg64(cpu_V0, rm + pass);
6121
tmp = tcg_temp_new_i32();
6122
gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
6127
neon_store_reg(rd, 0, tmp2);
6128
neon_store_reg(rd, 1, tmp);
6132
case NEON_2RM_VSHLL:
6133
if (q || (rd & 1)) {
6136
tmp = neon_load_reg(rm, 0);
6137
tmp2 = neon_load_reg(rm, 1);
6138
for (pass = 0; pass < 2; pass++) {
6141
gen_neon_widen(cpu_V0, tmp, size, 1);
6142
tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
6143
neon_store_reg64(cpu_V0, rd + pass);
6146
case NEON_2RM_VCVT_F16_F32:
6147
if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6151
tmp = tcg_temp_new_i32();
6152
tmp2 = tcg_temp_new_i32();
6153
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
6154
gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6155
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
6156
gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6157
tcg_gen_shli_i32(tmp2, tmp2, 16);
6158
tcg_gen_or_i32(tmp2, tmp2, tmp);
6159
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
6160
gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6161
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
6162
neon_store_reg(rd, 0, tmp2);
6163
tmp2 = tcg_temp_new_i32();
6164
gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6165
tcg_gen_shli_i32(tmp2, tmp2, 16);
6166
tcg_gen_or_i32(tmp2, tmp2, tmp);
6167
neon_store_reg(rd, 1, tmp2);
6168
tcg_temp_free_i32(tmp);
6170
case NEON_2RM_VCVT_F32_F16:
6171
if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6175
tmp3 = tcg_temp_new_i32();
6176
tmp = neon_load_reg(rm, 0);
6177
tmp2 = neon_load_reg(rm, 1);
6178
tcg_gen_ext16u_i32(tmp3, tmp);
6179
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6180
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
6181
tcg_gen_shri_i32(tmp3, tmp, 16);
6182
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6183
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
6184
tcg_temp_free_i32(tmp);
6185
tcg_gen_ext16u_i32(tmp3, tmp2);
6186
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6187
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
6188
tcg_gen_shri_i32(tmp3, tmp2, 16);
6189
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6190
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
6191
tcg_temp_free_i32(tmp2);
6192
tcg_temp_free_i32(tmp3);
6196
for (pass = 0; pass < (q ? 4 : 2); pass++) {
6197
if (neon_2rm_is_float_op(op)) {
6198
tcg_gen_ld_f32(cpu_F0s, cpu_env,
6199
neon_reg_offset(rm, pass));
6200
TCGV_UNUSED_I32(tmp);
6202
tmp = neon_load_reg(rm, pass);
6205
case NEON_2RM_VREV32:
6207
case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6208
case 1: gen_swap_half(tmp); break;
6212
case NEON_2RM_VREV16:
6217
case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6218
case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6219
case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6225
case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6226
case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6227
case 2: gen_helper_clz(tmp, tmp); break;
6232
gen_helper_neon_cnt_u8(tmp, tmp);
6235
tcg_gen_not_i32(tmp, tmp);
6237
case NEON_2RM_VQABS:
6240
gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6243
gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6246
gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6251
case NEON_2RM_VQNEG:
6254
gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6257
gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6260
gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6265
case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6266
tmp2 = tcg_const_i32(0);
6268
case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6269
case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6270
case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6273
tcg_temp_free_i32(tmp2);
6274
if (op == NEON_2RM_VCLE0) {
6275
tcg_gen_not_i32(tmp, tmp);
6278
case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6279
tmp2 = tcg_const_i32(0);
6281
case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6282
case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6283
case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6286
tcg_temp_free_i32(tmp2);
6287
if (op == NEON_2RM_VCLT0) {
6288
tcg_gen_not_i32(tmp, tmp);
6291
case NEON_2RM_VCEQ0:
6292
tmp2 = tcg_const_i32(0);
6294
case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6295
case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6296
case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6299
tcg_temp_free_i32(tmp2);
6303
case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
6304
case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
6305
case 2: tcg_gen_abs_i32(tmp, tmp); break;
6310
tmp2 = tcg_const_i32(0);
6311
gen_neon_rsb(size, tmp, tmp2);
6312
tcg_temp_free_i32(tmp2);
6314
case NEON_2RM_VCGT0_F:
6316
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6317
tmp2 = tcg_const_i32(0);
6318
gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6319
tcg_temp_free_i32(tmp2);
6320
tcg_temp_free_ptr(fpstatus);
6323
case NEON_2RM_VCGE0_F:
6325
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6326
tmp2 = tcg_const_i32(0);
6327
gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6328
tcg_temp_free_i32(tmp2);
6329
tcg_temp_free_ptr(fpstatus);
6332
case NEON_2RM_VCEQ0_F:
6334
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6335
tmp2 = tcg_const_i32(0);
6336
gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6337
tcg_temp_free_i32(tmp2);
6338
tcg_temp_free_ptr(fpstatus);
6341
case NEON_2RM_VCLE0_F:
6343
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6344
tmp2 = tcg_const_i32(0);
6345
gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6346
tcg_temp_free_i32(tmp2);
6347
tcg_temp_free_ptr(fpstatus);
6350
case NEON_2RM_VCLT0_F:
6352
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6353
tmp2 = tcg_const_i32(0);
6354
gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6355
tcg_temp_free_i32(tmp2);
6356
tcg_temp_free_ptr(fpstatus);
6359
case NEON_2RM_VABS_F:
6362
case NEON_2RM_VNEG_F:
6366
tmp2 = neon_load_reg(rd, pass);
6367
neon_store_reg(rm, pass, tmp2);
6370
tmp2 = neon_load_reg(rd, pass);
6372
case 0: gen_neon_trn_u8(tmp, tmp2); break;
6373
case 1: gen_neon_trn_u16(tmp, tmp2); break;
6376
neon_store_reg(rm, pass, tmp2);
6378
case NEON_2RM_VRECPE:
6379
gen_helper_recpe_u32(tmp, tmp, cpu_env);
6381
case NEON_2RM_VRSQRTE:
6382
gen_helper_rsqrte_u32(tmp, tmp, cpu_env);
6384
case NEON_2RM_VRECPE_F:
6385
gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
6387
case NEON_2RM_VRSQRTE_F:
6388
gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
6390
case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6393
case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6396
case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6397
gen_vfp_tosiz(0, 1);
6399
case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6400
gen_vfp_touiz(0, 1);
6403
/* Reserved op values were caught by the
6404
* neon_2rm_sizes[] check earlier.
6408
if (neon_2rm_is_float_op(op)) {
6409
tcg_gen_st_f32(cpu_F0s, cpu_env,
6410
neon_reg_offset(rd, pass));
6412
neon_store_reg(rd, pass, tmp);
6417
} else if ((insn & (1 << 10)) == 0) {
6419
int n = ((insn >> 8) & 3) + 1;
6420
if ((rn + n) > 32) {
6421
/* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6422
* helper function running off the end of the register file.
6427
if (insn & (1 << 6)) {
6428
tmp = neon_load_reg(rd, 0);
6430
tmp = tcg_temp_new_i32();
6431
tcg_gen_movi_i32(tmp, 0);
6433
tmp2 = neon_load_reg(rm, 0);
6434
tmp4 = tcg_const_i32(rn);
6435
tmp5 = tcg_const_i32(n);
6436
gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
6437
tcg_temp_free_i32(tmp);
6438
if (insn & (1 << 6)) {
6439
tmp = neon_load_reg(rd, 1);
6441
tmp = tcg_temp_new_i32();
6442
tcg_gen_movi_i32(tmp, 0);
6444
tmp3 = neon_load_reg(rm, 1);
6445
gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
6446
tcg_temp_free_i32(tmp5);
6447
tcg_temp_free_i32(tmp4);
6448
neon_store_reg(rd, 0, tmp2);
6449
neon_store_reg(rd, 1, tmp3);
6450
tcg_temp_free_i32(tmp);
6451
} else if ((insn & 0x380) == 0) {
6453
if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
6456
if (insn & (1 << 19)) {
6457
tmp = neon_load_reg(rm, 1);
6459
tmp = neon_load_reg(rm, 0);
6461
if (insn & (1 << 16)) {
6462
gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
6463
} else if (insn & (1 << 17)) {
6464
if ((insn >> 18) & 1)
6465
gen_neon_dup_high16(tmp);
6467
gen_neon_dup_low16(tmp);
6469
for (pass = 0; pass < (q ? 4 : 2); pass++) {
6470
tmp2 = tcg_temp_new_i32();
6471
tcg_gen_mov_i32(tmp2, tmp);
6472
neon_store_reg(rd, pass, tmp2);
6474
tcg_temp_free_i32(tmp);
6483
static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
6485
int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
6486
const ARMCPRegInfo *ri;
6487
ARMCPU *cpu = arm_env_get_cpu(env);
6489
cpnum = (insn >> 8) & 0xf;
6490
if (arm_feature(env, ARM_FEATURE_XSCALE)
6491
&& ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
6494
/* First check for coprocessor space used for actual instructions */
6498
if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6499
return disas_iwmmxt_insn(env, s, insn);
6500
} else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
6501
return disas_dsp_insn(env, s, insn);
6508
/* Otherwise treat as a generic register access */
6509
is64 = (insn & (1 << 25)) == 0;
6510
if (!is64 && ((insn & (1 << 4)) == 0)) {
6518
opc1 = (insn >> 4) & 0xf;
6520
rt2 = (insn >> 16) & 0xf;
6522
crn = (insn >> 16) & 0xf;
6523
opc1 = (insn >> 21) & 7;
6524
opc2 = (insn >> 5) & 7;
6527
isread = (insn >> 20) & 1;
6528
rt = (insn >> 12) & 0xf;
6530
ri = get_arm_cp_reginfo(cpu,
6531
ENCODE_CP_REG(cpnum, is64, crn, crm, opc1, opc2));
6533
/* Check access permissions */
6534
if (!cp_access_ok(env, ri, isread)) {
6538
/* Handle special cases first */
6539
switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
6546
gen_set_pc_im(s, s->pc);
6547
s->is_jmp = DISAS_WFI;
6553
if (use_icount && (ri->type & ARM_CP_IO)) {
6562
if (ri->type & ARM_CP_CONST) {
6563
tmp64 = tcg_const_i64(ri->resetvalue);
6564
} else if (ri->readfn) {
6566
gen_set_pc_im(s, s->pc);
6567
tmp64 = tcg_temp_new_i64();
6568
tmpptr = tcg_const_ptr(ri);
6569
gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
6570
tcg_temp_free_ptr(tmpptr);
6572
tmp64 = tcg_temp_new_i64();
6573
tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
6575
tmp = tcg_temp_new_i32();
6576
tcg_gen_trunc_i64_i32(tmp, tmp64);
6577
store_reg(s, rt, tmp);
6578
tcg_gen_shri_i64(tmp64, tmp64, 32);
6579
tmp = tcg_temp_new_i32();
6580
tcg_gen_trunc_i64_i32(tmp, tmp64);
6581
tcg_temp_free_i64(tmp64);
6582
store_reg(s, rt2, tmp);
6585
if (ri->type & ARM_CP_CONST) {
6586
tmp = tcg_const_i32(ri->resetvalue);
6587
} else if (ri->readfn) {
6589
gen_set_pc_im(s, s->pc);
6590
tmp = tcg_temp_new_i32();
6591
tmpptr = tcg_const_ptr(ri);
6592
gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
6593
tcg_temp_free_ptr(tmpptr);
6595
tmp = load_cpu_offset(ri->fieldoffset);
6598
/* Destination register of r15 for 32 bit loads sets
6599
* the condition codes from the high 4 bits of the value
6602
tcg_temp_free_i32(tmp);
6604
store_reg(s, rt, tmp);
6609
if (ri->type & ARM_CP_CONST) {
6610
/* If not forbidden by access permissions, treat as WI */
6615
TCGv_i32 tmplo, tmphi;
6616
TCGv_i64 tmp64 = tcg_temp_new_i64();
6617
tmplo = load_reg(s, rt);
6618
tmphi = load_reg(s, rt2);
6619
tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
6620
tcg_temp_free_i32(tmplo);
6621
tcg_temp_free_i32(tmphi);
6623
TCGv_ptr tmpptr = tcg_const_ptr(ri);
6624
gen_set_pc_im(s, s->pc);
6625
gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
6626
tcg_temp_free_ptr(tmpptr);
6628
tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
6630
tcg_temp_free_i64(tmp64);
6635
gen_set_pc_im(s, s->pc);
6636
tmp = load_reg(s, rt);
6637
tmpptr = tcg_const_ptr(ri);
6638
gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
6639
tcg_temp_free_ptr(tmpptr);
6640
tcg_temp_free_i32(tmp);
6642
TCGv_i32 tmp = load_reg(s, rt);
6643
store_cpu_offset(tmp, ri->fieldoffset);
6648
if (use_icount && (ri->type & ARM_CP_IO)) {
6649
/* I/O operations must end the TB here (whether read or write) */
6652
} else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
6653
/* We default to ending the TB on a coprocessor register write,
6654
* but allow this to be suppressed by the register definition
6655
* (usually only necessary to work around guest bugs).
6667
/* Store a 64-bit value to a register pair. Clobbers val. */
6668
static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
6671
tmp = tcg_temp_new_i32();
6672
tcg_gen_trunc_i64_i32(tmp, val);
6673
store_reg(s, rlow, tmp);
6674
tmp = tcg_temp_new_i32();
6675
tcg_gen_shri_i64(val, val, 32);
6676
tcg_gen_trunc_i64_i32(tmp, val);
6677
store_reg(s, rhigh, tmp);
6680
/* load a 32-bit value from a register and perform a 64-bit accumulate. */
6681
static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
6686
/* Load value and extend to 64 bits. */
6687
tmp = tcg_temp_new_i64();
6688
tmp2 = load_reg(s, rlow);
6689
tcg_gen_extu_i32_i64(tmp, tmp2);
6690
tcg_temp_free_i32(tmp2);
6691
tcg_gen_add_i64(val, val, tmp);
6692
tcg_temp_free_i64(tmp);
6695
/* load and add a 64-bit value from a register pair. */
6696
static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
6702
/* Load 64-bit value rd:rn. */
6703
tmpl = load_reg(s, rlow);
6704
tmph = load_reg(s, rhigh);
6705
tmp = tcg_temp_new_i64();
6706
tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
6707
tcg_temp_free_i32(tmpl);
6708
tcg_temp_free_i32(tmph);
6709
tcg_gen_add_i64(val, val, tmp);
6710
tcg_temp_free_i64(tmp);
6713
/* Set N and Z flags from hi|lo. */
6714
static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
6716
tcg_gen_mov_i32(cpu_NF, hi);
6717
tcg_gen_or_i32(cpu_ZF, lo, hi);
6720
/* Load/Store exclusive instructions are implemented by remembering
6721
the value/address loaded, and seeing if these are the same
6722
when the store is performed. This should be sufficient to implement
6723
the architecturally mandated semantics, and avoids having to monitor
6726
In system emulation mode only one CPU will be running at once, so
6727
this sequence is effectively atomic. In user emulation mode we
6728
throw an exception and handle the atomic operation elsewhere. */
6729
static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
6730
TCGv_i32 addr, int size)
6732
TCGv_i32 tmp = tcg_temp_new_i32();
6736
gen_aa32_ld8u(tmp, addr, IS_USER(s));
6739
gen_aa32_ld16u(tmp, addr, IS_USER(s));
6743
gen_aa32_ld32u(tmp, addr, IS_USER(s));
6748
tcg_gen_mov_i32(cpu_exclusive_val, tmp);
6749
store_reg(s, rt, tmp);
6751
TCGv_i32 tmp2 = tcg_temp_new_i32();
6752
tcg_gen_addi_i32(tmp2, addr, 4);
6753
tmp = tcg_temp_new_i32();
6754
gen_aa32_ld32u(tmp, tmp2, IS_USER(s));
6755
tcg_temp_free_i32(tmp2);
6756
tcg_gen_mov_i32(cpu_exclusive_high, tmp);
6757
store_reg(s, rt2, tmp);
6759
tcg_gen_mov_i32(cpu_exclusive_addr, addr);
6762
static void gen_clrex(DisasContext *s)
6764
tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6767
#ifdef CONFIG_USER_ONLY
6768
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6769
TCGv_i32 addr, int size)
6771
tcg_gen_mov_i32(cpu_exclusive_test, addr);
6772
tcg_gen_movi_i32(cpu_exclusive_info,
6773
size | (rd << 4) | (rt << 8) | (rt2 << 12));
6774
gen_exception_insn(s, 4, EXCP_STREX);
6777
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6778
TCGv_i32 addr, int size)
6784
/* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6790
fail_label = gen_new_label();
6791
done_label = gen_new_label();
6792
tcg_gen_brcond_i32(TCG_COND_NE, addr, cpu_exclusive_addr, fail_label);
6793
tmp = tcg_temp_new_i32();
6796
gen_aa32_ld8u(tmp, addr, IS_USER(s));
6799
gen_aa32_ld16u(tmp, addr, IS_USER(s));
6803
gen_aa32_ld32u(tmp, addr, IS_USER(s));
6808
tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_val, fail_label);
6809
tcg_temp_free_i32(tmp);
6811
TCGv_i32 tmp2 = tcg_temp_new_i32();
6812
tcg_gen_addi_i32(tmp2, addr, 4);
6813
tmp = tcg_temp_new_i32();
6814
gen_aa32_ld32u(tmp, tmp2, IS_USER(s));
6815
tcg_temp_free_i32(tmp2);
6816
tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_high, fail_label);
6817
tcg_temp_free_i32(tmp);
6819
tmp = load_reg(s, rt);
6822
gen_aa32_st8(tmp, addr, IS_USER(s));
6825
gen_aa32_st16(tmp, addr, IS_USER(s));
6829
gen_aa32_st32(tmp, addr, IS_USER(s));
6834
tcg_temp_free_i32(tmp);
6836
tcg_gen_addi_i32(addr, addr, 4);
6837
tmp = load_reg(s, rt2);
6838
gen_aa32_st32(tmp, addr, IS_USER(s));
6839
tcg_temp_free_i32(tmp);
6841
tcg_gen_movi_i32(cpu_R[rd], 0);
6842
tcg_gen_br(done_label);
6843
gen_set_label(fail_label);
6844
tcg_gen_movi_i32(cpu_R[rd], 1);
6845
gen_set_label(done_label);
6846
tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6853
* @mode: mode field from insn (which stack to store to)
6854
* @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
6855
* @writeback: true if writeback bit set
6857
* Generate code for the SRS (Store Return State) insn.
6859
static void gen_srs(DisasContext *s,
6860
uint32_t mode, uint32_t amode, bool writeback)
6863
TCGv_i32 addr = tcg_temp_new_i32();
6864
TCGv_i32 tmp = tcg_const_i32(mode);
6865
gen_helper_get_r13_banked(addr, cpu_env, tmp);
6866
tcg_temp_free_i32(tmp);
6883
tcg_gen_addi_i32(addr, addr, offset);
6884
tmp = load_reg(s, 14);
6885
gen_aa32_st32(tmp, addr, 0);
6886
tcg_temp_free_i32(tmp);
6887
tmp = load_cpu_field(spsr);
6888
tcg_gen_addi_i32(addr, addr, 4);
6889
gen_aa32_st32(tmp, addr, 0);
6890
tcg_temp_free_i32(tmp);
6908
tcg_gen_addi_i32(addr, addr, offset);
6909
tmp = tcg_const_i32(mode);
6910
gen_helper_set_r13_banked(cpu_env, tmp, addr);
6911
tcg_temp_free_i32(tmp);
6913
tcg_temp_free_i32(addr);
6916
static void disas_arm_insn(CPUARMState * env, DisasContext *s)
6918
unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
6925
insn = arm_ldl_code(env, s->pc, s->bswap_code);
6928
/* M variants do not implement ARM mode. */
6933
/* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
6934
* choose to UNDEF. In ARMv5 and above the space is used
6935
* for miscellaneous unconditional instructions.
6939
/* Unconditional instructions. */
6940
if (((insn >> 25) & 7) == 1) {
6941
/* NEON Data processing. */
6942
if (!arm_feature(env, ARM_FEATURE_NEON))
6945
if (disas_neon_data_insn(env, s, insn))
6949
if ((insn & 0x0f100000) == 0x04000000) {
6950
/* NEON load/store. */
6951
if (!arm_feature(env, ARM_FEATURE_NEON))
6954
if (disas_neon_ls_insn(env, s, insn))
6958
if ((insn & 0x0f000e10) == 0x0e000a00) {
6960
if (disas_vfp_insn(env, s, insn)) {
6965
if (((insn & 0x0f30f000) == 0x0510f000) ||
6966
((insn & 0x0f30f010) == 0x0710f000)) {
6967
if ((insn & (1 << 22)) == 0) {
6969
if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6973
/* Otherwise PLD; v5TE+ */
6977
if (((insn & 0x0f70f000) == 0x0450f000) ||
6978
((insn & 0x0f70f010) == 0x0650f000)) {
6980
return; /* PLI; V7 */
6982
if (((insn & 0x0f700000) == 0x04100000) ||
6983
((insn & 0x0f700010) == 0x06100000)) {
6984
if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6987
return; /* v7MP: Unallocated memory hint: must NOP */
6990
if ((insn & 0x0ffffdff) == 0x01010000) {
6993
if (((insn >> 9) & 1) != s->bswap_code) {
6994
/* Dynamic endianness switching not implemented. */
6995
qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
6999
} else if ((insn & 0x0fffff00) == 0x057ff000) {
7000
switch ((insn >> 4) & 0xf) {
7009
/* We don't emulate caches so these are a no-op. */
7014
} else if ((insn & 0x0e5fffe0) == 0x084d0500) {
7020
gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
7022
} else if ((insn & 0x0e50ffe0) == 0x08100a00) {
7028
rn = (insn >> 16) & 0xf;
7029
addr = load_reg(s, rn);
7030
i = (insn >> 23) & 3;
7032
case 0: offset = -4; break; /* DA */
7033
case 1: offset = 0; break; /* IA */
7034
case 2: offset = -8; break; /* DB */
7035
case 3: offset = 4; break; /* IB */
7039
tcg_gen_addi_i32(addr, addr, offset);
7040
/* Load PC into tmp and CPSR into tmp2. */
7041
tmp = tcg_temp_new_i32();
7042
gen_aa32_ld32u(tmp, addr, 0);
7043
tcg_gen_addi_i32(addr, addr, 4);
7044
tmp2 = tcg_temp_new_i32();
7045
gen_aa32_ld32u(tmp2, addr, 0);
7046
if (insn & (1 << 21)) {
7047
/* Base writeback. */
7049
case 0: offset = -8; break;
7050
case 1: offset = 4; break;
7051
case 2: offset = -4; break;
7052
case 3: offset = 0; break;
7056
tcg_gen_addi_i32(addr, addr, offset);
7057
store_reg(s, rn, addr);
7059
tcg_temp_free_i32(addr);
7061
gen_rfe(s, tmp, tmp2);
7063
} else if ((insn & 0x0e000000) == 0x0a000000) {
7064
/* branch link and change to thumb (blx <offset>) */
7067
val = (uint32_t)s->pc;
7068
tmp = tcg_temp_new_i32();
7069
tcg_gen_movi_i32(tmp, val);
7070
store_reg(s, 14, tmp);
7071
/* Sign-extend the 24-bit offset */
7072
offset = (((int32_t)insn) << 8) >> 8;
7073
/* offset * 4 + bit24 * 2 + (thumb bit) */
7074
val += (offset << 2) | ((insn >> 23) & 2) | 1;
7075
/* pipeline offset */
7077
/* protected by ARCH(5); above, near the start of uncond block */
7080
} else if ((insn & 0x0e000f00) == 0x0c000100) {
7081
if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
7082
/* iWMMXt register transfer. */
7083
if (env->cp15.c15_cpar & (1 << 1))
7084
if (!disas_iwmmxt_insn(env, s, insn))
7087
} else if ((insn & 0x0fe00000) == 0x0c400000) {
7088
/* Coprocessor double register transfer. */
7090
/* XXX doesn't belong in the trustzone patch: should just UNDEF? */
7091
cpu_abort(env, "unsupported coprocessor double register transfer\n");
7092
} else if ((insn & 0x0f000010) == 0x0e000010) {
7093
/* Additional coprocessor register transfer. */
7094
if (!disas_coproc_insn(env, s, insn)) {
7097
} else if ((insn & 0x0ff10020) == 0x01000000) {
7100
/* cps (privileged) */
7104
if (insn & (1 << 19)) {
7105
if (insn & (1 << 8))
7107
if (insn & (1 << 7))
7109
if (insn & (1 << 6))
7111
if (insn & (1 << 18))
7114
if (insn & (1 << 17)) {
7116
val |= (insn & 0x1f);
7119
gen_set_psr_im(s, mask, 0, val);
7126
/* if not always execute, we generate a conditional jump to
7128
s->condlabel = gen_new_label();
7129
gen_test_cc(cond ^ 1, s->condlabel);
7132
if ((insn & 0x0f900000) == 0x03000000) {
7133
if ((insn & (1 << 21)) == 0) {
7135
rd = (insn >> 12) & 0xf;
7136
val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
7137
if ((insn & (1 << 22)) == 0) {
7139
tmp = tcg_temp_new_i32();
7140
tcg_gen_movi_i32(tmp, val);
7143
tmp = load_reg(s, rd);
7144
tcg_gen_ext16u_i32(tmp, tmp);
7145
tcg_gen_ori_i32(tmp, tmp, val << 16);
7147
store_reg(s, rd, tmp);
7149
if (((insn >> 12) & 0xf) != 0xf)
7151
if (((insn >> 16) & 0xf) == 0) {
7152
gen_nop_hint(s, insn & 0xff);
7154
/* CPSR = immediate */
7156
shift = ((insn >> 8) & 0xf) * 2;
7158
val = (val >> shift) | (val << (32 - shift));
7159
i = ((insn & (1 << 22)) != 0);
7160
if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val))
7164
} else if ((insn & 0x0f900000) == 0x01000000
7165
&& (insn & 0x00000090) != 0x00000090) {
7166
/* miscellaneous instructions */
7167
op1 = (insn >> 21) & 3;
7168
sh = (insn >> 4) & 0xf;
7171
case 0x0: /* move program status register */
7174
tmp = load_reg(s, rm);
7175
i = ((op1 & 2) != 0);
7176
if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp))
7180
rd = (insn >> 12) & 0xf;
7184
tmp = load_cpu_field(spsr);
7186
tmp = tcg_temp_new_i32();
7187
gen_helper_cpsr_read(tmp, cpu_env);
7189
store_reg(s, rd, tmp);
7194
/* branch/exchange thumb (bx). */
7196
tmp = load_reg(s, rm);
7198
} else if (op1 == 3) {
7201
rd = (insn >> 12) & 0xf;
7202
tmp = load_reg(s, rm);
7203
gen_helper_clz(tmp, tmp);
7204
store_reg(s, rd, tmp);
7212
/* Trivial implementation equivalent to bx. */
7213
tmp = load_reg(s, rm);
7224
/* branch link/exchange thumb (blx) */
7225
tmp = load_reg(s, rm);
7226
tmp2 = tcg_temp_new_i32();
7227
tcg_gen_movi_i32(tmp2, s->pc);
7228
store_reg(s, 14, tmp2);
7231
case 0x5: /* saturating add/subtract */
7233
rd = (insn >> 12) & 0xf;
7234
rn = (insn >> 16) & 0xf;
7235
tmp = load_reg(s, rm);
7236
tmp2 = load_reg(s, rn);
7238
gen_helper_double_saturate(tmp2, cpu_env, tmp2);
7240
gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
7242
gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
7243
tcg_temp_free_i32(tmp2);
7244
store_reg(s, rd, tmp);
7250
gen_exception_insn(s, 4, EXCP_BKPT);
7251
} else if (op1 == 3) {
7253
if (!arm_feature(env, ARM_FEATURE_TRUSTZONE) || IS_USER(s)) {
7261
case 0x8: /* signed multiply */
7266
rs = (insn >> 8) & 0xf;
7267
rn = (insn >> 12) & 0xf;
7268
rd = (insn >> 16) & 0xf;
7270
/* (32 * 16) >> 16 */
7271
tmp = load_reg(s, rm);
7272
tmp2 = load_reg(s, rs);
7274
tcg_gen_sari_i32(tmp2, tmp2, 16);
7277
tmp64 = gen_muls_i64_i32(tmp, tmp2);
7278
tcg_gen_shri_i64(tmp64, tmp64, 16);
7279
tmp = tcg_temp_new_i32();
7280
tcg_gen_trunc_i64_i32(tmp, tmp64);
7281
tcg_temp_free_i64(tmp64);
7282
if ((sh & 2) == 0) {
7283
tmp2 = load_reg(s, rn);
7284
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7285
tcg_temp_free_i32(tmp2);
7287
store_reg(s, rd, tmp);
7290
tmp = load_reg(s, rm);
7291
tmp2 = load_reg(s, rs);
7292
gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
7293
tcg_temp_free_i32(tmp2);
7295
tmp64 = tcg_temp_new_i64();
7296
tcg_gen_ext_i32_i64(tmp64, tmp);
7297
tcg_temp_free_i32(tmp);
7298
gen_addq(s, tmp64, rn, rd);
7299
gen_storeq_reg(s, rn, rd, tmp64);
7300
tcg_temp_free_i64(tmp64);
7303
tmp2 = load_reg(s, rn);
7304
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7305
tcg_temp_free_i32(tmp2);
7307
store_reg(s, rd, tmp);
7314
} else if (((insn & 0x0e000000) == 0 &&
7315
(insn & 0x00000090) != 0x90) ||
7316
((insn & 0x0e000000) == (1 << 25))) {
7317
int set_cc, logic_cc, shiftop;
7319
op1 = (insn >> 21) & 0xf;
7320
set_cc = (insn >> 20) & 1;
7321
logic_cc = table_logic_cc[op1] & set_cc;
7323
/* data processing instruction */
7324
if (insn & (1 << 25)) {
7325
/* immediate operand */
7327
shift = ((insn >> 8) & 0xf) * 2;
7329
val = (val >> shift) | (val << (32 - shift));
7331
tmp2 = tcg_temp_new_i32();
7332
tcg_gen_movi_i32(tmp2, val);
7333
if (logic_cc && shift) {
7334
gen_set_CF_bit31(tmp2);
7339
tmp2 = load_reg(s, rm);
7340
shiftop = (insn >> 5) & 3;
7341
if (!(insn & (1 << 4))) {
7342
shift = (insn >> 7) & 0x1f;
7343
gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
7345
rs = (insn >> 8) & 0xf;
7346
tmp = load_reg(s, rs);
7347
gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
7350
if (op1 != 0x0f && op1 != 0x0d) {
7351
rn = (insn >> 16) & 0xf;
7352
tmp = load_reg(s, rn);
7354
TCGV_UNUSED_I32(tmp);
7356
rd = (insn >> 12) & 0xf;
7359
tcg_gen_and_i32(tmp, tmp, tmp2);
7363
store_reg_bx(env, s, rd, tmp);
7366
tcg_gen_xor_i32(tmp, tmp, tmp2);
7370
store_reg_bx(env, s, rd, tmp);
7373
if (set_cc && rd == 15) {
7374
/* SUBS r15, ... is used for exception return. */
7378
gen_sub_CC(tmp, tmp, tmp2);
7379
gen_exception_return(s, tmp);
7382
gen_sub_CC(tmp, tmp, tmp2);
7384
tcg_gen_sub_i32(tmp, tmp, tmp2);
7386
store_reg_bx(env, s, rd, tmp);
7391
gen_sub_CC(tmp, tmp2, tmp);
7393
tcg_gen_sub_i32(tmp, tmp2, tmp);
7395
store_reg_bx(env, s, rd, tmp);
7399
gen_add_CC(tmp, tmp, tmp2);
7401
tcg_gen_add_i32(tmp, tmp, tmp2);
7403
store_reg_bx(env, s, rd, tmp);
7407
gen_adc_CC(tmp, tmp, tmp2);
7409
gen_add_carry(tmp, tmp, tmp2);
7411
store_reg_bx(env, s, rd, tmp);
7415
gen_sbc_CC(tmp, tmp, tmp2);
7417
gen_sub_carry(tmp, tmp, tmp2);
7419
store_reg_bx(env, s, rd, tmp);
7423
gen_sbc_CC(tmp, tmp2, tmp);
7425
gen_sub_carry(tmp, tmp2, tmp);
7427
store_reg_bx(env, s, rd, tmp);
7431
tcg_gen_and_i32(tmp, tmp, tmp2);
7434
tcg_temp_free_i32(tmp);
7438
tcg_gen_xor_i32(tmp, tmp, tmp2);
7441
tcg_temp_free_i32(tmp);
7445
gen_sub_CC(tmp, tmp, tmp2);
7447
tcg_temp_free_i32(tmp);
7451
gen_add_CC(tmp, tmp, tmp2);
7453
tcg_temp_free_i32(tmp);
7456
tcg_gen_or_i32(tmp, tmp, tmp2);
7460
store_reg_bx(env, s, rd, tmp);
7463
if (logic_cc && rd == 15) {
7464
/* MOVS r15, ... is used for exception return. */
7468
gen_exception_return(s, tmp2);
7473
store_reg_bx(env, s, rd, tmp2);
7477
tcg_gen_andc_i32(tmp, tmp, tmp2);
7481
store_reg_bx(env, s, rd, tmp);
7485
tcg_gen_not_i32(tmp2, tmp2);
7489
store_reg_bx(env, s, rd, tmp2);
7492
if (op1 != 0x0f && op1 != 0x0d) {
7493
tcg_temp_free_i32(tmp2);
7496
/* other instructions */
7497
op1 = (insn >> 24) & 0xf;
7501
/* multiplies, extra load/stores */
7502
sh = (insn >> 5) & 3;
7505
rd = (insn >> 16) & 0xf;
7506
rn = (insn >> 12) & 0xf;
7507
rs = (insn >> 8) & 0xf;
7509
op1 = (insn >> 20) & 0xf;
7511
case 0: case 1: case 2: case 3: case 6:
7513
tmp = load_reg(s, rs);
7514
tmp2 = load_reg(s, rm);
7515
tcg_gen_mul_i32(tmp, tmp, tmp2);
7516
tcg_temp_free_i32(tmp2);
7517
if (insn & (1 << 22)) {
7518
/* Subtract (mls) */
7520
tmp2 = load_reg(s, rn);
7521
tcg_gen_sub_i32(tmp, tmp2, tmp);
7522
tcg_temp_free_i32(tmp2);
7523
} else if (insn & (1 << 21)) {
7525
tmp2 = load_reg(s, rn);
7526
tcg_gen_add_i32(tmp, tmp, tmp2);
7527
tcg_temp_free_i32(tmp2);
7529
if (insn & (1 << 20))
7531
store_reg(s, rd, tmp);
7534
/* 64 bit mul double accumulate (UMAAL) */
7536
tmp = load_reg(s, rs);
7537
tmp2 = load_reg(s, rm);
7538
tmp64 = gen_mulu_i64_i32(tmp, tmp2);
7539
gen_addq_lo(s, tmp64, rn);
7540
gen_addq_lo(s, tmp64, rd);
7541
gen_storeq_reg(s, rn, rd, tmp64);
7542
tcg_temp_free_i64(tmp64);
7544
case 8: case 9: case 10: case 11:
7545
case 12: case 13: case 14: case 15:
7546
/* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7547
tmp = load_reg(s, rs);
7548
tmp2 = load_reg(s, rm);
7549
if (insn & (1 << 22)) {
7550
tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
7552
tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
7554
if (insn & (1 << 21)) { /* mult accumulate */
7555
TCGv_i32 al = load_reg(s, rn);
7556
TCGv_i32 ah = load_reg(s, rd);
7557
tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
7558
tcg_temp_free_i32(al);
7559
tcg_temp_free_i32(ah);
7561
if (insn & (1 << 20)) {
7562
gen_logicq_cc(tmp, tmp2);
7564
store_reg(s, rn, tmp);
7565
store_reg(s, rd, tmp2);
7571
rn = (insn >> 16) & 0xf;
7572
rd = (insn >> 12) & 0xf;
7573
if (insn & (1 << 23)) {
7574
/* load/store exclusive */
7575
int op2 = (insn >> 8) & 3;
7576
op1 = (insn >> 21) & 0x3;
7579
case 0: /* lda/stl */
7585
case 1: /* reserved */
7587
case 2: /* ldaex/stlex */
7590
case 3: /* ldrex/strex */
7599
addr = tcg_temp_local_new_i32();
7600
load_reg_var(s, addr, rn);
7602
/* Since the emulation does not have barriers,
7603
the acquire/release semantics need no special
7606
if (insn & (1 << 20)) {
7607
tmp = tcg_temp_new_i32();
7610
gen_aa32_ld32u(tmp, addr, IS_USER(s));
7613
gen_aa32_ld8u(tmp, addr, IS_USER(s));
7616
gen_aa32_ld16u(tmp, addr, IS_USER(s));
7621
store_reg(s, rd, tmp);
7624
tmp = load_reg(s, rm);
7627
gen_aa32_st32(tmp, addr, IS_USER(s));
7630
gen_aa32_st8(tmp, addr, IS_USER(s));
7633
gen_aa32_st16(tmp, addr, IS_USER(s));
7638
tcg_temp_free_i32(tmp);
7640
} else if (insn & (1 << 20)) {
7643
gen_load_exclusive(s, rd, 15, addr, 2);
7645
case 1: /* ldrexd */
7646
gen_load_exclusive(s, rd, rd + 1, addr, 3);
7648
case 2: /* ldrexb */
7649
gen_load_exclusive(s, rd, 15, addr, 0);
7651
case 3: /* ldrexh */
7652
gen_load_exclusive(s, rd, 15, addr, 1);
7661
gen_store_exclusive(s, rd, rm, 15, addr, 2);
7663
case 1: /* strexd */
7664
gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
7666
case 2: /* strexb */
7667
gen_store_exclusive(s, rd, rm, 15, addr, 0);
7669
case 3: /* strexh */
7670
gen_store_exclusive(s, rd, rm, 15, addr, 1);
7676
tcg_temp_free_i32(addr);
7678
/* SWP instruction */
7681
/* ??? This is not really atomic. However we know
7682
we never have multiple CPUs running in parallel,
7683
so it is good enough. */
7684
addr = load_reg(s, rn);
7685
tmp = load_reg(s, rm);
7686
tmp2 = tcg_temp_new_i32();
7687
if (insn & (1 << 22)) {
7688
gen_aa32_ld8u(tmp2, addr, IS_USER(s));
7689
gen_aa32_st8(tmp, addr, IS_USER(s));
7691
gen_aa32_ld32u(tmp2, addr, IS_USER(s));
7692
gen_aa32_st32(tmp, addr, IS_USER(s));
7694
tcg_temp_free_i32(tmp);
7695
tcg_temp_free_i32(addr);
7696
store_reg(s, rd, tmp2);
7702
/* Misc load/store */
7703
rn = (insn >> 16) & 0xf;
7704
rd = (insn >> 12) & 0xf;
7705
addr = load_reg(s, rn);
7706
if (insn & (1 << 24))
7707
gen_add_datah_offset(s, insn, 0, addr);
7709
if (insn & (1 << 20)) {
7711
tmp = tcg_temp_new_i32();
7714
gen_aa32_ld16u(tmp, addr, IS_USER(s));
7717
gen_aa32_ld8s(tmp, addr, IS_USER(s));
7721
gen_aa32_ld16s(tmp, addr, IS_USER(s));
7725
} else if (sh & 2) {
7730
tmp = load_reg(s, rd);
7731
gen_aa32_st32(tmp, addr, IS_USER(s));
7732
tcg_temp_free_i32(tmp);
7733
tcg_gen_addi_i32(addr, addr, 4);
7734
tmp = load_reg(s, rd + 1);
7735
gen_aa32_st32(tmp, addr, IS_USER(s));
7736
tcg_temp_free_i32(tmp);
7740
tmp = tcg_temp_new_i32();
7741
gen_aa32_ld32u(tmp, addr, IS_USER(s));
7742
store_reg(s, rd, tmp);
7743
tcg_gen_addi_i32(addr, addr, 4);
7744
tmp = tcg_temp_new_i32();
7745
gen_aa32_ld32u(tmp, addr, IS_USER(s));
7749
address_offset = -4;
7752
tmp = load_reg(s, rd);
7753
gen_aa32_st16(tmp, addr, IS_USER(s));
7754
tcg_temp_free_i32(tmp);
7757
/* Perform base writeback before the loaded value to
7758
ensure correct behavior with overlapping index registers.
7759
ldrd with base writeback is is undefined if the
7760
destination and index registers overlap. */
7761
if (!(insn & (1 << 24))) {
7762
gen_add_datah_offset(s, insn, address_offset, addr);
7763
store_reg(s, rn, addr);
7764
} else if (insn & (1 << 21)) {
7766
tcg_gen_addi_i32(addr, addr, address_offset);
7767
store_reg(s, rn, addr);
7769
tcg_temp_free_i32(addr);
7772
/* Complete the load. */
7773
store_reg(s, rd, tmp);
7782
if (insn & (1 << 4)) {
7784
/* Armv6 Media instructions. */
7786
rn = (insn >> 16) & 0xf;
7787
rd = (insn >> 12) & 0xf;
7788
rs = (insn >> 8) & 0xf;
7789
switch ((insn >> 23) & 3) {
7790
case 0: /* Parallel add/subtract. */
7791
op1 = (insn >> 20) & 7;
7792
tmp = load_reg(s, rn);
7793
tmp2 = load_reg(s, rm);
7794
sh = (insn >> 5) & 7;
7795
if ((op1 & 3) == 0 || sh == 5 || sh == 6)
7797
gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
7798
tcg_temp_free_i32(tmp2);
7799
store_reg(s, rd, tmp);
7802
if ((insn & 0x00700020) == 0) {
7803
/* Halfword pack. */
7804
tmp = load_reg(s, rn);
7805
tmp2 = load_reg(s, rm);
7806
shift = (insn >> 7) & 0x1f;
7807
if (insn & (1 << 6)) {
7811
tcg_gen_sari_i32(tmp2, tmp2, shift);
7812
tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
7813
tcg_gen_ext16u_i32(tmp2, tmp2);
7817
tcg_gen_shli_i32(tmp2, tmp2, shift);
7818
tcg_gen_ext16u_i32(tmp, tmp);
7819
tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
7821
tcg_gen_or_i32(tmp, tmp, tmp2);
7822
tcg_temp_free_i32(tmp2);
7823
store_reg(s, rd, tmp);
7824
} else if ((insn & 0x00200020) == 0x00200000) {
7826
tmp = load_reg(s, rm);
7827
shift = (insn >> 7) & 0x1f;
7828
if (insn & (1 << 6)) {
7831
tcg_gen_sari_i32(tmp, tmp, shift);
7833
tcg_gen_shli_i32(tmp, tmp, shift);
7835
sh = (insn >> 16) & 0x1f;
7836
tmp2 = tcg_const_i32(sh);
7837
if (insn & (1 << 22))
7838
gen_helper_usat(tmp, cpu_env, tmp, tmp2);
7840
gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
7841
tcg_temp_free_i32(tmp2);
7842
store_reg(s, rd, tmp);
7843
} else if ((insn & 0x00300fe0) == 0x00200f20) {
7845
tmp = load_reg(s, rm);
7846
sh = (insn >> 16) & 0x1f;
7847
tmp2 = tcg_const_i32(sh);
7848
if (insn & (1 << 22))
7849
gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
7851
gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
7852
tcg_temp_free_i32(tmp2);
7853
store_reg(s, rd, tmp);
7854
} else if ((insn & 0x00700fe0) == 0x00000fa0) {
7856
tmp = load_reg(s, rn);
7857
tmp2 = load_reg(s, rm);
7858
tmp3 = tcg_temp_new_i32();
7859
tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
7860
gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7861
tcg_temp_free_i32(tmp3);
7862
tcg_temp_free_i32(tmp2);
7863
store_reg(s, rd, tmp);
7864
} else if ((insn & 0x000003e0) == 0x00000060) {
7865
tmp = load_reg(s, rm);
7866
shift = (insn >> 10) & 3;
7867
/* ??? In many cases it's not necessary to do a
7868
rotate, a shift is sufficient. */
7870
tcg_gen_rotri_i32(tmp, tmp, shift * 8);
7871
op1 = (insn >> 20) & 7;
7873
case 0: gen_sxtb16(tmp); break;
7874
case 2: gen_sxtb(tmp); break;
7875
case 3: gen_sxth(tmp); break;
7876
case 4: gen_uxtb16(tmp); break;
7877
case 6: gen_uxtb(tmp); break;
7878
case 7: gen_uxth(tmp); break;
7879
default: goto illegal_op;
7882
tmp2 = load_reg(s, rn);
7883
if ((op1 & 3) == 0) {
7884
gen_add16(tmp, tmp2);
7886
tcg_gen_add_i32(tmp, tmp, tmp2);
7887
tcg_temp_free_i32(tmp2);
7890
store_reg(s, rd, tmp);
7891
} else if ((insn & 0x003f0f60) == 0x003f0f20) {
7893
tmp = load_reg(s, rm);
7894
if (insn & (1 << 22)) {
7895
if (insn & (1 << 7)) {
7899
gen_helper_rbit(tmp, tmp);
7902
if (insn & (1 << 7))
7905
tcg_gen_bswap32_i32(tmp, tmp);
7907
store_reg(s, rd, tmp);
7912
case 2: /* Multiplies (Type 3). */
7913
switch ((insn >> 20) & 0x7) {
7915
if (((insn >> 6) ^ (insn >> 7)) & 1) {
7916
/* op2 not 00x or 11x : UNDEF */
7919
/* Signed multiply most significant [accumulate].
7920
(SMMUL, SMMLA, SMMLS) */
7921
tmp = load_reg(s, rm);
7922
tmp2 = load_reg(s, rs);
7923
tmp64 = gen_muls_i64_i32(tmp, tmp2);
7926
tmp = load_reg(s, rd);
7927
if (insn & (1 << 6)) {
7928
tmp64 = gen_subq_msw(tmp64, tmp);
7930
tmp64 = gen_addq_msw(tmp64, tmp);
7933
if (insn & (1 << 5)) {
7934
tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
7936
tcg_gen_shri_i64(tmp64, tmp64, 32);
7937
tmp = tcg_temp_new_i32();
7938
tcg_gen_trunc_i64_i32(tmp, tmp64);
7939
tcg_temp_free_i64(tmp64);
7940
store_reg(s, rn, tmp);
7944
/* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
7945
if (insn & (1 << 7)) {
7948
tmp = load_reg(s, rm);
7949
tmp2 = load_reg(s, rs);
7950
if (insn & (1 << 5))
7951
gen_swap_half(tmp2);
7952
gen_smul_dual(tmp, tmp2);
7953
if (insn & (1 << 6)) {
7954
/* This subtraction cannot overflow. */
7955
tcg_gen_sub_i32(tmp, tmp, tmp2);
7957
/* This addition cannot overflow 32 bits;
7958
* however it may overflow considered as a signed
7959
* operation, in which case we must set the Q flag.
7961
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7963
tcg_temp_free_i32(tmp2);
7964
if (insn & (1 << 22)) {
7965
/* smlald, smlsld */
7966
tmp64 = tcg_temp_new_i64();
7967
tcg_gen_ext_i32_i64(tmp64, tmp);
7968
tcg_temp_free_i32(tmp);
7969
gen_addq(s, tmp64, rd, rn);
7970
gen_storeq_reg(s, rd, rn, tmp64);
7971
tcg_temp_free_i64(tmp64);
7973
/* smuad, smusd, smlad, smlsd */
7976
tmp2 = load_reg(s, rd);
7977
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7978
tcg_temp_free_i32(tmp2);
7980
store_reg(s, rn, tmp);
7986
if (!arm_feature(env, ARM_FEATURE_ARM_DIV)) {
7989
if (((insn >> 5) & 7) || (rd != 15)) {
7992
tmp = load_reg(s, rm);
7993
tmp2 = load_reg(s, rs);
7994
if (insn & (1 << 21)) {
7995
gen_helper_udiv(tmp, tmp, tmp2);
7997
gen_helper_sdiv(tmp, tmp, tmp2);
7999
tcg_temp_free_i32(tmp2);
8000
store_reg(s, rn, tmp);
8007
op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
8009
case 0: /* Unsigned sum of absolute differences. */
8011
tmp = load_reg(s, rm);
8012
tmp2 = load_reg(s, rs);
8013
gen_helper_usad8(tmp, tmp, tmp2);
8014
tcg_temp_free_i32(tmp2);
8016
tmp2 = load_reg(s, rd);
8017
tcg_gen_add_i32(tmp, tmp, tmp2);
8018
tcg_temp_free_i32(tmp2);
8020
store_reg(s, rn, tmp);
8022
case 0x20: case 0x24: case 0x28: case 0x2c:
8023
/* Bitfield insert/clear. */
8025
shift = (insn >> 7) & 0x1f;
8026
i = (insn >> 16) & 0x1f;
8029
tmp = tcg_temp_new_i32();
8030
tcg_gen_movi_i32(tmp, 0);
8032
tmp = load_reg(s, rm);
8035
tmp2 = load_reg(s, rd);
8036
tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
8037
tcg_temp_free_i32(tmp2);
8039
store_reg(s, rd, tmp);
8041
case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8042
case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8044
tmp = load_reg(s, rm);
8045
shift = (insn >> 7) & 0x1f;
8046
i = ((insn >> 16) & 0x1f) + 1;
8051
gen_ubfx(tmp, shift, (1u << i) - 1);
8053
gen_sbfx(tmp, shift, i);
8056
store_reg(s, rd, tmp);
8066
/* Check for undefined extension instructions
8067
* per the ARM Bible IE:
8068
* xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8070
sh = (0xf << 20) | (0xf << 4);
8071
if (op1 == 0x7 && ((insn & sh) == sh))
8075
/* load/store byte/word */
8076
rn = (insn >> 16) & 0xf;
8077
rd = (insn >> 12) & 0xf;
8078
tmp2 = load_reg(s, rn);
8079
i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
8080
if (insn & (1 << 24))
8081
gen_add_data_offset(s, insn, tmp2);
8082
if (insn & (1 << 20)) {
8084
tmp = tcg_temp_new_i32();
8085
if (insn & (1 << 22)) {
8086
gen_aa32_ld8u(tmp, tmp2, i);
8088
gen_aa32_ld32u(tmp, tmp2, i);
8092
tmp = load_reg(s, rd);
8093
if (insn & (1 << 22)) {
8094
gen_aa32_st8(tmp, tmp2, i);
8096
gen_aa32_st32(tmp, tmp2, i);
8098
tcg_temp_free_i32(tmp);
8100
if (!(insn & (1 << 24))) {
8101
gen_add_data_offset(s, insn, tmp2);
8102
store_reg(s, rn, tmp2);
8103
} else if (insn & (1 << 21)) {
8104
store_reg(s, rn, tmp2);
8106
tcg_temp_free_i32(tmp2);
8108
if (insn & (1 << 20)) {
8109
/* Complete the load. */
8110
store_reg_from_load(env, s, rd, tmp);
8116
int j, n, user, loaded_base;
8117
TCGv_i32 loaded_var;
8118
/* load/store multiple words */
8119
/* XXX: store correct base if write back */
8121
if (insn & (1 << 22)) {
8123
goto illegal_op; /* only usable in supervisor mode */
8125
if ((insn & (1 << 15)) == 0)
8128
rn = (insn >> 16) & 0xf;
8129
addr = load_reg(s, rn);
8131
/* compute total size */
8133
TCGV_UNUSED_I32(loaded_var);
8136
if (insn & (1 << i))
8139
/* XXX: test invalid n == 0 case ? */
8140
if (insn & (1 << 23)) {
8141
if (insn & (1 << 24)) {
8143
tcg_gen_addi_i32(addr, addr, 4);
8145
/* post increment */
8148
if (insn & (1 << 24)) {
8150
tcg_gen_addi_i32(addr, addr, -(n * 4));
8152
/* post decrement */
8154
tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8159
if (insn & (1 << i)) {
8160
if (insn & (1 << 20)) {
8162
tmp = tcg_temp_new_i32();
8163
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8165
tmp2 = tcg_const_i32(i);
8166
gen_helper_set_user_reg(cpu_env, tmp2, tmp);
8167
tcg_temp_free_i32(tmp2);
8168
tcg_temp_free_i32(tmp);
8169
} else if (i == rn) {
8173
store_reg_from_load(env, s, i, tmp);
8178
/* special case: r15 = PC + 8 */
8179
val = (long)s->pc + 4;
8180
tmp = tcg_temp_new_i32();
8181
tcg_gen_movi_i32(tmp, val);
8183
tmp = tcg_temp_new_i32();
8184
tmp2 = tcg_const_i32(i);
8185
gen_helper_get_user_reg(tmp, cpu_env, tmp2);
8186
tcg_temp_free_i32(tmp2);
8188
tmp = load_reg(s, i);
8190
gen_aa32_st32(tmp, addr, IS_USER(s));
8191
tcg_temp_free_i32(tmp);
8194
/* no need to add after the last transfer */
8196
tcg_gen_addi_i32(addr, addr, 4);
8199
if (insn & (1 << 21)) {
8201
if (insn & (1 << 23)) {
8202
if (insn & (1 << 24)) {
8205
/* post increment */
8206
tcg_gen_addi_i32(addr, addr, 4);
8209
if (insn & (1 << 24)) {
8212
tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8214
/* post decrement */
8215
tcg_gen_addi_i32(addr, addr, -(n * 4));
8218
store_reg(s, rn, addr);
8220
tcg_temp_free_i32(addr);
8223
store_reg(s, rn, loaded_var);
8225
if ((insn & (1 << 22)) && !user) {
8226
/* Restore CPSR from SPSR. */
8227
tmp = load_cpu_field(spsr);
8228
gen_set_cpsr(tmp, 0xffffffff);
8229
tcg_temp_free_i32(tmp);
8230
s->is_jmp = DISAS_UPDATE;
8239
/* branch (and link) */
8240
val = (int32_t)s->pc;
8241
if (insn & (1 << 24)) {
8242
tmp = tcg_temp_new_i32();
8243
tcg_gen_movi_i32(tmp, val);
8244
store_reg(s, 14, tmp);
8246
offset = sextract32(insn << 2, 0, 26);
8254
if (((insn >> 8) & 0xe) == 10) {
8256
if (disas_vfp_insn(env, s, insn)) {
8259
} else if (disas_coproc_insn(env, s, insn)) {
8266
gen_set_pc_im(s, s->pc);
8267
s->is_jmp = DISAS_SWI;
8271
gen_exception_insn(s, 4, EXCP_UDEF);
8277
/* Return true if this is a Thumb-2 logical op. */
8279
thumb2_logic_op(int op)
8284
/* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
8285
then set condition code flags based on the result of the operation.
8286
If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8287
to the high bit of T1.
8288
Returns zero if the opcode is valid. */
8291
gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
8292
TCGv_i32 t0, TCGv_i32 t1)
8299
tcg_gen_and_i32(t0, t0, t1);
8303
tcg_gen_andc_i32(t0, t0, t1);
8307
tcg_gen_or_i32(t0, t0, t1);
8311
tcg_gen_orc_i32(t0, t0, t1);
8315
tcg_gen_xor_i32(t0, t0, t1);
8320
gen_add_CC(t0, t0, t1);
8322
tcg_gen_add_i32(t0, t0, t1);
8326
gen_adc_CC(t0, t0, t1);
8332
gen_sbc_CC(t0, t0, t1);
8334
gen_sub_carry(t0, t0, t1);
8339
gen_sub_CC(t0, t0, t1);
8341
tcg_gen_sub_i32(t0, t0, t1);
8345
gen_sub_CC(t0, t1, t0);
8347
tcg_gen_sub_i32(t0, t1, t0);
8349
default: /* 5, 6, 7, 9, 12, 15. */
8355
gen_set_CF_bit31(t1);
8360
/* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
8362
static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
8364
uint32_t insn, imm, shift, offset;
8365
uint32_t rd, rn, rm, rs;
8376
if (!(arm_feature(env, ARM_FEATURE_THUMB2)
8377
|| arm_feature (env, ARM_FEATURE_M))) {
8378
/* Thumb-1 cores may need to treat bl and blx as a pair of
8379
16-bit instructions to get correct prefetch abort behavior. */
8381
if ((insn & (1 << 12)) == 0) {
8383
/* Second half of blx. */
8384
offset = ((insn & 0x7ff) << 1);
8385
tmp = load_reg(s, 14);
8386
tcg_gen_addi_i32(tmp, tmp, offset);
8387
tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
8389
tmp2 = tcg_temp_new_i32();
8390
tcg_gen_movi_i32(tmp2, s->pc | 1);
8391
store_reg(s, 14, tmp2);
8395
if (insn & (1 << 11)) {
8396
/* Second half of bl. */
8397
offset = ((insn & 0x7ff) << 1) | 1;
8398
tmp = load_reg(s, 14);
8399
tcg_gen_addi_i32(tmp, tmp, offset);
8401
tmp2 = tcg_temp_new_i32();
8402
tcg_gen_movi_i32(tmp2, s->pc | 1);
8403
store_reg(s, 14, tmp2);
8407
if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
8408
/* Instruction spans a page boundary. Implement it as two
8409
16-bit instructions in case the second half causes an
8411
offset = ((int32_t)insn << 21) >> 9;
8412
tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
8415
/* Fall through to 32-bit decode. */
8418
insn = arm_lduw_code(env, s->pc, s->bswap_code);
8420
insn |= (uint32_t)insn_hw1 << 16;
8422
if ((insn & 0xf800e800) != 0xf000e800) {
8426
rn = (insn >> 16) & 0xf;
8427
rs = (insn >> 12) & 0xf;
8428
rd = (insn >> 8) & 0xf;
8430
switch ((insn >> 25) & 0xf) {
8431
case 0: case 1: case 2: case 3:
8432
/* 16-bit instructions. Should never happen. */
8435
if (insn & (1 << 22)) {
8436
/* Other load/store, table branch. */
8437
if (insn & 0x01200000) {
8438
/* Load/store doubleword. */
8440
addr = tcg_temp_new_i32();
8441
tcg_gen_movi_i32(addr, s->pc & ~3);
8443
addr = load_reg(s, rn);
8445
offset = (insn & 0xff) * 4;
8446
if ((insn & (1 << 23)) == 0)
8448
if (insn & (1 << 24)) {
8449
tcg_gen_addi_i32(addr, addr, offset);
8452
if (insn & (1 << 20)) {
8454
tmp = tcg_temp_new_i32();
8455
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8456
store_reg(s, rs, tmp);
8457
tcg_gen_addi_i32(addr, addr, 4);
8458
tmp = tcg_temp_new_i32();
8459
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8460
store_reg(s, rd, tmp);
8463
tmp = load_reg(s, rs);
8464
gen_aa32_st32(tmp, addr, IS_USER(s));
8465
tcg_temp_free_i32(tmp);
8466
tcg_gen_addi_i32(addr, addr, 4);
8467
tmp = load_reg(s, rd);
8468
gen_aa32_st32(tmp, addr, IS_USER(s));
8469
tcg_temp_free_i32(tmp);
8471
if (insn & (1 << 21)) {
8472
/* Base writeback. */
8475
tcg_gen_addi_i32(addr, addr, offset - 4);
8476
store_reg(s, rn, addr);
8478
tcg_temp_free_i32(addr);
8480
} else if ((insn & (1 << 23)) == 0) {
8481
/* Load/store exclusive word. */
8482
addr = tcg_temp_local_new_i32();
8483
load_reg_var(s, addr, rn);
8484
tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
8485
if (insn & (1 << 20)) {
8486
gen_load_exclusive(s, rs, 15, addr, 2);
8488
gen_store_exclusive(s, rd, rs, 15, addr, 2);
8490
tcg_temp_free_i32(addr);
8491
} else if ((insn & (7 << 5)) == 0) {
8494
addr = tcg_temp_new_i32();
8495
tcg_gen_movi_i32(addr, s->pc);
8497
addr = load_reg(s, rn);
8499
tmp = load_reg(s, rm);
8500
tcg_gen_add_i32(addr, addr, tmp);
8501
if (insn & (1 << 4)) {
8503
tcg_gen_add_i32(addr, addr, tmp);
8504
tcg_temp_free_i32(tmp);
8505
tmp = tcg_temp_new_i32();
8506
gen_aa32_ld16u(tmp, addr, IS_USER(s));
8508
tcg_temp_free_i32(tmp);
8509
tmp = tcg_temp_new_i32();
8510
gen_aa32_ld8u(tmp, addr, IS_USER(s));
8512
tcg_temp_free_i32(addr);
8513
tcg_gen_shli_i32(tmp, tmp, 1);
8514
tcg_gen_addi_i32(tmp, tmp, s->pc);
8515
store_reg(s, 15, tmp);
8517
int op2 = (insn >> 6) & 0x3;
8518
op = (insn >> 4) & 0x3;
8523
/* Load/store exclusive byte/halfword/doubleword */
8530
/* Load-acquire/store-release */
8536
/* Load-acquire/store-release exclusive */
8540
addr = tcg_temp_local_new_i32();
8541
load_reg_var(s, addr, rn);
8543
if (insn & (1 << 20)) {
8544
tmp = tcg_temp_new_i32();
8547
gen_aa32_ld8u(tmp, addr, IS_USER(s));
8550
gen_aa32_ld16u(tmp, addr, IS_USER(s));
8553
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8558
store_reg(s, rs, tmp);
8560
tmp = load_reg(s, rs);
8563
gen_aa32_st8(tmp, addr, IS_USER(s));
8566
gen_aa32_st16(tmp, addr, IS_USER(s));
8569
gen_aa32_st32(tmp, addr, IS_USER(s));
8574
tcg_temp_free_i32(tmp);
8576
} else if (insn & (1 << 20)) {
8577
gen_load_exclusive(s, rs, rd, addr, op);
8579
gen_store_exclusive(s, rm, rs, rd, addr, op);
8581
tcg_temp_free_i32(addr);
8584
/* Load/store multiple, RFE, SRS. */
8585
if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
8586
/* RFE, SRS: not available in user mode or on M profile */
8587
if (IS_USER(s) || IS_M(env)) {
8590
if (insn & (1 << 20)) {
8592
addr = load_reg(s, rn);
8593
if ((insn & (1 << 24)) == 0)
8594
tcg_gen_addi_i32(addr, addr, -8);
8595
/* Load PC into tmp and CPSR into tmp2. */
8596
tmp = tcg_temp_new_i32();
8597
gen_aa32_ld32u(tmp, addr, 0);
8598
tcg_gen_addi_i32(addr, addr, 4);
8599
tmp2 = tcg_temp_new_i32();
8600
gen_aa32_ld32u(tmp2, addr, 0);
8601
if (insn & (1 << 21)) {
8602
/* Base writeback. */
8603
if (insn & (1 << 24)) {
8604
tcg_gen_addi_i32(addr, addr, 4);
8606
tcg_gen_addi_i32(addr, addr, -4);
8608
store_reg(s, rn, addr);
8610
tcg_temp_free_i32(addr);
8612
gen_rfe(s, tmp, tmp2);
8615
gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
8619
int i, loaded_base = 0;
8620
TCGv_i32 loaded_var;
8621
/* Load/store multiple. */
8622
addr = load_reg(s, rn);
8624
for (i = 0; i < 16; i++) {
8625
if (insn & (1 << i))
8628
if (insn & (1 << 24)) {
8629
tcg_gen_addi_i32(addr, addr, -offset);
8632
TCGV_UNUSED_I32(loaded_var);
8633
for (i = 0; i < 16; i++) {
8634
if ((insn & (1 << i)) == 0)
8636
if (insn & (1 << 20)) {
8638
tmp = tcg_temp_new_i32();
8639
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8642
} else if (i == rn) {
8646
store_reg(s, i, tmp);
8650
tmp = load_reg(s, i);
8651
gen_aa32_st32(tmp, addr, IS_USER(s));
8652
tcg_temp_free_i32(tmp);
8654
tcg_gen_addi_i32(addr, addr, 4);
8657
store_reg(s, rn, loaded_var);
8659
if (insn & (1 << 21)) {
8660
/* Base register writeback. */
8661
if (insn & (1 << 24)) {
8662
tcg_gen_addi_i32(addr, addr, -offset);
8664
/* Fault if writeback register is in register list. */
8665
if (insn & (1 << rn))
8667
store_reg(s, rn, addr);
8669
tcg_temp_free_i32(addr);
8676
op = (insn >> 21) & 0xf;
8678
/* Halfword pack. */
8679
tmp = load_reg(s, rn);
8680
tmp2 = load_reg(s, rm);
8681
shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
8682
if (insn & (1 << 5)) {
8686
tcg_gen_sari_i32(tmp2, tmp2, shift);
8687
tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8688
tcg_gen_ext16u_i32(tmp2, tmp2);
8692
tcg_gen_shli_i32(tmp2, tmp2, shift);
8693
tcg_gen_ext16u_i32(tmp, tmp);
8694
tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8696
tcg_gen_or_i32(tmp, tmp, tmp2);
8697
tcg_temp_free_i32(tmp2);
8698
store_reg(s, rd, tmp);
8700
/* Data processing register constant shift. */
8702
tmp = tcg_temp_new_i32();
8703
tcg_gen_movi_i32(tmp, 0);
8705
tmp = load_reg(s, rn);
8707
tmp2 = load_reg(s, rm);
8709
shiftop = (insn >> 4) & 3;
8710
shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
8711
conds = (insn & (1 << 20)) != 0;
8712
logic_cc = (conds && thumb2_logic_op(op));
8713
gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8714
if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
8716
tcg_temp_free_i32(tmp2);
8718
store_reg(s, rd, tmp);
8720
tcg_temp_free_i32(tmp);
8724
case 13: /* Misc data processing. */
8725
op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
8726
if (op < 4 && (insn & 0xf000) != 0xf000)
8729
case 0: /* Register controlled shift. */
8730
tmp = load_reg(s, rn);
8731
tmp2 = load_reg(s, rm);
8732
if ((insn & 0x70) != 0)
8734
op = (insn >> 21) & 3;
8735
logic_cc = (insn & (1 << 20)) != 0;
8736
gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
8739
store_reg_bx(env, s, rd, tmp);
8741
case 1: /* Sign/zero extend. */
8742
tmp = load_reg(s, rm);
8743
shift = (insn >> 4) & 3;
8744
/* ??? In many cases it's not necessary to do a
8745
rotate, a shift is sufficient. */
8747
tcg_gen_rotri_i32(tmp, tmp, shift * 8);
8748
op = (insn >> 20) & 7;
8750
case 0: gen_sxth(tmp); break;
8751
case 1: gen_uxth(tmp); break;
8752
case 2: gen_sxtb16(tmp); break;
8753
case 3: gen_uxtb16(tmp); break;
8754
case 4: gen_sxtb(tmp); break;
8755
case 5: gen_uxtb(tmp); break;
8756
default: goto illegal_op;
8759
tmp2 = load_reg(s, rn);
8760
if ((op >> 1) == 1) {
8761
gen_add16(tmp, tmp2);
8763
tcg_gen_add_i32(tmp, tmp, tmp2);
8764
tcg_temp_free_i32(tmp2);
8767
store_reg(s, rd, tmp);
8769
case 2: /* SIMD add/subtract. */
8770
op = (insn >> 20) & 7;
8771
shift = (insn >> 4) & 7;
8772
if ((op & 3) == 3 || (shift & 3) == 3)
8774
tmp = load_reg(s, rn);
8775
tmp2 = load_reg(s, rm);
8776
gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
8777
tcg_temp_free_i32(tmp2);
8778
store_reg(s, rd, tmp);
8780
case 3: /* Other data processing. */
8781
op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
8783
/* Saturating add/subtract. */
8784
tmp = load_reg(s, rn);
8785
tmp2 = load_reg(s, rm);
8787
gen_helper_double_saturate(tmp, cpu_env, tmp);
8789
gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
8791
gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8792
tcg_temp_free_i32(tmp2);
8794
tmp = load_reg(s, rn);
8796
case 0x0a: /* rbit */
8797
gen_helper_rbit(tmp, tmp);
8799
case 0x08: /* rev */
8800
tcg_gen_bswap32_i32(tmp, tmp);
8802
case 0x09: /* rev16 */
8805
case 0x0b: /* revsh */
8808
case 0x10: /* sel */
8809
tmp2 = load_reg(s, rm);
8810
tmp3 = tcg_temp_new_i32();
8811
tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
8812
gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
8813
tcg_temp_free_i32(tmp3);
8814
tcg_temp_free_i32(tmp2);
8816
case 0x18: /* clz */
8817
gen_helper_clz(tmp, tmp);
8823
store_reg(s, rd, tmp);
8825
case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
8826
op = (insn >> 4) & 0xf;
8827
tmp = load_reg(s, rn);
8828
tmp2 = load_reg(s, rm);
8829
switch ((insn >> 20) & 7) {
8830
case 0: /* 32 x 32 -> 32 */
8831
tcg_gen_mul_i32(tmp, tmp, tmp2);
8832
tcg_temp_free_i32(tmp2);
8834
tmp2 = load_reg(s, rs);
8836
tcg_gen_sub_i32(tmp, tmp2, tmp);
8838
tcg_gen_add_i32(tmp, tmp, tmp2);
8839
tcg_temp_free_i32(tmp2);
8842
case 1: /* 16 x 16 -> 32 */
8843
gen_mulxy(tmp, tmp2, op & 2, op & 1);
8844
tcg_temp_free_i32(tmp2);
8846
tmp2 = load_reg(s, rs);
8847
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8848
tcg_temp_free_i32(tmp2);
8851
case 2: /* Dual multiply add. */
8852
case 4: /* Dual multiply subtract. */
8854
gen_swap_half(tmp2);
8855
gen_smul_dual(tmp, tmp2);
8856
if (insn & (1 << 22)) {
8857
/* This subtraction cannot overflow. */
8858
tcg_gen_sub_i32(tmp, tmp, tmp2);
8860
/* This addition cannot overflow 32 bits;
8861
* however it may overflow considered as a signed
8862
* operation, in which case we must set the Q flag.
8864
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8866
tcg_temp_free_i32(tmp2);
8869
tmp2 = load_reg(s, rs);
8870
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8871
tcg_temp_free_i32(tmp2);
8874
case 3: /* 32 * 16 -> 32msb */
8876
tcg_gen_sari_i32(tmp2, tmp2, 16);
8879
tmp64 = gen_muls_i64_i32(tmp, tmp2);
8880
tcg_gen_shri_i64(tmp64, tmp64, 16);
8881
tmp = tcg_temp_new_i32();
8882
tcg_gen_trunc_i64_i32(tmp, tmp64);
8883
tcg_temp_free_i64(tmp64);
8886
tmp2 = load_reg(s, rs);
8887
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8888
tcg_temp_free_i32(tmp2);
8891
case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
8892
tmp64 = gen_muls_i64_i32(tmp, tmp2);
8894
tmp = load_reg(s, rs);
8895
if (insn & (1 << 20)) {
8896
tmp64 = gen_addq_msw(tmp64, tmp);
8898
tmp64 = gen_subq_msw(tmp64, tmp);
8901
if (insn & (1 << 4)) {
8902
tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
8904
tcg_gen_shri_i64(tmp64, tmp64, 32);
8905
tmp = tcg_temp_new_i32();
8906
tcg_gen_trunc_i64_i32(tmp, tmp64);
8907
tcg_temp_free_i64(tmp64);
8909
case 7: /* Unsigned sum of absolute differences. */
8910
gen_helper_usad8(tmp, tmp, tmp2);
8911
tcg_temp_free_i32(tmp2);
8913
tmp2 = load_reg(s, rs);
8914
tcg_gen_add_i32(tmp, tmp, tmp2);
8915
tcg_temp_free_i32(tmp2);
8919
store_reg(s, rd, tmp);
8921
case 6: case 7: /* 64-bit multiply, Divide. */
8922
op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
8923
tmp = load_reg(s, rn);
8924
tmp2 = load_reg(s, rm);
8925
if ((op & 0x50) == 0x10) {
8927
if (!arm_feature(env, ARM_FEATURE_THUMB_DIV)) {
8931
gen_helper_udiv(tmp, tmp, tmp2);
8933
gen_helper_sdiv(tmp, tmp, tmp2);
8934
tcg_temp_free_i32(tmp2);
8935
store_reg(s, rd, tmp);
8936
} else if ((op & 0xe) == 0xc) {
8937
/* Dual multiply accumulate long. */
8939
gen_swap_half(tmp2);
8940
gen_smul_dual(tmp, tmp2);
8942
tcg_gen_sub_i32(tmp, tmp, tmp2);
8944
tcg_gen_add_i32(tmp, tmp, tmp2);
8946
tcg_temp_free_i32(tmp2);
8948
tmp64 = tcg_temp_new_i64();
8949
tcg_gen_ext_i32_i64(tmp64, tmp);
8950
tcg_temp_free_i32(tmp);
8951
gen_addq(s, tmp64, rs, rd);
8952
gen_storeq_reg(s, rs, rd, tmp64);
8953
tcg_temp_free_i64(tmp64);
8956
/* Unsigned 64-bit multiply */
8957
tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8961
gen_mulxy(tmp, tmp2, op & 2, op & 1);
8962
tcg_temp_free_i32(tmp2);
8963
tmp64 = tcg_temp_new_i64();
8964
tcg_gen_ext_i32_i64(tmp64, tmp);
8965
tcg_temp_free_i32(tmp);
8967
/* Signed 64-bit multiply */
8968
tmp64 = gen_muls_i64_i32(tmp, tmp2);
8973
gen_addq_lo(s, tmp64, rs);
8974
gen_addq_lo(s, tmp64, rd);
8975
} else if (op & 0x40) {
8976
/* 64-bit accumulate. */
8977
gen_addq(s, tmp64, rs, rd);
8979
gen_storeq_reg(s, rs, rd, tmp64);
8980
tcg_temp_free_i64(tmp64);
8985
case 6: case 7: case 14: case 15:
8987
if (((insn >> 24) & 3) == 3) {
8988
/* Translate into the equivalent ARM encoding. */
8989
insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
8990
if (disas_neon_data_insn(env, s, insn))
8992
} else if (((insn >> 8) & 0xe) == 10) {
8993
if (disas_vfp_insn(env, s, insn)) {
8997
if (insn & (1 << 28))
8999
if (disas_coproc_insn (env, s, insn))
9003
case 8: case 9: case 10: case 11:
9004
if (insn & (1 << 15)) {
9005
/* Branches, misc control. */
9006
if (insn & 0x5000) {
9007
/* Unconditional branch. */
9008
/* signextend(hw1[10:0]) -> offset[:12]. */
9009
offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
9010
/* hw1[10:0] -> offset[11:1]. */
9011
offset |= (insn & 0x7ff) << 1;
9012
/* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9013
offset[24:22] already have the same value because of the
9014
sign extension above. */
9015
offset ^= ((~insn) & (1 << 13)) << 10;
9016
offset ^= ((~insn) & (1 << 11)) << 11;
9018
if (insn & (1 << 14)) {
9019
/* Branch and link. */
9020
tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
9024
if (insn & (1 << 12)) {
9029
offset &= ~(uint32_t)2;
9030
/* thumb2 bx, no need to check */
9031
gen_bx_im(s, offset);
9033
} else if (((insn >> 23) & 7) == 7) {
9035
if (insn & (1 << 13))
9038
if (insn & (1 << 26)) {
9039
/* Secure monitor call / smc (v6Z) */
9040
if (!arm_feature(env, ARM_FEATURE_TRUSTZONE)
9046
op = (insn >> 20) & 7;
9048
case 0: /* msr cpsr. */
9050
tmp = load_reg(s, rn);
9051
addr = tcg_const_i32(insn & 0xff);
9052
gen_helper_v7m_msr(cpu_env, addr, tmp);
9053
tcg_temp_free_i32(addr);
9054
tcg_temp_free_i32(tmp);
9059
case 1: /* msr spsr. */
9062
tmp = load_reg(s, rn);
9064
msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
9068
case 2: /* cps, nop-hint. */
9069
if (((insn >> 8) & 7) == 0) {
9070
gen_nop_hint(s, insn & 0xff);
9072
/* Implemented as NOP in user mode. */
9077
if (insn & (1 << 10)) {
9078
if (insn & (1 << 7))
9080
if (insn & (1 << 6))
9082
if (insn & (1 << 5))
9084
if (insn & (1 << 9))
9085
imm = CPSR_A | CPSR_I | CPSR_F;
9087
if (insn & (1 << 8)) {
9089
imm |= (insn & 0x1f);
9092
gen_set_psr_im(s, offset, 0, imm);
9095
case 3: /* Special control operations. */
9097
op = (insn >> 4) & 0xf;
9105
/* These execute as NOPs. */
9112
/* Trivial implementation equivalent to bx. */
9113
tmp = load_reg(s, rn);
9116
case 5: /* Exception return. */
9120
if (rn != 14 || rd != 15) {
9123
tmp = load_reg(s, rn);
9124
tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
9125
gen_exception_return(s, tmp);
9127
case 6: /* mrs cpsr. */
9128
tmp = tcg_temp_new_i32();
9130
addr = tcg_const_i32(insn & 0xff);
9131
gen_helper_v7m_mrs(tmp, cpu_env, addr);
9132
tcg_temp_free_i32(addr);
9134
gen_helper_cpsr_read(tmp, cpu_env);
9136
store_reg(s, rd, tmp);
9138
case 7: /* mrs spsr. */
9139
/* Not accessible in user mode. */
9140
if (IS_USER(s) || IS_M(env))
9142
tmp = load_cpu_field(spsr);
9143
store_reg(s, rd, tmp);
9148
/* Conditional branch. */
9149
op = (insn >> 22) & 0xf;
9150
/* Generate a conditional jump to next instruction. */
9151
s->condlabel = gen_new_label();
9152
gen_test_cc(op ^ 1, s->condlabel);
9155
/* offset[11:1] = insn[10:0] */
9156
offset = (insn & 0x7ff) << 1;
9157
/* offset[17:12] = insn[21:16]. */
9158
offset |= (insn & 0x003f0000) >> 4;
9159
/* offset[31:20] = insn[26]. */
9160
offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
9161
/* offset[18] = insn[13]. */
9162
offset |= (insn & (1 << 13)) << 5;
9163
/* offset[19] = insn[11]. */
9164
offset |= (insn & (1 << 11)) << 8;
9166
/* jump to the offset */
9167
gen_jmp(s, s->pc + offset);
9170
/* Data processing immediate. */
9171
if (insn & (1 << 25)) {
9172
if (insn & (1 << 24)) {
9173
if (insn & (1 << 20))
9175
/* Bitfield/Saturate. */
9176
op = (insn >> 21) & 7;
9178
shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9180
tmp = tcg_temp_new_i32();
9181
tcg_gen_movi_i32(tmp, 0);
9183
tmp = load_reg(s, rn);
9186
case 2: /* Signed bitfield extract. */
9188
if (shift + imm > 32)
9191
gen_sbfx(tmp, shift, imm);
9193
case 6: /* Unsigned bitfield extract. */
9195
if (shift + imm > 32)
9198
gen_ubfx(tmp, shift, (1u << imm) - 1);
9200
case 3: /* Bitfield insert/clear. */
9203
imm = imm + 1 - shift;
9205
tmp2 = load_reg(s, rd);
9206
tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
9207
tcg_temp_free_i32(tmp2);
9212
default: /* Saturate. */
9215
tcg_gen_sari_i32(tmp, tmp, shift);
9217
tcg_gen_shli_i32(tmp, tmp, shift);
9219
tmp2 = tcg_const_i32(imm);
9222
if ((op & 1) && shift == 0)
9223
gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9225
gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9228
if ((op & 1) && shift == 0)
9229
gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9231
gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9233
tcg_temp_free_i32(tmp2);
9236
store_reg(s, rd, tmp);
9238
imm = ((insn & 0x04000000) >> 15)
9239
| ((insn & 0x7000) >> 4) | (insn & 0xff);
9240
if (insn & (1 << 22)) {
9241
/* 16-bit immediate. */
9242
imm |= (insn >> 4) & 0xf000;
9243
if (insn & (1 << 23)) {
9245
tmp = load_reg(s, rd);
9246
tcg_gen_ext16u_i32(tmp, tmp);
9247
tcg_gen_ori_i32(tmp, tmp, imm << 16);
9250
tmp = tcg_temp_new_i32();
9251
tcg_gen_movi_i32(tmp, imm);
9254
/* Add/sub 12-bit immediate. */
9256
offset = s->pc & ~(uint32_t)3;
9257
if (insn & (1 << 23))
9261
tmp = tcg_temp_new_i32();
9262
tcg_gen_movi_i32(tmp, offset);
9264
tmp = load_reg(s, rn);
9265
if (insn & (1 << 23))
9266
tcg_gen_subi_i32(tmp, tmp, imm);
9268
tcg_gen_addi_i32(tmp, tmp, imm);
9271
store_reg(s, rd, tmp);
9274
int shifter_out = 0;
9275
/* modified 12-bit immediate. */
9276
shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
9277
imm = (insn & 0xff);
9280
/* Nothing to do. */
9282
case 1: /* 00XY00XY */
9285
case 2: /* XY00XY00 */
9289
case 3: /* XYXYXYXY */
9293
default: /* Rotated constant. */
9294
shift = (shift << 1) | (imm >> 7);
9296
imm = imm << (32 - shift);
9300
tmp2 = tcg_temp_new_i32();
9301
tcg_gen_movi_i32(tmp2, imm);
9302
rn = (insn >> 16) & 0xf;
9304
tmp = tcg_temp_new_i32();
9305
tcg_gen_movi_i32(tmp, 0);
9307
tmp = load_reg(s, rn);
9309
op = (insn >> 21) & 0xf;
9310
if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
9311
shifter_out, tmp, tmp2))
9313
tcg_temp_free_i32(tmp2);
9314
rd = (insn >> 8) & 0xf;
9316
store_reg(s, rd, tmp);
9318
tcg_temp_free_i32(tmp);
9323
case 12: /* Load/store single data item. */
9328
if ((insn & 0x01100000) == 0x01000000) {
9329
if (disas_neon_ls_insn(env, s, insn))
9333
op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
9335
if (!(insn & (1 << 20))) {
9339
/* Byte or halfword load space with dest == r15 : memory hints.
9340
* Catch them early so we don't emit pointless addressing code.
9341
* This space is a mix of:
9342
* PLD/PLDW/PLI, which we implement as NOPs (note that unlike
9343
* the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
9345
* unallocated hints, which must be treated as NOPs
9346
* UNPREDICTABLE space, which we NOP or UNDEF depending on
9347
* which is easiest for the decoding logic
9348
* Some space which must UNDEF
9350
int op1 = (insn >> 23) & 3;
9351
int op2 = (insn >> 6) & 0x3f;
9356
/* UNPREDICTABLE, unallocated hint or
9357
* PLD/PLDW/PLI (literal)
9362
return 0; /* PLD/PLDW/PLI or unallocated hint */
9364
if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
9365
return 0; /* PLD/PLDW/PLI or unallocated hint */
9367
/* UNDEF space, or an UNPREDICTABLE */
9373
addr = tcg_temp_new_i32();
9375
/* s->pc has already been incremented by 4. */
9376
imm = s->pc & 0xfffffffc;
9377
if (insn & (1 << 23))
9378
imm += insn & 0xfff;
9380
imm -= insn & 0xfff;
9381
tcg_gen_movi_i32(addr, imm);
9383
addr = load_reg(s, rn);
9384
if (insn & (1 << 23)) {
9385
/* Positive offset. */
9387
tcg_gen_addi_i32(addr, addr, imm);
9390
switch ((insn >> 8) & 0xf) {
9391
case 0x0: /* Shifted Register. */
9392
shift = (insn >> 4) & 0xf;
9394
tcg_temp_free_i32(addr);
9397
tmp = load_reg(s, rm);
9399
tcg_gen_shli_i32(tmp, tmp, shift);
9400
tcg_gen_add_i32(addr, addr, tmp);
9401
tcg_temp_free_i32(tmp);
9403
case 0xc: /* Negative offset. */
9404
tcg_gen_addi_i32(addr, addr, -imm);
9406
case 0xe: /* User privilege. */
9407
tcg_gen_addi_i32(addr, addr, imm);
9410
case 0x9: /* Post-decrement. */
9413
case 0xb: /* Post-increment. */
9417
case 0xd: /* Pre-decrement. */
9420
case 0xf: /* Pre-increment. */
9421
tcg_gen_addi_i32(addr, addr, imm);
9425
tcg_temp_free_i32(addr);
9430
if (insn & (1 << 20)) {
9432
tmp = tcg_temp_new_i32();
9435
gen_aa32_ld8u(tmp, addr, user);
9438
gen_aa32_ld8s(tmp, addr, user);
9441
gen_aa32_ld16u(tmp, addr, user);
9444
gen_aa32_ld16s(tmp, addr, user);
9447
gen_aa32_ld32u(tmp, addr, user);
9450
tcg_temp_free_i32(tmp);
9451
tcg_temp_free_i32(addr);
9457
store_reg(s, rs, tmp);
9461
tmp = load_reg(s, rs);
9464
gen_aa32_st8(tmp, addr, user);
9467
gen_aa32_st16(tmp, addr, user);
9470
gen_aa32_st32(tmp, addr, user);
9473
tcg_temp_free_i32(tmp);
9474
tcg_temp_free_i32(addr);
9477
tcg_temp_free_i32(tmp);
9480
tcg_gen_addi_i32(addr, addr, imm);
9482
store_reg(s, rn, addr);
9484
tcg_temp_free_i32(addr);
9496
static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
9498
uint32_t val, insn, op, rm, rn, rd, shift, cond;
9505
if (s->condexec_mask) {
9506
cond = s->condexec_cond;
9507
if (cond != 0x0e) { /* Skip conditional when condition is AL. */
9508
s->condlabel = gen_new_label();
9509
gen_test_cc(cond ^ 1, s->condlabel);
9514
insn = arm_lduw_code(env, s->pc, s->bswap_code);
9517
switch (insn >> 12) {
9521
op = (insn >> 11) & 3;
9524
rn = (insn >> 3) & 7;
9525
tmp = load_reg(s, rn);
9526
if (insn & (1 << 10)) {
9528
tmp2 = tcg_temp_new_i32();
9529
tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
9532
rm = (insn >> 6) & 7;
9533
tmp2 = load_reg(s, rm);
9535
if (insn & (1 << 9)) {
9536
if (s->condexec_mask)
9537
tcg_gen_sub_i32(tmp, tmp, tmp2);
9539
gen_sub_CC(tmp, tmp, tmp2);
9541
if (s->condexec_mask)
9542
tcg_gen_add_i32(tmp, tmp, tmp2);
9544
gen_add_CC(tmp, tmp, tmp2);
9546
tcg_temp_free_i32(tmp2);
9547
store_reg(s, rd, tmp);
9549
/* shift immediate */
9550
rm = (insn >> 3) & 7;
9551
shift = (insn >> 6) & 0x1f;
9552
tmp = load_reg(s, rm);
9553
gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
9554
if (!s->condexec_mask)
9556
store_reg(s, rd, tmp);
9560
/* arithmetic large immediate */
9561
op = (insn >> 11) & 3;
9562
rd = (insn >> 8) & 0x7;
9563
if (op == 0) { /* mov */
9564
tmp = tcg_temp_new_i32();
9565
tcg_gen_movi_i32(tmp, insn & 0xff);
9566
if (!s->condexec_mask)
9568
store_reg(s, rd, tmp);
9570
tmp = load_reg(s, rd);
9571
tmp2 = tcg_temp_new_i32();
9572
tcg_gen_movi_i32(tmp2, insn & 0xff);
9575
gen_sub_CC(tmp, tmp, tmp2);
9576
tcg_temp_free_i32(tmp);
9577
tcg_temp_free_i32(tmp2);
9580
if (s->condexec_mask)
9581
tcg_gen_add_i32(tmp, tmp, tmp2);
9583
gen_add_CC(tmp, tmp, tmp2);
9584
tcg_temp_free_i32(tmp2);
9585
store_reg(s, rd, tmp);
9588
if (s->condexec_mask)
9589
tcg_gen_sub_i32(tmp, tmp, tmp2);
9591
gen_sub_CC(tmp, tmp, tmp2);
9592
tcg_temp_free_i32(tmp2);
9593
store_reg(s, rd, tmp);
9599
if (insn & (1 << 11)) {
9600
rd = (insn >> 8) & 7;
9601
/* load pc-relative. Bit 1 of PC is ignored. */
9602
val = s->pc + 2 + ((insn & 0xff) * 4);
9603
val &= ~(uint32_t)2;
9604
addr = tcg_temp_new_i32();
9605
tcg_gen_movi_i32(addr, val);
9606
tmp = tcg_temp_new_i32();
9607
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9608
tcg_temp_free_i32(addr);
9609
store_reg(s, rd, tmp);
9612
if (insn & (1 << 10)) {
9613
/* data processing extended or blx */
9614
rd = (insn & 7) | ((insn >> 4) & 8);
9615
rm = (insn >> 3) & 0xf;
9616
op = (insn >> 8) & 3;
9619
tmp = load_reg(s, rd);
9620
tmp2 = load_reg(s, rm);
9621
tcg_gen_add_i32(tmp, tmp, tmp2);
9622
tcg_temp_free_i32(tmp2);
9623
store_reg(s, rd, tmp);
9626
tmp = load_reg(s, rd);
9627
tmp2 = load_reg(s, rm);
9628
gen_sub_CC(tmp, tmp, tmp2);
9629
tcg_temp_free_i32(tmp2);
9630
tcg_temp_free_i32(tmp);
9632
case 2: /* mov/cpy */
9633
tmp = load_reg(s, rm);
9634
store_reg(s, rd, tmp);
9636
case 3:/* branch [and link] exchange thumb register */
9637
tmp = load_reg(s, rm);
9638
if (insn & (1 << 7)) {
9640
val = (uint32_t)s->pc | 1;
9641
tmp2 = tcg_temp_new_i32();
9642
tcg_gen_movi_i32(tmp2, val);
9643
store_reg(s, 14, tmp2);
9645
/* already thumb, no need to check */
9652
/* data processing register */
9654
rm = (insn >> 3) & 7;
9655
op = (insn >> 6) & 0xf;
9656
if (op == 2 || op == 3 || op == 4 || op == 7) {
9657
/* the shift/rotate ops want the operands backwards */
9666
if (op == 9) { /* neg */
9667
tmp = tcg_temp_new_i32();
9668
tcg_gen_movi_i32(tmp, 0);
9669
} else if (op != 0xf) { /* mvn doesn't read its first operand */
9670
tmp = load_reg(s, rd);
9672
TCGV_UNUSED_I32(tmp);
9675
tmp2 = load_reg(s, rm);
9678
tcg_gen_and_i32(tmp, tmp, tmp2);
9679
if (!s->condexec_mask)
9683
tcg_gen_xor_i32(tmp, tmp, tmp2);
9684
if (!s->condexec_mask)
9688
if (s->condexec_mask) {
9689
gen_shl(tmp2, tmp2, tmp);
9691
gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
9696
if (s->condexec_mask) {
9697
gen_shr(tmp2, tmp2, tmp);
9699
gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
9704
if (s->condexec_mask) {
9705
gen_sar(tmp2, tmp2, tmp);
9707
gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
9712
if (s->condexec_mask) {
9715
gen_adc_CC(tmp, tmp, tmp2);
9719
if (s->condexec_mask) {
9720
gen_sub_carry(tmp, tmp, tmp2);
9722
gen_sbc_CC(tmp, tmp, tmp2);
9726
if (s->condexec_mask) {
9727
tcg_gen_andi_i32(tmp, tmp, 0x1f);
9728
tcg_gen_rotr_i32(tmp2, tmp2, tmp);
9730
gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
9735
tcg_gen_and_i32(tmp, tmp, tmp2);
9740
if (s->condexec_mask)
9741
tcg_gen_neg_i32(tmp, tmp2);
9743
gen_sub_CC(tmp, tmp, tmp2);
9746
gen_sub_CC(tmp, tmp, tmp2);
9750
gen_add_CC(tmp, tmp, tmp2);
9754
tcg_gen_or_i32(tmp, tmp, tmp2);
9755
if (!s->condexec_mask)
9759
tcg_gen_mul_i32(tmp, tmp, tmp2);
9760
if (!s->condexec_mask)
9764
tcg_gen_andc_i32(tmp, tmp, tmp2);
9765
if (!s->condexec_mask)
9769
tcg_gen_not_i32(tmp2, tmp2);
9770
if (!s->condexec_mask)
9778
store_reg(s, rm, tmp2);
9780
tcg_temp_free_i32(tmp);
9782
store_reg(s, rd, tmp);
9783
tcg_temp_free_i32(tmp2);
9786
tcg_temp_free_i32(tmp);
9787
tcg_temp_free_i32(tmp2);
9792
/* load/store register offset. */
9794
rn = (insn >> 3) & 7;
9795
rm = (insn >> 6) & 7;
9796
op = (insn >> 9) & 7;
9797
addr = load_reg(s, rn);
9798
tmp = load_reg(s, rm);
9799
tcg_gen_add_i32(addr, addr, tmp);
9800
tcg_temp_free_i32(tmp);
9802
if (op < 3) { /* store */
9803
tmp = load_reg(s, rd);
9805
tmp = tcg_temp_new_i32();
9810
gen_aa32_st32(tmp, addr, IS_USER(s));
9813
gen_aa32_st16(tmp, addr, IS_USER(s));
9816
gen_aa32_st8(tmp, addr, IS_USER(s));
9819
gen_aa32_ld8s(tmp, addr, IS_USER(s));
9822
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9825
gen_aa32_ld16u(tmp, addr, IS_USER(s));
9828
gen_aa32_ld8u(tmp, addr, IS_USER(s));
9831
gen_aa32_ld16s(tmp, addr, IS_USER(s));
9834
if (op >= 3) { /* load */
9835
store_reg(s, rd, tmp);
9837
tcg_temp_free_i32(tmp);
9839
tcg_temp_free_i32(addr);
9843
/* load/store word immediate offset */
9845
rn = (insn >> 3) & 7;
9846
addr = load_reg(s, rn);
9847
val = (insn >> 4) & 0x7c;
9848
tcg_gen_addi_i32(addr, addr, val);
9850
if (insn & (1 << 11)) {
9852
tmp = tcg_temp_new_i32();
9853
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9854
store_reg(s, rd, tmp);
9857
tmp = load_reg(s, rd);
9858
gen_aa32_st32(tmp, addr, IS_USER(s));
9859
tcg_temp_free_i32(tmp);
9861
tcg_temp_free_i32(addr);
9865
/* load/store byte immediate offset */
9867
rn = (insn >> 3) & 7;
9868
addr = load_reg(s, rn);
9869
val = (insn >> 6) & 0x1f;
9870
tcg_gen_addi_i32(addr, addr, val);
9872
if (insn & (1 << 11)) {
9874
tmp = tcg_temp_new_i32();
9875
gen_aa32_ld8u(tmp, addr, IS_USER(s));
9876
store_reg(s, rd, tmp);
9879
tmp = load_reg(s, rd);
9880
gen_aa32_st8(tmp, addr, IS_USER(s));
9881
tcg_temp_free_i32(tmp);
9883
tcg_temp_free_i32(addr);
9887
/* load/store halfword immediate offset */
9889
rn = (insn >> 3) & 7;
9890
addr = load_reg(s, rn);
9891
val = (insn >> 5) & 0x3e;
9892
tcg_gen_addi_i32(addr, addr, val);
9894
if (insn & (1 << 11)) {
9896
tmp = tcg_temp_new_i32();
9897
gen_aa32_ld16u(tmp, addr, IS_USER(s));
9898
store_reg(s, rd, tmp);
9901
tmp = load_reg(s, rd);
9902
gen_aa32_st16(tmp, addr, IS_USER(s));
9903
tcg_temp_free_i32(tmp);
9905
tcg_temp_free_i32(addr);
9909
/* load/store from stack */
9910
rd = (insn >> 8) & 7;
9911
addr = load_reg(s, 13);
9912
val = (insn & 0xff) * 4;
9913
tcg_gen_addi_i32(addr, addr, val);
9915
if (insn & (1 << 11)) {
9917
tmp = tcg_temp_new_i32();
9918
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9919
store_reg(s, rd, tmp);
9922
tmp = load_reg(s, rd);
9923
gen_aa32_st32(tmp, addr, IS_USER(s));
9924
tcg_temp_free_i32(tmp);
9926
tcg_temp_free_i32(addr);
9930
/* add to high reg */
9931
rd = (insn >> 8) & 7;
9932
if (insn & (1 << 11)) {
9934
tmp = load_reg(s, 13);
9936
/* PC. bit 1 is ignored. */
9937
tmp = tcg_temp_new_i32();
9938
tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
9940
val = (insn & 0xff) * 4;
9941
tcg_gen_addi_i32(tmp, tmp, val);
9942
store_reg(s, rd, tmp);
9947
op = (insn >> 8) & 0xf;
9950
/* adjust stack pointer */
9951
tmp = load_reg(s, 13);
9952
val = (insn & 0x7f) * 4;
9953
if (insn & (1 << 7))
9954
val = -(int32_t)val;
9955
tcg_gen_addi_i32(tmp, tmp, val);
9956
store_reg(s, 13, tmp);
9959
case 2: /* sign/zero extend. */
9962
rm = (insn >> 3) & 7;
9963
tmp = load_reg(s, rm);
9964
switch ((insn >> 6) & 3) {
9965
case 0: gen_sxth(tmp); break;
9966
case 1: gen_sxtb(tmp); break;
9967
case 2: gen_uxth(tmp); break;
9968
case 3: gen_uxtb(tmp); break;
9970
store_reg(s, rd, tmp);
9972
case 4: case 5: case 0xc: case 0xd:
9974
addr = load_reg(s, 13);
9975
if (insn & (1 << 8))
9979
for (i = 0; i < 8; i++) {
9980
if (insn & (1 << i))
9983
if ((insn & (1 << 11)) == 0) {
9984
tcg_gen_addi_i32(addr, addr, -offset);
9986
for (i = 0; i < 8; i++) {
9987
if (insn & (1 << i)) {
9988
if (insn & (1 << 11)) {
9990
tmp = tcg_temp_new_i32();
9991
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9992
store_reg(s, i, tmp);
9995
tmp = load_reg(s, i);
9996
gen_aa32_st32(tmp, addr, IS_USER(s));
9997
tcg_temp_free_i32(tmp);
9999
/* advance to the next address. */
10000
tcg_gen_addi_i32(addr, addr, 4);
10003
TCGV_UNUSED_I32(tmp);
10004
if (insn & (1 << 8)) {
10005
if (insn & (1 << 11)) {
10007
tmp = tcg_temp_new_i32();
10008
gen_aa32_ld32u(tmp, addr, IS_USER(s));
10009
/* don't set the pc until the rest of the instruction
10013
tmp = load_reg(s, 14);
10014
gen_aa32_st32(tmp, addr, IS_USER(s));
10015
tcg_temp_free_i32(tmp);
10017
tcg_gen_addi_i32(addr, addr, 4);
10019
if ((insn & (1 << 11)) == 0) {
10020
tcg_gen_addi_i32(addr, addr, -offset);
10022
/* write back the new stack pointer */
10023
store_reg(s, 13, addr);
10024
/* set the new PC value */
10025
if ((insn & 0x0900) == 0x0900) {
10026
store_reg_from_load(env, s, 15, tmp);
10030
case 1: case 3: case 9: case 11: /* czb */
10032
tmp = load_reg(s, rm);
10033
s->condlabel = gen_new_label();
10035
if (insn & (1 << 11))
10036
tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
10038
tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
10039
tcg_temp_free_i32(tmp);
10040
offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
10041
val = (uint32_t)s->pc + 2;
10046
case 15: /* IT, nop-hint. */
10047
if ((insn & 0xf) == 0) {
10048
gen_nop_hint(s, (insn >> 4) & 0xf);
10052
s->condexec_cond = (insn >> 4) & 0xe;
10053
s->condexec_mask = insn & 0x1f;
10054
/* No actual code generated for this insn, just setup state. */
10057
case 0xe: /* bkpt */
10059
gen_exception_insn(s, 2, EXCP_BKPT);
10062
case 0xa: /* rev */
10064
rn = (insn >> 3) & 0x7;
10066
tmp = load_reg(s, rn);
10067
switch ((insn >> 6) & 3) {
10068
case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
10069
case 1: gen_rev16(tmp); break;
10070
case 3: gen_revsh(tmp); break;
10071
default: goto illegal_op;
10073
store_reg(s, rd, tmp);
10077
switch ((insn >> 5) & 7) {
10081
if (((insn >> 3) & 1) != s->bswap_code) {
10082
/* Dynamic endianness switching not implemented. */
10083
qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
10094
tmp = tcg_const_i32((insn & (1 << 4)) != 0);
10097
addr = tcg_const_i32(19);
10098
gen_helper_v7m_msr(cpu_env, addr, tmp);
10099
tcg_temp_free_i32(addr);
10103
addr = tcg_const_i32(16);
10104
gen_helper_v7m_msr(cpu_env, addr, tmp);
10105
tcg_temp_free_i32(addr);
10107
tcg_temp_free_i32(tmp);
10110
if (insn & (1 << 4)) {
10111
shift = CPSR_A | CPSR_I | CPSR_F;
10115
gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
10130
/* load/store multiple */
10131
TCGv_i32 loaded_var;
10132
TCGV_UNUSED_I32(loaded_var);
10133
rn = (insn >> 8) & 0x7;
10134
addr = load_reg(s, rn);
10135
for (i = 0; i < 8; i++) {
10136
if (insn & (1 << i)) {
10137
if (insn & (1 << 11)) {
10139
tmp = tcg_temp_new_i32();
10140
gen_aa32_ld32u(tmp, addr, IS_USER(s));
10144
store_reg(s, i, tmp);
10148
tmp = load_reg(s, i);
10149
gen_aa32_st32(tmp, addr, IS_USER(s));
10150
tcg_temp_free_i32(tmp);
10152
/* advance to the next address */
10153
tcg_gen_addi_i32(addr, addr, 4);
10156
if ((insn & (1 << rn)) == 0) {
10157
/* base reg not in list: base register writeback */
10158
store_reg(s, rn, addr);
10160
/* base reg in list: if load, complete it now */
10161
if (insn & (1 << 11)) {
10162
store_reg(s, rn, loaded_var);
10164
tcg_temp_free_i32(addr);
10169
/* conditional branch or swi */
10170
cond = (insn >> 8) & 0xf;
10176
gen_set_pc_im(s, s->pc);
10177
s->is_jmp = DISAS_SWI;
10180
/* generate a conditional jump to next instruction */
10181
s->condlabel = gen_new_label();
10182
gen_test_cc(cond ^ 1, s->condlabel);
10185
/* jump to the offset */
10186
val = (uint32_t)s->pc + 2;
10187
offset = ((int32_t)insn << 24) >> 24;
10188
val += offset << 1;
10193
if (insn & (1 << 11)) {
10194
if (disas_thumb2_insn(env, s, insn))
10198
/* unconditional branch */
10199
val = (uint32_t)s->pc;
10200
offset = ((int32_t)insn << 21) >> 21;
10201
val += (offset << 1) + 2;
10206
if (disas_thumb2_insn(env, s, insn))
10212
gen_exception_insn(s, 4, EXCP_UDEF);
10216
gen_exception_insn(s, 2, EXCP_UDEF);
10219
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
10220
basic block 'tb'. If search_pc is TRUE, also generate PC
10221
information for each intermediate instruction. */
10222
static inline void gen_intermediate_code_internal(ARMCPU *cpu,
10223
TranslationBlock *tb,
10226
CPUState *cs = CPU(cpu);
10227
CPUARMState *env = &cpu->env;
10228
DisasContext dc1, *dc = &dc1;
10230
uint16_t *gen_opc_end;
10232
target_ulong pc_start;
10233
target_ulong next_page_start;
10237
/* generate intermediate code */
10242
gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
10244
dc->is_jmp = DISAS_NEXT;
10246
dc->singlestep_enabled = cs->singlestep_enabled;
10249
if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
10252
dc->bswap_code = 0;
10253
dc->condexec_mask = 0;
10254
dc->condexec_cond = 0;
10255
#if !defined(CONFIG_USER_ONLY)
10258
dc->vfp_enabled = 0;
10260
dc->vec_stride = 0;
10263
dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
10264
dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags);
10265
dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
10266
dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
10267
#if !defined(CONFIG_USER_ONLY)
10268
dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
10270
dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
10271
dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
10272
dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
10274
cpu_F0s = tcg_temp_new_i32();
10275
cpu_F1s = tcg_temp_new_i32();
10276
cpu_F0d = tcg_temp_new_i64();
10277
cpu_F1d = tcg_temp_new_i64();
10280
/* FIXME: cpu_M0 can probably be the same as cpu_V0. */
10281
cpu_M0 = tcg_temp_new_i64();
10282
next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
10285
max_insns = tb->cflags & CF_COUNT_MASK;
10286
if (max_insns == 0)
10287
max_insns = CF_COUNT_MASK;
10291
tcg_clear_temp_count();
10293
/* A note on handling of the condexec (IT) bits:
10295
* We want to avoid the overhead of having to write the updated condexec
10296
* bits back to the CPUARMState for every instruction in an IT block. So:
10297
* (1) if the condexec bits are not already zero then we write
10298
* zero back into the CPUARMState now. This avoids complications trying
10299
* to do it at the end of the block. (For example if we don't do this
10300
* it's hard to identify whether we can safely skip writing condexec
10301
* at the end of the TB, which we definitely want to do for the case
10302
* where a TB doesn't do anything with the IT state at all.)
10303
* (2) if we are going to leave the TB then we call gen_set_condexec()
10304
* which will write the correct value into CPUARMState if zero is wrong.
10305
* This is done both for leaving the TB at the end, and for leaving
10306
* it because of an exception we know will happen, which is done in
10307
* gen_exception_insn(). The latter is necessary because we need to
10308
* leave the TB with the PC/IT state just prior to execution of the
10309
* instruction which caused the exception.
10310
* (3) if we leave the TB unexpectedly (eg a data abort on a load)
10311
* then the CPUARMState will be wrong and we need to reset it.
10312
* This is handled in the same way as restoration of the
10313
* PC in these situations: we will be called again with search_pc=1
10314
* and generate a mapping of the condexec bits for each PC in
10315
* gen_opc_condexec_bits[]. restore_state_to_opc() then uses
10316
* this to restore the condexec bits.
10318
* Note that there are no instructions which can read the condexec
10319
* bits, and none which can write non-static values to them, so
10320
* we don't need to care about whether CPUARMState is correct in the
10324
/* Reset the conditional execution bits immediately. This avoids
10325
complications trying to do it at the end of the block. */
10326
if (dc->condexec_mask || dc->condexec_cond)
10328
TCGv_i32 tmp = tcg_temp_new_i32();
10329
tcg_gen_movi_i32(tmp, 0);
10330
store_cpu_field(tmp, condexec_bits);
10333
#ifdef CONFIG_USER_ONLY
10334
/* Intercept jump to the magic kernel page. */
10335
if (!dc->aarch64 && dc->pc >= 0xffff0000) {
10336
/* We always get here via a jump, so know we are not in a
10337
conditional execution block. */
10338
gen_exception(EXCP_KERNEL_TRAP);
10339
dc->is_jmp = DISAS_UPDATE;
10343
if (dc->pc >= 0xfffffff0 && IS_M(env)) {
10344
/* We always get here via a jump, so know we are not in a
10345
conditional execution block. */
10346
gen_exception(EXCP_EXCEPTION_EXIT);
10347
dc->is_jmp = DISAS_UPDATE;
10352
if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
10353
QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
10354
if (bp->pc == dc->pc) {
10355
gen_exception_insn(dc, 0, EXCP_DEBUG);
10356
/* Advance PC so that clearing the breakpoint will
10357
invalidate this TB. */
10359
goto done_generating;
10364
j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10368
tcg_ctx.gen_opc_instr_start[lj++] = 0;
10370
tcg_ctx.gen_opc_pc[lj] = dc->pc;
10371
gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
10372
tcg_ctx.gen_opc_instr_start[lj] = 1;
10373
tcg_ctx.gen_opc_icount[lj] = num_insns;
10376
if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
10379
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
10380
tcg_gen_debug_insn_start(dc->pc);
10384
disas_a64_insn(env, dc);
10385
} else if (dc->thumb) {
10386
disas_thumb_insn(env, dc);
10387
if (dc->condexec_mask) {
10388
dc->condexec_cond = (dc->condexec_cond & 0xe)
10389
| ((dc->condexec_mask >> 4) & 1);
10390
dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
10391
if (dc->condexec_mask == 0) {
10392
dc->condexec_cond = 0;
10396
disas_arm_insn(env, dc);
10399
if (dc->condjmp && !dc->is_jmp) {
10400
gen_set_label(dc->condlabel);
10404
if (tcg_check_temp_count()) {
10405
fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
10409
/* Translation stops when a conditional branch is encountered.
10410
* Otherwise the subsequent code could get translated several times.
10411
* Also stop translation when a page boundary is reached. This
10412
* ensures prefetch aborts occur at the right place. */
10414
} while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
10415
!cs->singlestep_enabled &&
10417
dc->pc < next_page_start &&
10418
num_insns < max_insns);
10420
if (tb->cflags & CF_LAST_IO) {
10422
/* FIXME: This can theoretically happen with self-modifying
10424
cpu_abort(env, "IO on conditional branch instruction");
10429
/* At this stage dc->condjmp will only be set when the skipped
10430
instruction was a conditional branch or trap, and the PC has
10431
already been written. */
10432
if (unlikely(cs->singlestep_enabled)) {
10433
/* Make sure the pc is updated, and raise a debug exception. */
10435
gen_set_condexec(dc);
10436
if (dc->is_jmp == DISAS_SWI) {
10437
gen_exception(EXCP_SWI);
10438
} else if (dc->is_jmp == DISAS_SMC) {
10439
gen_exception(EXCP_SMC);
10441
gen_exception(EXCP_DEBUG);
10443
gen_set_label(dc->condlabel);
10445
if (dc->condjmp || !dc->is_jmp) {
10446
gen_set_pc_im(dc, dc->pc);
10449
gen_set_condexec(dc);
10450
if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
10451
gen_exception(EXCP_SWI);
10452
} else if (dc->is_jmp == DISAS_SMC && !dc->condjmp) {
10453
gen_exception(EXCP_SMC);
10455
/* FIXME: Single stepping a WFI insn will not halt
10457
gen_exception(EXCP_DEBUG);
10460
/* While branches must always occur at the end of an IT block,
10461
there are a few other things that can cause us to terminate
10462
the TB in the middle of an IT block:
10463
- Exception generating instructions (bkpt, swi, undefined).
10465
- Hardware watchpoints.
10466
Hardware breakpoints have already been handled and skip this code.
10468
gen_set_condexec(dc);
10469
switch(dc->is_jmp) {
10471
gen_goto_tb(dc, 1, dc->pc);
10476
/* indicate that the hash table must be used to find the next TB */
10477
tcg_gen_exit_tb(0);
10479
case DISAS_TB_JUMP:
10480
/* nothing more to generate */
10483
gen_helper_wfi(cpu_env);
10486
gen_exception(EXCP_SWI);
10489
gen_exception(EXCP_SMC);
10493
gen_set_label(dc->condlabel);
10494
gen_set_condexec(dc);
10495
gen_goto_tb(dc, 1, dc->pc);
10501
gen_tb_end(tb, num_insns);
10502
*tcg_ctx.gen_opc_ptr = INDEX_op_end;
10505
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
10506
qemu_log("----------------\n");
10507
qemu_log("IN: %s\n", lookup_symbol(pc_start));
10508
log_target_disas(env, pc_start, dc->pc - pc_start,
10509
dc->thumb | (dc->bswap_code << 1));
10514
j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10517
tcg_ctx.gen_opc_instr_start[lj++] = 0;
10519
tb->size = dc->pc - pc_start;
10520
tb->icount = num_insns;
10524
void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
10526
gen_intermediate_code_internal(arm_env_get_cpu(env), tb, false);
10529
void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb)
10531
gen_intermediate_code_internal(arm_env_get_cpu(env), tb, true);
10534
static const char *cpu_mode_names[16] = {
10535
"usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
10536
"???", "???", "???", "und", "???", "???", "???", "sys"
10539
void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
10542
ARMCPU *cpu = ARM_CPU(cs);
10543
CPUARMState *env = &cpu->env;
10547
for(i=0;i<16;i++) {
10548
cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
10550
cpu_fprintf(f, "\n");
10552
cpu_fprintf(f, " ");
10554
psr = cpsr_read(env);
10555
cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
10557
psr & (1 << 31) ? 'N' : '-',
10558
psr & (1 << 30) ? 'Z' : '-',
10559
psr & (1 << 29) ? 'C' : '-',
10560
psr & (1 << 28) ? 'V' : '-',
10561
psr & CPSR_T ? 'T' : 'A',
10562
cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
10564
if (flags & CPU_DUMP_FPU) {
10565
int numvfpregs = 0;
10566
if (arm_feature(env, ARM_FEATURE_VFP)) {
10569
if (arm_feature(env, ARM_FEATURE_VFP3)) {
10572
for (i = 0; i < numvfpregs; i++) {
10573
uint64_t v = float64_val(env->vfp.regs[i]);
10574
cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
10575
i * 2, (uint32_t)v,
10576
i * 2 + 1, (uint32_t)(v >> 32),
10579
cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
10583
void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos)
10586
env->pc = tcg_ctx.gen_opc_pc[pc_pos];
10588
env->regs[15] = tcg_ctx.gen_opc_pc[pc_pos];
10590
env->condexec_bits = gen_opc_condexec_bits[pc_pos];