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 "internals.h"
29 #include "disas/disas.h"
32 #include "qemu/bitops.h"
35 #include "exec/helper-proto.h"
36 #include "exec/helper-gen.h"
38 #define ENABLE_ARCH_4T arm_feature(env, ARM_FEATURE_V4T)
39 #define ENABLE_ARCH_5 arm_feature(env, ARM_FEATURE_V5)
40 /* currently all emulated v5 cores are also v5TE, so don't bother */
41 #define ENABLE_ARCH_5TE arm_feature(env, ARM_FEATURE_V5)
42 #define ENABLE_ARCH_5J 0
43 #define ENABLE_ARCH_6 arm_feature(env, ARM_FEATURE_V6)
44 #define ENABLE_ARCH_6K arm_feature(env, ARM_FEATURE_V6K)
45 #define ENABLE_ARCH_6T2 arm_feature(env, ARM_FEATURE_THUMB2)
46 #define ENABLE_ARCH_7 arm_feature(env, ARM_FEATURE_V7)
47 #define ENABLE_ARCH_8 arm_feature(env, ARM_FEATURE_V8)
49 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
51 #include "translate.h"
52 static uint32_t gen_opc_condexec_bits
[OPC_BUF_SIZE
];
54 #if defined(CONFIG_USER_ONLY)
57 #define IS_USER(s) (s->user)
61 /* We reuse the same 64-bit temporaries for efficiency. */
62 static TCGv_i64 cpu_V0
, cpu_V1
, cpu_M0
;
63 static TCGv_i32 cpu_R
[16];
64 static TCGv_i32 cpu_CF
, cpu_NF
, cpu_VF
, cpu_ZF
;
65 static TCGv_i64 cpu_exclusive_addr
;
66 static TCGv_i64 cpu_exclusive_val
;
67 #ifdef CONFIG_USER_ONLY
68 static TCGv_i64 cpu_exclusive_test
;
69 static TCGv_i32 cpu_exclusive_info
;
72 /* FIXME: These should be removed. */
73 static TCGv_i32 cpu_F0s
, cpu_F1s
;
74 static TCGv_i64 cpu_F0d
, cpu_F1d
;
76 #include "exec/gen-icount.h"
78 static const char *regnames
[] =
79 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
80 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
82 /* initialize TCG globals. */
83 void arm_translate_init(void)
87 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
89 for (i
= 0; i
< 16; i
++) {
90 cpu_R
[i
] = tcg_global_mem_new_i32(TCG_AREG0
,
91 offsetof(CPUARMState
, regs
[i
]),
94 cpu_CF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, CF
), "CF");
95 cpu_NF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, NF
), "NF");
96 cpu_VF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, VF
), "VF");
97 cpu_ZF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, ZF
), "ZF");
99 cpu_exclusive_addr
= tcg_global_mem_new_i64(TCG_AREG0
,
100 offsetof(CPUARMState
, exclusive_addr
), "exclusive_addr");
101 cpu_exclusive_val
= tcg_global_mem_new_i64(TCG_AREG0
,
102 offsetof(CPUARMState
, exclusive_val
), "exclusive_val");
103 #ifdef CONFIG_USER_ONLY
104 cpu_exclusive_test
= tcg_global_mem_new_i64(TCG_AREG0
,
105 offsetof(CPUARMState
, exclusive_test
), "exclusive_test");
106 cpu_exclusive_info
= tcg_global_mem_new_i32(TCG_AREG0
,
107 offsetof(CPUARMState
, exclusive_info
), "exclusive_info");
110 a64_translate_init();
113 static inline TCGv_i32
load_cpu_offset(int offset
)
115 TCGv_i32 tmp
= tcg_temp_new_i32();
116 tcg_gen_ld_i32(tmp
, cpu_env
, offset
);
120 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
122 static inline void store_cpu_offset(TCGv_i32 var
, int offset
)
124 tcg_gen_st_i32(var
, cpu_env
, offset
);
125 tcg_temp_free_i32(var
);
128 #define store_cpu_field(var, name) \
129 store_cpu_offset(var, offsetof(CPUARMState, name))
131 /* Set a variable to the value of a CPU register. */
132 static void load_reg_var(DisasContext
*s
, TCGv_i32 var
, int reg
)
136 /* normally, since we updated PC, we need only to add one insn */
138 addr
= (long)s
->pc
+ 2;
140 addr
= (long)s
->pc
+ 4;
141 tcg_gen_movi_i32(var
, addr
);
143 tcg_gen_mov_i32(var
, cpu_R
[reg
]);
147 /* Create a new temporary and set it to the value of a CPU register. */
148 static inline TCGv_i32
load_reg(DisasContext
*s
, int reg
)
150 TCGv_i32 tmp
= tcg_temp_new_i32();
151 load_reg_var(s
, tmp
, reg
);
155 /* Set a CPU register. The source must be a temporary and will be
157 static void store_reg(DisasContext
*s
, int reg
, TCGv_i32 var
)
160 tcg_gen_andi_i32(var
, var
, ~1);
161 s
->is_jmp
= DISAS_JUMP
;
163 tcg_gen_mov_i32(cpu_R
[reg
], var
);
164 tcg_temp_free_i32(var
);
167 /* Value extensions. */
168 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
169 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
170 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
171 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
173 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
174 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
177 static inline void gen_set_cpsr(TCGv_i32 var
, uint32_t mask
)
179 TCGv_i32 tmp_mask
= tcg_const_i32(mask
);
180 gen_helper_cpsr_write(cpu_env
, var
, tmp_mask
);
181 tcg_temp_free_i32(tmp_mask
);
183 /* Set NZCV flags from the high 4 bits of var. */
184 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
186 static void gen_exception_internal(int excp
)
188 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
190 assert(excp_is_internal(excp
));
191 gen_helper_exception_internal(cpu_env
, tcg_excp
);
192 tcg_temp_free_i32(tcg_excp
);
195 static void gen_exception(int excp
, uint32_t syndrome
)
197 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
198 TCGv_i32 tcg_syn
= tcg_const_i32(syndrome
);
200 gen_helper_exception_with_syndrome(cpu_env
, tcg_excp
, tcg_syn
);
201 tcg_temp_free_i32(tcg_syn
);
202 tcg_temp_free_i32(tcg_excp
);
205 static void gen_smul_dual(TCGv_i32 a
, TCGv_i32 b
)
207 TCGv_i32 tmp1
= tcg_temp_new_i32();
208 TCGv_i32 tmp2
= tcg_temp_new_i32();
209 tcg_gen_ext16s_i32(tmp1
, a
);
210 tcg_gen_ext16s_i32(tmp2
, b
);
211 tcg_gen_mul_i32(tmp1
, tmp1
, tmp2
);
212 tcg_temp_free_i32(tmp2
);
213 tcg_gen_sari_i32(a
, a
, 16);
214 tcg_gen_sari_i32(b
, b
, 16);
215 tcg_gen_mul_i32(b
, b
, a
);
216 tcg_gen_mov_i32(a
, tmp1
);
217 tcg_temp_free_i32(tmp1
);
220 /* Byteswap each halfword. */
221 static void gen_rev16(TCGv_i32 var
)
223 TCGv_i32 tmp
= tcg_temp_new_i32();
224 tcg_gen_shri_i32(tmp
, var
, 8);
225 tcg_gen_andi_i32(tmp
, tmp
, 0x00ff00ff);
226 tcg_gen_shli_i32(var
, var
, 8);
227 tcg_gen_andi_i32(var
, var
, 0xff00ff00);
228 tcg_gen_or_i32(var
, var
, tmp
);
229 tcg_temp_free_i32(tmp
);
232 /* Byteswap low halfword and sign extend. */
233 static void gen_revsh(TCGv_i32 var
)
235 tcg_gen_ext16u_i32(var
, var
);
236 tcg_gen_bswap16_i32(var
, var
);
237 tcg_gen_ext16s_i32(var
, var
);
240 /* Unsigned bitfield extract. */
241 static void gen_ubfx(TCGv_i32 var
, int shift
, uint32_t mask
)
244 tcg_gen_shri_i32(var
, var
, shift
);
245 tcg_gen_andi_i32(var
, var
, mask
);
248 /* Signed bitfield extract. */
249 static void gen_sbfx(TCGv_i32 var
, int shift
, int width
)
254 tcg_gen_sari_i32(var
, var
, shift
);
255 if (shift
+ width
< 32) {
256 signbit
= 1u << (width
- 1);
257 tcg_gen_andi_i32(var
, var
, (1u << width
) - 1);
258 tcg_gen_xori_i32(var
, var
, signbit
);
259 tcg_gen_subi_i32(var
, var
, signbit
);
263 /* Return (b << 32) + a. Mark inputs as dead */
264 static TCGv_i64
gen_addq_msw(TCGv_i64 a
, TCGv_i32 b
)
266 TCGv_i64 tmp64
= tcg_temp_new_i64();
268 tcg_gen_extu_i32_i64(tmp64
, b
);
269 tcg_temp_free_i32(b
);
270 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
271 tcg_gen_add_i64(a
, tmp64
, a
);
273 tcg_temp_free_i64(tmp64
);
277 /* Return (b << 32) - a. Mark inputs as dead. */
278 static TCGv_i64
gen_subq_msw(TCGv_i64 a
, TCGv_i32 b
)
280 TCGv_i64 tmp64
= tcg_temp_new_i64();
282 tcg_gen_extu_i32_i64(tmp64
, b
);
283 tcg_temp_free_i32(b
);
284 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
285 tcg_gen_sub_i64(a
, tmp64
, a
);
287 tcg_temp_free_i64(tmp64
);
291 /* 32x32->64 multiply. Marks inputs as dead. */
292 static TCGv_i64
gen_mulu_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
294 TCGv_i32 lo
= tcg_temp_new_i32();
295 TCGv_i32 hi
= tcg_temp_new_i32();
298 tcg_gen_mulu2_i32(lo
, hi
, a
, b
);
299 tcg_temp_free_i32(a
);
300 tcg_temp_free_i32(b
);
302 ret
= tcg_temp_new_i64();
303 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
304 tcg_temp_free_i32(lo
);
305 tcg_temp_free_i32(hi
);
310 static TCGv_i64
gen_muls_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
312 TCGv_i32 lo
= tcg_temp_new_i32();
313 TCGv_i32 hi
= tcg_temp_new_i32();
316 tcg_gen_muls2_i32(lo
, hi
, a
, b
);
317 tcg_temp_free_i32(a
);
318 tcg_temp_free_i32(b
);
320 ret
= tcg_temp_new_i64();
321 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
322 tcg_temp_free_i32(lo
);
323 tcg_temp_free_i32(hi
);
328 /* Swap low and high halfwords. */
329 static void gen_swap_half(TCGv_i32 var
)
331 TCGv_i32 tmp
= tcg_temp_new_i32();
332 tcg_gen_shri_i32(tmp
, var
, 16);
333 tcg_gen_shli_i32(var
, var
, 16);
334 tcg_gen_or_i32(var
, var
, tmp
);
335 tcg_temp_free_i32(tmp
);
338 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
339 tmp = (t0 ^ t1) & 0x8000;
342 t0 = (t0 + t1) ^ tmp;
345 static void gen_add16(TCGv_i32 t0
, TCGv_i32 t1
)
347 TCGv_i32 tmp
= tcg_temp_new_i32();
348 tcg_gen_xor_i32(tmp
, t0
, t1
);
349 tcg_gen_andi_i32(tmp
, tmp
, 0x8000);
350 tcg_gen_andi_i32(t0
, t0
, ~0x8000);
351 tcg_gen_andi_i32(t1
, t1
, ~0x8000);
352 tcg_gen_add_i32(t0
, t0
, t1
);
353 tcg_gen_xor_i32(t0
, t0
, tmp
);
354 tcg_temp_free_i32(tmp
);
355 tcg_temp_free_i32(t1
);
358 /* Set CF to the top bit of var. */
359 static void gen_set_CF_bit31(TCGv_i32 var
)
361 tcg_gen_shri_i32(cpu_CF
, var
, 31);
364 /* Set N and Z flags from var. */
365 static inline void gen_logic_CC(TCGv_i32 var
)
367 tcg_gen_mov_i32(cpu_NF
, var
);
368 tcg_gen_mov_i32(cpu_ZF
, var
);
372 static void gen_adc(TCGv_i32 t0
, TCGv_i32 t1
)
374 tcg_gen_add_i32(t0
, t0
, t1
);
375 tcg_gen_add_i32(t0
, t0
, cpu_CF
);
378 /* dest = T0 + T1 + CF. */
379 static void gen_add_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
381 tcg_gen_add_i32(dest
, t0
, t1
);
382 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
385 /* dest = T0 - T1 + CF - 1. */
386 static void gen_sub_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
388 tcg_gen_sub_i32(dest
, t0
, t1
);
389 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
390 tcg_gen_subi_i32(dest
, dest
, 1);
393 /* dest = T0 + T1. Compute C, N, V and Z flags */
394 static void gen_add_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
396 TCGv_i32 tmp
= tcg_temp_new_i32();
397 tcg_gen_movi_i32(tmp
, 0);
398 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, t1
, tmp
);
399 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
400 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
401 tcg_gen_xor_i32(tmp
, t0
, t1
);
402 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
403 tcg_temp_free_i32(tmp
);
404 tcg_gen_mov_i32(dest
, cpu_NF
);
407 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
408 static void gen_adc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
410 TCGv_i32 tmp
= tcg_temp_new_i32();
411 if (TCG_TARGET_HAS_add2_i32
) {
412 tcg_gen_movi_i32(tmp
, 0);
413 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, cpu_CF
, tmp
);
414 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, cpu_NF
, cpu_CF
, t1
, tmp
);
416 TCGv_i64 q0
= tcg_temp_new_i64();
417 TCGv_i64 q1
= tcg_temp_new_i64();
418 tcg_gen_extu_i32_i64(q0
, t0
);
419 tcg_gen_extu_i32_i64(q1
, t1
);
420 tcg_gen_add_i64(q0
, q0
, q1
);
421 tcg_gen_extu_i32_i64(q1
, cpu_CF
);
422 tcg_gen_add_i64(q0
, q0
, q1
);
423 tcg_gen_extr_i64_i32(cpu_NF
, cpu_CF
, q0
);
424 tcg_temp_free_i64(q0
);
425 tcg_temp_free_i64(q1
);
427 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
428 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
429 tcg_gen_xor_i32(tmp
, t0
, t1
);
430 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
431 tcg_temp_free_i32(tmp
);
432 tcg_gen_mov_i32(dest
, cpu_NF
);
435 /* dest = T0 - T1. Compute C, N, V and Z flags */
436 static void gen_sub_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
439 tcg_gen_sub_i32(cpu_NF
, t0
, t1
);
440 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
441 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_CF
, t0
, t1
);
442 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
443 tmp
= tcg_temp_new_i32();
444 tcg_gen_xor_i32(tmp
, t0
, t1
);
445 tcg_gen_and_i32(cpu_VF
, cpu_VF
, tmp
);
446 tcg_temp_free_i32(tmp
);
447 tcg_gen_mov_i32(dest
, cpu_NF
);
450 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
451 static void gen_sbc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
453 TCGv_i32 tmp
= tcg_temp_new_i32();
454 tcg_gen_not_i32(tmp
, t1
);
455 gen_adc_CC(dest
, t0
, tmp
);
456 tcg_temp_free_i32(tmp
);
459 #define GEN_SHIFT(name) \
460 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
462 TCGv_i32 tmp1, tmp2, tmp3; \
463 tmp1 = tcg_temp_new_i32(); \
464 tcg_gen_andi_i32(tmp1, t1, 0xff); \
465 tmp2 = tcg_const_i32(0); \
466 tmp3 = tcg_const_i32(0x1f); \
467 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
468 tcg_temp_free_i32(tmp3); \
469 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
470 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
471 tcg_temp_free_i32(tmp2); \
472 tcg_temp_free_i32(tmp1); \
478 static void gen_sar(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
481 tmp1
= tcg_temp_new_i32();
482 tcg_gen_andi_i32(tmp1
, t1
, 0xff);
483 tmp2
= tcg_const_i32(0x1f);
484 tcg_gen_movcond_i32(TCG_COND_GTU
, tmp1
, tmp1
, tmp2
, tmp2
, tmp1
);
485 tcg_temp_free_i32(tmp2
);
486 tcg_gen_sar_i32(dest
, t0
, tmp1
);
487 tcg_temp_free_i32(tmp1
);
490 static void tcg_gen_abs_i32(TCGv_i32 dest
, TCGv_i32 src
)
492 TCGv_i32 c0
= tcg_const_i32(0);
493 TCGv_i32 tmp
= tcg_temp_new_i32();
494 tcg_gen_neg_i32(tmp
, src
);
495 tcg_gen_movcond_i32(TCG_COND_GT
, dest
, src
, c0
, src
, tmp
);
496 tcg_temp_free_i32(c0
);
497 tcg_temp_free_i32(tmp
);
500 static void shifter_out_im(TCGv_i32 var
, int shift
)
503 tcg_gen_andi_i32(cpu_CF
, var
, 1);
505 tcg_gen_shri_i32(cpu_CF
, var
, shift
);
507 tcg_gen_andi_i32(cpu_CF
, cpu_CF
, 1);
512 /* Shift by immediate. Includes special handling for shift == 0. */
513 static inline void gen_arm_shift_im(TCGv_i32 var
, int shiftop
,
514 int shift
, int flags
)
520 shifter_out_im(var
, 32 - shift
);
521 tcg_gen_shli_i32(var
, var
, shift
);
527 tcg_gen_shri_i32(cpu_CF
, var
, 31);
529 tcg_gen_movi_i32(var
, 0);
532 shifter_out_im(var
, shift
- 1);
533 tcg_gen_shri_i32(var
, var
, shift
);
540 shifter_out_im(var
, shift
- 1);
543 tcg_gen_sari_i32(var
, var
, shift
);
545 case 3: /* ROR/RRX */
548 shifter_out_im(var
, shift
- 1);
549 tcg_gen_rotri_i32(var
, var
, shift
); break;
551 TCGv_i32 tmp
= tcg_temp_new_i32();
552 tcg_gen_shli_i32(tmp
, cpu_CF
, 31);
554 shifter_out_im(var
, 0);
555 tcg_gen_shri_i32(var
, var
, 1);
556 tcg_gen_or_i32(var
, var
, tmp
);
557 tcg_temp_free_i32(tmp
);
562 static inline void gen_arm_shift_reg(TCGv_i32 var
, int shiftop
,
563 TCGv_i32 shift
, int flags
)
567 case 0: gen_helper_shl_cc(var
, cpu_env
, var
, shift
); break;
568 case 1: gen_helper_shr_cc(var
, cpu_env
, var
, shift
); break;
569 case 2: gen_helper_sar_cc(var
, cpu_env
, var
, shift
); break;
570 case 3: gen_helper_ror_cc(var
, cpu_env
, var
, shift
); break;
575 gen_shl(var
, var
, shift
);
578 gen_shr(var
, var
, shift
);
581 gen_sar(var
, var
, shift
);
583 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
584 tcg_gen_rotr_i32(var
, var
, shift
); break;
587 tcg_temp_free_i32(shift
);
590 #define PAS_OP(pfx) \
592 case 0: gen_pas_helper(glue(pfx,add16)); break; \
593 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
594 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
595 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
596 case 4: gen_pas_helper(glue(pfx,add8)); break; \
597 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
599 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
604 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
606 tmp
= tcg_temp_new_ptr();
607 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
609 tcg_temp_free_ptr(tmp
);
612 tmp
= tcg_temp_new_ptr();
613 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
615 tcg_temp_free_ptr(tmp
);
617 #undef gen_pas_helper
618 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
631 #undef gen_pas_helper
636 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
637 #define PAS_OP(pfx) \
639 case 0: gen_pas_helper(glue(pfx,add8)); break; \
640 case 1: gen_pas_helper(glue(pfx,add16)); break; \
641 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
642 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
643 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
644 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
646 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
651 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
653 tmp
= tcg_temp_new_ptr();
654 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
656 tcg_temp_free_ptr(tmp
);
659 tmp
= tcg_temp_new_ptr();
660 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
662 tcg_temp_free_ptr(tmp
);
664 #undef gen_pas_helper
665 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
678 #undef gen_pas_helper
684 * generate a conditional branch based on ARM condition code cc.
685 * This is common between ARM and Aarch64 targets.
687 void arm_gen_test_cc(int cc
, int label
)
694 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
697 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_ZF
, 0, label
);
700 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_CF
, 0, label
);
703 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, label
);
706 tcg_gen_brcondi_i32(TCG_COND_LT
, cpu_NF
, 0, label
);
709 tcg_gen_brcondi_i32(TCG_COND_GE
, cpu_NF
, 0, label
);
712 tcg_gen_brcondi_i32(TCG_COND_LT
, cpu_VF
, 0, label
);
715 tcg_gen_brcondi_i32(TCG_COND_GE
, cpu_VF
, 0, label
);
717 case 8: /* hi: C && !Z */
718 inv
= gen_new_label();
719 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, inv
);
720 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_ZF
, 0, label
);
723 case 9: /* ls: !C || Z */
724 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, label
);
725 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
727 case 10: /* ge: N == V -> N ^ V == 0 */
728 tmp
= tcg_temp_new_i32();
729 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
730 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
731 tcg_temp_free_i32(tmp
);
733 case 11: /* lt: N != V -> N ^ V != 0 */
734 tmp
= tcg_temp_new_i32();
735 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
736 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
737 tcg_temp_free_i32(tmp
);
739 case 12: /* gt: !Z && N == V */
740 inv
= gen_new_label();
741 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, inv
);
742 tmp
= tcg_temp_new_i32();
743 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
744 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
745 tcg_temp_free_i32(tmp
);
748 case 13: /* le: Z || N != V */
749 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
750 tmp
= tcg_temp_new_i32();
751 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
752 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
753 tcg_temp_free_i32(tmp
);
756 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
761 static const uint8_t table_logic_cc
[16] = {
780 /* Set PC and Thumb state from an immediate address. */
781 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
785 s
->is_jmp
= DISAS_UPDATE
;
786 if (s
->thumb
!= (addr
& 1)) {
787 tmp
= tcg_temp_new_i32();
788 tcg_gen_movi_i32(tmp
, addr
& 1);
789 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUARMState
, thumb
));
790 tcg_temp_free_i32(tmp
);
792 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
795 /* Set PC and Thumb state from var. var is marked as dead. */
796 static inline void gen_bx(DisasContext
*s
, TCGv_i32 var
)
798 s
->is_jmp
= DISAS_UPDATE
;
799 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
800 tcg_gen_andi_i32(var
, var
, 1);
801 store_cpu_field(var
, thumb
);
804 /* Variant of store_reg which uses branch&exchange logic when storing
805 to r15 in ARM architecture v7 and above. The source must be a temporary
806 and will be marked as dead. */
807 static inline void store_reg_bx(CPUARMState
*env
, DisasContext
*s
,
808 int reg
, TCGv_i32 var
)
810 if (reg
== 15 && ENABLE_ARCH_7
) {
813 store_reg(s
, reg
, var
);
817 /* Variant of store_reg which uses branch&exchange logic when storing
818 * to r15 in ARM architecture v5T and above. This is used for storing
819 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
820 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
821 static inline void store_reg_from_load(CPUARMState
*env
, DisasContext
*s
,
822 int reg
, TCGv_i32 var
)
824 if (reg
== 15 && ENABLE_ARCH_5
) {
827 store_reg(s
, reg
, var
);
831 /* Abstractions of "generate code to do a guest load/store for
832 * AArch32", where a vaddr is always 32 bits (and is zero
833 * extended if we're a 64 bit core) and data is also
834 * 32 bits unless specifically doing a 64 bit access.
835 * These functions work like tcg_gen_qemu_{ld,st}* except
836 * that the address argument is TCGv_i32 rather than TCGv.
838 #if TARGET_LONG_BITS == 32
840 #define DO_GEN_LD(SUFF, OPC) \
841 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
843 tcg_gen_qemu_ld_i32(val, addr, index, OPC); \
846 #define DO_GEN_ST(SUFF, OPC) \
847 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
849 tcg_gen_qemu_st_i32(val, addr, index, OPC); \
852 static inline void gen_aa32_ld64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
854 tcg_gen_qemu_ld_i64(val
, addr
, index
, MO_TEQ
);
857 static inline void gen_aa32_st64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
859 tcg_gen_qemu_st_i64(val
, addr
, index
, MO_TEQ
);
864 #define DO_GEN_LD(SUFF, OPC) \
865 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
867 TCGv addr64 = tcg_temp_new(); \
868 tcg_gen_extu_i32_i64(addr64, addr); \
869 tcg_gen_qemu_ld_i32(val, addr64, index, OPC); \
870 tcg_temp_free(addr64); \
873 #define DO_GEN_ST(SUFF, OPC) \
874 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
876 TCGv addr64 = tcg_temp_new(); \
877 tcg_gen_extu_i32_i64(addr64, addr); \
878 tcg_gen_qemu_st_i32(val, addr64, index, OPC); \
879 tcg_temp_free(addr64); \
882 static inline void gen_aa32_ld64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
884 TCGv addr64
= tcg_temp_new();
885 tcg_gen_extu_i32_i64(addr64
, addr
);
886 tcg_gen_qemu_ld_i64(val
, addr64
, index
, MO_TEQ
);
887 tcg_temp_free(addr64
);
890 static inline void gen_aa32_st64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
892 TCGv addr64
= tcg_temp_new();
893 tcg_gen_extu_i32_i64(addr64
, addr
);
894 tcg_gen_qemu_st_i64(val
, addr64
, index
, MO_TEQ
);
895 tcg_temp_free(addr64
);
902 DO_GEN_LD(16s
, MO_TESW
)
903 DO_GEN_LD(16u, MO_TEUW
)
904 DO_GEN_LD(32u, MO_TEUL
)
906 DO_GEN_ST(16, MO_TEUW
)
907 DO_GEN_ST(32, MO_TEUL
)
909 static inline void gen_set_pc_im(DisasContext
*s
, target_ulong val
)
911 tcg_gen_movi_i32(cpu_R
[15], val
);
915 gen_set_condexec (DisasContext
*s
)
917 if (s
->condexec_mask
) {
918 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
919 TCGv_i32 tmp
= tcg_temp_new_i32();
920 tcg_gen_movi_i32(tmp
, val
);
921 store_cpu_field(tmp
, condexec_bits
);
925 static void gen_exception_internal_insn(DisasContext
*s
, int offset
, int excp
)
928 gen_set_pc_im(s
, s
->pc
- offset
);
929 gen_exception_internal(excp
);
930 s
->is_jmp
= DISAS_JUMP
;
933 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
, int syn
)
936 gen_set_pc_im(s
, s
->pc
- offset
);
937 gen_exception(excp
, syn
);
938 s
->is_jmp
= DISAS_JUMP
;
941 /* Force a TB lookup after an instruction that changes the CPU state. */
942 static inline void gen_lookup_tb(DisasContext
*s
)
944 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
945 s
->is_jmp
= DISAS_UPDATE
;
948 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
951 int val
, rm
, shift
, shiftop
;
954 if (!(insn
& (1 << 25))) {
957 if (!(insn
& (1 << 23)))
960 tcg_gen_addi_i32(var
, var
, val
);
964 shift
= (insn
>> 7) & 0x1f;
965 shiftop
= (insn
>> 5) & 3;
966 offset
= load_reg(s
, rm
);
967 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
968 if (!(insn
& (1 << 23)))
969 tcg_gen_sub_i32(var
, var
, offset
);
971 tcg_gen_add_i32(var
, var
, offset
);
972 tcg_temp_free_i32(offset
);
976 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
977 int extra
, TCGv_i32 var
)
982 if (insn
& (1 << 22)) {
984 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
985 if (!(insn
& (1 << 23)))
989 tcg_gen_addi_i32(var
, var
, val
);
993 tcg_gen_addi_i32(var
, var
, extra
);
995 offset
= load_reg(s
, rm
);
996 if (!(insn
& (1 << 23)))
997 tcg_gen_sub_i32(var
, var
, offset
);
999 tcg_gen_add_i32(var
, var
, offset
);
1000 tcg_temp_free_i32(offset
);
1004 static TCGv_ptr
get_fpstatus_ptr(int neon
)
1006 TCGv_ptr statusptr
= tcg_temp_new_ptr();
1009 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
1011 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
1013 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
1017 #define VFP_OP2(name) \
1018 static inline void gen_vfp_##name(int dp) \
1020 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1022 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1024 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1026 tcg_temp_free_ptr(fpst); \
1036 static inline void gen_vfp_F1_mul(int dp
)
1038 /* Like gen_vfp_mul() but put result in F1 */
1039 TCGv_ptr fpst
= get_fpstatus_ptr(0);
1041 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
1043 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
1045 tcg_temp_free_ptr(fpst
);
1048 static inline void gen_vfp_F1_neg(int dp
)
1050 /* Like gen_vfp_neg() but put result in F1 */
1052 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
1054 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
1058 static inline void gen_vfp_abs(int dp
)
1061 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
1063 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
1066 static inline void gen_vfp_neg(int dp
)
1069 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
1071 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
1074 static inline void gen_vfp_sqrt(int dp
)
1077 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
1079 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
1082 static inline void gen_vfp_cmp(int dp
)
1085 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
1087 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
1090 static inline void gen_vfp_cmpe(int dp
)
1093 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
1095 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
1098 static inline void gen_vfp_F1_ld0(int dp
)
1101 tcg_gen_movi_i64(cpu_F1d
, 0);
1103 tcg_gen_movi_i32(cpu_F1s
, 0);
1106 #define VFP_GEN_ITOF(name) \
1107 static inline void gen_vfp_##name(int dp, int neon) \
1109 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1111 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1113 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1115 tcg_temp_free_ptr(statusptr); \
1122 #define VFP_GEN_FTOI(name) \
1123 static inline void gen_vfp_##name(int dp, int neon) \
1125 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1127 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1129 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1131 tcg_temp_free_ptr(statusptr); \
1140 #define VFP_GEN_FIX(name, round) \
1141 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1143 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1144 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1146 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1149 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1152 tcg_temp_free_i32(tmp_shift); \
1153 tcg_temp_free_ptr(statusptr); \
1155 VFP_GEN_FIX(tosh
, _round_to_zero
)
1156 VFP_GEN_FIX(tosl
, _round_to_zero
)
1157 VFP_GEN_FIX(touh
, _round_to_zero
)
1158 VFP_GEN_FIX(toul
, _round_to_zero
)
1165 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1168 gen_aa32_ld64(cpu_F0d
, addr
, get_mem_index(s
));
1170 gen_aa32_ld32u(cpu_F0s
, addr
, get_mem_index(s
));
1174 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1177 gen_aa32_st64(cpu_F0d
, addr
, get_mem_index(s
));
1179 gen_aa32_st32(cpu_F0s
, addr
, get_mem_index(s
));
1184 vfp_reg_offset (int dp
, int reg
)
1187 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1189 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1190 + offsetof(CPU_DoubleU
, l
.upper
);
1192 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1193 + offsetof(CPU_DoubleU
, l
.lower
);
1197 /* Return the offset of a 32-bit piece of a NEON register.
1198 zero is the least significant end of the register. */
1200 neon_reg_offset (int reg
, int n
)
1204 return vfp_reg_offset(0, sreg
);
1207 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1209 TCGv_i32 tmp
= tcg_temp_new_i32();
1210 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1214 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1216 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1217 tcg_temp_free_i32(var
);
1220 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1222 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1225 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1227 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1230 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1231 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1232 #define tcg_gen_st_f32 tcg_gen_st_i32
1233 #define tcg_gen_st_f64 tcg_gen_st_i64
1235 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1238 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1240 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1243 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1246 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1248 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1251 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1254 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1256 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1259 #define ARM_CP_RW_BIT (1 << 20)
1261 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1263 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1266 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1268 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1271 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1273 TCGv_i32 var
= tcg_temp_new_i32();
1274 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1278 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1280 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1281 tcg_temp_free_i32(var
);
1284 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1286 iwmmxt_store_reg(cpu_M0
, rn
);
1289 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1291 iwmmxt_load_reg(cpu_M0
, rn
);
1294 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1296 iwmmxt_load_reg(cpu_V1
, rn
);
1297 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1300 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1302 iwmmxt_load_reg(cpu_V1
, rn
);
1303 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1306 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1308 iwmmxt_load_reg(cpu_V1
, rn
);
1309 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1312 #define IWMMXT_OP(name) \
1313 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1315 iwmmxt_load_reg(cpu_V1, rn); \
1316 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1319 #define IWMMXT_OP_ENV(name) \
1320 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1322 iwmmxt_load_reg(cpu_V1, rn); \
1323 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1326 #define IWMMXT_OP_ENV_SIZE(name) \
1327 IWMMXT_OP_ENV(name##b) \
1328 IWMMXT_OP_ENV(name##w) \
1329 IWMMXT_OP_ENV(name##l)
1331 #define IWMMXT_OP_ENV1(name) \
1332 static inline void gen_op_iwmmxt_##name##_M0(void) \
1334 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1348 IWMMXT_OP_ENV_SIZE(unpackl
)
1349 IWMMXT_OP_ENV_SIZE(unpackh
)
1351 IWMMXT_OP_ENV1(unpacklub
)
1352 IWMMXT_OP_ENV1(unpackluw
)
1353 IWMMXT_OP_ENV1(unpacklul
)
1354 IWMMXT_OP_ENV1(unpackhub
)
1355 IWMMXT_OP_ENV1(unpackhuw
)
1356 IWMMXT_OP_ENV1(unpackhul
)
1357 IWMMXT_OP_ENV1(unpacklsb
)
1358 IWMMXT_OP_ENV1(unpacklsw
)
1359 IWMMXT_OP_ENV1(unpacklsl
)
1360 IWMMXT_OP_ENV1(unpackhsb
)
1361 IWMMXT_OP_ENV1(unpackhsw
)
1362 IWMMXT_OP_ENV1(unpackhsl
)
1364 IWMMXT_OP_ENV_SIZE(cmpeq
)
1365 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1366 IWMMXT_OP_ENV_SIZE(cmpgts
)
1368 IWMMXT_OP_ENV_SIZE(mins
)
1369 IWMMXT_OP_ENV_SIZE(minu
)
1370 IWMMXT_OP_ENV_SIZE(maxs
)
1371 IWMMXT_OP_ENV_SIZE(maxu
)
1373 IWMMXT_OP_ENV_SIZE(subn
)
1374 IWMMXT_OP_ENV_SIZE(addn
)
1375 IWMMXT_OP_ENV_SIZE(subu
)
1376 IWMMXT_OP_ENV_SIZE(addu
)
1377 IWMMXT_OP_ENV_SIZE(subs
)
1378 IWMMXT_OP_ENV_SIZE(adds
)
1380 IWMMXT_OP_ENV(avgb0
)
1381 IWMMXT_OP_ENV(avgb1
)
1382 IWMMXT_OP_ENV(avgw0
)
1383 IWMMXT_OP_ENV(avgw1
)
1387 IWMMXT_OP_ENV(packuw
)
1388 IWMMXT_OP_ENV(packul
)
1389 IWMMXT_OP_ENV(packuq
)
1390 IWMMXT_OP_ENV(packsw
)
1391 IWMMXT_OP_ENV(packsl
)
1392 IWMMXT_OP_ENV(packsq
)
1394 static void gen_op_iwmmxt_set_mup(void)
1397 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1398 tcg_gen_ori_i32(tmp
, tmp
, 2);
1399 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1402 static void gen_op_iwmmxt_set_cup(void)
1405 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1406 tcg_gen_ori_i32(tmp
, tmp
, 1);
1407 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1410 static void gen_op_iwmmxt_setpsr_nz(void)
1412 TCGv_i32 tmp
= tcg_temp_new_i32();
1413 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1414 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1417 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1419 iwmmxt_load_reg(cpu_V1
, rn
);
1420 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1421 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1424 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1431 rd
= (insn
>> 16) & 0xf;
1432 tmp
= load_reg(s
, rd
);
1434 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1435 if (insn
& (1 << 24)) {
1437 if (insn
& (1 << 23))
1438 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1440 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1441 tcg_gen_mov_i32(dest
, tmp
);
1442 if (insn
& (1 << 21))
1443 store_reg(s
, rd
, tmp
);
1445 tcg_temp_free_i32(tmp
);
1446 } else if (insn
& (1 << 21)) {
1448 tcg_gen_mov_i32(dest
, tmp
);
1449 if (insn
& (1 << 23))
1450 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1452 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1453 store_reg(s
, rd
, tmp
);
1454 } else if (!(insn
& (1 << 23)))
1459 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1461 int rd
= (insn
>> 0) & 0xf;
1464 if (insn
& (1 << 8)) {
1465 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1468 tmp
= iwmmxt_load_creg(rd
);
1471 tmp
= tcg_temp_new_i32();
1472 iwmmxt_load_reg(cpu_V0
, rd
);
1473 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
1475 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1476 tcg_gen_mov_i32(dest
, tmp
);
1477 tcg_temp_free_i32(tmp
);
1481 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1482 (ie. an undefined instruction). */
1483 static int disas_iwmmxt_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
1486 int rdhi
, rdlo
, rd0
, rd1
, i
;
1488 TCGv_i32 tmp
, tmp2
, tmp3
;
1490 if ((insn
& 0x0e000e00) == 0x0c000000) {
1491 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1493 rdlo
= (insn
>> 12) & 0xf;
1494 rdhi
= (insn
>> 16) & 0xf;
1495 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1496 iwmmxt_load_reg(cpu_V0
, wrd
);
1497 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1498 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1499 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1500 } else { /* TMCRR */
1501 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1502 iwmmxt_store_reg(cpu_V0
, wrd
);
1503 gen_op_iwmmxt_set_mup();
1508 wrd
= (insn
>> 12) & 0xf;
1509 addr
= tcg_temp_new_i32();
1510 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1511 tcg_temp_free_i32(addr
);
1514 if (insn
& ARM_CP_RW_BIT
) {
1515 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1516 tmp
= tcg_temp_new_i32();
1517 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
1518 iwmmxt_store_creg(wrd
, tmp
);
1521 if (insn
& (1 << 8)) {
1522 if (insn
& (1 << 22)) { /* WLDRD */
1523 gen_aa32_ld64(cpu_M0
, addr
, get_mem_index(s
));
1525 } else { /* WLDRW wRd */
1526 tmp
= tcg_temp_new_i32();
1527 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
1530 tmp
= tcg_temp_new_i32();
1531 if (insn
& (1 << 22)) { /* WLDRH */
1532 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
1533 } else { /* WLDRB */
1534 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
1538 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1539 tcg_temp_free_i32(tmp
);
1541 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1544 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1545 tmp
= iwmmxt_load_creg(wrd
);
1546 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
1548 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1549 tmp
= tcg_temp_new_i32();
1550 if (insn
& (1 << 8)) {
1551 if (insn
& (1 << 22)) { /* WSTRD */
1552 gen_aa32_st64(cpu_M0
, addr
, get_mem_index(s
));
1553 } else { /* WSTRW wRd */
1554 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1555 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
1558 if (insn
& (1 << 22)) { /* WSTRH */
1559 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1560 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
1561 } else { /* WSTRB */
1562 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1563 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
1567 tcg_temp_free_i32(tmp
);
1569 tcg_temp_free_i32(addr
);
1573 if ((insn
& 0x0f000000) != 0x0e000000)
1576 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1577 case 0x000: /* WOR */
1578 wrd
= (insn
>> 12) & 0xf;
1579 rd0
= (insn
>> 0) & 0xf;
1580 rd1
= (insn
>> 16) & 0xf;
1581 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1582 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1583 gen_op_iwmmxt_setpsr_nz();
1584 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1585 gen_op_iwmmxt_set_mup();
1586 gen_op_iwmmxt_set_cup();
1588 case 0x011: /* TMCR */
1591 rd
= (insn
>> 12) & 0xf;
1592 wrd
= (insn
>> 16) & 0xf;
1594 case ARM_IWMMXT_wCID
:
1595 case ARM_IWMMXT_wCASF
:
1597 case ARM_IWMMXT_wCon
:
1598 gen_op_iwmmxt_set_cup();
1600 case ARM_IWMMXT_wCSSF
:
1601 tmp
= iwmmxt_load_creg(wrd
);
1602 tmp2
= load_reg(s
, rd
);
1603 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1604 tcg_temp_free_i32(tmp2
);
1605 iwmmxt_store_creg(wrd
, tmp
);
1607 case ARM_IWMMXT_wCGR0
:
1608 case ARM_IWMMXT_wCGR1
:
1609 case ARM_IWMMXT_wCGR2
:
1610 case ARM_IWMMXT_wCGR3
:
1611 gen_op_iwmmxt_set_cup();
1612 tmp
= load_reg(s
, rd
);
1613 iwmmxt_store_creg(wrd
, tmp
);
1619 case 0x100: /* WXOR */
1620 wrd
= (insn
>> 12) & 0xf;
1621 rd0
= (insn
>> 0) & 0xf;
1622 rd1
= (insn
>> 16) & 0xf;
1623 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1624 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1625 gen_op_iwmmxt_setpsr_nz();
1626 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1627 gen_op_iwmmxt_set_mup();
1628 gen_op_iwmmxt_set_cup();
1630 case 0x111: /* TMRC */
1633 rd
= (insn
>> 12) & 0xf;
1634 wrd
= (insn
>> 16) & 0xf;
1635 tmp
= iwmmxt_load_creg(wrd
);
1636 store_reg(s
, rd
, tmp
);
1638 case 0x300: /* WANDN */
1639 wrd
= (insn
>> 12) & 0xf;
1640 rd0
= (insn
>> 0) & 0xf;
1641 rd1
= (insn
>> 16) & 0xf;
1642 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1643 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1644 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1645 gen_op_iwmmxt_setpsr_nz();
1646 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1647 gen_op_iwmmxt_set_mup();
1648 gen_op_iwmmxt_set_cup();
1650 case 0x200: /* WAND */
1651 wrd
= (insn
>> 12) & 0xf;
1652 rd0
= (insn
>> 0) & 0xf;
1653 rd1
= (insn
>> 16) & 0xf;
1654 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1655 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1656 gen_op_iwmmxt_setpsr_nz();
1657 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1658 gen_op_iwmmxt_set_mup();
1659 gen_op_iwmmxt_set_cup();
1661 case 0x810: case 0xa10: /* WMADD */
1662 wrd
= (insn
>> 12) & 0xf;
1663 rd0
= (insn
>> 0) & 0xf;
1664 rd1
= (insn
>> 16) & 0xf;
1665 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1666 if (insn
& (1 << 21))
1667 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1669 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1670 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1671 gen_op_iwmmxt_set_mup();
1673 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1674 wrd
= (insn
>> 12) & 0xf;
1675 rd0
= (insn
>> 16) & 0xf;
1676 rd1
= (insn
>> 0) & 0xf;
1677 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1678 switch ((insn
>> 22) & 3) {
1680 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1683 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1686 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1691 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1692 gen_op_iwmmxt_set_mup();
1693 gen_op_iwmmxt_set_cup();
1695 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1696 wrd
= (insn
>> 12) & 0xf;
1697 rd0
= (insn
>> 16) & 0xf;
1698 rd1
= (insn
>> 0) & 0xf;
1699 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1700 switch ((insn
>> 22) & 3) {
1702 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1705 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1708 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1713 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1714 gen_op_iwmmxt_set_mup();
1715 gen_op_iwmmxt_set_cup();
1717 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1718 wrd
= (insn
>> 12) & 0xf;
1719 rd0
= (insn
>> 16) & 0xf;
1720 rd1
= (insn
>> 0) & 0xf;
1721 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1722 if (insn
& (1 << 22))
1723 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1725 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1726 if (!(insn
& (1 << 20)))
1727 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1728 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1729 gen_op_iwmmxt_set_mup();
1731 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1732 wrd
= (insn
>> 12) & 0xf;
1733 rd0
= (insn
>> 16) & 0xf;
1734 rd1
= (insn
>> 0) & 0xf;
1735 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1736 if (insn
& (1 << 21)) {
1737 if (insn
& (1 << 20))
1738 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1740 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1742 if (insn
& (1 << 20))
1743 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1745 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1747 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1748 gen_op_iwmmxt_set_mup();
1750 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1751 wrd
= (insn
>> 12) & 0xf;
1752 rd0
= (insn
>> 16) & 0xf;
1753 rd1
= (insn
>> 0) & 0xf;
1754 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1755 if (insn
& (1 << 21))
1756 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1758 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1759 if (!(insn
& (1 << 20))) {
1760 iwmmxt_load_reg(cpu_V1
, wrd
);
1761 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1763 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1764 gen_op_iwmmxt_set_mup();
1766 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1767 wrd
= (insn
>> 12) & 0xf;
1768 rd0
= (insn
>> 16) & 0xf;
1769 rd1
= (insn
>> 0) & 0xf;
1770 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1771 switch ((insn
>> 22) & 3) {
1773 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
1776 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1779 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
1784 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1785 gen_op_iwmmxt_set_mup();
1786 gen_op_iwmmxt_set_cup();
1788 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1789 wrd
= (insn
>> 12) & 0xf;
1790 rd0
= (insn
>> 16) & 0xf;
1791 rd1
= (insn
>> 0) & 0xf;
1792 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1793 if (insn
& (1 << 22)) {
1794 if (insn
& (1 << 20))
1795 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1797 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1799 if (insn
& (1 << 20))
1800 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1802 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
1804 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1805 gen_op_iwmmxt_set_mup();
1806 gen_op_iwmmxt_set_cup();
1808 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1809 wrd
= (insn
>> 12) & 0xf;
1810 rd0
= (insn
>> 16) & 0xf;
1811 rd1
= (insn
>> 0) & 0xf;
1812 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1813 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
1814 tcg_gen_andi_i32(tmp
, tmp
, 7);
1815 iwmmxt_load_reg(cpu_V1
, rd1
);
1816 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
1817 tcg_temp_free_i32(tmp
);
1818 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1819 gen_op_iwmmxt_set_mup();
1821 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1822 if (((insn
>> 6) & 3) == 3)
1824 rd
= (insn
>> 12) & 0xf;
1825 wrd
= (insn
>> 16) & 0xf;
1826 tmp
= load_reg(s
, rd
);
1827 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1828 switch ((insn
>> 6) & 3) {
1830 tmp2
= tcg_const_i32(0xff);
1831 tmp3
= tcg_const_i32((insn
& 7) << 3);
1834 tmp2
= tcg_const_i32(0xffff);
1835 tmp3
= tcg_const_i32((insn
& 3) << 4);
1838 tmp2
= tcg_const_i32(0xffffffff);
1839 tmp3
= tcg_const_i32((insn
& 1) << 5);
1842 TCGV_UNUSED_I32(tmp2
);
1843 TCGV_UNUSED_I32(tmp3
);
1845 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
1846 tcg_temp_free_i32(tmp3
);
1847 tcg_temp_free_i32(tmp2
);
1848 tcg_temp_free_i32(tmp
);
1849 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1850 gen_op_iwmmxt_set_mup();
1852 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1853 rd
= (insn
>> 12) & 0xf;
1854 wrd
= (insn
>> 16) & 0xf;
1855 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
1857 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1858 tmp
= tcg_temp_new_i32();
1859 switch ((insn
>> 22) & 3) {
1861 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
1862 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1864 tcg_gen_ext8s_i32(tmp
, tmp
);
1866 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
1870 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
1871 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1873 tcg_gen_ext16s_i32(tmp
, tmp
);
1875 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
1879 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
1880 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1883 store_reg(s
, rd
, tmp
);
1885 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1886 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1888 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1889 switch ((insn
>> 22) & 3) {
1891 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
1894 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
1897 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
1900 tcg_gen_shli_i32(tmp
, tmp
, 28);
1902 tcg_temp_free_i32(tmp
);
1904 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1905 if (((insn
>> 6) & 3) == 3)
1907 rd
= (insn
>> 12) & 0xf;
1908 wrd
= (insn
>> 16) & 0xf;
1909 tmp
= load_reg(s
, rd
);
1910 switch ((insn
>> 6) & 3) {
1912 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
1915 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
1918 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
1921 tcg_temp_free_i32(tmp
);
1922 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1923 gen_op_iwmmxt_set_mup();
1925 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1926 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1928 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1929 tmp2
= tcg_temp_new_i32();
1930 tcg_gen_mov_i32(tmp2
, tmp
);
1931 switch ((insn
>> 22) & 3) {
1933 for (i
= 0; i
< 7; i
++) {
1934 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1935 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1939 for (i
= 0; i
< 3; i
++) {
1940 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1941 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1945 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1946 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1950 tcg_temp_free_i32(tmp2
);
1951 tcg_temp_free_i32(tmp
);
1953 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1954 wrd
= (insn
>> 12) & 0xf;
1955 rd0
= (insn
>> 16) & 0xf;
1956 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1957 switch ((insn
>> 22) & 3) {
1959 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
1962 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
1965 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
1970 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1971 gen_op_iwmmxt_set_mup();
1973 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1974 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1976 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1977 tmp2
= tcg_temp_new_i32();
1978 tcg_gen_mov_i32(tmp2
, tmp
);
1979 switch ((insn
>> 22) & 3) {
1981 for (i
= 0; i
< 7; i
++) {
1982 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1983 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1987 for (i
= 0; i
< 3; i
++) {
1988 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1989 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1993 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1994 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1998 tcg_temp_free_i32(tmp2
);
1999 tcg_temp_free_i32(tmp
);
2001 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2002 rd
= (insn
>> 12) & 0xf;
2003 rd0
= (insn
>> 16) & 0xf;
2004 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
2006 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2007 tmp
= tcg_temp_new_i32();
2008 switch ((insn
>> 22) & 3) {
2010 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
2013 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
2016 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
2019 store_reg(s
, rd
, tmp
);
2021 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2022 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2023 wrd
= (insn
>> 12) & 0xf;
2024 rd0
= (insn
>> 16) & 0xf;
2025 rd1
= (insn
>> 0) & 0xf;
2026 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2027 switch ((insn
>> 22) & 3) {
2029 if (insn
& (1 << 21))
2030 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
2032 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
2035 if (insn
& (1 << 21))
2036 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2038 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2041 if (insn
& (1 << 21))
2042 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2044 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2049 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2050 gen_op_iwmmxt_set_mup();
2051 gen_op_iwmmxt_set_cup();
2053 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2054 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2055 wrd
= (insn
>> 12) & 0xf;
2056 rd0
= (insn
>> 16) & 0xf;
2057 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2058 switch ((insn
>> 22) & 3) {
2060 if (insn
& (1 << 21))
2061 gen_op_iwmmxt_unpacklsb_M0();
2063 gen_op_iwmmxt_unpacklub_M0();
2066 if (insn
& (1 << 21))
2067 gen_op_iwmmxt_unpacklsw_M0();
2069 gen_op_iwmmxt_unpackluw_M0();
2072 if (insn
& (1 << 21))
2073 gen_op_iwmmxt_unpacklsl_M0();
2075 gen_op_iwmmxt_unpacklul_M0();
2080 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2081 gen_op_iwmmxt_set_mup();
2082 gen_op_iwmmxt_set_cup();
2084 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2085 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2086 wrd
= (insn
>> 12) & 0xf;
2087 rd0
= (insn
>> 16) & 0xf;
2088 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2089 switch ((insn
>> 22) & 3) {
2091 if (insn
& (1 << 21))
2092 gen_op_iwmmxt_unpackhsb_M0();
2094 gen_op_iwmmxt_unpackhub_M0();
2097 if (insn
& (1 << 21))
2098 gen_op_iwmmxt_unpackhsw_M0();
2100 gen_op_iwmmxt_unpackhuw_M0();
2103 if (insn
& (1 << 21))
2104 gen_op_iwmmxt_unpackhsl_M0();
2106 gen_op_iwmmxt_unpackhul_M0();
2111 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2112 gen_op_iwmmxt_set_mup();
2113 gen_op_iwmmxt_set_cup();
2115 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2116 case 0x214: case 0x614: case 0xa14: case 0xe14:
2117 if (((insn
>> 22) & 3) == 0)
2119 wrd
= (insn
>> 12) & 0xf;
2120 rd0
= (insn
>> 16) & 0xf;
2121 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2122 tmp
= tcg_temp_new_i32();
2123 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2124 tcg_temp_free_i32(tmp
);
2127 switch ((insn
>> 22) & 3) {
2129 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2132 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2135 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2138 tcg_temp_free_i32(tmp
);
2139 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2140 gen_op_iwmmxt_set_mup();
2141 gen_op_iwmmxt_set_cup();
2143 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2144 case 0x014: case 0x414: case 0x814: case 0xc14:
2145 if (((insn
>> 22) & 3) == 0)
2147 wrd
= (insn
>> 12) & 0xf;
2148 rd0
= (insn
>> 16) & 0xf;
2149 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2150 tmp
= tcg_temp_new_i32();
2151 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2152 tcg_temp_free_i32(tmp
);
2155 switch ((insn
>> 22) & 3) {
2157 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2160 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2163 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2166 tcg_temp_free_i32(tmp
);
2167 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2168 gen_op_iwmmxt_set_mup();
2169 gen_op_iwmmxt_set_cup();
2171 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2172 case 0x114: case 0x514: case 0x914: case 0xd14:
2173 if (((insn
>> 22) & 3) == 0)
2175 wrd
= (insn
>> 12) & 0xf;
2176 rd0
= (insn
>> 16) & 0xf;
2177 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2178 tmp
= tcg_temp_new_i32();
2179 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2180 tcg_temp_free_i32(tmp
);
2183 switch ((insn
>> 22) & 3) {
2185 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2188 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2191 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2194 tcg_temp_free_i32(tmp
);
2195 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2196 gen_op_iwmmxt_set_mup();
2197 gen_op_iwmmxt_set_cup();
2199 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2200 case 0x314: case 0x714: case 0xb14: case 0xf14:
2201 if (((insn
>> 22) & 3) == 0)
2203 wrd
= (insn
>> 12) & 0xf;
2204 rd0
= (insn
>> 16) & 0xf;
2205 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2206 tmp
= tcg_temp_new_i32();
2207 switch ((insn
>> 22) & 3) {
2209 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2210 tcg_temp_free_i32(tmp
);
2213 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2216 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2217 tcg_temp_free_i32(tmp
);
2220 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2223 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2224 tcg_temp_free_i32(tmp
);
2227 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2230 tcg_temp_free_i32(tmp
);
2231 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2232 gen_op_iwmmxt_set_mup();
2233 gen_op_iwmmxt_set_cup();
2235 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2236 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2237 wrd
= (insn
>> 12) & 0xf;
2238 rd0
= (insn
>> 16) & 0xf;
2239 rd1
= (insn
>> 0) & 0xf;
2240 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2241 switch ((insn
>> 22) & 3) {
2243 if (insn
& (1 << 21))
2244 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2246 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2249 if (insn
& (1 << 21))
2250 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2252 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2255 if (insn
& (1 << 21))
2256 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2258 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2263 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2264 gen_op_iwmmxt_set_mup();
2266 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2267 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2268 wrd
= (insn
>> 12) & 0xf;
2269 rd0
= (insn
>> 16) & 0xf;
2270 rd1
= (insn
>> 0) & 0xf;
2271 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2272 switch ((insn
>> 22) & 3) {
2274 if (insn
& (1 << 21))
2275 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2277 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2280 if (insn
& (1 << 21))
2281 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2283 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2286 if (insn
& (1 << 21))
2287 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2289 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2294 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2295 gen_op_iwmmxt_set_mup();
2297 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2298 case 0x402: case 0x502: case 0x602: case 0x702:
2299 wrd
= (insn
>> 12) & 0xf;
2300 rd0
= (insn
>> 16) & 0xf;
2301 rd1
= (insn
>> 0) & 0xf;
2302 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2303 tmp
= tcg_const_i32((insn
>> 20) & 3);
2304 iwmmxt_load_reg(cpu_V1
, rd1
);
2305 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2306 tcg_temp_free_i32(tmp
);
2307 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2308 gen_op_iwmmxt_set_mup();
2310 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2311 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2312 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2313 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2314 wrd
= (insn
>> 12) & 0xf;
2315 rd0
= (insn
>> 16) & 0xf;
2316 rd1
= (insn
>> 0) & 0xf;
2317 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2318 switch ((insn
>> 20) & 0xf) {
2320 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2323 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2326 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2329 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2332 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2335 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2338 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2341 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2344 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2349 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2350 gen_op_iwmmxt_set_mup();
2351 gen_op_iwmmxt_set_cup();
2353 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2354 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2355 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2356 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2357 wrd
= (insn
>> 12) & 0xf;
2358 rd0
= (insn
>> 16) & 0xf;
2359 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2360 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2361 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2362 tcg_temp_free_i32(tmp
);
2363 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2364 gen_op_iwmmxt_set_mup();
2365 gen_op_iwmmxt_set_cup();
2367 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2368 case 0x418: case 0x518: case 0x618: case 0x718:
2369 case 0x818: case 0x918: case 0xa18: case 0xb18:
2370 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2371 wrd
= (insn
>> 12) & 0xf;
2372 rd0
= (insn
>> 16) & 0xf;
2373 rd1
= (insn
>> 0) & 0xf;
2374 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2375 switch ((insn
>> 20) & 0xf) {
2377 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2380 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2383 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2386 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2389 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2392 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2395 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2398 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2401 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2406 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2407 gen_op_iwmmxt_set_mup();
2408 gen_op_iwmmxt_set_cup();
2410 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2411 case 0x408: case 0x508: case 0x608: case 0x708:
2412 case 0x808: case 0x908: case 0xa08: case 0xb08:
2413 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2414 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2416 wrd
= (insn
>> 12) & 0xf;
2417 rd0
= (insn
>> 16) & 0xf;
2418 rd1
= (insn
>> 0) & 0xf;
2419 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2420 switch ((insn
>> 22) & 3) {
2422 if (insn
& (1 << 21))
2423 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2425 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2428 if (insn
& (1 << 21))
2429 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2431 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2434 if (insn
& (1 << 21))
2435 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2437 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2440 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2441 gen_op_iwmmxt_set_mup();
2442 gen_op_iwmmxt_set_cup();
2444 case 0x201: case 0x203: case 0x205: case 0x207:
2445 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2446 case 0x211: case 0x213: case 0x215: case 0x217:
2447 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2448 wrd
= (insn
>> 5) & 0xf;
2449 rd0
= (insn
>> 12) & 0xf;
2450 rd1
= (insn
>> 0) & 0xf;
2451 if (rd0
== 0xf || rd1
== 0xf)
2453 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2454 tmp
= load_reg(s
, rd0
);
2455 tmp2
= load_reg(s
, rd1
);
2456 switch ((insn
>> 16) & 0xf) {
2457 case 0x0: /* TMIA */
2458 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2460 case 0x8: /* TMIAPH */
2461 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2463 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2464 if (insn
& (1 << 16))
2465 tcg_gen_shri_i32(tmp
, tmp
, 16);
2466 if (insn
& (1 << 17))
2467 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2468 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2471 tcg_temp_free_i32(tmp2
);
2472 tcg_temp_free_i32(tmp
);
2475 tcg_temp_free_i32(tmp2
);
2476 tcg_temp_free_i32(tmp
);
2477 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2478 gen_op_iwmmxt_set_mup();
2487 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2488 (ie. an undefined instruction). */
2489 static int disas_dsp_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
2491 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2494 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2495 /* Multiply with Internal Accumulate Format */
2496 rd0
= (insn
>> 12) & 0xf;
2498 acc
= (insn
>> 5) & 7;
2503 tmp
= load_reg(s
, rd0
);
2504 tmp2
= load_reg(s
, rd1
);
2505 switch ((insn
>> 16) & 0xf) {
2507 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2509 case 0x8: /* MIAPH */
2510 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2512 case 0xc: /* MIABB */
2513 case 0xd: /* MIABT */
2514 case 0xe: /* MIATB */
2515 case 0xf: /* MIATT */
2516 if (insn
& (1 << 16))
2517 tcg_gen_shri_i32(tmp
, tmp
, 16);
2518 if (insn
& (1 << 17))
2519 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2520 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2525 tcg_temp_free_i32(tmp2
);
2526 tcg_temp_free_i32(tmp
);
2528 gen_op_iwmmxt_movq_wRn_M0(acc
);
2532 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2533 /* Internal Accumulator Access Format */
2534 rdhi
= (insn
>> 16) & 0xf;
2535 rdlo
= (insn
>> 12) & 0xf;
2541 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2542 iwmmxt_load_reg(cpu_V0
, acc
);
2543 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2544 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2545 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2546 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2548 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2549 iwmmxt_store_reg(cpu_V0
, acc
);
2557 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2558 #define VFP_SREG(insn, bigbit, smallbit) \
2559 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2560 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2561 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2562 reg = (((insn) >> (bigbit)) & 0x0f) \
2563 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2565 if (insn & (1 << (smallbit))) \
2567 reg = ((insn) >> (bigbit)) & 0x0f; \
2570 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2571 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2572 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2573 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2574 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2575 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2577 /* Move between integer and VFP cores. */
2578 static TCGv_i32
gen_vfp_mrs(void)
2580 TCGv_i32 tmp
= tcg_temp_new_i32();
2581 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2585 static void gen_vfp_msr(TCGv_i32 tmp
)
2587 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2588 tcg_temp_free_i32(tmp
);
2591 static void gen_neon_dup_u8(TCGv_i32 var
, int shift
)
2593 TCGv_i32 tmp
= tcg_temp_new_i32();
2595 tcg_gen_shri_i32(var
, var
, shift
);
2596 tcg_gen_ext8u_i32(var
, var
);
2597 tcg_gen_shli_i32(tmp
, var
, 8);
2598 tcg_gen_or_i32(var
, var
, tmp
);
2599 tcg_gen_shli_i32(tmp
, var
, 16);
2600 tcg_gen_or_i32(var
, var
, tmp
);
2601 tcg_temp_free_i32(tmp
);
2604 static void gen_neon_dup_low16(TCGv_i32 var
)
2606 TCGv_i32 tmp
= tcg_temp_new_i32();
2607 tcg_gen_ext16u_i32(var
, var
);
2608 tcg_gen_shli_i32(tmp
, var
, 16);
2609 tcg_gen_or_i32(var
, var
, tmp
);
2610 tcg_temp_free_i32(tmp
);
2613 static void gen_neon_dup_high16(TCGv_i32 var
)
2615 TCGv_i32 tmp
= tcg_temp_new_i32();
2616 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2617 tcg_gen_shri_i32(tmp
, var
, 16);
2618 tcg_gen_or_i32(var
, var
, tmp
);
2619 tcg_temp_free_i32(tmp
);
2622 static TCGv_i32
gen_load_and_replicate(DisasContext
*s
, TCGv_i32 addr
, int size
)
2624 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2625 TCGv_i32 tmp
= tcg_temp_new_i32();
2628 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
2629 gen_neon_dup_u8(tmp
, 0);
2632 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
2633 gen_neon_dup_low16(tmp
);
2636 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
2638 default: /* Avoid compiler warnings. */
2644 static int handle_vsel(uint32_t insn
, uint32_t rd
, uint32_t rn
, uint32_t rm
,
2647 uint32_t cc
= extract32(insn
, 20, 2);
2650 TCGv_i64 frn
, frm
, dest
;
2651 TCGv_i64 tmp
, zero
, zf
, nf
, vf
;
2653 zero
= tcg_const_i64(0);
2655 frn
= tcg_temp_new_i64();
2656 frm
= tcg_temp_new_i64();
2657 dest
= tcg_temp_new_i64();
2659 zf
= tcg_temp_new_i64();
2660 nf
= tcg_temp_new_i64();
2661 vf
= tcg_temp_new_i64();
2663 tcg_gen_extu_i32_i64(zf
, cpu_ZF
);
2664 tcg_gen_ext_i32_i64(nf
, cpu_NF
);
2665 tcg_gen_ext_i32_i64(vf
, cpu_VF
);
2667 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2668 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2671 tcg_gen_movcond_i64(TCG_COND_EQ
, dest
, zf
, zero
,
2675 tcg_gen_movcond_i64(TCG_COND_LT
, dest
, vf
, zero
,
2678 case 2: /* ge: N == V -> N ^ V == 0 */
2679 tmp
= tcg_temp_new_i64();
2680 tcg_gen_xor_i64(tmp
, vf
, nf
);
2681 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2683 tcg_temp_free_i64(tmp
);
2685 case 3: /* gt: !Z && N == V */
2686 tcg_gen_movcond_i64(TCG_COND_NE
, dest
, zf
, zero
,
2688 tmp
= tcg_temp_new_i64();
2689 tcg_gen_xor_i64(tmp
, vf
, nf
);
2690 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2692 tcg_temp_free_i64(tmp
);
2695 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2696 tcg_temp_free_i64(frn
);
2697 tcg_temp_free_i64(frm
);
2698 tcg_temp_free_i64(dest
);
2700 tcg_temp_free_i64(zf
);
2701 tcg_temp_free_i64(nf
);
2702 tcg_temp_free_i64(vf
);
2704 tcg_temp_free_i64(zero
);
2706 TCGv_i32 frn
, frm
, dest
;
2709 zero
= tcg_const_i32(0);
2711 frn
= tcg_temp_new_i32();
2712 frm
= tcg_temp_new_i32();
2713 dest
= tcg_temp_new_i32();
2714 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2715 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2718 tcg_gen_movcond_i32(TCG_COND_EQ
, dest
, cpu_ZF
, zero
,
2722 tcg_gen_movcond_i32(TCG_COND_LT
, dest
, cpu_VF
, zero
,
2725 case 2: /* ge: N == V -> N ^ V == 0 */
2726 tmp
= tcg_temp_new_i32();
2727 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2728 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2730 tcg_temp_free_i32(tmp
);
2732 case 3: /* gt: !Z && N == V */
2733 tcg_gen_movcond_i32(TCG_COND_NE
, dest
, cpu_ZF
, zero
,
2735 tmp
= tcg_temp_new_i32();
2736 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2737 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2739 tcg_temp_free_i32(tmp
);
2742 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2743 tcg_temp_free_i32(frn
);
2744 tcg_temp_free_i32(frm
);
2745 tcg_temp_free_i32(dest
);
2747 tcg_temp_free_i32(zero
);
2753 static int handle_vminmaxnm(uint32_t insn
, uint32_t rd
, uint32_t rn
,
2754 uint32_t rm
, uint32_t dp
)
2756 uint32_t vmin
= extract32(insn
, 6, 1);
2757 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2760 TCGv_i64 frn
, frm
, dest
;
2762 frn
= tcg_temp_new_i64();
2763 frm
= tcg_temp_new_i64();
2764 dest
= tcg_temp_new_i64();
2766 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2767 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2769 gen_helper_vfp_minnumd(dest
, frn
, frm
, fpst
);
2771 gen_helper_vfp_maxnumd(dest
, frn
, frm
, fpst
);
2773 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2774 tcg_temp_free_i64(frn
);
2775 tcg_temp_free_i64(frm
);
2776 tcg_temp_free_i64(dest
);
2778 TCGv_i32 frn
, frm
, dest
;
2780 frn
= tcg_temp_new_i32();
2781 frm
= tcg_temp_new_i32();
2782 dest
= tcg_temp_new_i32();
2784 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2785 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2787 gen_helper_vfp_minnums(dest
, frn
, frm
, fpst
);
2789 gen_helper_vfp_maxnums(dest
, frn
, frm
, fpst
);
2791 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2792 tcg_temp_free_i32(frn
);
2793 tcg_temp_free_i32(frm
);
2794 tcg_temp_free_i32(dest
);
2797 tcg_temp_free_ptr(fpst
);
2801 static int handle_vrint(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
2804 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2807 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
2808 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2813 tcg_op
= tcg_temp_new_i64();
2814 tcg_res
= tcg_temp_new_i64();
2815 tcg_gen_ld_f64(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
2816 gen_helper_rintd(tcg_res
, tcg_op
, fpst
);
2817 tcg_gen_st_f64(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
2818 tcg_temp_free_i64(tcg_op
);
2819 tcg_temp_free_i64(tcg_res
);
2823 tcg_op
= tcg_temp_new_i32();
2824 tcg_res
= tcg_temp_new_i32();
2825 tcg_gen_ld_f32(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
2826 gen_helper_rints(tcg_res
, tcg_op
, fpst
);
2827 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
2828 tcg_temp_free_i32(tcg_op
);
2829 tcg_temp_free_i32(tcg_res
);
2832 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2833 tcg_temp_free_i32(tcg_rmode
);
2835 tcg_temp_free_ptr(fpst
);
2839 static int handle_vcvt(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
2842 bool is_signed
= extract32(insn
, 7, 1);
2843 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2844 TCGv_i32 tcg_rmode
, tcg_shift
;
2846 tcg_shift
= tcg_const_i32(0);
2848 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
2849 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2852 TCGv_i64 tcg_double
, tcg_res
;
2854 /* Rd is encoded as a single precision register even when the source
2855 * is double precision.
2857 rd
= ((rd
<< 1) & 0x1e) | ((rd
>> 4) & 0x1);
2858 tcg_double
= tcg_temp_new_i64();
2859 tcg_res
= tcg_temp_new_i64();
2860 tcg_tmp
= tcg_temp_new_i32();
2861 tcg_gen_ld_f64(tcg_double
, cpu_env
, vfp_reg_offset(1, rm
));
2863 gen_helper_vfp_tosld(tcg_res
, tcg_double
, tcg_shift
, fpst
);
2865 gen_helper_vfp_tould(tcg_res
, tcg_double
, tcg_shift
, fpst
);
2867 tcg_gen_trunc_i64_i32(tcg_tmp
, tcg_res
);
2868 tcg_gen_st_f32(tcg_tmp
, cpu_env
, vfp_reg_offset(0, rd
));
2869 tcg_temp_free_i32(tcg_tmp
);
2870 tcg_temp_free_i64(tcg_res
);
2871 tcg_temp_free_i64(tcg_double
);
2873 TCGv_i32 tcg_single
, tcg_res
;
2874 tcg_single
= tcg_temp_new_i32();
2875 tcg_res
= tcg_temp_new_i32();
2876 tcg_gen_ld_f32(tcg_single
, cpu_env
, vfp_reg_offset(0, rm
));
2878 gen_helper_vfp_tosls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
2880 gen_helper_vfp_touls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
2882 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(0, rd
));
2883 tcg_temp_free_i32(tcg_res
);
2884 tcg_temp_free_i32(tcg_single
);
2887 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2888 tcg_temp_free_i32(tcg_rmode
);
2890 tcg_temp_free_i32(tcg_shift
);
2892 tcg_temp_free_ptr(fpst
);
2897 /* Table for converting the most common AArch32 encoding of
2898 * rounding mode to arm_fprounding order (which matches the
2899 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
2901 static const uint8_t fp_decode_rm
[] = {
2908 static int disas_vfp_v8_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
2910 uint32_t rd
, rn
, rm
, dp
= extract32(insn
, 8, 1);
2912 if (!arm_feature(env
, ARM_FEATURE_V8
)) {
2917 VFP_DREG_D(rd
, insn
);
2918 VFP_DREG_N(rn
, insn
);
2919 VFP_DREG_M(rm
, insn
);
2921 rd
= VFP_SREG_D(insn
);
2922 rn
= VFP_SREG_N(insn
);
2923 rm
= VFP_SREG_M(insn
);
2926 if ((insn
& 0x0f800e50) == 0x0e000a00) {
2927 return handle_vsel(insn
, rd
, rn
, rm
, dp
);
2928 } else if ((insn
& 0x0fb00e10) == 0x0e800a00) {
2929 return handle_vminmaxnm(insn
, rd
, rn
, rm
, dp
);
2930 } else if ((insn
& 0x0fbc0ed0) == 0x0eb80a40) {
2931 /* VRINTA, VRINTN, VRINTP, VRINTM */
2932 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
2933 return handle_vrint(insn
, rd
, rm
, dp
, rounding
);
2934 } else if ((insn
& 0x0fbc0e50) == 0x0ebc0a40) {
2935 /* VCVTA, VCVTN, VCVTP, VCVTM */
2936 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
2937 return handle_vcvt(insn
, rd
, rm
, dp
, rounding
);
2942 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
2943 (ie. an undefined instruction). */
2944 static int disas_vfp_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
2946 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
2952 if (!arm_feature(env
, ARM_FEATURE_VFP
))
2955 /* FIXME: this access check should not take precedence over UNDEF
2956 * for invalid encodings; we will generate incorrect syndrome information
2957 * for attempts to execute invalid vfp/neon encodings with FP disabled.
2959 if (!s
->cpacr_fpen
) {
2960 gen_exception_insn(s
, 4, EXCP_UDEF
,
2961 syn_fp_access_trap(1, 0xe, s
->thumb
));
2965 if (!s
->vfp_enabled
) {
2966 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2967 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
2969 rn
= (insn
>> 16) & 0xf;
2970 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
&& rn
!= ARM_VFP_MVFR2
2971 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
) {
2976 if (extract32(insn
, 28, 4) == 0xf) {
2977 /* Encodings with T=1 (Thumb) or unconditional (ARM):
2978 * only used in v8 and above.
2980 return disas_vfp_v8_insn(env
, s
, insn
);
2983 dp
= ((insn
& 0xf00) == 0xb00);
2984 switch ((insn
>> 24) & 0xf) {
2986 if (insn
& (1 << 4)) {
2987 /* single register transfer */
2988 rd
= (insn
>> 12) & 0xf;
2993 VFP_DREG_N(rn
, insn
);
2996 if (insn
& 0x00c00060
2997 && !arm_feature(env
, ARM_FEATURE_NEON
))
3000 pass
= (insn
>> 21) & 1;
3001 if (insn
& (1 << 22)) {
3003 offset
= ((insn
>> 5) & 3) * 8;
3004 } else if (insn
& (1 << 5)) {
3006 offset
= (insn
& (1 << 6)) ? 16 : 0;
3011 if (insn
& ARM_CP_RW_BIT
) {
3013 tmp
= neon_load_reg(rn
, pass
);
3017 tcg_gen_shri_i32(tmp
, tmp
, offset
);
3018 if (insn
& (1 << 23))
3024 if (insn
& (1 << 23)) {
3026 tcg_gen_shri_i32(tmp
, tmp
, 16);
3032 tcg_gen_sari_i32(tmp
, tmp
, 16);
3041 store_reg(s
, rd
, tmp
);
3044 tmp
= load_reg(s
, rd
);
3045 if (insn
& (1 << 23)) {
3048 gen_neon_dup_u8(tmp
, 0);
3049 } else if (size
== 1) {
3050 gen_neon_dup_low16(tmp
);
3052 for (n
= 0; n
<= pass
* 2; n
++) {
3053 tmp2
= tcg_temp_new_i32();
3054 tcg_gen_mov_i32(tmp2
, tmp
);
3055 neon_store_reg(rn
, n
, tmp2
);
3057 neon_store_reg(rn
, n
, tmp
);
3062 tmp2
= neon_load_reg(rn
, pass
);
3063 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 8);
3064 tcg_temp_free_i32(tmp2
);
3067 tmp2
= neon_load_reg(rn
, pass
);
3068 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 16);
3069 tcg_temp_free_i32(tmp2
);
3074 neon_store_reg(rn
, pass
, tmp
);
3078 if ((insn
& 0x6f) != 0x00)
3080 rn
= VFP_SREG_N(insn
);
3081 if (insn
& ARM_CP_RW_BIT
) {
3083 if (insn
& (1 << 21)) {
3084 /* system register */
3089 /* VFP2 allows access to FSID from userspace.
3090 VFP3 restricts all id registers to privileged
3093 && arm_feature(env
, ARM_FEATURE_VFP3
))
3095 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3100 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3102 case ARM_VFP_FPINST
:
3103 case ARM_VFP_FPINST2
:
3104 /* Not present in VFP3. */
3106 || arm_feature(env
, ARM_FEATURE_VFP3
))
3108 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3112 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
3113 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
3115 tmp
= tcg_temp_new_i32();
3116 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
3120 if (!arm_feature(env
, ARM_FEATURE_V8
)) {
3127 || !arm_feature(env
, ARM_FEATURE_MVFR
))
3129 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3135 gen_mov_F0_vreg(0, rn
);
3136 tmp
= gen_vfp_mrs();
3139 /* Set the 4 flag bits in the CPSR. */
3141 tcg_temp_free_i32(tmp
);
3143 store_reg(s
, rd
, tmp
);
3147 if (insn
& (1 << 21)) {
3149 /* system register */
3154 /* Writes are ignored. */
3157 tmp
= load_reg(s
, rd
);
3158 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
3159 tcg_temp_free_i32(tmp
);
3165 /* TODO: VFP subarchitecture support.
3166 * For now, keep the EN bit only */
3167 tmp
= load_reg(s
, rd
);
3168 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
3169 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3172 case ARM_VFP_FPINST
:
3173 case ARM_VFP_FPINST2
:
3174 tmp
= load_reg(s
, rd
);
3175 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3181 tmp
= load_reg(s
, rd
);
3183 gen_mov_vreg_F0(0, rn
);
3188 /* data processing */
3189 /* The opcode is in bits 23, 21, 20 and 6. */
3190 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
3194 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
3196 /* rn is register number */
3197 VFP_DREG_N(rn
, insn
);
3200 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18) ||
3201 ((rn
& 0x1e) == 0x6))) {
3202 /* Integer or single/half precision destination. */
3203 rd
= VFP_SREG_D(insn
);
3205 VFP_DREG_D(rd
, insn
);
3208 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14) ||
3209 ((rn
& 0x1e) == 0x4))) {
3210 /* VCVT from int or half precision is always from S reg
3211 * regardless of dp bit. VCVT with immediate frac_bits
3212 * has same format as SREG_M.
3214 rm
= VFP_SREG_M(insn
);
3216 VFP_DREG_M(rm
, insn
);
3219 rn
= VFP_SREG_N(insn
);
3220 if (op
== 15 && rn
== 15) {
3221 /* Double precision destination. */
3222 VFP_DREG_D(rd
, insn
);
3224 rd
= VFP_SREG_D(insn
);
3226 /* NB that we implicitly rely on the encoding for the frac_bits
3227 * in VCVT of fixed to float being the same as that of an SREG_M
3229 rm
= VFP_SREG_M(insn
);
3232 veclen
= s
->vec_len
;
3233 if (op
== 15 && rn
> 3)
3236 /* Shut up compiler warnings. */
3247 /* Figure out what type of vector operation this is. */
3248 if ((rd
& bank_mask
) == 0) {
3253 delta_d
= (s
->vec_stride
>> 1) + 1;
3255 delta_d
= s
->vec_stride
+ 1;
3257 if ((rm
& bank_mask
) == 0) {
3258 /* mixed scalar/vector */
3267 /* Load the initial operands. */
3272 /* Integer source */
3273 gen_mov_F0_vreg(0, rm
);
3278 gen_mov_F0_vreg(dp
, rd
);
3279 gen_mov_F1_vreg(dp
, rm
);
3283 /* Compare with zero */
3284 gen_mov_F0_vreg(dp
, rd
);
3295 /* Source and destination the same. */
3296 gen_mov_F0_vreg(dp
, rd
);
3302 /* VCVTB, VCVTT: only present with the halfprec extension
3303 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3304 * (we choose to UNDEF)
3306 if ((dp
&& !arm_feature(env
, ARM_FEATURE_V8
)) ||
3307 !arm_feature(env
, ARM_FEATURE_VFP_FP16
)) {
3310 if (!extract32(rn
, 1, 1)) {
3311 /* Half precision source. */
3312 gen_mov_F0_vreg(0, rm
);
3315 /* Otherwise fall through */
3317 /* One source operand. */
3318 gen_mov_F0_vreg(dp
, rm
);
3322 /* Two source operands. */
3323 gen_mov_F0_vreg(dp
, rn
);
3324 gen_mov_F1_vreg(dp
, rm
);
3328 /* Perform the calculation. */
3330 case 0: /* VMLA: fd + (fn * fm) */
3331 /* Note that order of inputs to the add matters for NaNs */
3333 gen_mov_F0_vreg(dp
, rd
);
3336 case 1: /* VMLS: fd + -(fn * fm) */
3339 gen_mov_F0_vreg(dp
, rd
);
3342 case 2: /* VNMLS: -fd + (fn * fm) */
3343 /* Note that it isn't valid to replace (-A + B) with (B - A)
3344 * or similar plausible looking simplifications
3345 * because this will give wrong results for NaNs.
3348 gen_mov_F0_vreg(dp
, rd
);
3352 case 3: /* VNMLA: -fd + -(fn * fm) */
3355 gen_mov_F0_vreg(dp
, rd
);
3359 case 4: /* mul: fn * fm */
3362 case 5: /* nmul: -(fn * fm) */
3366 case 6: /* add: fn + fm */
3369 case 7: /* sub: fn - fm */
3372 case 8: /* div: fn / fm */
3375 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3376 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3377 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3378 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3379 /* These are fused multiply-add, and must be done as one
3380 * floating point operation with no rounding between the
3381 * multiplication and addition steps.
3382 * NB that doing the negations here as separate steps is
3383 * correct : an input NaN should come out with its sign bit
3384 * flipped if it is a negated-input.
3386 if (!arm_feature(env
, ARM_FEATURE_VFP4
)) {
3394 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3396 frd
= tcg_temp_new_i64();
3397 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3400 gen_helper_vfp_negd(frd
, frd
);
3402 fpst
= get_fpstatus_ptr(0);
3403 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3404 cpu_F1d
, frd
, fpst
);
3405 tcg_temp_free_ptr(fpst
);
3406 tcg_temp_free_i64(frd
);
3412 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3414 frd
= tcg_temp_new_i32();
3415 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3417 gen_helper_vfp_negs(frd
, frd
);
3419 fpst
= get_fpstatus_ptr(0);
3420 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3421 cpu_F1s
, frd
, fpst
);
3422 tcg_temp_free_ptr(fpst
);
3423 tcg_temp_free_i32(frd
);
3426 case 14: /* fconst */
3427 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3430 n
= (insn
<< 12) & 0x80000000;
3431 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3438 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3445 tcg_gen_movi_i32(cpu_F0s
, n
);
3448 case 15: /* extension space */
3462 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3463 tmp
= gen_vfp_mrs();
3464 tcg_gen_ext16u_i32(tmp
, tmp
);
3466 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3469 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3472 tcg_temp_free_i32(tmp
);
3474 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3475 tmp
= gen_vfp_mrs();
3476 tcg_gen_shri_i32(tmp
, tmp
, 16);
3478 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3481 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3484 tcg_temp_free_i32(tmp
);
3486 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3487 tmp
= tcg_temp_new_i32();
3489 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3492 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3495 gen_mov_F0_vreg(0, rd
);
3496 tmp2
= gen_vfp_mrs();
3497 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3498 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3499 tcg_temp_free_i32(tmp2
);
3502 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3503 tmp
= tcg_temp_new_i32();
3505 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3508 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3511 tcg_gen_shli_i32(tmp
, tmp
, 16);
3512 gen_mov_F0_vreg(0, rd
);
3513 tmp2
= gen_vfp_mrs();
3514 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3515 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3516 tcg_temp_free_i32(tmp2
);
3528 case 11: /* cmpez */
3532 case 12: /* vrintr */
3534 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3536 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3538 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3540 tcg_temp_free_ptr(fpst
);
3543 case 13: /* vrintz */
3545 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3547 tcg_rmode
= tcg_const_i32(float_round_to_zero
);
3548 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3550 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3552 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3554 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3555 tcg_temp_free_i32(tcg_rmode
);
3556 tcg_temp_free_ptr(fpst
);
3559 case 14: /* vrintx */
3561 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3563 gen_helper_rintd_exact(cpu_F0d
, cpu_F0d
, fpst
);
3565 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpst
);
3567 tcg_temp_free_ptr(fpst
);
3570 case 15: /* single<->double conversion */
3572 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3574 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3576 case 16: /* fuito */
3577 gen_vfp_uito(dp
, 0);
3579 case 17: /* fsito */
3580 gen_vfp_sito(dp
, 0);
3582 case 20: /* fshto */
3583 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3585 gen_vfp_shto(dp
, 16 - rm
, 0);
3587 case 21: /* fslto */
3588 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3590 gen_vfp_slto(dp
, 32 - rm
, 0);
3592 case 22: /* fuhto */
3593 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3595 gen_vfp_uhto(dp
, 16 - rm
, 0);
3597 case 23: /* fulto */
3598 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3600 gen_vfp_ulto(dp
, 32 - rm
, 0);
3602 case 24: /* ftoui */
3603 gen_vfp_toui(dp
, 0);
3605 case 25: /* ftouiz */
3606 gen_vfp_touiz(dp
, 0);
3608 case 26: /* ftosi */
3609 gen_vfp_tosi(dp
, 0);
3611 case 27: /* ftosiz */
3612 gen_vfp_tosiz(dp
, 0);
3614 case 28: /* ftosh */
3615 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3617 gen_vfp_tosh(dp
, 16 - rm
, 0);
3619 case 29: /* ftosl */
3620 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3622 gen_vfp_tosl(dp
, 32 - rm
, 0);
3624 case 30: /* ftouh */
3625 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3627 gen_vfp_touh(dp
, 16 - rm
, 0);
3629 case 31: /* ftoul */
3630 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3632 gen_vfp_toul(dp
, 32 - rm
, 0);
3634 default: /* undefined */
3638 default: /* undefined */
3642 /* Write back the result. */
3643 if (op
== 15 && (rn
>= 8 && rn
<= 11)) {
3644 /* Comparison, do nothing. */
3645 } else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18 ||
3646 (rn
& 0x1e) == 0x6)) {
3647 /* VCVT double to int: always integer result.
3648 * VCVT double to half precision is always a single
3651 gen_mov_vreg_F0(0, rd
);
3652 } else if (op
== 15 && rn
== 15) {
3654 gen_mov_vreg_F0(!dp
, rd
);
3656 gen_mov_vreg_F0(dp
, rd
);
3659 /* break out of the loop if we have finished */
3663 if (op
== 15 && delta_m
== 0) {
3664 /* single source one-many */
3666 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3668 gen_mov_vreg_F0(dp
, rd
);
3672 /* Setup the next operands. */
3674 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3678 /* One source operand. */
3679 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3681 gen_mov_F0_vreg(dp
, rm
);
3683 /* Two source operands. */
3684 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3686 gen_mov_F0_vreg(dp
, rn
);
3688 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3690 gen_mov_F1_vreg(dp
, rm
);
3698 if ((insn
& 0x03e00000) == 0x00400000) {
3699 /* two-register transfer */
3700 rn
= (insn
>> 16) & 0xf;
3701 rd
= (insn
>> 12) & 0xf;
3703 VFP_DREG_M(rm
, insn
);
3705 rm
= VFP_SREG_M(insn
);
3708 if (insn
& ARM_CP_RW_BIT
) {
3711 gen_mov_F0_vreg(0, rm
* 2);
3712 tmp
= gen_vfp_mrs();
3713 store_reg(s
, rd
, tmp
);
3714 gen_mov_F0_vreg(0, rm
* 2 + 1);
3715 tmp
= gen_vfp_mrs();
3716 store_reg(s
, rn
, tmp
);
3718 gen_mov_F0_vreg(0, rm
);
3719 tmp
= gen_vfp_mrs();
3720 store_reg(s
, rd
, tmp
);
3721 gen_mov_F0_vreg(0, rm
+ 1);
3722 tmp
= gen_vfp_mrs();
3723 store_reg(s
, rn
, tmp
);
3728 tmp
= load_reg(s
, rd
);
3730 gen_mov_vreg_F0(0, rm
* 2);
3731 tmp
= load_reg(s
, rn
);
3733 gen_mov_vreg_F0(0, rm
* 2 + 1);
3735 tmp
= load_reg(s
, rd
);
3737 gen_mov_vreg_F0(0, rm
);
3738 tmp
= load_reg(s
, rn
);
3740 gen_mov_vreg_F0(0, rm
+ 1);
3745 rn
= (insn
>> 16) & 0xf;
3747 VFP_DREG_D(rd
, insn
);
3749 rd
= VFP_SREG_D(insn
);
3750 if ((insn
& 0x01200000) == 0x01000000) {
3751 /* Single load/store */
3752 offset
= (insn
& 0xff) << 2;
3753 if ((insn
& (1 << 23)) == 0)
3755 if (s
->thumb
&& rn
== 15) {
3756 /* This is actually UNPREDICTABLE */
3757 addr
= tcg_temp_new_i32();
3758 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3760 addr
= load_reg(s
, rn
);
3762 tcg_gen_addi_i32(addr
, addr
, offset
);
3763 if (insn
& (1 << 20)) {
3764 gen_vfp_ld(s
, dp
, addr
);
3765 gen_mov_vreg_F0(dp
, rd
);
3767 gen_mov_F0_vreg(dp
, rd
);
3768 gen_vfp_st(s
, dp
, addr
);
3770 tcg_temp_free_i32(addr
);
3772 /* load/store multiple */
3773 int w
= insn
& (1 << 21);
3775 n
= (insn
>> 1) & 0x7f;
3779 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
3780 /* P == U , W == 1 => UNDEF */
3783 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
3784 /* UNPREDICTABLE cases for bad immediates: we choose to
3785 * UNDEF to avoid generating huge numbers of TCG ops
3789 if (rn
== 15 && w
) {
3790 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3794 if (s
->thumb
&& rn
== 15) {
3795 /* This is actually UNPREDICTABLE */
3796 addr
= tcg_temp_new_i32();
3797 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3799 addr
= load_reg(s
, rn
);
3801 if (insn
& (1 << 24)) /* pre-decrement */
3802 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
3808 for (i
= 0; i
< n
; i
++) {
3809 if (insn
& ARM_CP_RW_BIT
) {
3811 gen_vfp_ld(s
, dp
, addr
);
3812 gen_mov_vreg_F0(dp
, rd
+ i
);
3815 gen_mov_F0_vreg(dp
, rd
+ i
);
3816 gen_vfp_st(s
, dp
, addr
);
3818 tcg_gen_addi_i32(addr
, addr
, offset
);
3822 if (insn
& (1 << 24))
3823 offset
= -offset
* n
;
3824 else if (dp
&& (insn
& 1))
3830 tcg_gen_addi_i32(addr
, addr
, offset
);
3831 store_reg(s
, rn
, addr
);
3833 tcg_temp_free_i32(addr
);
3839 /* Should never happen. */
3845 static inline void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
3847 TranslationBlock
*tb
;
3850 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
3852 gen_set_pc_im(s
, dest
);
3853 tcg_gen_exit_tb((uintptr_t)tb
+ n
);
3855 gen_set_pc_im(s
, dest
);
3860 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
3862 if (unlikely(s
->singlestep_enabled
)) {
3863 /* An indirect jump so that we still trigger the debug exception. */
3868 gen_goto_tb(s
, 0, dest
);
3869 s
->is_jmp
= DISAS_TB_JUMP
;
3873 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
3876 tcg_gen_sari_i32(t0
, t0
, 16);
3880 tcg_gen_sari_i32(t1
, t1
, 16);
3883 tcg_gen_mul_i32(t0
, t0
, t1
);
3886 /* Return the mask of PSR bits set by a MSR instruction. */
3887 static uint32_t msr_mask(CPUARMState
*env
, DisasContext
*s
, int flags
, int spsr
) {
3891 if (flags
& (1 << 0))
3893 if (flags
& (1 << 1))
3895 if (flags
& (1 << 2))
3897 if (flags
& (1 << 3))
3900 /* Mask out undefined bits. */
3901 mask
&= ~CPSR_RESERVED
;
3902 if (!arm_feature(env
, ARM_FEATURE_V4T
))
3904 if (!arm_feature(env
, ARM_FEATURE_V5
))
3905 mask
&= ~CPSR_Q
; /* V5TE in reality*/
3906 if (!arm_feature(env
, ARM_FEATURE_V6
))
3907 mask
&= ~(CPSR_E
| CPSR_GE
);
3908 if (!arm_feature(env
, ARM_FEATURE_THUMB2
))
3910 /* Mask out execution state bits. */
3913 /* Mask out privileged bits. */
3919 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3920 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
3924 /* ??? This is also undefined in system mode. */
3928 tmp
= load_cpu_field(spsr
);
3929 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
3930 tcg_gen_andi_i32(t0
, t0
, mask
);
3931 tcg_gen_or_i32(tmp
, tmp
, t0
);
3932 store_cpu_field(tmp
, spsr
);
3934 gen_set_cpsr(t0
, mask
);
3936 tcg_temp_free_i32(t0
);
3941 /* Returns nonzero if access to the PSR is not permitted. */
3942 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
3945 tmp
= tcg_temp_new_i32();
3946 tcg_gen_movi_i32(tmp
, val
);
3947 return gen_set_psr(s
, mask
, spsr
, tmp
);
3950 /* Generate an old-style exception return. Marks pc as dead. */
3951 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
3954 store_reg(s
, 15, pc
);
3955 tmp
= load_cpu_field(spsr
);
3956 gen_set_cpsr(tmp
, 0xffffffff);
3957 tcg_temp_free_i32(tmp
);
3958 s
->is_jmp
= DISAS_UPDATE
;
3961 /* Generate a v6 exception return. Marks both values as dead. */
3962 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
3964 gen_set_cpsr(cpsr
, 0xffffffff);
3965 tcg_temp_free_i32(cpsr
);
3966 store_reg(s
, 15, pc
);
3967 s
->is_jmp
= DISAS_UPDATE
;
3970 static void gen_nop_hint(DisasContext
*s
, int val
)
3974 gen_set_pc_im(s
, s
->pc
);
3975 s
->is_jmp
= DISAS_WFI
;
3978 gen_set_pc_im(s
, s
->pc
);
3979 s
->is_jmp
= DISAS_WFE
;
3983 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3989 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3991 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
3994 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
3995 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
3996 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
4001 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4004 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
4005 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
4006 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
4011 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4012 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4013 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4014 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4015 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4017 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4018 switch ((size << 1) | u) { \
4020 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4023 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4026 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4029 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4032 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4035 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4037 default: return 1; \
4040 #define GEN_NEON_INTEGER_OP(name) do { \
4041 switch ((size << 1) | u) { \
4043 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4046 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4049 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4052 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4055 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4058 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4060 default: return 1; \
4063 static TCGv_i32
neon_load_scratch(int scratch
)
4065 TCGv_i32 tmp
= tcg_temp_new_i32();
4066 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4070 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
4072 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4073 tcg_temp_free_i32(var
);
4076 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
4080 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
4082 gen_neon_dup_high16(tmp
);
4084 gen_neon_dup_low16(tmp
);
4087 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
4092 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
4095 if (!q
&& size
== 2) {
4098 tmp
= tcg_const_i32(rd
);
4099 tmp2
= tcg_const_i32(rm
);
4103 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
4106 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
4109 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
4117 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
4120 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
4126 tcg_temp_free_i32(tmp
);
4127 tcg_temp_free_i32(tmp2
);
4131 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
4134 if (!q
&& size
== 2) {
4137 tmp
= tcg_const_i32(rd
);
4138 tmp2
= tcg_const_i32(rm
);
4142 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
4145 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
4148 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
4156 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
4159 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
4165 tcg_temp_free_i32(tmp
);
4166 tcg_temp_free_i32(tmp2
);
4170 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
4174 rd
= tcg_temp_new_i32();
4175 tmp
= tcg_temp_new_i32();
4177 tcg_gen_shli_i32(rd
, t0
, 8);
4178 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
4179 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
4180 tcg_gen_or_i32(rd
, rd
, tmp
);
4182 tcg_gen_shri_i32(t1
, t1
, 8);
4183 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
4184 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
4185 tcg_gen_or_i32(t1
, t1
, tmp
);
4186 tcg_gen_mov_i32(t0
, rd
);
4188 tcg_temp_free_i32(tmp
);
4189 tcg_temp_free_i32(rd
);
4192 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
4196 rd
= tcg_temp_new_i32();
4197 tmp
= tcg_temp_new_i32();
4199 tcg_gen_shli_i32(rd
, t0
, 16);
4200 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
4201 tcg_gen_or_i32(rd
, rd
, tmp
);
4202 tcg_gen_shri_i32(t1
, t1
, 16);
4203 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
4204 tcg_gen_or_i32(t1
, t1
, tmp
);
4205 tcg_gen_mov_i32(t0
, rd
);
4207 tcg_temp_free_i32(tmp
);
4208 tcg_temp_free_i32(rd
);
4216 } neon_ls_element_type
[11] = {
4230 /* Translate a NEON load/store element instruction. Return nonzero if the
4231 instruction is invalid. */
4232 static int disas_neon_ls_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
4251 /* FIXME: this access check should not take precedence over UNDEF
4252 * for invalid encodings; we will generate incorrect syndrome information
4253 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4255 if (!s
->cpacr_fpen
) {
4256 gen_exception_insn(s
, 4, EXCP_UDEF
,
4257 syn_fp_access_trap(1, 0xe, s
->thumb
));
4261 if (!s
->vfp_enabled
)
4263 VFP_DREG_D(rd
, insn
);
4264 rn
= (insn
>> 16) & 0xf;
4266 load
= (insn
& (1 << 21)) != 0;
4267 if ((insn
& (1 << 23)) == 0) {
4268 /* Load store all elements. */
4269 op
= (insn
>> 8) & 0xf;
4270 size
= (insn
>> 6) & 3;
4273 /* Catch UNDEF cases for bad values of align field */
4276 if (((insn
>> 5) & 1) == 1) {
4281 if (((insn
>> 4) & 3) == 3) {
4288 nregs
= neon_ls_element_type
[op
].nregs
;
4289 interleave
= neon_ls_element_type
[op
].interleave
;
4290 spacing
= neon_ls_element_type
[op
].spacing
;
4291 if (size
== 3 && (interleave
| spacing
) != 1)
4293 addr
= tcg_temp_new_i32();
4294 load_reg_var(s
, addr
, rn
);
4295 stride
= (1 << size
) * interleave
;
4296 for (reg
= 0; reg
< nregs
; reg
++) {
4297 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
4298 load_reg_var(s
, addr
, rn
);
4299 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
4300 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
4301 load_reg_var(s
, addr
, rn
);
4302 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4305 tmp64
= tcg_temp_new_i64();
4307 gen_aa32_ld64(tmp64
, addr
, get_mem_index(s
));
4308 neon_store_reg64(tmp64
, rd
);
4310 neon_load_reg64(tmp64
, rd
);
4311 gen_aa32_st64(tmp64
, addr
, get_mem_index(s
));
4313 tcg_temp_free_i64(tmp64
);
4314 tcg_gen_addi_i32(addr
, addr
, stride
);
4316 for (pass
= 0; pass
< 2; pass
++) {
4319 tmp
= tcg_temp_new_i32();
4320 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
4321 neon_store_reg(rd
, pass
, tmp
);
4323 tmp
= neon_load_reg(rd
, pass
);
4324 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
4325 tcg_temp_free_i32(tmp
);
4327 tcg_gen_addi_i32(addr
, addr
, stride
);
4328 } else if (size
== 1) {
4330 tmp
= tcg_temp_new_i32();
4331 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
4332 tcg_gen_addi_i32(addr
, addr
, stride
);
4333 tmp2
= tcg_temp_new_i32();
4334 gen_aa32_ld16u(tmp2
, addr
, get_mem_index(s
));
4335 tcg_gen_addi_i32(addr
, addr
, stride
);
4336 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
4337 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4338 tcg_temp_free_i32(tmp2
);
4339 neon_store_reg(rd
, pass
, tmp
);
4341 tmp
= neon_load_reg(rd
, pass
);
4342 tmp2
= tcg_temp_new_i32();
4343 tcg_gen_shri_i32(tmp2
, tmp
, 16);
4344 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
4345 tcg_temp_free_i32(tmp
);
4346 tcg_gen_addi_i32(addr
, addr
, stride
);
4347 gen_aa32_st16(tmp2
, addr
, get_mem_index(s
));
4348 tcg_temp_free_i32(tmp2
);
4349 tcg_gen_addi_i32(addr
, addr
, stride
);
4351 } else /* size == 0 */ {
4353 TCGV_UNUSED_I32(tmp2
);
4354 for (n
= 0; n
< 4; n
++) {
4355 tmp
= tcg_temp_new_i32();
4356 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
4357 tcg_gen_addi_i32(addr
, addr
, stride
);
4361 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
4362 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
4363 tcg_temp_free_i32(tmp
);
4366 neon_store_reg(rd
, pass
, tmp2
);
4368 tmp2
= neon_load_reg(rd
, pass
);
4369 for (n
= 0; n
< 4; n
++) {
4370 tmp
= tcg_temp_new_i32();
4372 tcg_gen_mov_i32(tmp
, tmp2
);
4374 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
4376 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
4377 tcg_temp_free_i32(tmp
);
4378 tcg_gen_addi_i32(addr
, addr
, stride
);
4380 tcg_temp_free_i32(tmp2
);
4387 tcg_temp_free_i32(addr
);
4390 size
= (insn
>> 10) & 3;
4392 /* Load single element to all lanes. */
4393 int a
= (insn
>> 4) & 1;
4397 size
= (insn
>> 6) & 3;
4398 nregs
= ((insn
>> 8) & 3) + 1;
4401 if (nregs
!= 4 || a
== 0) {
4404 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4407 if (nregs
== 1 && a
== 1 && size
== 0) {
4410 if (nregs
== 3 && a
== 1) {
4413 addr
= tcg_temp_new_i32();
4414 load_reg_var(s
, addr
, rn
);
4416 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4417 tmp
= gen_load_and_replicate(s
, addr
, size
);
4418 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4419 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4420 if (insn
& (1 << 5)) {
4421 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
4422 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
4424 tcg_temp_free_i32(tmp
);
4426 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4427 stride
= (insn
& (1 << 5)) ? 2 : 1;
4428 for (reg
= 0; reg
< nregs
; reg
++) {
4429 tmp
= gen_load_and_replicate(s
, addr
, size
);
4430 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4431 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4432 tcg_temp_free_i32(tmp
);
4433 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4437 tcg_temp_free_i32(addr
);
4438 stride
= (1 << size
) * nregs
;
4440 /* Single element. */
4441 int idx
= (insn
>> 4) & 0xf;
4442 pass
= (insn
>> 7) & 1;
4445 shift
= ((insn
>> 5) & 3) * 8;
4449 shift
= ((insn
>> 6) & 1) * 16;
4450 stride
= (insn
& (1 << 5)) ? 2 : 1;
4454 stride
= (insn
& (1 << 6)) ? 2 : 1;
4459 nregs
= ((insn
>> 8) & 3) + 1;
4460 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4463 if (((idx
& (1 << size
)) != 0) ||
4464 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
4469 if ((idx
& 1) != 0) {
4474 if (size
== 2 && (idx
& 2) != 0) {
4479 if ((size
== 2) && ((idx
& 3) == 3)) {
4486 if ((rd
+ stride
* (nregs
- 1)) > 31) {
4487 /* Attempts to write off the end of the register file
4488 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4489 * the neon_load_reg() would write off the end of the array.
4493 addr
= tcg_temp_new_i32();
4494 load_reg_var(s
, addr
, rn
);
4495 for (reg
= 0; reg
< nregs
; reg
++) {
4497 tmp
= tcg_temp_new_i32();
4500 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
4503 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
4506 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
4508 default: /* Avoid compiler warnings. */
4512 tmp2
= neon_load_reg(rd
, pass
);
4513 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
4514 shift
, size
? 16 : 8);
4515 tcg_temp_free_i32(tmp2
);
4517 neon_store_reg(rd
, pass
, tmp
);
4518 } else { /* Store */
4519 tmp
= neon_load_reg(rd
, pass
);
4521 tcg_gen_shri_i32(tmp
, tmp
, shift
);
4524 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
4527 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
4530 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
4533 tcg_temp_free_i32(tmp
);
4536 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4538 tcg_temp_free_i32(addr
);
4539 stride
= nregs
* (1 << size
);
4545 base
= load_reg(s
, rn
);
4547 tcg_gen_addi_i32(base
, base
, stride
);
4550 index
= load_reg(s
, rm
);
4551 tcg_gen_add_i32(base
, base
, index
);
4552 tcg_temp_free_i32(index
);
4554 store_reg(s
, rn
, base
);
4559 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4560 static void gen_neon_bsl(TCGv_i32 dest
, TCGv_i32 t
, TCGv_i32 f
, TCGv_i32 c
)
4562 tcg_gen_and_i32(t
, t
, c
);
4563 tcg_gen_andc_i32(f
, f
, c
);
4564 tcg_gen_or_i32(dest
, t
, f
);
4567 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4570 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4571 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4572 case 2: tcg_gen_trunc_i64_i32(dest
, src
); break;
4577 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4580 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4581 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4582 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
4587 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4590 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
4591 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
4592 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
4597 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4600 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
4601 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
4602 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
4607 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
4613 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
4614 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
4619 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
4620 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
4627 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
4628 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
4633 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
4634 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
4641 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
4645 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
4646 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
4647 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
4652 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
4653 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
4654 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
4658 tcg_temp_free_i32(src
);
4661 static inline void gen_neon_addl(int size
)
4664 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
4665 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
4666 case 2: tcg_gen_add_i64(CPU_V001
); break;
4671 static inline void gen_neon_subl(int size
)
4674 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
4675 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
4676 case 2: tcg_gen_sub_i64(CPU_V001
); break;
4681 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
4684 case 0: gen_helper_neon_negl_u16(var
, var
); break;
4685 case 1: gen_helper_neon_negl_u32(var
, var
); break;
4687 tcg_gen_neg_i64(var
, var
);
4693 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
4696 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
4697 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
4702 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
4707 switch ((size
<< 1) | u
) {
4708 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
4709 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
4710 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
4711 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
4713 tmp
= gen_muls_i64_i32(a
, b
);
4714 tcg_gen_mov_i64(dest
, tmp
);
4715 tcg_temp_free_i64(tmp
);
4718 tmp
= gen_mulu_i64_i32(a
, b
);
4719 tcg_gen_mov_i64(dest
, tmp
);
4720 tcg_temp_free_i64(tmp
);
4725 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4726 Don't forget to clean them now. */
4728 tcg_temp_free_i32(a
);
4729 tcg_temp_free_i32(b
);
4733 static void gen_neon_narrow_op(int op
, int u
, int size
,
4734 TCGv_i32 dest
, TCGv_i64 src
)
4738 gen_neon_unarrow_sats(size
, dest
, src
);
4740 gen_neon_narrow(size
, dest
, src
);
4744 gen_neon_narrow_satu(size
, dest
, src
);
4746 gen_neon_narrow_sats(size
, dest
, src
);
4751 /* Symbolic constants for op fields for Neon 3-register same-length.
4752 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4755 #define NEON_3R_VHADD 0
4756 #define NEON_3R_VQADD 1
4757 #define NEON_3R_VRHADD 2
4758 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4759 #define NEON_3R_VHSUB 4
4760 #define NEON_3R_VQSUB 5
4761 #define NEON_3R_VCGT 6
4762 #define NEON_3R_VCGE 7
4763 #define NEON_3R_VSHL 8
4764 #define NEON_3R_VQSHL 9
4765 #define NEON_3R_VRSHL 10
4766 #define NEON_3R_VQRSHL 11
4767 #define NEON_3R_VMAX 12
4768 #define NEON_3R_VMIN 13
4769 #define NEON_3R_VABD 14
4770 #define NEON_3R_VABA 15
4771 #define NEON_3R_VADD_VSUB 16
4772 #define NEON_3R_VTST_VCEQ 17
4773 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4774 #define NEON_3R_VMUL 19
4775 #define NEON_3R_VPMAX 20
4776 #define NEON_3R_VPMIN 21
4777 #define NEON_3R_VQDMULH_VQRDMULH 22
4778 #define NEON_3R_VPADD 23
4779 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
4780 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4781 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4782 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4783 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4784 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4785 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4786 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4788 static const uint8_t neon_3r_sizes
[] = {
4789 [NEON_3R_VHADD
] = 0x7,
4790 [NEON_3R_VQADD
] = 0xf,
4791 [NEON_3R_VRHADD
] = 0x7,
4792 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
4793 [NEON_3R_VHSUB
] = 0x7,
4794 [NEON_3R_VQSUB
] = 0xf,
4795 [NEON_3R_VCGT
] = 0x7,
4796 [NEON_3R_VCGE
] = 0x7,
4797 [NEON_3R_VSHL
] = 0xf,
4798 [NEON_3R_VQSHL
] = 0xf,
4799 [NEON_3R_VRSHL
] = 0xf,
4800 [NEON_3R_VQRSHL
] = 0xf,
4801 [NEON_3R_VMAX
] = 0x7,
4802 [NEON_3R_VMIN
] = 0x7,
4803 [NEON_3R_VABD
] = 0x7,
4804 [NEON_3R_VABA
] = 0x7,
4805 [NEON_3R_VADD_VSUB
] = 0xf,
4806 [NEON_3R_VTST_VCEQ
] = 0x7,
4807 [NEON_3R_VML
] = 0x7,
4808 [NEON_3R_VMUL
] = 0x7,
4809 [NEON_3R_VPMAX
] = 0x7,
4810 [NEON_3R_VPMIN
] = 0x7,
4811 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
4812 [NEON_3R_VPADD
] = 0x7,
4813 [NEON_3R_SHA
] = 0xf, /* size field encodes op type */
4814 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
4815 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
4816 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
4817 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
4818 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
4819 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
4820 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
4823 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4824 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4827 #define NEON_2RM_VREV64 0
4828 #define NEON_2RM_VREV32 1
4829 #define NEON_2RM_VREV16 2
4830 #define NEON_2RM_VPADDL 4
4831 #define NEON_2RM_VPADDL_U 5
4832 #define NEON_2RM_AESE 6 /* Includes AESD */
4833 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4834 #define NEON_2RM_VCLS 8
4835 #define NEON_2RM_VCLZ 9
4836 #define NEON_2RM_VCNT 10
4837 #define NEON_2RM_VMVN 11
4838 #define NEON_2RM_VPADAL 12
4839 #define NEON_2RM_VPADAL_U 13
4840 #define NEON_2RM_VQABS 14
4841 #define NEON_2RM_VQNEG 15
4842 #define NEON_2RM_VCGT0 16
4843 #define NEON_2RM_VCGE0 17
4844 #define NEON_2RM_VCEQ0 18
4845 #define NEON_2RM_VCLE0 19
4846 #define NEON_2RM_VCLT0 20
4847 #define NEON_2RM_SHA1H 21
4848 #define NEON_2RM_VABS 22
4849 #define NEON_2RM_VNEG 23
4850 #define NEON_2RM_VCGT0_F 24
4851 #define NEON_2RM_VCGE0_F 25
4852 #define NEON_2RM_VCEQ0_F 26
4853 #define NEON_2RM_VCLE0_F 27
4854 #define NEON_2RM_VCLT0_F 28
4855 #define NEON_2RM_VABS_F 30
4856 #define NEON_2RM_VNEG_F 31
4857 #define NEON_2RM_VSWP 32
4858 #define NEON_2RM_VTRN 33
4859 #define NEON_2RM_VUZP 34
4860 #define NEON_2RM_VZIP 35
4861 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4862 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4863 #define NEON_2RM_VSHLL 38
4864 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
4865 #define NEON_2RM_VRINTN 40
4866 #define NEON_2RM_VRINTX 41
4867 #define NEON_2RM_VRINTA 42
4868 #define NEON_2RM_VRINTZ 43
4869 #define NEON_2RM_VCVT_F16_F32 44
4870 #define NEON_2RM_VRINTM 45
4871 #define NEON_2RM_VCVT_F32_F16 46
4872 #define NEON_2RM_VRINTP 47
4873 #define NEON_2RM_VCVTAU 48
4874 #define NEON_2RM_VCVTAS 49
4875 #define NEON_2RM_VCVTNU 50
4876 #define NEON_2RM_VCVTNS 51
4877 #define NEON_2RM_VCVTPU 52
4878 #define NEON_2RM_VCVTPS 53
4879 #define NEON_2RM_VCVTMU 54
4880 #define NEON_2RM_VCVTMS 55
4881 #define NEON_2RM_VRECPE 56
4882 #define NEON_2RM_VRSQRTE 57
4883 #define NEON_2RM_VRECPE_F 58
4884 #define NEON_2RM_VRSQRTE_F 59
4885 #define NEON_2RM_VCVT_FS 60
4886 #define NEON_2RM_VCVT_FU 61
4887 #define NEON_2RM_VCVT_SF 62
4888 #define NEON_2RM_VCVT_UF 63
4890 static int neon_2rm_is_float_op(int op
)
4892 /* Return true if this neon 2reg-misc op is float-to-float */
4893 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
4894 (op
>= NEON_2RM_VRINTN
&& op
<= NEON_2RM_VRINTZ
) ||
4895 op
== NEON_2RM_VRINTM
||
4896 (op
>= NEON_2RM_VRINTP
&& op
<= NEON_2RM_VCVTMS
) ||
4897 op
>= NEON_2RM_VRECPE_F
);
4900 /* Each entry in this array has bit n set if the insn allows
4901 * size value n (otherwise it will UNDEF). Since unallocated
4902 * op values will have no bits set they always UNDEF.
4904 static const uint8_t neon_2rm_sizes
[] = {
4905 [NEON_2RM_VREV64
] = 0x7,
4906 [NEON_2RM_VREV32
] = 0x3,
4907 [NEON_2RM_VREV16
] = 0x1,
4908 [NEON_2RM_VPADDL
] = 0x7,
4909 [NEON_2RM_VPADDL_U
] = 0x7,
4910 [NEON_2RM_AESE
] = 0x1,
4911 [NEON_2RM_AESMC
] = 0x1,
4912 [NEON_2RM_VCLS
] = 0x7,
4913 [NEON_2RM_VCLZ
] = 0x7,
4914 [NEON_2RM_VCNT
] = 0x1,
4915 [NEON_2RM_VMVN
] = 0x1,
4916 [NEON_2RM_VPADAL
] = 0x7,
4917 [NEON_2RM_VPADAL_U
] = 0x7,
4918 [NEON_2RM_VQABS
] = 0x7,
4919 [NEON_2RM_VQNEG
] = 0x7,
4920 [NEON_2RM_VCGT0
] = 0x7,
4921 [NEON_2RM_VCGE0
] = 0x7,
4922 [NEON_2RM_VCEQ0
] = 0x7,
4923 [NEON_2RM_VCLE0
] = 0x7,
4924 [NEON_2RM_VCLT0
] = 0x7,
4925 [NEON_2RM_SHA1H
] = 0x4,
4926 [NEON_2RM_VABS
] = 0x7,
4927 [NEON_2RM_VNEG
] = 0x7,
4928 [NEON_2RM_VCGT0_F
] = 0x4,
4929 [NEON_2RM_VCGE0_F
] = 0x4,
4930 [NEON_2RM_VCEQ0_F
] = 0x4,
4931 [NEON_2RM_VCLE0_F
] = 0x4,
4932 [NEON_2RM_VCLT0_F
] = 0x4,
4933 [NEON_2RM_VABS_F
] = 0x4,
4934 [NEON_2RM_VNEG_F
] = 0x4,
4935 [NEON_2RM_VSWP
] = 0x1,
4936 [NEON_2RM_VTRN
] = 0x7,
4937 [NEON_2RM_VUZP
] = 0x7,
4938 [NEON_2RM_VZIP
] = 0x7,
4939 [NEON_2RM_VMOVN
] = 0x7,
4940 [NEON_2RM_VQMOVN
] = 0x7,
4941 [NEON_2RM_VSHLL
] = 0x7,
4942 [NEON_2RM_SHA1SU1
] = 0x4,
4943 [NEON_2RM_VRINTN
] = 0x4,
4944 [NEON_2RM_VRINTX
] = 0x4,
4945 [NEON_2RM_VRINTA
] = 0x4,
4946 [NEON_2RM_VRINTZ
] = 0x4,
4947 [NEON_2RM_VCVT_F16_F32
] = 0x2,
4948 [NEON_2RM_VRINTM
] = 0x4,
4949 [NEON_2RM_VCVT_F32_F16
] = 0x2,
4950 [NEON_2RM_VRINTP
] = 0x4,
4951 [NEON_2RM_VCVTAU
] = 0x4,
4952 [NEON_2RM_VCVTAS
] = 0x4,
4953 [NEON_2RM_VCVTNU
] = 0x4,
4954 [NEON_2RM_VCVTNS
] = 0x4,
4955 [NEON_2RM_VCVTPU
] = 0x4,
4956 [NEON_2RM_VCVTPS
] = 0x4,
4957 [NEON_2RM_VCVTMU
] = 0x4,
4958 [NEON_2RM_VCVTMS
] = 0x4,
4959 [NEON_2RM_VRECPE
] = 0x4,
4960 [NEON_2RM_VRSQRTE
] = 0x4,
4961 [NEON_2RM_VRECPE_F
] = 0x4,
4962 [NEON_2RM_VRSQRTE_F
] = 0x4,
4963 [NEON_2RM_VCVT_FS
] = 0x4,
4964 [NEON_2RM_VCVT_FU
] = 0x4,
4965 [NEON_2RM_VCVT_SF
] = 0x4,
4966 [NEON_2RM_VCVT_UF
] = 0x4,
4969 /* Translate a NEON data processing instruction. Return nonzero if the
4970 instruction is invalid.
4971 We process data in a mixture of 32-bit and 64-bit chunks.
4972 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4974 static int disas_neon_data_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
4986 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
4989 /* FIXME: this access check should not take precedence over UNDEF
4990 * for invalid encodings; we will generate incorrect syndrome information
4991 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4993 if (!s
->cpacr_fpen
) {
4994 gen_exception_insn(s
, 4, EXCP_UDEF
,
4995 syn_fp_access_trap(1, 0xe, s
->thumb
));
4999 if (!s
->vfp_enabled
)
5001 q
= (insn
& (1 << 6)) != 0;
5002 u
= (insn
>> 24) & 1;
5003 VFP_DREG_D(rd
, insn
);
5004 VFP_DREG_N(rn
, insn
);
5005 VFP_DREG_M(rm
, insn
);
5006 size
= (insn
>> 20) & 3;
5007 if ((insn
& (1 << 23)) == 0) {
5008 /* Three register same length. */
5009 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
5010 /* Catch invalid op and bad size combinations: UNDEF */
5011 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
5014 /* All insns of this form UNDEF for either this condition or the
5015 * superset of cases "Q==1"; we catch the latter later.
5017 if (q
&& ((rd
| rn
| rm
) & 1)) {
5021 * The SHA-1/SHA-256 3-register instructions require special treatment
5022 * here, as their size field is overloaded as an op type selector, and
5023 * they all consume their input in a single pass.
5025 if (op
== NEON_3R_SHA
) {
5029 if (!u
) { /* SHA-1 */
5030 if (!arm_feature(env
, ARM_FEATURE_V8_SHA1
)) {
5033 tmp
= tcg_const_i32(rd
);
5034 tmp2
= tcg_const_i32(rn
);
5035 tmp3
= tcg_const_i32(rm
);
5036 tmp4
= tcg_const_i32(size
);
5037 gen_helper_crypto_sha1_3reg(cpu_env
, tmp
, tmp2
, tmp3
, tmp4
);
5038 tcg_temp_free_i32(tmp4
);
5039 } else { /* SHA-256 */
5040 if (!arm_feature(env
, ARM_FEATURE_V8_SHA256
) || size
== 3) {
5043 tmp
= tcg_const_i32(rd
);
5044 tmp2
= tcg_const_i32(rn
);
5045 tmp3
= tcg_const_i32(rm
);
5048 gen_helper_crypto_sha256h(cpu_env
, tmp
, tmp2
, tmp3
);
5051 gen_helper_crypto_sha256h2(cpu_env
, tmp
, tmp2
, tmp3
);
5054 gen_helper_crypto_sha256su1(cpu_env
, tmp
, tmp2
, tmp3
);
5058 tcg_temp_free_i32(tmp
);
5059 tcg_temp_free_i32(tmp2
);
5060 tcg_temp_free_i32(tmp3
);
5063 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
5064 /* 64-bit element instructions. */
5065 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5066 neon_load_reg64(cpu_V0
, rn
+ pass
);
5067 neon_load_reg64(cpu_V1
, rm
+ pass
);
5071 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
5074 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
5080 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
5083 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
5089 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5091 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5096 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5099 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5105 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5107 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5110 case NEON_3R_VQRSHL
:
5112 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
5115 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
5119 case NEON_3R_VADD_VSUB
:
5121 tcg_gen_sub_i64(CPU_V001
);
5123 tcg_gen_add_i64(CPU_V001
);
5129 neon_store_reg64(cpu_V0
, rd
+ pass
);
5138 case NEON_3R_VQRSHL
:
5141 /* Shift instruction operands are reversed. */
5156 case NEON_3R_FLOAT_ARITH
:
5157 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
5159 case NEON_3R_FLOAT_MINMAX
:
5160 pairwise
= u
; /* if VPMIN/VPMAX (float) */
5162 case NEON_3R_FLOAT_CMP
:
5164 /* no encoding for U=0 C=1x */
5168 case NEON_3R_FLOAT_ACMP
:
5173 case NEON_3R_FLOAT_MISC
:
5174 /* VMAXNM/VMINNM in ARMv8 */
5175 if (u
&& !arm_feature(env
, ARM_FEATURE_V8
)) {
5180 if (u
&& (size
!= 0)) {
5181 /* UNDEF on invalid size for polynomial subcase */
5186 if (!arm_feature(env
, ARM_FEATURE_VFP4
) || u
) {
5194 if (pairwise
&& q
) {
5195 /* All the pairwise insns UNDEF if Q is set */
5199 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5204 tmp
= neon_load_reg(rn
, 0);
5205 tmp2
= neon_load_reg(rn
, 1);
5207 tmp
= neon_load_reg(rm
, 0);
5208 tmp2
= neon_load_reg(rm
, 1);
5212 tmp
= neon_load_reg(rn
, pass
);
5213 tmp2
= neon_load_reg(rm
, pass
);
5217 GEN_NEON_INTEGER_OP(hadd
);
5220 GEN_NEON_INTEGER_OP_ENV(qadd
);
5222 case NEON_3R_VRHADD
:
5223 GEN_NEON_INTEGER_OP(rhadd
);
5225 case NEON_3R_LOGIC
: /* Logic ops. */
5226 switch ((u
<< 2) | size
) {
5228 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
5231 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
5234 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5237 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
5240 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
5243 tmp3
= neon_load_reg(rd
, pass
);
5244 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
5245 tcg_temp_free_i32(tmp3
);
5248 tmp3
= neon_load_reg(rd
, pass
);
5249 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
5250 tcg_temp_free_i32(tmp3
);
5253 tmp3
= neon_load_reg(rd
, pass
);
5254 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
5255 tcg_temp_free_i32(tmp3
);
5260 GEN_NEON_INTEGER_OP(hsub
);
5263 GEN_NEON_INTEGER_OP_ENV(qsub
);
5266 GEN_NEON_INTEGER_OP(cgt
);
5269 GEN_NEON_INTEGER_OP(cge
);
5272 GEN_NEON_INTEGER_OP(shl
);
5275 GEN_NEON_INTEGER_OP_ENV(qshl
);
5278 GEN_NEON_INTEGER_OP(rshl
);
5280 case NEON_3R_VQRSHL
:
5281 GEN_NEON_INTEGER_OP_ENV(qrshl
);
5284 GEN_NEON_INTEGER_OP(max
);
5287 GEN_NEON_INTEGER_OP(min
);
5290 GEN_NEON_INTEGER_OP(abd
);
5293 GEN_NEON_INTEGER_OP(abd
);
5294 tcg_temp_free_i32(tmp2
);
5295 tmp2
= neon_load_reg(rd
, pass
);
5296 gen_neon_add(size
, tmp
, tmp2
);
5298 case NEON_3R_VADD_VSUB
:
5299 if (!u
) { /* VADD */
5300 gen_neon_add(size
, tmp
, tmp2
);
5303 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
5304 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
5305 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
5310 case NEON_3R_VTST_VCEQ
:
5311 if (!u
) { /* VTST */
5313 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
5314 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
5315 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
5320 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
5321 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
5322 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
5327 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
5329 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5330 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5331 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5334 tcg_temp_free_i32(tmp2
);
5335 tmp2
= neon_load_reg(rd
, pass
);
5337 gen_neon_rsb(size
, tmp
, tmp2
);
5339 gen_neon_add(size
, tmp
, tmp2
);
5343 if (u
) { /* polynomial */
5344 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
5345 } else { /* Integer */
5347 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5348 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5349 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5355 GEN_NEON_INTEGER_OP(pmax
);
5358 GEN_NEON_INTEGER_OP(pmin
);
5360 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
5361 if (!u
) { /* VQDMULH */
5364 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5367 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5371 } else { /* VQRDMULH */
5374 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5377 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5385 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
5386 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
5387 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
5391 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
5393 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5394 switch ((u
<< 2) | size
) {
5397 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5400 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
5403 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
5408 tcg_temp_free_ptr(fpstatus
);
5411 case NEON_3R_FLOAT_MULTIPLY
:
5413 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5414 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5416 tcg_temp_free_i32(tmp2
);
5417 tmp2
= neon_load_reg(rd
, pass
);
5419 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5421 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5424 tcg_temp_free_ptr(fpstatus
);
5427 case NEON_3R_FLOAT_CMP
:
5429 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5431 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
5434 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5436 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5439 tcg_temp_free_ptr(fpstatus
);
5442 case NEON_3R_FLOAT_ACMP
:
5444 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5446 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5448 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5450 tcg_temp_free_ptr(fpstatus
);
5453 case NEON_3R_FLOAT_MINMAX
:
5455 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5457 gen_helper_vfp_maxs(tmp
, tmp
, tmp2
, fpstatus
);
5459 gen_helper_vfp_mins(tmp
, tmp
, tmp2
, fpstatus
);
5461 tcg_temp_free_ptr(fpstatus
);
5464 case NEON_3R_FLOAT_MISC
:
5467 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5469 gen_helper_vfp_maxnums(tmp
, tmp
, tmp2
, fpstatus
);
5471 gen_helper_vfp_minnums(tmp
, tmp
, tmp2
, fpstatus
);
5473 tcg_temp_free_ptr(fpstatus
);
5476 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
5478 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
5484 /* VFMA, VFMS: fused multiply-add */
5485 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5486 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
5489 gen_helper_vfp_negs(tmp
, tmp
);
5491 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
5492 tcg_temp_free_i32(tmp3
);
5493 tcg_temp_free_ptr(fpstatus
);
5499 tcg_temp_free_i32(tmp2
);
5501 /* Save the result. For elementwise operations we can put it
5502 straight into the destination register. For pairwise operations
5503 we have to be careful to avoid clobbering the source operands. */
5504 if (pairwise
&& rd
== rm
) {
5505 neon_store_scratch(pass
, tmp
);
5507 neon_store_reg(rd
, pass
, tmp
);
5511 if (pairwise
&& rd
== rm
) {
5512 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5513 tmp
= neon_load_scratch(pass
);
5514 neon_store_reg(rd
, pass
, tmp
);
5517 /* End of 3 register same size operations. */
5518 } else if (insn
& (1 << 4)) {
5519 if ((insn
& 0x00380080) != 0) {
5520 /* Two registers and shift. */
5521 op
= (insn
>> 8) & 0xf;
5522 if (insn
& (1 << 7)) {
5530 while ((insn
& (1 << (size
+ 19))) == 0)
5533 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
5534 /* To avoid excessive duplication of ops we implement shift
5535 by immediate using the variable shift operations. */
5537 /* Shift by immediate:
5538 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5539 if (q
&& ((rd
| rm
) & 1)) {
5542 if (!u
&& (op
== 4 || op
== 6)) {
5545 /* Right shifts are encoded as N - shift, where N is the
5546 element size in bits. */
5548 shift
= shift
- (1 << (size
+ 3));
5556 imm
= (uint8_t) shift
;
5561 imm
= (uint16_t) shift
;
5572 for (pass
= 0; pass
< count
; pass
++) {
5574 neon_load_reg64(cpu_V0
, rm
+ pass
);
5575 tcg_gen_movi_i64(cpu_V1
, imm
);
5580 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5582 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5587 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5589 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5592 case 5: /* VSHL, VSLI */
5593 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5595 case 6: /* VQSHLU */
5596 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
5601 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5604 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5609 if (op
== 1 || op
== 3) {
5611 neon_load_reg64(cpu_V1
, rd
+ pass
);
5612 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5613 } else if (op
== 4 || (op
== 5 && u
)) {
5615 neon_load_reg64(cpu_V1
, rd
+ pass
);
5617 if (shift
< -63 || shift
> 63) {
5621 mask
= 0xffffffffffffffffull
>> -shift
;
5623 mask
= 0xffffffffffffffffull
<< shift
;
5626 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
5627 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5629 neon_store_reg64(cpu_V0
, rd
+ pass
);
5630 } else { /* size < 3 */
5631 /* Operands in T0 and T1. */
5632 tmp
= neon_load_reg(rm
, pass
);
5633 tmp2
= tcg_temp_new_i32();
5634 tcg_gen_movi_i32(tmp2
, imm
);
5638 GEN_NEON_INTEGER_OP(shl
);
5642 GEN_NEON_INTEGER_OP(rshl
);
5645 case 5: /* VSHL, VSLI */
5647 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
5648 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
5649 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
5653 case 6: /* VQSHLU */
5656 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
5660 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
5664 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
5672 GEN_NEON_INTEGER_OP_ENV(qshl
);
5675 tcg_temp_free_i32(tmp2
);
5677 if (op
== 1 || op
== 3) {
5679 tmp2
= neon_load_reg(rd
, pass
);
5680 gen_neon_add(size
, tmp
, tmp2
);
5681 tcg_temp_free_i32(tmp2
);
5682 } else if (op
== 4 || (op
== 5 && u
)) {
5687 mask
= 0xff >> -shift
;
5689 mask
= (uint8_t)(0xff << shift
);
5695 mask
= 0xffff >> -shift
;
5697 mask
= (uint16_t)(0xffff << shift
);
5701 if (shift
< -31 || shift
> 31) {
5705 mask
= 0xffffffffu
>> -shift
;
5707 mask
= 0xffffffffu
<< shift
;
5713 tmp2
= neon_load_reg(rd
, pass
);
5714 tcg_gen_andi_i32(tmp
, tmp
, mask
);
5715 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
5716 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5717 tcg_temp_free_i32(tmp2
);
5719 neon_store_reg(rd
, pass
, tmp
);
5722 } else if (op
< 10) {
5723 /* Shift by immediate and narrow:
5724 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5725 int input_unsigned
= (op
== 8) ? !u
: u
;
5729 shift
= shift
- (1 << (size
+ 3));
5732 tmp64
= tcg_const_i64(shift
);
5733 neon_load_reg64(cpu_V0
, rm
);
5734 neon_load_reg64(cpu_V1
, rm
+ 1);
5735 for (pass
= 0; pass
< 2; pass
++) {
5743 if (input_unsigned
) {
5744 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
5746 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
5749 if (input_unsigned
) {
5750 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
5752 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
5755 tmp
= tcg_temp_new_i32();
5756 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5757 neon_store_reg(rd
, pass
, tmp
);
5759 tcg_temp_free_i64(tmp64
);
5762 imm
= (uint16_t)shift
;
5766 imm
= (uint32_t)shift
;
5768 tmp2
= tcg_const_i32(imm
);
5769 tmp4
= neon_load_reg(rm
+ 1, 0);
5770 tmp5
= neon_load_reg(rm
+ 1, 1);
5771 for (pass
= 0; pass
< 2; pass
++) {
5773 tmp
= neon_load_reg(rm
, 0);
5777 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
5780 tmp3
= neon_load_reg(rm
, 1);
5784 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
5786 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
5787 tcg_temp_free_i32(tmp
);
5788 tcg_temp_free_i32(tmp3
);
5789 tmp
= tcg_temp_new_i32();
5790 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5791 neon_store_reg(rd
, pass
, tmp
);
5793 tcg_temp_free_i32(tmp2
);
5795 } else if (op
== 10) {
5797 if (q
|| (rd
& 1)) {
5800 tmp
= neon_load_reg(rm
, 0);
5801 tmp2
= neon_load_reg(rm
, 1);
5802 for (pass
= 0; pass
< 2; pass
++) {
5806 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5809 /* The shift is less than the width of the source
5810 type, so we can just shift the whole register. */
5811 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
5812 /* Widen the result of shift: we need to clear
5813 * the potential overflow bits resulting from
5814 * left bits of the narrow input appearing as
5815 * right bits of left the neighbour narrow
5817 if (size
< 2 || !u
) {
5820 imm
= (0xffu
>> (8 - shift
));
5822 } else if (size
== 1) {
5823 imm
= 0xffff >> (16 - shift
);
5826 imm
= 0xffffffff >> (32 - shift
);
5829 imm64
= imm
| (((uint64_t)imm
) << 32);
5833 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
5836 neon_store_reg64(cpu_V0
, rd
+ pass
);
5838 } else if (op
>= 14) {
5839 /* VCVT fixed-point. */
5840 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
5843 /* We have already masked out the must-be-1 top bit of imm6,
5844 * hence this 32-shift where the ARM ARM has 64-imm6.
5847 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5848 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
5851 gen_vfp_ulto(0, shift
, 1);
5853 gen_vfp_slto(0, shift
, 1);
5856 gen_vfp_toul(0, shift
, 1);
5858 gen_vfp_tosl(0, shift
, 1);
5860 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
5865 } else { /* (insn & 0x00380080) == 0 */
5867 if (q
&& (rd
& 1)) {
5871 op
= (insn
>> 8) & 0xf;
5872 /* One register and immediate. */
5873 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
5874 invert
= (insn
& (1 << 5)) != 0;
5875 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5876 * We choose to not special-case this and will behave as if a
5877 * valid constant encoding of 0 had been given.
5896 imm
= (imm
<< 8) | (imm
<< 24);
5899 imm
= (imm
<< 8) | 0xff;
5902 imm
= (imm
<< 16) | 0xffff;
5905 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
5913 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
5914 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
5920 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5921 if (op
& 1 && op
< 12) {
5922 tmp
= neon_load_reg(rd
, pass
);
5924 /* The immediate value has already been inverted, so
5926 tcg_gen_andi_i32(tmp
, tmp
, imm
);
5928 tcg_gen_ori_i32(tmp
, tmp
, imm
);
5932 tmp
= tcg_temp_new_i32();
5933 if (op
== 14 && invert
) {
5937 for (n
= 0; n
< 4; n
++) {
5938 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
5939 val
|= 0xff << (n
* 8);
5941 tcg_gen_movi_i32(tmp
, val
);
5943 tcg_gen_movi_i32(tmp
, imm
);
5946 neon_store_reg(rd
, pass
, tmp
);
5949 } else { /* (insn & 0x00800010 == 0x00800000) */
5951 op
= (insn
>> 8) & 0xf;
5952 if ((insn
& (1 << 6)) == 0) {
5953 /* Three registers of different lengths. */
5957 /* undefreq: bit 0 : UNDEF if size != 0
5958 * bit 1 : UNDEF if size == 0
5959 * bit 2 : UNDEF if U == 1
5960 * Note that [1:0] set implies 'always UNDEF'
5963 /* prewiden, src1_wide, src2_wide, undefreq */
5964 static const int neon_3reg_wide
[16][4] = {
5965 {1, 0, 0, 0}, /* VADDL */
5966 {1, 1, 0, 0}, /* VADDW */
5967 {1, 0, 0, 0}, /* VSUBL */
5968 {1, 1, 0, 0}, /* VSUBW */
5969 {0, 1, 1, 0}, /* VADDHN */
5970 {0, 0, 0, 0}, /* VABAL */
5971 {0, 1, 1, 0}, /* VSUBHN */
5972 {0, 0, 0, 0}, /* VABDL */
5973 {0, 0, 0, 0}, /* VMLAL */
5974 {0, 0, 0, 6}, /* VQDMLAL */
5975 {0, 0, 0, 0}, /* VMLSL */
5976 {0, 0, 0, 6}, /* VQDMLSL */
5977 {0, 0, 0, 0}, /* Integer VMULL */
5978 {0, 0, 0, 2}, /* VQDMULL */
5979 {0, 0, 0, 5}, /* Polynomial VMULL */
5980 {0, 0, 0, 3}, /* Reserved: always UNDEF */
5983 prewiden
= neon_3reg_wide
[op
][0];
5984 src1_wide
= neon_3reg_wide
[op
][1];
5985 src2_wide
= neon_3reg_wide
[op
][2];
5986 undefreq
= neon_3reg_wide
[op
][3];
5988 if (((undefreq
& 1) && (size
!= 0)) ||
5989 ((undefreq
& 2) && (size
== 0)) ||
5990 ((undefreq
& 4) && u
)) {
5993 if ((src1_wide
&& (rn
& 1)) ||
5994 (src2_wide
&& (rm
& 1)) ||
5995 (!src2_wide
&& (rd
& 1))) {
5999 /* Avoid overlapping operands. Wide source operands are
6000 always aligned so will never overlap with wide
6001 destinations in problematic ways. */
6002 if (rd
== rm
&& !src2_wide
) {
6003 tmp
= neon_load_reg(rm
, 1);
6004 neon_store_scratch(2, tmp
);
6005 } else if (rd
== rn
&& !src1_wide
) {
6006 tmp
= neon_load_reg(rn
, 1);
6007 neon_store_scratch(2, tmp
);
6009 TCGV_UNUSED_I32(tmp3
);
6010 for (pass
= 0; pass
< 2; pass
++) {
6012 neon_load_reg64(cpu_V0
, rn
+ pass
);
6013 TCGV_UNUSED_I32(tmp
);
6015 if (pass
== 1 && rd
== rn
) {
6016 tmp
= neon_load_scratch(2);
6018 tmp
= neon_load_reg(rn
, pass
);
6021 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6025 neon_load_reg64(cpu_V1
, rm
+ pass
);
6026 TCGV_UNUSED_I32(tmp2
);
6028 if (pass
== 1 && rd
== rm
) {
6029 tmp2
= neon_load_scratch(2);
6031 tmp2
= neon_load_reg(rm
, pass
);
6034 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
6038 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6039 gen_neon_addl(size
);
6041 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6042 gen_neon_subl(size
);
6044 case 5: case 7: /* VABAL, VABDL */
6045 switch ((size
<< 1) | u
) {
6047 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
6050 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
6053 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
6056 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
6059 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
6062 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
6066 tcg_temp_free_i32(tmp2
);
6067 tcg_temp_free_i32(tmp
);
6069 case 8: case 9: case 10: case 11: case 12: case 13:
6070 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6071 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6073 case 14: /* Polynomial VMULL */
6074 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
6075 tcg_temp_free_i32(tmp2
);
6076 tcg_temp_free_i32(tmp
);
6078 default: /* 15 is RESERVED: caught earlier */
6083 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6084 neon_store_reg64(cpu_V0
, rd
+ pass
);
6085 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
6087 neon_load_reg64(cpu_V1
, rd
+ pass
);
6089 case 10: /* VMLSL */
6090 gen_neon_negl(cpu_V0
, size
);
6092 case 5: case 8: /* VABAL, VMLAL */
6093 gen_neon_addl(size
);
6095 case 9: case 11: /* VQDMLAL, VQDMLSL */
6096 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6098 gen_neon_negl(cpu_V0
, size
);
6100 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6105 neon_store_reg64(cpu_V0
, rd
+ pass
);
6106 } else if (op
== 4 || op
== 6) {
6107 /* Narrowing operation. */
6108 tmp
= tcg_temp_new_i32();
6112 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
6115 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
6118 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6119 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
6126 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
6129 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
6132 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
6133 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6134 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
6142 neon_store_reg(rd
, 0, tmp3
);
6143 neon_store_reg(rd
, 1, tmp
);
6146 /* Write back the result. */
6147 neon_store_reg64(cpu_V0
, rd
+ pass
);
6151 /* Two registers and a scalar. NB that for ops of this form
6152 * the ARM ARM labels bit 24 as Q, but it is in our variable
6159 case 1: /* Float VMLA scalar */
6160 case 5: /* Floating point VMLS scalar */
6161 case 9: /* Floating point VMUL scalar */
6166 case 0: /* Integer VMLA scalar */
6167 case 4: /* Integer VMLS scalar */
6168 case 8: /* Integer VMUL scalar */
6169 case 12: /* VQDMULH scalar */
6170 case 13: /* VQRDMULH scalar */
6171 if (u
&& ((rd
| rn
) & 1)) {
6174 tmp
= neon_get_scalar(size
, rm
);
6175 neon_store_scratch(0, tmp
);
6176 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6177 tmp
= neon_load_scratch(0);
6178 tmp2
= neon_load_reg(rn
, pass
);
6181 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6183 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6185 } else if (op
== 13) {
6187 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6189 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6191 } else if (op
& 1) {
6192 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6193 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6194 tcg_temp_free_ptr(fpstatus
);
6197 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6198 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6199 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6203 tcg_temp_free_i32(tmp2
);
6206 tmp2
= neon_load_reg(rd
, pass
);
6209 gen_neon_add(size
, tmp
, tmp2
);
6213 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6214 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6215 tcg_temp_free_ptr(fpstatus
);
6219 gen_neon_rsb(size
, tmp
, tmp2
);
6223 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6224 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6225 tcg_temp_free_ptr(fpstatus
);
6231 tcg_temp_free_i32(tmp2
);
6233 neon_store_reg(rd
, pass
, tmp
);
6236 case 3: /* VQDMLAL scalar */
6237 case 7: /* VQDMLSL scalar */
6238 case 11: /* VQDMULL scalar */
6243 case 2: /* VMLAL sclar */
6244 case 6: /* VMLSL scalar */
6245 case 10: /* VMULL scalar */
6249 tmp2
= neon_get_scalar(size
, rm
);
6250 /* We need a copy of tmp2 because gen_neon_mull
6251 * deletes it during pass 0. */
6252 tmp4
= tcg_temp_new_i32();
6253 tcg_gen_mov_i32(tmp4
, tmp2
);
6254 tmp3
= neon_load_reg(rn
, 1);
6256 for (pass
= 0; pass
< 2; pass
++) {
6258 tmp
= neon_load_reg(rn
, 0);
6263 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6265 neon_load_reg64(cpu_V1
, rd
+ pass
);
6269 gen_neon_negl(cpu_V0
, size
);
6272 gen_neon_addl(size
);
6275 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6277 gen_neon_negl(cpu_V0
, size
);
6279 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6285 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6290 neon_store_reg64(cpu_V0
, rd
+ pass
);
6295 default: /* 14 and 15 are RESERVED */
6299 } else { /* size == 3 */
6302 imm
= (insn
>> 8) & 0xf;
6307 if (q
&& ((rd
| rn
| rm
) & 1)) {
6312 neon_load_reg64(cpu_V0
, rn
);
6314 neon_load_reg64(cpu_V1
, rn
+ 1);
6316 } else if (imm
== 8) {
6317 neon_load_reg64(cpu_V0
, rn
+ 1);
6319 neon_load_reg64(cpu_V1
, rm
);
6322 tmp64
= tcg_temp_new_i64();
6324 neon_load_reg64(cpu_V0
, rn
);
6325 neon_load_reg64(tmp64
, rn
+ 1);
6327 neon_load_reg64(cpu_V0
, rn
+ 1);
6328 neon_load_reg64(tmp64
, rm
);
6330 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
6331 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
6332 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6334 neon_load_reg64(cpu_V1
, rm
);
6336 neon_load_reg64(cpu_V1
, rm
+ 1);
6339 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6340 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
6341 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
6342 tcg_temp_free_i64(tmp64
);
6345 neon_load_reg64(cpu_V0
, rn
);
6346 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
6347 neon_load_reg64(cpu_V1
, rm
);
6348 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6349 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6351 neon_store_reg64(cpu_V0
, rd
);
6353 neon_store_reg64(cpu_V1
, rd
+ 1);
6355 } else if ((insn
& (1 << 11)) == 0) {
6356 /* Two register misc. */
6357 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
6358 size
= (insn
>> 18) & 3;
6359 /* UNDEF for unknown op values and bad op-size combinations */
6360 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
6363 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
6364 q
&& ((rm
| rd
) & 1)) {
6368 case NEON_2RM_VREV64
:
6369 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
6370 tmp
= neon_load_reg(rm
, pass
* 2);
6371 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
6373 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6374 case 1: gen_swap_half(tmp
); break;
6375 case 2: /* no-op */ break;
6378 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
6380 neon_store_reg(rd
, pass
* 2, tmp2
);
6383 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
6384 case 1: gen_swap_half(tmp2
); break;
6387 neon_store_reg(rd
, pass
* 2, tmp2
);
6391 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
6392 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
6393 for (pass
= 0; pass
< q
+ 1; pass
++) {
6394 tmp
= neon_load_reg(rm
, pass
* 2);
6395 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
6396 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
6397 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
6399 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
6400 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
6401 case 2: tcg_gen_add_i64(CPU_V001
); break;
6404 if (op
>= NEON_2RM_VPADAL
) {
6406 neon_load_reg64(cpu_V1
, rd
+ pass
);
6407 gen_neon_addl(size
);
6409 neon_store_reg64(cpu_V0
, rd
+ pass
);
6415 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
6416 tmp
= neon_load_reg(rm
, n
);
6417 tmp2
= neon_load_reg(rd
, n
+ 1);
6418 neon_store_reg(rm
, n
, tmp2
);
6419 neon_store_reg(rd
, n
+ 1, tmp
);
6426 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
6431 if (gen_neon_zip(rd
, rm
, size
, q
)) {
6435 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
6436 /* also VQMOVUN; op field and mnemonics don't line up */
6440 TCGV_UNUSED_I32(tmp2
);
6441 for (pass
= 0; pass
< 2; pass
++) {
6442 neon_load_reg64(cpu_V0
, rm
+ pass
);
6443 tmp
= tcg_temp_new_i32();
6444 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
6449 neon_store_reg(rd
, 0, tmp2
);
6450 neon_store_reg(rd
, 1, tmp
);
6454 case NEON_2RM_VSHLL
:
6455 if (q
|| (rd
& 1)) {
6458 tmp
= neon_load_reg(rm
, 0);
6459 tmp2
= neon_load_reg(rm
, 1);
6460 for (pass
= 0; pass
< 2; pass
++) {
6463 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
6464 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
6465 neon_store_reg64(cpu_V0
, rd
+ pass
);
6468 case NEON_2RM_VCVT_F16_F32
:
6469 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
6473 tmp
= tcg_temp_new_i32();
6474 tmp2
= tcg_temp_new_i32();
6475 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
6476 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6477 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
6478 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6479 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6480 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6481 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
6482 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6483 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
6484 neon_store_reg(rd
, 0, tmp2
);
6485 tmp2
= tcg_temp_new_i32();
6486 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6487 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6488 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6489 neon_store_reg(rd
, 1, tmp2
);
6490 tcg_temp_free_i32(tmp
);
6492 case NEON_2RM_VCVT_F32_F16
:
6493 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
6497 tmp3
= tcg_temp_new_i32();
6498 tmp
= neon_load_reg(rm
, 0);
6499 tmp2
= neon_load_reg(rm
, 1);
6500 tcg_gen_ext16u_i32(tmp3
, tmp
);
6501 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6502 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
6503 tcg_gen_shri_i32(tmp3
, tmp
, 16);
6504 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6505 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
6506 tcg_temp_free_i32(tmp
);
6507 tcg_gen_ext16u_i32(tmp3
, tmp2
);
6508 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6509 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
6510 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
6511 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6512 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
6513 tcg_temp_free_i32(tmp2
);
6514 tcg_temp_free_i32(tmp3
);
6516 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
6517 if (!arm_feature(env
, ARM_FEATURE_V8_AES
)
6518 || ((rm
| rd
) & 1)) {
6521 tmp
= tcg_const_i32(rd
);
6522 tmp2
= tcg_const_i32(rm
);
6524 /* Bit 6 is the lowest opcode bit; it distinguishes between
6525 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6527 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
6529 if (op
== NEON_2RM_AESE
) {
6530 gen_helper_crypto_aese(cpu_env
, tmp
, tmp2
, tmp3
);
6532 gen_helper_crypto_aesmc(cpu_env
, tmp
, tmp2
, tmp3
);
6534 tcg_temp_free_i32(tmp
);
6535 tcg_temp_free_i32(tmp2
);
6536 tcg_temp_free_i32(tmp3
);
6538 case NEON_2RM_SHA1H
:
6539 if (!arm_feature(env
, ARM_FEATURE_V8_SHA1
)
6540 || ((rm
| rd
) & 1)) {
6543 tmp
= tcg_const_i32(rd
);
6544 tmp2
= tcg_const_i32(rm
);
6546 gen_helper_crypto_sha1h(cpu_env
, tmp
, tmp2
);
6548 tcg_temp_free_i32(tmp
);
6549 tcg_temp_free_i32(tmp2
);
6551 case NEON_2RM_SHA1SU1
:
6552 if ((rm
| rd
) & 1) {
6555 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6557 if (!arm_feature(env
, ARM_FEATURE_V8_SHA256
)) {
6560 } else if (!arm_feature(env
, ARM_FEATURE_V8_SHA1
)) {
6563 tmp
= tcg_const_i32(rd
);
6564 tmp2
= tcg_const_i32(rm
);
6566 gen_helper_crypto_sha256su0(cpu_env
, tmp
, tmp2
);
6568 gen_helper_crypto_sha1su1(cpu_env
, tmp
, tmp2
);
6570 tcg_temp_free_i32(tmp
);
6571 tcg_temp_free_i32(tmp2
);
6575 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6576 if (neon_2rm_is_float_op(op
)) {
6577 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
6578 neon_reg_offset(rm
, pass
));
6579 TCGV_UNUSED_I32(tmp
);
6581 tmp
= neon_load_reg(rm
, pass
);
6584 case NEON_2RM_VREV32
:
6586 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6587 case 1: gen_swap_half(tmp
); break;
6591 case NEON_2RM_VREV16
:
6596 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
6597 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
6598 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
6604 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
6605 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
6606 case 2: gen_helper_clz(tmp
, tmp
); break;
6611 gen_helper_neon_cnt_u8(tmp
, tmp
);
6614 tcg_gen_not_i32(tmp
, tmp
);
6616 case NEON_2RM_VQABS
:
6619 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
6622 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
6625 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
6630 case NEON_2RM_VQNEG
:
6633 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
6636 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
6639 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
6644 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
6645 tmp2
= tcg_const_i32(0);
6647 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
6648 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
6649 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
6652 tcg_temp_free_i32(tmp2
);
6653 if (op
== NEON_2RM_VCLE0
) {
6654 tcg_gen_not_i32(tmp
, tmp
);
6657 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
6658 tmp2
= tcg_const_i32(0);
6660 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
6661 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
6662 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
6665 tcg_temp_free_i32(tmp2
);
6666 if (op
== NEON_2RM_VCLT0
) {
6667 tcg_gen_not_i32(tmp
, tmp
);
6670 case NEON_2RM_VCEQ0
:
6671 tmp2
= tcg_const_i32(0);
6673 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
6674 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
6675 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
6678 tcg_temp_free_i32(tmp2
);
6682 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
6683 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
6684 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
6689 tmp2
= tcg_const_i32(0);
6690 gen_neon_rsb(size
, tmp
, tmp2
);
6691 tcg_temp_free_i32(tmp2
);
6693 case NEON_2RM_VCGT0_F
:
6695 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6696 tmp2
= tcg_const_i32(0);
6697 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6698 tcg_temp_free_i32(tmp2
);
6699 tcg_temp_free_ptr(fpstatus
);
6702 case NEON_2RM_VCGE0_F
:
6704 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6705 tmp2
= tcg_const_i32(0);
6706 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6707 tcg_temp_free_i32(tmp2
);
6708 tcg_temp_free_ptr(fpstatus
);
6711 case NEON_2RM_VCEQ0_F
:
6713 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6714 tmp2
= tcg_const_i32(0);
6715 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6716 tcg_temp_free_i32(tmp2
);
6717 tcg_temp_free_ptr(fpstatus
);
6720 case NEON_2RM_VCLE0_F
:
6722 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6723 tmp2
= tcg_const_i32(0);
6724 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
6725 tcg_temp_free_i32(tmp2
);
6726 tcg_temp_free_ptr(fpstatus
);
6729 case NEON_2RM_VCLT0_F
:
6731 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6732 tmp2
= tcg_const_i32(0);
6733 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
6734 tcg_temp_free_i32(tmp2
);
6735 tcg_temp_free_ptr(fpstatus
);
6738 case NEON_2RM_VABS_F
:
6741 case NEON_2RM_VNEG_F
:
6745 tmp2
= neon_load_reg(rd
, pass
);
6746 neon_store_reg(rm
, pass
, tmp2
);
6749 tmp2
= neon_load_reg(rd
, pass
);
6751 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
6752 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
6755 neon_store_reg(rm
, pass
, tmp2
);
6757 case NEON_2RM_VRINTN
:
6758 case NEON_2RM_VRINTA
:
6759 case NEON_2RM_VRINTM
:
6760 case NEON_2RM_VRINTP
:
6761 case NEON_2RM_VRINTZ
:
6764 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6767 if (op
== NEON_2RM_VRINTZ
) {
6768 rmode
= FPROUNDING_ZERO
;
6770 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
6773 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
6774 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6776 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpstatus
);
6777 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6779 tcg_temp_free_ptr(fpstatus
);
6780 tcg_temp_free_i32(tcg_rmode
);
6783 case NEON_2RM_VRINTX
:
6785 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6786 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpstatus
);
6787 tcg_temp_free_ptr(fpstatus
);
6790 case NEON_2RM_VCVTAU
:
6791 case NEON_2RM_VCVTAS
:
6792 case NEON_2RM_VCVTNU
:
6793 case NEON_2RM_VCVTNS
:
6794 case NEON_2RM_VCVTPU
:
6795 case NEON_2RM_VCVTPS
:
6796 case NEON_2RM_VCVTMU
:
6797 case NEON_2RM_VCVTMS
:
6799 bool is_signed
= !extract32(insn
, 7, 1);
6800 TCGv_ptr fpst
= get_fpstatus_ptr(1);
6801 TCGv_i32 tcg_rmode
, tcg_shift
;
6802 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
6804 tcg_shift
= tcg_const_i32(0);
6805 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
6806 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6810 gen_helper_vfp_tosls(cpu_F0s
, cpu_F0s
,
6813 gen_helper_vfp_touls(cpu_F0s
, cpu_F0s
,
6817 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6819 tcg_temp_free_i32(tcg_rmode
);
6820 tcg_temp_free_i32(tcg_shift
);
6821 tcg_temp_free_ptr(fpst
);
6824 case NEON_2RM_VRECPE
:
6826 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6827 gen_helper_recpe_u32(tmp
, tmp
, fpstatus
);
6828 tcg_temp_free_ptr(fpstatus
);
6831 case NEON_2RM_VRSQRTE
:
6833 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6834 gen_helper_rsqrte_u32(tmp
, tmp
, fpstatus
);
6835 tcg_temp_free_ptr(fpstatus
);
6838 case NEON_2RM_VRECPE_F
:
6840 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6841 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
6842 tcg_temp_free_ptr(fpstatus
);
6845 case NEON_2RM_VRSQRTE_F
:
6847 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6848 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
6849 tcg_temp_free_ptr(fpstatus
);
6852 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
6855 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
6858 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
6859 gen_vfp_tosiz(0, 1);
6861 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
6862 gen_vfp_touiz(0, 1);
6865 /* Reserved op values were caught by the
6866 * neon_2rm_sizes[] check earlier.
6870 if (neon_2rm_is_float_op(op
)) {
6871 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
6872 neon_reg_offset(rd
, pass
));
6874 neon_store_reg(rd
, pass
, tmp
);
6879 } else if ((insn
& (1 << 10)) == 0) {
6881 int n
= ((insn
>> 8) & 3) + 1;
6882 if ((rn
+ n
) > 32) {
6883 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6884 * helper function running off the end of the register file.
6889 if (insn
& (1 << 6)) {
6890 tmp
= neon_load_reg(rd
, 0);
6892 tmp
= tcg_temp_new_i32();
6893 tcg_gen_movi_i32(tmp
, 0);
6895 tmp2
= neon_load_reg(rm
, 0);
6896 tmp4
= tcg_const_i32(rn
);
6897 tmp5
= tcg_const_i32(n
);
6898 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
6899 tcg_temp_free_i32(tmp
);
6900 if (insn
& (1 << 6)) {
6901 tmp
= neon_load_reg(rd
, 1);
6903 tmp
= tcg_temp_new_i32();
6904 tcg_gen_movi_i32(tmp
, 0);
6906 tmp3
= neon_load_reg(rm
, 1);
6907 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
6908 tcg_temp_free_i32(tmp5
);
6909 tcg_temp_free_i32(tmp4
);
6910 neon_store_reg(rd
, 0, tmp2
);
6911 neon_store_reg(rd
, 1, tmp3
);
6912 tcg_temp_free_i32(tmp
);
6913 } else if ((insn
& 0x380) == 0) {
6915 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
6918 if (insn
& (1 << 19)) {
6919 tmp
= neon_load_reg(rm
, 1);
6921 tmp
= neon_load_reg(rm
, 0);
6923 if (insn
& (1 << 16)) {
6924 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
6925 } else if (insn
& (1 << 17)) {
6926 if ((insn
>> 18) & 1)
6927 gen_neon_dup_high16(tmp
);
6929 gen_neon_dup_low16(tmp
);
6931 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6932 tmp2
= tcg_temp_new_i32();
6933 tcg_gen_mov_i32(tmp2
, tmp
);
6934 neon_store_reg(rd
, pass
, tmp2
);
6936 tcg_temp_free_i32(tmp
);
6945 static int disas_coproc_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
6947 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
6948 const ARMCPRegInfo
*ri
;
6950 cpnum
= (insn
>> 8) & 0xf;
6951 if (arm_feature(env
, ARM_FEATURE_XSCALE
)
6952 && ((env
->cp15
.c15_cpar
^ 0x3fff) & (1 << cpnum
)))
6955 /* First check for coprocessor space used for actual instructions */
6959 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
6960 return disas_iwmmxt_insn(env
, s
, insn
);
6961 } else if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
6962 return disas_dsp_insn(env
, s
, insn
);
6969 /* Otherwise treat as a generic register access */
6970 is64
= (insn
& (1 << 25)) == 0;
6971 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
6979 opc1
= (insn
>> 4) & 0xf;
6981 rt2
= (insn
>> 16) & 0xf;
6983 crn
= (insn
>> 16) & 0xf;
6984 opc1
= (insn
>> 21) & 7;
6985 opc2
= (insn
>> 5) & 7;
6988 isread
= (insn
>> 20) & 1;
6989 rt
= (insn
>> 12) & 0xf;
6991 ri
= get_arm_cp_reginfo(s
->cp_regs
,
6992 ENCODE_CP_REG(cpnum
, is64
, crn
, crm
, opc1
, opc2
));
6994 /* Check access permissions */
6995 if (!cp_access_ok(s
->current_pl
, ri
, isread
)) {
7000 /* Emit code to perform further access permissions checks at
7001 * runtime; this may result in an exception.
7007 /* Note that since we are an implementation which takes an
7008 * exception on a trapped conditional instruction only if the
7009 * instruction passes its condition code check, we can take
7010 * advantage of the clause in the ARM ARM that allows us to set
7011 * the COND field in the instruction to 0xE in all cases.
7012 * We could fish the actual condition out of the insn (ARM)
7013 * or the condexec bits (Thumb) but it isn't necessary.
7018 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7021 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7022 rt
, isread
, s
->thumb
);
7027 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7030 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7031 rt
, isread
, s
->thumb
);
7035 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7036 * so this can only happen if this is an ARMv7 or earlier CPU,
7037 * in which case the syndrome information won't actually be
7040 assert(!arm_feature(env
, ARM_FEATURE_V8
));
7041 syndrome
= syn_uncategorized();
7045 gen_set_pc_im(s
, s
->pc
);
7046 tmpptr
= tcg_const_ptr(ri
);
7047 tcg_syn
= tcg_const_i32(syndrome
);
7048 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
);
7049 tcg_temp_free_ptr(tmpptr
);
7050 tcg_temp_free_i32(tcg_syn
);
7053 /* Handle special cases first */
7054 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
7061 gen_set_pc_im(s
, s
->pc
);
7062 s
->is_jmp
= DISAS_WFI
;
7068 if (use_icount
&& (ri
->type
& ARM_CP_IO
)) {
7077 if (ri
->type
& ARM_CP_CONST
) {
7078 tmp64
= tcg_const_i64(ri
->resetvalue
);
7079 } else if (ri
->readfn
) {
7081 tmp64
= tcg_temp_new_i64();
7082 tmpptr
= tcg_const_ptr(ri
);
7083 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
7084 tcg_temp_free_ptr(tmpptr
);
7086 tmp64
= tcg_temp_new_i64();
7087 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7089 tmp
= tcg_temp_new_i32();
7090 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7091 store_reg(s
, rt
, tmp
);
7092 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7093 tmp
= tcg_temp_new_i32();
7094 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7095 tcg_temp_free_i64(tmp64
);
7096 store_reg(s
, rt2
, tmp
);
7099 if (ri
->type
& ARM_CP_CONST
) {
7100 tmp
= tcg_const_i32(ri
->resetvalue
);
7101 } else if (ri
->readfn
) {
7103 tmp
= tcg_temp_new_i32();
7104 tmpptr
= tcg_const_ptr(ri
);
7105 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
7106 tcg_temp_free_ptr(tmpptr
);
7108 tmp
= load_cpu_offset(ri
->fieldoffset
);
7111 /* Destination register of r15 for 32 bit loads sets
7112 * the condition codes from the high 4 bits of the value
7115 tcg_temp_free_i32(tmp
);
7117 store_reg(s
, rt
, tmp
);
7122 if (ri
->type
& ARM_CP_CONST
) {
7123 /* If not forbidden by access permissions, treat as WI */
7128 TCGv_i32 tmplo
, tmphi
;
7129 TCGv_i64 tmp64
= tcg_temp_new_i64();
7130 tmplo
= load_reg(s
, rt
);
7131 tmphi
= load_reg(s
, rt2
);
7132 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
7133 tcg_temp_free_i32(tmplo
);
7134 tcg_temp_free_i32(tmphi
);
7136 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
7137 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
7138 tcg_temp_free_ptr(tmpptr
);
7140 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7142 tcg_temp_free_i64(tmp64
);
7147 tmp
= load_reg(s
, rt
);
7148 tmpptr
= tcg_const_ptr(ri
);
7149 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
7150 tcg_temp_free_ptr(tmpptr
);
7151 tcg_temp_free_i32(tmp
);
7153 TCGv_i32 tmp
= load_reg(s
, rt
);
7154 store_cpu_offset(tmp
, ri
->fieldoffset
);
7159 if (use_icount
&& (ri
->type
& ARM_CP_IO
)) {
7160 /* I/O operations must end the TB here (whether read or write) */
7163 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
7164 /* We default to ending the TB on a coprocessor register write,
7165 * but allow this to be suppressed by the register definition
7166 * (usually only necessary to work around guest bugs).
7174 /* Unknown register; this might be a guest error or a QEMU
7175 * unimplemented feature.
7178 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7179 "64 bit system register cp:%d opc1: %d crm:%d\n",
7180 isread
? "read" : "write", cpnum
, opc1
, crm
);
7182 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7183 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d\n",
7184 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
);
7191 /* Store a 64-bit value to a register pair. Clobbers val. */
7192 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
7195 tmp
= tcg_temp_new_i32();
7196 tcg_gen_trunc_i64_i32(tmp
, val
);
7197 store_reg(s
, rlow
, tmp
);
7198 tmp
= tcg_temp_new_i32();
7199 tcg_gen_shri_i64(val
, val
, 32);
7200 tcg_gen_trunc_i64_i32(tmp
, val
);
7201 store_reg(s
, rhigh
, tmp
);
7204 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7205 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
7210 /* Load value and extend to 64 bits. */
7211 tmp
= tcg_temp_new_i64();
7212 tmp2
= load_reg(s
, rlow
);
7213 tcg_gen_extu_i32_i64(tmp
, tmp2
);
7214 tcg_temp_free_i32(tmp2
);
7215 tcg_gen_add_i64(val
, val
, tmp
);
7216 tcg_temp_free_i64(tmp
);
7219 /* load and add a 64-bit value from a register pair. */
7220 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
7226 /* Load 64-bit value rd:rn. */
7227 tmpl
= load_reg(s
, rlow
);
7228 tmph
= load_reg(s
, rhigh
);
7229 tmp
= tcg_temp_new_i64();
7230 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
7231 tcg_temp_free_i32(tmpl
);
7232 tcg_temp_free_i32(tmph
);
7233 tcg_gen_add_i64(val
, val
, tmp
);
7234 tcg_temp_free_i64(tmp
);
7237 /* Set N and Z flags from hi|lo. */
7238 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
7240 tcg_gen_mov_i32(cpu_NF
, hi
);
7241 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
7244 /* Load/Store exclusive instructions are implemented by remembering
7245 the value/address loaded, and seeing if these are the same
7246 when the store is performed. This should be sufficient to implement
7247 the architecturally mandated semantics, and avoids having to monitor
7250 In system emulation mode only one CPU will be running at once, so
7251 this sequence is effectively atomic. In user emulation mode we
7252 throw an exception and handle the atomic operation elsewhere. */
7253 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
7254 TCGv_i32 addr
, int size
)
7256 TCGv_i32 tmp
= tcg_temp_new_i32();
7260 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
7263 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
7267 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
7274 TCGv_i32 tmp2
= tcg_temp_new_i32();
7275 TCGv_i32 tmp3
= tcg_temp_new_i32();
7277 tcg_gen_addi_i32(tmp2
, addr
, 4);
7278 gen_aa32_ld32u(tmp3
, tmp2
, get_mem_index(s
));
7279 tcg_temp_free_i32(tmp2
);
7280 tcg_gen_concat_i32_i64(cpu_exclusive_val
, tmp
, tmp3
);
7281 store_reg(s
, rt2
, tmp3
);
7283 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
7286 store_reg(s
, rt
, tmp
);
7287 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
7290 static void gen_clrex(DisasContext
*s
)
7292 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7295 #ifdef CONFIG_USER_ONLY
7296 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7297 TCGv_i32 addr
, int size
)
7299 tcg_gen_extu_i32_i64(cpu_exclusive_test
, addr
);
7300 tcg_gen_movi_i32(cpu_exclusive_info
,
7301 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
7302 gen_exception_internal_insn(s
, 4, EXCP_STREX
);
7305 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7306 TCGv_i32 addr
, int size
)
7309 TCGv_i64 val64
, extaddr
;
7313 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7319 fail_label
= gen_new_label();
7320 done_label
= gen_new_label();
7321 extaddr
= tcg_temp_new_i64();
7322 tcg_gen_extu_i32_i64(extaddr
, addr
);
7323 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
7324 tcg_temp_free_i64(extaddr
);
7326 tmp
= tcg_temp_new_i32();
7329 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
7332 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
7336 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
7342 val64
= tcg_temp_new_i64();
7344 TCGv_i32 tmp2
= tcg_temp_new_i32();
7345 TCGv_i32 tmp3
= tcg_temp_new_i32();
7346 tcg_gen_addi_i32(tmp2
, addr
, 4);
7347 gen_aa32_ld32u(tmp3
, tmp2
, get_mem_index(s
));
7348 tcg_temp_free_i32(tmp2
);
7349 tcg_gen_concat_i32_i64(val64
, tmp
, tmp3
);
7350 tcg_temp_free_i32(tmp3
);
7352 tcg_gen_extu_i32_i64(val64
, tmp
);
7354 tcg_temp_free_i32(tmp
);
7356 tcg_gen_brcond_i64(TCG_COND_NE
, val64
, cpu_exclusive_val
, fail_label
);
7357 tcg_temp_free_i64(val64
);
7359 tmp
= load_reg(s
, rt
);
7362 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
7365 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
7369 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7374 tcg_temp_free_i32(tmp
);
7376 tcg_gen_addi_i32(addr
, addr
, 4);
7377 tmp
= load_reg(s
, rt2
);
7378 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7379 tcg_temp_free_i32(tmp
);
7381 tcg_gen_movi_i32(cpu_R
[rd
], 0);
7382 tcg_gen_br(done_label
);
7383 gen_set_label(fail_label
);
7384 tcg_gen_movi_i32(cpu_R
[rd
], 1);
7385 gen_set_label(done_label
);
7386 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7393 * @mode: mode field from insn (which stack to store to)
7394 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7395 * @writeback: true if writeback bit set
7397 * Generate code for the SRS (Store Return State) insn.
7399 static void gen_srs(DisasContext
*s
,
7400 uint32_t mode
, uint32_t amode
, bool writeback
)
7403 TCGv_i32 addr
= tcg_temp_new_i32();
7404 TCGv_i32 tmp
= tcg_const_i32(mode
);
7405 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
7406 tcg_temp_free_i32(tmp
);
7423 tcg_gen_addi_i32(addr
, addr
, offset
);
7424 tmp
= load_reg(s
, 14);
7425 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7426 tcg_temp_free_i32(tmp
);
7427 tmp
= load_cpu_field(spsr
);
7428 tcg_gen_addi_i32(addr
, addr
, 4);
7429 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7430 tcg_temp_free_i32(tmp
);
7448 tcg_gen_addi_i32(addr
, addr
, offset
);
7449 tmp
= tcg_const_i32(mode
);
7450 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
7451 tcg_temp_free_i32(tmp
);
7453 tcg_temp_free_i32(addr
);
7456 static void disas_arm_insn(CPUARMState
* env
, DisasContext
*s
)
7458 unsigned int cond
, insn
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
7465 insn
= arm_ldl_code(env
, s
->pc
, s
->bswap_code
);
7468 /* M variants do not implement ARM mode. */
7473 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7474 * choose to UNDEF. In ARMv5 and above the space is used
7475 * for miscellaneous unconditional instructions.
7479 /* Unconditional instructions. */
7480 if (((insn
>> 25) & 7) == 1) {
7481 /* NEON Data processing. */
7482 if (!arm_feature(env
, ARM_FEATURE_NEON
))
7485 if (disas_neon_data_insn(env
, s
, insn
))
7489 if ((insn
& 0x0f100000) == 0x04000000) {
7490 /* NEON load/store. */
7491 if (!arm_feature(env
, ARM_FEATURE_NEON
))
7494 if (disas_neon_ls_insn(env
, s
, insn
))
7498 if ((insn
& 0x0f000e10) == 0x0e000a00) {
7500 if (disas_vfp_insn(env
, s
, insn
)) {
7505 if (((insn
& 0x0f30f000) == 0x0510f000) ||
7506 ((insn
& 0x0f30f010) == 0x0710f000)) {
7507 if ((insn
& (1 << 22)) == 0) {
7509 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
7513 /* Otherwise PLD; v5TE+ */
7517 if (((insn
& 0x0f70f000) == 0x0450f000) ||
7518 ((insn
& 0x0f70f010) == 0x0650f000)) {
7520 return; /* PLI; V7 */
7522 if (((insn
& 0x0f700000) == 0x04100000) ||
7523 ((insn
& 0x0f700010) == 0x06100000)) {
7524 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
7527 return; /* v7MP: Unallocated memory hint: must NOP */
7530 if ((insn
& 0x0ffffdff) == 0x01010000) {
7533 if (((insn
>> 9) & 1) != s
->bswap_code
) {
7534 /* Dynamic endianness switching not implemented. */
7535 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
7539 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
7540 switch ((insn
>> 4) & 0xf) {
7549 /* We don't emulate caches so these are a no-op. */
7554 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
7560 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
7562 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
7568 rn
= (insn
>> 16) & 0xf;
7569 addr
= load_reg(s
, rn
);
7570 i
= (insn
>> 23) & 3;
7572 case 0: offset
= -4; break; /* DA */
7573 case 1: offset
= 0; break; /* IA */
7574 case 2: offset
= -8; break; /* DB */
7575 case 3: offset
= 4; break; /* IB */
7579 tcg_gen_addi_i32(addr
, addr
, offset
);
7580 /* Load PC into tmp and CPSR into tmp2. */
7581 tmp
= tcg_temp_new_i32();
7582 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
7583 tcg_gen_addi_i32(addr
, addr
, 4);
7584 tmp2
= tcg_temp_new_i32();
7585 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
7586 if (insn
& (1 << 21)) {
7587 /* Base writeback. */
7589 case 0: offset
= -8; break;
7590 case 1: offset
= 4; break;
7591 case 2: offset
= -4; break;
7592 case 3: offset
= 0; break;
7596 tcg_gen_addi_i32(addr
, addr
, offset
);
7597 store_reg(s
, rn
, addr
);
7599 tcg_temp_free_i32(addr
);
7601 gen_rfe(s
, tmp
, tmp2
);
7603 } else if ((insn
& 0x0e000000) == 0x0a000000) {
7604 /* branch link and change to thumb (blx <offset>) */
7607 val
= (uint32_t)s
->pc
;
7608 tmp
= tcg_temp_new_i32();
7609 tcg_gen_movi_i32(tmp
, val
);
7610 store_reg(s
, 14, tmp
);
7611 /* Sign-extend the 24-bit offset */
7612 offset
= (((int32_t)insn
) << 8) >> 8;
7613 /* offset * 4 + bit24 * 2 + (thumb bit) */
7614 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
7615 /* pipeline offset */
7617 /* protected by ARCH(5); above, near the start of uncond block */
7620 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
7621 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
7622 /* iWMMXt register transfer. */
7623 if (env
->cp15
.c15_cpar
& (1 << 1))
7624 if (!disas_iwmmxt_insn(env
, s
, insn
))
7627 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
7628 /* Coprocessor double register transfer. */
7630 } else if ((insn
& 0x0f000010) == 0x0e000010) {
7631 /* Additional coprocessor register transfer. */
7632 } else if ((insn
& 0x0ff10020) == 0x01000000) {
7635 /* cps (privileged) */
7639 if (insn
& (1 << 19)) {
7640 if (insn
& (1 << 8))
7642 if (insn
& (1 << 7))
7644 if (insn
& (1 << 6))
7646 if (insn
& (1 << 18))
7649 if (insn
& (1 << 17)) {
7651 val
|= (insn
& 0x1f);
7654 gen_set_psr_im(s
, mask
, 0, val
);
7661 /* if not always execute, we generate a conditional jump to
7663 s
->condlabel
= gen_new_label();
7664 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
7667 if ((insn
& 0x0f900000) == 0x03000000) {
7668 if ((insn
& (1 << 21)) == 0) {
7670 rd
= (insn
>> 12) & 0xf;
7671 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
7672 if ((insn
& (1 << 22)) == 0) {
7674 tmp
= tcg_temp_new_i32();
7675 tcg_gen_movi_i32(tmp
, val
);
7678 tmp
= load_reg(s
, rd
);
7679 tcg_gen_ext16u_i32(tmp
, tmp
);
7680 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
7682 store_reg(s
, rd
, tmp
);
7684 if (((insn
>> 12) & 0xf) != 0xf)
7686 if (((insn
>> 16) & 0xf) == 0) {
7687 gen_nop_hint(s
, insn
& 0xff);
7689 /* CPSR = immediate */
7691 shift
= ((insn
>> 8) & 0xf) * 2;
7693 val
= (val
>> shift
) | (val
<< (32 - shift
));
7694 i
= ((insn
& (1 << 22)) != 0);
7695 if (gen_set_psr_im(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, val
))
7699 } else if ((insn
& 0x0f900000) == 0x01000000
7700 && (insn
& 0x00000090) != 0x00000090) {
7701 /* miscellaneous instructions */
7702 op1
= (insn
>> 21) & 3;
7703 sh
= (insn
>> 4) & 0xf;
7706 case 0x0: /* move program status register */
7709 tmp
= load_reg(s
, rm
);
7710 i
= ((op1
& 2) != 0);
7711 if (gen_set_psr(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
7715 rd
= (insn
>> 12) & 0xf;
7719 tmp
= load_cpu_field(spsr
);
7721 tmp
= tcg_temp_new_i32();
7722 gen_helper_cpsr_read(tmp
, cpu_env
);
7724 store_reg(s
, rd
, tmp
);
7729 /* branch/exchange thumb (bx). */
7731 tmp
= load_reg(s
, rm
);
7733 } else if (op1
== 3) {
7736 rd
= (insn
>> 12) & 0xf;
7737 tmp
= load_reg(s
, rm
);
7738 gen_helper_clz(tmp
, tmp
);
7739 store_reg(s
, rd
, tmp
);
7747 /* Trivial implementation equivalent to bx. */
7748 tmp
= load_reg(s
, rm
);
7759 /* branch link/exchange thumb (blx) */
7760 tmp
= load_reg(s
, rm
);
7761 tmp2
= tcg_temp_new_i32();
7762 tcg_gen_movi_i32(tmp2
, s
->pc
);
7763 store_reg(s
, 14, tmp2
);
7769 uint32_t c
= extract32(insn
, 8, 4);
7771 /* Check this CPU supports ARMv8 CRC instructions.
7772 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
7773 * Bits 8, 10 and 11 should be zero.
7775 if (!arm_feature(env
, ARM_FEATURE_CRC
) || op1
== 0x3 ||
7780 rn
= extract32(insn
, 16, 4);
7781 rd
= extract32(insn
, 12, 4);
7783 tmp
= load_reg(s
, rn
);
7784 tmp2
= load_reg(s
, rm
);
7785 tmp3
= tcg_const_i32(1 << op1
);
7787 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
7789 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
7791 tcg_temp_free_i32(tmp2
);
7792 tcg_temp_free_i32(tmp3
);
7793 store_reg(s
, rd
, tmp
);
7796 case 0x5: /* saturating add/subtract */
7798 rd
= (insn
>> 12) & 0xf;
7799 rn
= (insn
>> 16) & 0xf;
7800 tmp
= load_reg(s
, rm
);
7801 tmp2
= load_reg(s
, rn
);
7803 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
7805 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
7807 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
7808 tcg_temp_free_i32(tmp2
);
7809 store_reg(s
, rd
, tmp
);
7813 int imm16
= extract32(insn
, 0, 4) | (extract32(insn
, 8, 12) << 4);
7814 /* SMC instruction (op1 == 3)
7815 and undefined instructions (op1 == 0 || op1 == 2)
7822 gen_exception_insn(s
, 4, EXCP_BKPT
, syn_aa32_bkpt(imm16
, false));
7825 case 0x8: /* signed multiply */
7830 rs
= (insn
>> 8) & 0xf;
7831 rn
= (insn
>> 12) & 0xf;
7832 rd
= (insn
>> 16) & 0xf;
7834 /* (32 * 16) >> 16 */
7835 tmp
= load_reg(s
, rm
);
7836 tmp2
= load_reg(s
, rs
);
7838 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
7841 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7842 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
7843 tmp
= tcg_temp_new_i32();
7844 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7845 tcg_temp_free_i64(tmp64
);
7846 if ((sh
& 2) == 0) {
7847 tmp2
= load_reg(s
, rn
);
7848 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7849 tcg_temp_free_i32(tmp2
);
7851 store_reg(s
, rd
, tmp
);
7854 tmp
= load_reg(s
, rm
);
7855 tmp2
= load_reg(s
, rs
);
7856 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
7857 tcg_temp_free_i32(tmp2
);
7859 tmp64
= tcg_temp_new_i64();
7860 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7861 tcg_temp_free_i32(tmp
);
7862 gen_addq(s
, tmp64
, rn
, rd
);
7863 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7864 tcg_temp_free_i64(tmp64
);
7867 tmp2
= load_reg(s
, rn
);
7868 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7869 tcg_temp_free_i32(tmp2
);
7871 store_reg(s
, rd
, tmp
);
7878 } else if (((insn
& 0x0e000000) == 0 &&
7879 (insn
& 0x00000090) != 0x90) ||
7880 ((insn
& 0x0e000000) == (1 << 25))) {
7881 int set_cc
, logic_cc
, shiftop
;
7883 op1
= (insn
>> 21) & 0xf;
7884 set_cc
= (insn
>> 20) & 1;
7885 logic_cc
= table_logic_cc
[op1
] & set_cc
;
7887 /* data processing instruction */
7888 if (insn
& (1 << 25)) {
7889 /* immediate operand */
7891 shift
= ((insn
>> 8) & 0xf) * 2;
7893 val
= (val
>> shift
) | (val
<< (32 - shift
));
7895 tmp2
= tcg_temp_new_i32();
7896 tcg_gen_movi_i32(tmp2
, val
);
7897 if (logic_cc
&& shift
) {
7898 gen_set_CF_bit31(tmp2
);
7903 tmp2
= load_reg(s
, rm
);
7904 shiftop
= (insn
>> 5) & 3;
7905 if (!(insn
& (1 << 4))) {
7906 shift
= (insn
>> 7) & 0x1f;
7907 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
7909 rs
= (insn
>> 8) & 0xf;
7910 tmp
= load_reg(s
, rs
);
7911 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
7914 if (op1
!= 0x0f && op1
!= 0x0d) {
7915 rn
= (insn
>> 16) & 0xf;
7916 tmp
= load_reg(s
, rn
);
7918 TCGV_UNUSED_I32(tmp
);
7920 rd
= (insn
>> 12) & 0xf;
7923 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
7927 store_reg_bx(env
, s
, rd
, tmp
);
7930 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
7934 store_reg_bx(env
, s
, rd
, tmp
);
7937 if (set_cc
&& rd
== 15) {
7938 /* SUBS r15, ... is used for exception return. */
7942 gen_sub_CC(tmp
, tmp
, tmp2
);
7943 gen_exception_return(s
, tmp
);
7946 gen_sub_CC(tmp
, tmp
, tmp2
);
7948 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7950 store_reg_bx(env
, s
, rd
, tmp
);
7955 gen_sub_CC(tmp
, tmp2
, tmp
);
7957 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7959 store_reg_bx(env
, s
, rd
, tmp
);
7963 gen_add_CC(tmp
, tmp
, tmp2
);
7965 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7967 store_reg_bx(env
, s
, rd
, tmp
);
7971 gen_adc_CC(tmp
, tmp
, tmp2
);
7973 gen_add_carry(tmp
, tmp
, tmp2
);
7975 store_reg_bx(env
, s
, rd
, tmp
);
7979 gen_sbc_CC(tmp
, tmp
, tmp2
);
7981 gen_sub_carry(tmp
, tmp
, tmp2
);
7983 store_reg_bx(env
, s
, rd
, tmp
);
7987 gen_sbc_CC(tmp
, tmp2
, tmp
);
7989 gen_sub_carry(tmp
, tmp2
, tmp
);
7991 store_reg_bx(env
, s
, rd
, tmp
);
7995 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
7998 tcg_temp_free_i32(tmp
);
8002 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8005 tcg_temp_free_i32(tmp
);
8009 gen_sub_CC(tmp
, tmp
, tmp2
);
8011 tcg_temp_free_i32(tmp
);
8015 gen_add_CC(tmp
, tmp
, tmp2
);
8017 tcg_temp_free_i32(tmp
);
8020 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8024 store_reg_bx(env
, s
, rd
, tmp
);
8027 if (logic_cc
&& rd
== 15) {
8028 /* MOVS r15, ... is used for exception return. */
8032 gen_exception_return(s
, tmp2
);
8037 store_reg_bx(env
, s
, rd
, tmp2
);
8041 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
8045 store_reg_bx(env
, s
, rd
, tmp
);
8049 tcg_gen_not_i32(tmp2
, tmp2
);
8053 store_reg_bx(env
, s
, rd
, tmp2
);
8056 if (op1
!= 0x0f && op1
!= 0x0d) {
8057 tcg_temp_free_i32(tmp2
);
8060 /* other instructions */
8061 op1
= (insn
>> 24) & 0xf;
8065 /* multiplies, extra load/stores */
8066 sh
= (insn
>> 5) & 3;
8069 rd
= (insn
>> 16) & 0xf;
8070 rn
= (insn
>> 12) & 0xf;
8071 rs
= (insn
>> 8) & 0xf;
8073 op1
= (insn
>> 20) & 0xf;
8075 case 0: case 1: case 2: case 3: case 6:
8077 tmp
= load_reg(s
, rs
);
8078 tmp2
= load_reg(s
, rm
);
8079 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8080 tcg_temp_free_i32(tmp2
);
8081 if (insn
& (1 << 22)) {
8082 /* Subtract (mls) */
8084 tmp2
= load_reg(s
, rn
);
8085 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8086 tcg_temp_free_i32(tmp2
);
8087 } else if (insn
& (1 << 21)) {
8089 tmp2
= load_reg(s
, rn
);
8090 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8091 tcg_temp_free_i32(tmp2
);
8093 if (insn
& (1 << 20))
8095 store_reg(s
, rd
, tmp
);
8098 /* 64 bit mul double accumulate (UMAAL) */
8100 tmp
= load_reg(s
, rs
);
8101 tmp2
= load_reg(s
, rm
);
8102 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8103 gen_addq_lo(s
, tmp64
, rn
);
8104 gen_addq_lo(s
, tmp64
, rd
);
8105 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8106 tcg_temp_free_i64(tmp64
);
8108 case 8: case 9: case 10: case 11:
8109 case 12: case 13: case 14: case 15:
8110 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8111 tmp
= load_reg(s
, rs
);
8112 tmp2
= load_reg(s
, rm
);
8113 if (insn
& (1 << 22)) {
8114 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
8116 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
8118 if (insn
& (1 << 21)) { /* mult accumulate */
8119 TCGv_i32 al
= load_reg(s
, rn
);
8120 TCGv_i32 ah
= load_reg(s
, rd
);
8121 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
8122 tcg_temp_free_i32(al
);
8123 tcg_temp_free_i32(ah
);
8125 if (insn
& (1 << 20)) {
8126 gen_logicq_cc(tmp
, tmp2
);
8128 store_reg(s
, rn
, tmp
);
8129 store_reg(s
, rd
, tmp2
);
8135 rn
= (insn
>> 16) & 0xf;
8136 rd
= (insn
>> 12) & 0xf;
8137 if (insn
& (1 << 23)) {
8138 /* load/store exclusive */
8139 int op2
= (insn
>> 8) & 3;
8140 op1
= (insn
>> 21) & 0x3;
8143 case 0: /* lda/stl */
8149 case 1: /* reserved */
8151 case 2: /* ldaex/stlex */
8154 case 3: /* ldrex/strex */
8163 addr
= tcg_temp_local_new_i32();
8164 load_reg_var(s
, addr
, rn
);
8166 /* Since the emulation does not have barriers,
8167 the acquire/release semantics need no special
8170 if (insn
& (1 << 20)) {
8171 tmp
= tcg_temp_new_i32();
8174 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8177 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
8180 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
8185 store_reg(s
, rd
, tmp
);
8188 tmp
= load_reg(s
, rm
);
8191 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8194 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
8197 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
8202 tcg_temp_free_i32(tmp
);
8204 } else if (insn
& (1 << 20)) {
8207 gen_load_exclusive(s
, rd
, 15, addr
, 2);
8209 case 1: /* ldrexd */
8210 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
8212 case 2: /* ldrexb */
8213 gen_load_exclusive(s
, rd
, 15, addr
, 0);
8215 case 3: /* ldrexh */
8216 gen_load_exclusive(s
, rd
, 15, addr
, 1);
8225 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
8227 case 1: /* strexd */
8228 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
8230 case 2: /* strexb */
8231 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
8233 case 3: /* strexh */
8234 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
8240 tcg_temp_free_i32(addr
);
8242 /* SWP instruction */
8245 /* ??? This is not really atomic. However we know
8246 we never have multiple CPUs running in parallel,
8247 so it is good enough. */
8248 addr
= load_reg(s
, rn
);
8249 tmp
= load_reg(s
, rm
);
8250 tmp2
= tcg_temp_new_i32();
8251 if (insn
& (1 << 22)) {
8252 gen_aa32_ld8u(tmp2
, addr
, get_mem_index(s
));
8253 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
8255 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
8256 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8258 tcg_temp_free_i32(tmp
);
8259 tcg_temp_free_i32(addr
);
8260 store_reg(s
, rd
, tmp2
);
8266 /* Misc load/store */
8267 rn
= (insn
>> 16) & 0xf;
8268 rd
= (insn
>> 12) & 0xf;
8269 addr
= load_reg(s
, rn
);
8270 if (insn
& (1 << 24))
8271 gen_add_datah_offset(s
, insn
, 0, addr
);
8273 if (insn
& (1 << 20)) {
8275 tmp
= tcg_temp_new_i32();
8278 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
8281 gen_aa32_ld8s(tmp
, addr
, get_mem_index(s
));
8285 gen_aa32_ld16s(tmp
, addr
, get_mem_index(s
));
8289 } else if (sh
& 2) {
8294 tmp
= load_reg(s
, rd
);
8295 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8296 tcg_temp_free_i32(tmp
);
8297 tcg_gen_addi_i32(addr
, addr
, 4);
8298 tmp
= load_reg(s
, rd
+ 1);
8299 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8300 tcg_temp_free_i32(tmp
);
8304 tmp
= tcg_temp_new_i32();
8305 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8306 store_reg(s
, rd
, tmp
);
8307 tcg_gen_addi_i32(addr
, addr
, 4);
8308 tmp
= tcg_temp_new_i32();
8309 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8313 address_offset
= -4;
8316 tmp
= load_reg(s
, rd
);
8317 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
8318 tcg_temp_free_i32(tmp
);
8321 /* Perform base writeback before the loaded value to
8322 ensure correct behavior with overlapping index registers.
8323 ldrd with base writeback is is undefined if the
8324 destination and index registers overlap. */
8325 if (!(insn
& (1 << 24))) {
8326 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
8327 store_reg(s
, rn
, addr
);
8328 } else if (insn
& (1 << 21)) {
8330 tcg_gen_addi_i32(addr
, addr
, address_offset
);
8331 store_reg(s
, rn
, addr
);
8333 tcg_temp_free_i32(addr
);
8336 /* Complete the load. */
8337 store_reg(s
, rd
, tmp
);
8346 if (insn
& (1 << 4)) {
8348 /* Armv6 Media instructions. */
8350 rn
= (insn
>> 16) & 0xf;
8351 rd
= (insn
>> 12) & 0xf;
8352 rs
= (insn
>> 8) & 0xf;
8353 switch ((insn
>> 23) & 3) {
8354 case 0: /* Parallel add/subtract. */
8355 op1
= (insn
>> 20) & 7;
8356 tmp
= load_reg(s
, rn
);
8357 tmp2
= load_reg(s
, rm
);
8358 sh
= (insn
>> 5) & 7;
8359 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
8361 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
8362 tcg_temp_free_i32(tmp2
);
8363 store_reg(s
, rd
, tmp
);
8366 if ((insn
& 0x00700020) == 0) {
8367 /* Halfword pack. */
8368 tmp
= load_reg(s
, rn
);
8369 tmp2
= load_reg(s
, rm
);
8370 shift
= (insn
>> 7) & 0x1f;
8371 if (insn
& (1 << 6)) {
8375 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8376 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8377 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8381 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8382 tcg_gen_ext16u_i32(tmp
, tmp
);
8383 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8385 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8386 tcg_temp_free_i32(tmp2
);
8387 store_reg(s
, rd
, tmp
);
8388 } else if ((insn
& 0x00200020) == 0x00200000) {
8390 tmp
= load_reg(s
, rm
);
8391 shift
= (insn
>> 7) & 0x1f;
8392 if (insn
& (1 << 6)) {
8395 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8397 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8399 sh
= (insn
>> 16) & 0x1f;
8400 tmp2
= tcg_const_i32(sh
);
8401 if (insn
& (1 << 22))
8402 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
8404 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
8405 tcg_temp_free_i32(tmp2
);
8406 store_reg(s
, rd
, tmp
);
8407 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
8409 tmp
= load_reg(s
, rm
);
8410 sh
= (insn
>> 16) & 0x1f;
8411 tmp2
= tcg_const_i32(sh
);
8412 if (insn
& (1 << 22))
8413 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
8415 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
8416 tcg_temp_free_i32(tmp2
);
8417 store_reg(s
, rd
, tmp
);
8418 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
8420 tmp
= load_reg(s
, rn
);
8421 tmp2
= load_reg(s
, rm
);
8422 tmp3
= tcg_temp_new_i32();
8423 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
8424 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
8425 tcg_temp_free_i32(tmp3
);
8426 tcg_temp_free_i32(tmp2
);
8427 store_reg(s
, rd
, tmp
);
8428 } else if ((insn
& 0x000003e0) == 0x00000060) {
8429 tmp
= load_reg(s
, rm
);
8430 shift
= (insn
>> 10) & 3;
8431 /* ??? In many cases it's not necessary to do a
8432 rotate, a shift is sufficient. */
8434 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
8435 op1
= (insn
>> 20) & 7;
8437 case 0: gen_sxtb16(tmp
); break;
8438 case 2: gen_sxtb(tmp
); break;
8439 case 3: gen_sxth(tmp
); break;
8440 case 4: gen_uxtb16(tmp
); break;
8441 case 6: gen_uxtb(tmp
); break;
8442 case 7: gen_uxth(tmp
); break;
8443 default: goto illegal_op
;
8446 tmp2
= load_reg(s
, rn
);
8447 if ((op1
& 3) == 0) {
8448 gen_add16(tmp
, tmp2
);
8450 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8451 tcg_temp_free_i32(tmp2
);
8454 store_reg(s
, rd
, tmp
);
8455 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
8457 tmp
= load_reg(s
, rm
);
8458 if (insn
& (1 << 22)) {
8459 if (insn
& (1 << 7)) {
8463 gen_helper_rbit(tmp
, tmp
);
8466 if (insn
& (1 << 7))
8469 tcg_gen_bswap32_i32(tmp
, tmp
);
8471 store_reg(s
, rd
, tmp
);
8476 case 2: /* Multiplies (Type 3). */
8477 switch ((insn
>> 20) & 0x7) {
8479 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
8480 /* op2 not 00x or 11x : UNDEF */
8483 /* Signed multiply most significant [accumulate].
8484 (SMMUL, SMMLA, SMMLS) */
8485 tmp
= load_reg(s
, rm
);
8486 tmp2
= load_reg(s
, rs
);
8487 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8490 tmp
= load_reg(s
, rd
);
8491 if (insn
& (1 << 6)) {
8492 tmp64
= gen_subq_msw(tmp64
, tmp
);
8494 tmp64
= gen_addq_msw(tmp64
, tmp
);
8497 if (insn
& (1 << 5)) {
8498 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
8500 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
8501 tmp
= tcg_temp_new_i32();
8502 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8503 tcg_temp_free_i64(tmp64
);
8504 store_reg(s
, rn
, tmp
);
8508 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8509 if (insn
& (1 << 7)) {
8512 tmp
= load_reg(s
, rm
);
8513 tmp2
= load_reg(s
, rs
);
8514 if (insn
& (1 << 5))
8515 gen_swap_half(tmp2
);
8516 gen_smul_dual(tmp
, tmp2
);
8517 if (insn
& (1 << 22)) {
8518 /* smlald, smlsld */
8521 tmp64
= tcg_temp_new_i64();
8522 tmp64_2
= tcg_temp_new_i64();
8523 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8524 tcg_gen_ext_i32_i64(tmp64_2
, tmp2
);
8525 tcg_temp_free_i32(tmp
);
8526 tcg_temp_free_i32(tmp2
);
8527 if (insn
& (1 << 6)) {
8528 tcg_gen_sub_i64(tmp64
, tmp64
, tmp64_2
);
8530 tcg_gen_add_i64(tmp64
, tmp64
, tmp64_2
);
8532 tcg_temp_free_i64(tmp64_2
);
8533 gen_addq(s
, tmp64
, rd
, rn
);
8534 gen_storeq_reg(s
, rd
, rn
, tmp64
);
8535 tcg_temp_free_i64(tmp64
);
8537 /* smuad, smusd, smlad, smlsd */
8538 if (insn
& (1 << 6)) {
8539 /* This subtraction cannot overflow. */
8540 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8542 /* This addition cannot overflow 32 bits;
8543 * however it may overflow considered as a
8544 * signed operation, in which case we must set
8547 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8549 tcg_temp_free_i32(tmp2
);
8552 tmp2
= load_reg(s
, rd
);
8553 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8554 tcg_temp_free_i32(tmp2
);
8556 store_reg(s
, rn
, tmp
);
8562 if (!arm_feature(env
, ARM_FEATURE_ARM_DIV
)) {
8565 if (((insn
>> 5) & 7) || (rd
!= 15)) {
8568 tmp
= load_reg(s
, rm
);
8569 tmp2
= load_reg(s
, rs
);
8570 if (insn
& (1 << 21)) {
8571 gen_helper_udiv(tmp
, tmp
, tmp2
);
8573 gen_helper_sdiv(tmp
, tmp
, tmp2
);
8575 tcg_temp_free_i32(tmp2
);
8576 store_reg(s
, rn
, tmp
);
8583 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
8585 case 0: /* Unsigned sum of absolute differences. */
8587 tmp
= load_reg(s
, rm
);
8588 tmp2
= load_reg(s
, rs
);
8589 gen_helper_usad8(tmp
, tmp
, tmp2
);
8590 tcg_temp_free_i32(tmp2
);
8592 tmp2
= load_reg(s
, rd
);
8593 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8594 tcg_temp_free_i32(tmp2
);
8596 store_reg(s
, rn
, tmp
);
8598 case 0x20: case 0x24: case 0x28: case 0x2c:
8599 /* Bitfield insert/clear. */
8601 shift
= (insn
>> 7) & 0x1f;
8602 i
= (insn
>> 16) & 0x1f;
8605 tmp
= tcg_temp_new_i32();
8606 tcg_gen_movi_i32(tmp
, 0);
8608 tmp
= load_reg(s
, rm
);
8611 tmp2
= load_reg(s
, rd
);
8612 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
8613 tcg_temp_free_i32(tmp2
);
8615 store_reg(s
, rd
, tmp
);
8617 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8618 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8620 tmp
= load_reg(s
, rm
);
8621 shift
= (insn
>> 7) & 0x1f;
8622 i
= ((insn
>> 16) & 0x1f) + 1;
8627 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
8629 gen_sbfx(tmp
, shift
, i
);
8632 store_reg(s
, rd
, tmp
);
8642 /* Check for undefined extension instructions
8643 * per the ARM Bible IE:
8644 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8646 sh
= (0xf << 20) | (0xf << 4);
8647 if (op1
== 0x7 && ((insn
& sh
) == sh
))
8651 /* load/store byte/word */
8652 rn
= (insn
>> 16) & 0xf;
8653 rd
= (insn
>> 12) & 0xf;
8654 tmp2
= load_reg(s
, rn
);
8655 if ((insn
& 0x01200000) == 0x00200000) {
8659 i
= get_mem_index(s
);
8661 if (insn
& (1 << 24))
8662 gen_add_data_offset(s
, insn
, tmp2
);
8663 if (insn
& (1 << 20)) {
8665 tmp
= tcg_temp_new_i32();
8666 if (insn
& (1 << 22)) {
8667 gen_aa32_ld8u(tmp
, tmp2
, i
);
8669 gen_aa32_ld32u(tmp
, tmp2
, i
);
8673 tmp
= load_reg(s
, rd
);
8674 if (insn
& (1 << 22)) {
8675 gen_aa32_st8(tmp
, tmp2
, i
);
8677 gen_aa32_st32(tmp
, tmp2
, i
);
8679 tcg_temp_free_i32(tmp
);
8681 if (!(insn
& (1 << 24))) {
8682 gen_add_data_offset(s
, insn
, tmp2
);
8683 store_reg(s
, rn
, tmp2
);
8684 } else if (insn
& (1 << 21)) {
8685 store_reg(s
, rn
, tmp2
);
8687 tcg_temp_free_i32(tmp2
);
8689 if (insn
& (1 << 20)) {
8690 /* Complete the load. */
8691 store_reg_from_load(env
, s
, rd
, tmp
);
8697 int j
, n
, user
, loaded_base
;
8698 TCGv_i32 loaded_var
;
8699 /* load/store multiple words */
8700 /* XXX: store correct base if write back */
8702 if (insn
& (1 << 22)) {
8704 goto illegal_op
; /* only usable in supervisor mode */
8706 if ((insn
& (1 << 15)) == 0)
8709 rn
= (insn
>> 16) & 0xf;
8710 addr
= load_reg(s
, rn
);
8712 /* compute total size */
8714 TCGV_UNUSED_I32(loaded_var
);
8717 if (insn
& (1 << i
))
8720 /* XXX: test invalid n == 0 case ? */
8721 if (insn
& (1 << 23)) {
8722 if (insn
& (1 << 24)) {
8724 tcg_gen_addi_i32(addr
, addr
, 4);
8726 /* post increment */
8729 if (insn
& (1 << 24)) {
8731 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
8733 /* post decrement */
8735 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
8740 if (insn
& (1 << i
)) {
8741 if (insn
& (1 << 20)) {
8743 tmp
= tcg_temp_new_i32();
8744 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8746 tmp2
= tcg_const_i32(i
);
8747 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
8748 tcg_temp_free_i32(tmp2
);
8749 tcg_temp_free_i32(tmp
);
8750 } else if (i
== rn
) {
8754 store_reg_from_load(env
, s
, i
, tmp
);
8759 /* special case: r15 = PC + 8 */
8760 val
= (long)s
->pc
+ 4;
8761 tmp
= tcg_temp_new_i32();
8762 tcg_gen_movi_i32(tmp
, val
);
8764 tmp
= tcg_temp_new_i32();
8765 tmp2
= tcg_const_i32(i
);
8766 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
8767 tcg_temp_free_i32(tmp2
);
8769 tmp
= load_reg(s
, i
);
8771 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8772 tcg_temp_free_i32(tmp
);
8775 /* no need to add after the last transfer */
8777 tcg_gen_addi_i32(addr
, addr
, 4);
8780 if (insn
& (1 << 21)) {
8782 if (insn
& (1 << 23)) {
8783 if (insn
& (1 << 24)) {
8786 /* post increment */
8787 tcg_gen_addi_i32(addr
, addr
, 4);
8790 if (insn
& (1 << 24)) {
8793 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
8795 /* post decrement */
8796 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
8799 store_reg(s
, rn
, addr
);
8801 tcg_temp_free_i32(addr
);
8804 store_reg(s
, rn
, loaded_var
);
8806 if ((insn
& (1 << 22)) && !user
) {
8807 /* Restore CPSR from SPSR. */
8808 tmp
= load_cpu_field(spsr
);
8809 gen_set_cpsr(tmp
, 0xffffffff);
8810 tcg_temp_free_i32(tmp
);
8811 s
->is_jmp
= DISAS_UPDATE
;
8820 /* branch (and link) */
8821 val
= (int32_t)s
->pc
;
8822 if (insn
& (1 << 24)) {
8823 tmp
= tcg_temp_new_i32();
8824 tcg_gen_movi_i32(tmp
, val
);
8825 store_reg(s
, 14, tmp
);
8827 offset
= sextract32(insn
<< 2, 0, 26);
8835 if (((insn
>> 8) & 0xe) == 10) {
8837 if (disas_vfp_insn(env
, s
, insn
)) {
8840 } else if (disas_coproc_insn(env
, s
, insn
)) {
8847 gen_set_pc_im(s
, s
->pc
);
8848 s
->svc_imm
= extract32(insn
, 0, 24);
8849 s
->is_jmp
= DISAS_SWI
;
8853 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized());
8859 /* Return true if this is a Thumb-2 logical op. */
8861 thumb2_logic_op(int op
)
8866 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
8867 then set condition code flags based on the result of the operation.
8868 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8869 to the high bit of T1.
8870 Returns zero if the opcode is valid. */
8873 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
8874 TCGv_i32 t0
, TCGv_i32 t1
)
8881 tcg_gen_and_i32(t0
, t0
, t1
);
8885 tcg_gen_andc_i32(t0
, t0
, t1
);
8889 tcg_gen_or_i32(t0
, t0
, t1
);
8893 tcg_gen_orc_i32(t0
, t0
, t1
);
8897 tcg_gen_xor_i32(t0
, t0
, t1
);
8902 gen_add_CC(t0
, t0
, t1
);
8904 tcg_gen_add_i32(t0
, t0
, t1
);
8908 gen_adc_CC(t0
, t0
, t1
);
8914 gen_sbc_CC(t0
, t0
, t1
);
8916 gen_sub_carry(t0
, t0
, t1
);
8921 gen_sub_CC(t0
, t0
, t1
);
8923 tcg_gen_sub_i32(t0
, t0
, t1
);
8927 gen_sub_CC(t0
, t1
, t0
);
8929 tcg_gen_sub_i32(t0
, t1
, t0
);
8931 default: /* 5, 6, 7, 9, 12, 15. */
8937 gen_set_CF_bit31(t1
);
8942 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
8944 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
8946 uint32_t insn
, imm
, shift
, offset
;
8947 uint32_t rd
, rn
, rm
, rs
;
8958 if (!(arm_feature(env
, ARM_FEATURE_THUMB2
)
8959 || arm_feature (env
, ARM_FEATURE_M
))) {
8960 /* Thumb-1 cores may need to treat bl and blx as a pair of
8961 16-bit instructions to get correct prefetch abort behavior. */
8963 if ((insn
& (1 << 12)) == 0) {
8965 /* Second half of blx. */
8966 offset
= ((insn
& 0x7ff) << 1);
8967 tmp
= load_reg(s
, 14);
8968 tcg_gen_addi_i32(tmp
, tmp
, offset
);
8969 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
8971 tmp2
= tcg_temp_new_i32();
8972 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
8973 store_reg(s
, 14, tmp2
);
8977 if (insn
& (1 << 11)) {
8978 /* Second half of bl. */
8979 offset
= ((insn
& 0x7ff) << 1) | 1;
8980 tmp
= load_reg(s
, 14);
8981 tcg_gen_addi_i32(tmp
, tmp
, offset
);
8983 tmp2
= tcg_temp_new_i32();
8984 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
8985 store_reg(s
, 14, tmp2
);
8989 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
8990 /* Instruction spans a page boundary. Implement it as two
8991 16-bit instructions in case the second half causes an
8993 offset
= ((int32_t)insn
<< 21) >> 9;
8994 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
8997 /* Fall through to 32-bit decode. */
9000 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
9002 insn
|= (uint32_t)insn_hw1
<< 16;
9004 if ((insn
& 0xf800e800) != 0xf000e800) {
9008 rn
= (insn
>> 16) & 0xf;
9009 rs
= (insn
>> 12) & 0xf;
9010 rd
= (insn
>> 8) & 0xf;
9012 switch ((insn
>> 25) & 0xf) {
9013 case 0: case 1: case 2: case 3:
9014 /* 16-bit instructions. Should never happen. */
9017 if (insn
& (1 << 22)) {
9018 /* Other load/store, table branch. */
9019 if (insn
& 0x01200000) {
9020 /* Load/store doubleword. */
9022 addr
= tcg_temp_new_i32();
9023 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
9025 addr
= load_reg(s
, rn
);
9027 offset
= (insn
& 0xff) * 4;
9028 if ((insn
& (1 << 23)) == 0)
9030 if (insn
& (1 << 24)) {
9031 tcg_gen_addi_i32(addr
, addr
, offset
);
9034 if (insn
& (1 << 20)) {
9036 tmp
= tcg_temp_new_i32();
9037 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9038 store_reg(s
, rs
, tmp
);
9039 tcg_gen_addi_i32(addr
, addr
, 4);
9040 tmp
= tcg_temp_new_i32();
9041 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9042 store_reg(s
, rd
, tmp
);
9045 tmp
= load_reg(s
, rs
);
9046 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9047 tcg_temp_free_i32(tmp
);
9048 tcg_gen_addi_i32(addr
, addr
, 4);
9049 tmp
= load_reg(s
, rd
);
9050 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9051 tcg_temp_free_i32(tmp
);
9053 if (insn
& (1 << 21)) {
9054 /* Base writeback. */
9057 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
9058 store_reg(s
, rn
, addr
);
9060 tcg_temp_free_i32(addr
);
9062 } else if ((insn
& (1 << 23)) == 0) {
9063 /* Load/store exclusive word. */
9064 addr
= tcg_temp_local_new_i32();
9065 load_reg_var(s
, addr
, rn
);
9066 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
9067 if (insn
& (1 << 20)) {
9068 gen_load_exclusive(s
, rs
, 15, addr
, 2);
9070 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
9072 tcg_temp_free_i32(addr
);
9073 } else if ((insn
& (7 << 5)) == 0) {
9076 addr
= tcg_temp_new_i32();
9077 tcg_gen_movi_i32(addr
, s
->pc
);
9079 addr
= load_reg(s
, rn
);
9081 tmp
= load_reg(s
, rm
);
9082 tcg_gen_add_i32(addr
, addr
, tmp
);
9083 if (insn
& (1 << 4)) {
9085 tcg_gen_add_i32(addr
, addr
, tmp
);
9086 tcg_temp_free_i32(tmp
);
9087 tmp
= tcg_temp_new_i32();
9088 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
9090 tcg_temp_free_i32(tmp
);
9091 tmp
= tcg_temp_new_i32();
9092 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
9094 tcg_temp_free_i32(addr
);
9095 tcg_gen_shli_i32(tmp
, tmp
, 1);
9096 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
9097 store_reg(s
, 15, tmp
);
9099 int op2
= (insn
>> 6) & 0x3;
9100 op
= (insn
>> 4) & 0x3;
9105 /* Load/store exclusive byte/halfword/doubleword */
9112 /* Load-acquire/store-release */
9118 /* Load-acquire/store-release exclusive */
9122 addr
= tcg_temp_local_new_i32();
9123 load_reg_var(s
, addr
, rn
);
9125 if (insn
& (1 << 20)) {
9126 tmp
= tcg_temp_new_i32();
9129 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
9132 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
9135 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9140 store_reg(s
, rs
, tmp
);
9142 tmp
= load_reg(s
, rs
);
9145 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
9148 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
9151 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9156 tcg_temp_free_i32(tmp
);
9158 } else if (insn
& (1 << 20)) {
9159 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
9161 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
9163 tcg_temp_free_i32(addr
);
9166 /* Load/store multiple, RFE, SRS. */
9167 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
9168 /* RFE, SRS: not available in user mode or on M profile */
9169 if (IS_USER(s
) || IS_M(env
)) {
9172 if (insn
& (1 << 20)) {
9174 addr
= load_reg(s
, rn
);
9175 if ((insn
& (1 << 24)) == 0)
9176 tcg_gen_addi_i32(addr
, addr
, -8);
9177 /* Load PC into tmp and CPSR into tmp2. */
9178 tmp
= tcg_temp_new_i32();
9179 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9180 tcg_gen_addi_i32(addr
, addr
, 4);
9181 tmp2
= tcg_temp_new_i32();
9182 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
9183 if (insn
& (1 << 21)) {
9184 /* Base writeback. */
9185 if (insn
& (1 << 24)) {
9186 tcg_gen_addi_i32(addr
, addr
, 4);
9188 tcg_gen_addi_i32(addr
, addr
, -4);
9190 store_reg(s
, rn
, addr
);
9192 tcg_temp_free_i32(addr
);
9194 gen_rfe(s
, tmp
, tmp2
);
9197 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
9201 int i
, loaded_base
= 0;
9202 TCGv_i32 loaded_var
;
9203 /* Load/store multiple. */
9204 addr
= load_reg(s
, rn
);
9206 for (i
= 0; i
< 16; i
++) {
9207 if (insn
& (1 << i
))
9210 if (insn
& (1 << 24)) {
9211 tcg_gen_addi_i32(addr
, addr
, -offset
);
9214 TCGV_UNUSED_I32(loaded_var
);
9215 for (i
= 0; i
< 16; i
++) {
9216 if ((insn
& (1 << i
)) == 0)
9218 if (insn
& (1 << 20)) {
9220 tmp
= tcg_temp_new_i32();
9221 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9224 } else if (i
== rn
) {
9228 store_reg(s
, i
, tmp
);
9232 tmp
= load_reg(s
, i
);
9233 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9234 tcg_temp_free_i32(tmp
);
9236 tcg_gen_addi_i32(addr
, addr
, 4);
9239 store_reg(s
, rn
, loaded_var
);
9241 if (insn
& (1 << 21)) {
9242 /* Base register writeback. */
9243 if (insn
& (1 << 24)) {
9244 tcg_gen_addi_i32(addr
, addr
, -offset
);
9246 /* Fault if writeback register is in register list. */
9247 if (insn
& (1 << rn
))
9249 store_reg(s
, rn
, addr
);
9251 tcg_temp_free_i32(addr
);
9258 op
= (insn
>> 21) & 0xf;
9260 /* Halfword pack. */
9261 tmp
= load_reg(s
, rn
);
9262 tmp2
= load_reg(s
, rm
);
9263 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
9264 if (insn
& (1 << 5)) {
9268 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9269 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9270 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9274 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9275 tcg_gen_ext16u_i32(tmp
, tmp
);
9276 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9278 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9279 tcg_temp_free_i32(tmp2
);
9280 store_reg(s
, rd
, tmp
);
9282 /* Data processing register constant shift. */
9284 tmp
= tcg_temp_new_i32();
9285 tcg_gen_movi_i32(tmp
, 0);
9287 tmp
= load_reg(s
, rn
);
9289 tmp2
= load_reg(s
, rm
);
9291 shiftop
= (insn
>> 4) & 3;
9292 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
9293 conds
= (insn
& (1 << 20)) != 0;
9294 logic_cc
= (conds
&& thumb2_logic_op(op
));
9295 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
9296 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
9298 tcg_temp_free_i32(tmp2
);
9300 store_reg(s
, rd
, tmp
);
9302 tcg_temp_free_i32(tmp
);
9306 case 13: /* Misc data processing. */
9307 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
9308 if (op
< 4 && (insn
& 0xf000) != 0xf000)
9311 case 0: /* Register controlled shift. */
9312 tmp
= load_reg(s
, rn
);
9313 tmp2
= load_reg(s
, rm
);
9314 if ((insn
& 0x70) != 0)
9316 op
= (insn
>> 21) & 3;
9317 logic_cc
= (insn
& (1 << 20)) != 0;
9318 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
9321 store_reg_bx(env
, s
, rd
, tmp
);
9323 case 1: /* Sign/zero extend. */
9324 tmp
= load_reg(s
, rm
);
9325 shift
= (insn
>> 4) & 3;
9326 /* ??? In many cases it's not necessary to do a
9327 rotate, a shift is sufficient. */
9329 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9330 op
= (insn
>> 20) & 7;
9332 case 0: gen_sxth(tmp
); break;
9333 case 1: gen_uxth(tmp
); break;
9334 case 2: gen_sxtb16(tmp
); break;
9335 case 3: gen_uxtb16(tmp
); break;
9336 case 4: gen_sxtb(tmp
); break;
9337 case 5: gen_uxtb(tmp
); break;
9338 default: goto illegal_op
;
9341 tmp2
= load_reg(s
, rn
);
9342 if ((op
>> 1) == 1) {
9343 gen_add16(tmp
, tmp2
);
9345 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9346 tcg_temp_free_i32(tmp2
);
9349 store_reg(s
, rd
, tmp
);
9351 case 2: /* SIMD add/subtract. */
9352 op
= (insn
>> 20) & 7;
9353 shift
= (insn
>> 4) & 7;
9354 if ((op
& 3) == 3 || (shift
& 3) == 3)
9356 tmp
= load_reg(s
, rn
);
9357 tmp2
= load_reg(s
, rm
);
9358 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
9359 tcg_temp_free_i32(tmp2
);
9360 store_reg(s
, rd
, tmp
);
9362 case 3: /* Other data processing. */
9363 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
9365 /* Saturating add/subtract. */
9366 tmp
= load_reg(s
, rn
);
9367 tmp2
= load_reg(s
, rm
);
9369 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
9371 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
9373 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
9374 tcg_temp_free_i32(tmp2
);
9376 tmp
= load_reg(s
, rn
);
9378 case 0x0a: /* rbit */
9379 gen_helper_rbit(tmp
, tmp
);
9381 case 0x08: /* rev */
9382 tcg_gen_bswap32_i32(tmp
, tmp
);
9384 case 0x09: /* rev16 */
9387 case 0x0b: /* revsh */
9390 case 0x10: /* sel */
9391 tmp2
= load_reg(s
, rm
);
9392 tmp3
= tcg_temp_new_i32();
9393 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
9394 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
9395 tcg_temp_free_i32(tmp3
);
9396 tcg_temp_free_i32(tmp2
);
9398 case 0x18: /* clz */
9399 gen_helper_clz(tmp
, tmp
);
9409 uint32_t sz
= op
& 0x3;
9410 uint32_t c
= op
& 0x8;
9412 if (!arm_feature(env
, ARM_FEATURE_CRC
)) {
9416 tmp2
= load_reg(s
, rm
);
9417 tmp3
= tcg_const_i32(1 << sz
);
9419 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
9421 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
9423 tcg_temp_free_i32(tmp2
);
9424 tcg_temp_free_i32(tmp3
);
9431 store_reg(s
, rd
, tmp
);
9433 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
9434 op
= (insn
>> 4) & 0xf;
9435 tmp
= load_reg(s
, rn
);
9436 tmp2
= load_reg(s
, rm
);
9437 switch ((insn
>> 20) & 7) {
9438 case 0: /* 32 x 32 -> 32 */
9439 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
9440 tcg_temp_free_i32(tmp2
);
9442 tmp2
= load_reg(s
, rs
);
9444 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
9446 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9447 tcg_temp_free_i32(tmp2
);
9450 case 1: /* 16 x 16 -> 32 */
9451 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
9452 tcg_temp_free_i32(tmp2
);
9454 tmp2
= load_reg(s
, rs
);
9455 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9456 tcg_temp_free_i32(tmp2
);
9459 case 2: /* Dual multiply add. */
9460 case 4: /* Dual multiply subtract. */
9462 gen_swap_half(tmp2
);
9463 gen_smul_dual(tmp
, tmp2
);
9464 if (insn
& (1 << 22)) {
9465 /* This subtraction cannot overflow. */
9466 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9468 /* This addition cannot overflow 32 bits;
9469 * however it may overflow considered as a signed
9470 * operation, in which case we must set the Q flag.
9472 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9474 tcg_temp_free_i32(tmp2
);
9477 tmp2
= load_reg(s
, rs
);
9478 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9479 tcg_temp_free_i32(tmp2
);
9482 case 3: /* 32 * 16 -> 32msb */
9484 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
9487 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9488 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
9489 tmp
= tcg_temp_new_i32();
9490 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
9491 tcg_temp_free_i64(tmp64
);
9494 tmp2
= load_reg(s
, rs
);
9495 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9496 tcg_temp_free_i32(tmp2
);
9499 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9500 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9502 tmp
= load_reg(s
, rs
);
9503 if (insn
& (1 << 20)) {
9504 tmp64
= gen_addq_msw(tmp64
, tmp
);
9506 tmp64
= gen_subq_msw(tmp64
, tmp
);
9509 if (insn
& (1 << 4)) {
9510 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
9512 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
9513 tmp
= tcg_temp_new_i32();
9514 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
9515 tcg_temp_free_i64(tmp64
);
9517 case 7: /* Unsigned sum of absolute differences. */
9518 gen_helper_usad8(tmp
, tmp
, tmp2
);
9519 tcg_temp_free_i32(tmp2
);
9521 tmp2
= load_reg(s
, rs
);
9522 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9523 tcg_temp_free_i32(tmp2
);
9527 store_reg(s
, rd
, tmp
);
9529 case 6: case 7: /* 64-bit multiply, Divide. */
9530 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
9531 tmp
= load_reg(s
, rn
);
9532 tmp2
= load_reg(s
, rm
);
9533 if ((op
& 0x50) == 0x10) {
9535 if (!arm_feature(env
, ARM_FEATURE_THUMB_DIV
)) {
9539 gen_helper_udiv(tmp
, tmp
, tmp2
);
9541 gen_helper_sdiv(tmp
, tmp
, tmp2
);
9542 tcg_temp_free_i32(tmp2
);
9543 store_reg(s
, rd
, tmp
);
9544 } else if ((op
& 0xe) == 0xc) {
9545 /* Dual multiply accumulate long. */
9547 gen_swap_half(tmp2
);
9548 gen_smul_dual(tmp
, tmp2
);
9550 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9552 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9554 tcg_temp_free_i32(tmp2
);
9556 tmp64
= tcg_temp_new_i64();
9557 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9558 tcg_temp_free_i32(tmp
);
9559 gen_addq(s
, tmp64
, rs
, rd
);
9560 gen_storeq_reg(s
, rs
, rd
, tmp64
);
9561 tcg_temp_free_i64(tmp64
);
9564 /* Unsigned 64-bit multiply */
9565 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
9569 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
9570 tcg_temp_free_i32(tmp2
);
9571 tmp64
= tcg_temp_new_i64();
9572 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9573 tcg_temp_free_i32(tmp
);
9575 /* Signed 64-bit multiply */
9576 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9581 gen_addq_lo(s
, tmp64
, rs
);
9582 gen_addq_lo(s
, tmp64
, rd
);
9583 } else if (op
& 0x40) {
9584 /* 64-bit accumulate. */
9585 gen_addq(s
, tmp64
, rs
, rd
);
9587 gen_storeq_reg(s
, rs
, rd
, tmp64
);
9588 tcg_temp_free_i64(tmp64
);
9593 case 6: case 7: case 14: case 15:
9595 if (((insn
>> 24) & 3) == 3) {
9596 /* Translate into the equivalent ARM encoding. */
9597 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
9598 if (disas_neon_data_insn(env
, s
, insn
))
9600 } else if (((insn
>> 8) & 0xe) == 10) {
9601 if (disas_vfp_insn(env
, s
, insn
)) {
9605 if (insn
& (1 << 28))
9607 if (disas_coproc_insn (env
, s
, insn
))
9611 case 8: case 9: case 10: case 11:
9612 if (insn
& (1 << 15)) {
9613 /* Branches, misc control. */
9614 if (insn
& 0x5000) {
9615 /* Unconditional branch. */
9616 /* signextend(hw1[10:0]) -> offset[:12]. */
9617 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
9618 /* hw1[10:0] -> offset[11:1]. */
9619 offset
|= (insn
& 0x7ff) << 1;
9620 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9621 offset[24:22] already have the same value because of the
9622 sign extension above. */
9623 offset
^= ((~insn
) & (1 << 13)) << 10;
9624 offset
^= ((~insn
) & (1 << 11)) << 11;
9626 if (insn
& (1 << 14)) {
9627 /* Branch and link. */
9628 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
9632 if (insn
& (1 << 12)) {
9637 offset
&= ~(uint32_t)2;
9638 /* thumb2 bx, no need to check */
9639 gen_bx_im(s
, offset
);
9641 } else if (((insn
>> 23) & 7) == 7) {
9643 if (insn
& (1 << 13))
9646 if (insn
& (1 << 26)) {
9647 /* Secure monitor call (v6Z) */
9648 qemu_log_mask(LOG_UNIMP
,
9649 "arm: unimplemented secure monitor call\n");
9650 goto illegal_op
; /* not implemented. */
9652 op
= (insn
>> 20) & 7;
9654 case 0: /* msr cpsr. */
9656 tmp
= load_reg(s
, rn
);
9657 addr
= tcg_const_i32(insn
& 0xff);
9658 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9659 tcg_temp_free_i32(addr
);
9660 tcg_temp_free_i32(tmp
);
9665 case 1: /* msr spsr. */
9668 tmp
= load_reg(s
, rn
);
9670 msr_mask(env
, s
, (insn
>> 8) & 0xf, op
== 1),
9674 case 2: /* cps, nop-hint. */
9675 if (((insn
>> 8) & 7) == 0) {
9676 gen_nop_hint(s
, insn
& 0xff);
9678 /* Implemented as NOP in user mode. */
9683 if (insn
& (1 << 10)) {
9684 if (insn
& (1 << 7))
9686 if (insn
& (1 << 6))
9688 if (insn
& (1 << 5))
9690 if (insn
& (1 << 9))
9691 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
9693 if (insn
& (1 << 8)) {
9695 imm
|= (insn
& 0x1f);
9698 gen_set_psr_im(s
, offset
, 0, imm
);
9701 case 3: /* Special control operations. */
9703 op
= (insn
>> 4) & 0xf;
9711 /* These execute as NOPs. */
9718 /* Trivial implementation equivalent to bx. */
9719 tmp
= load_reg(s
, rn
);
9722 case 5: /* Exception return. */
9726 if (rn
!= 14 || rd
!= 15) {
9729 tmp
= load_reg(s
, rn
);
9730 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
9731 gen_exception_return(s
, tmp
);
9733 case 6: /* mrs cpsr. */
9734 tmp
= tcg_temp_new_i32();
9736 addr
= tcg_const_i32(insn
& 0xff);
9737 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
9738 tcg_temp_free_i32(addr
);
9740 gen_helper_cpsr_read(tmp
, cpu_env
);
9742 store_reg(s
, rd
, tmp
);
9744 case 7: /* mrs spsr. */
9745 /* Not accessible in user mode. */
9746 if (IS_USER(s
) || IS_M(env
))
9748 tmp
= load_cpu_field(spsr
);
9749 store_reg(s
, rd
, tmp
);
9754 /* Conditional branch. */
9755 op
= (insn
>> 22) & 0xf;
9756 /* Generate a conditional jump to next instruction. */
9757 s
->condlabel
= gen_new_label();
9758 arm_gen_test_cc(op
^ 1, s
->condlabel
);
9761 /* offset[11:1] = insn[10:0] */
9762 offset
= (insn
& 0x7ff) << 1;
9763 /* offset[17:12] = insn[21:16]. */
9764 offset
|= (insn
& 0x003f0000) >> 4;
9765 /* offset[31:20] = insn[26]. */
9766 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
9767 /* offset[18] = insn[13]. */
9768 offset
|= (insn
& (1 << 13)) << 5;
9769 /* offset[19] = insn[11]. */
9770 offset
|= (insn
& (1 << 11)) << 8;
9772 /* jump to the offset */
9773 gen_jmp(s
, s
->pc
+ offset
);
9776 /* Data processing immediate. */
9777 if (insn
& (1 << 25)) {
9778 if (insn
& (1 << 24)) {
9779 if (insn
& (1 << 20))
9781 /* Bitfield/Saturate. */
9782 op
= (insn
>> 21) & 7;
9784 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
9786 tmp
= tcg_temp_new_i32();
9787 tcg_gen_movi_i32(tmp
, 0);
9789 tmp
= load_reg(s
, rn
);
9792 case 2: /* Signed bitfield extract. */
9794 if (shift
+ imm
> 32)
9797 gen_sbfx(tmp
, shift
, imm
);
9799 case 6: /* Unsigned bitfield extract. */
9801 if (shift
+ imm
> 32)
9804 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
9806 case 3: /* Bitfield insert/clear. */
9809 imm
= imm
+ 1 - shift
;
9811 tmp2
= load_reg(s
, rd
);
9812 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
9813 tcg_temp_free_i32(tmp2
);
9818 default: /* Saturate. */
9821 tcg_gen_sari_i32(tmp
, tmp
, shift
);
9823 tcg_gen_shli_i32(tmp
, tmp
, shift
);
9825 tmp2
= tcg_const_i32(imm
);
9828 if ((op
& 1) && shift
== 0)
9829 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
9831 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
9834 if ((op
& 1) && shift
== 0)
9835 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
9837 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
9839 tcg_temp_free_i32(tmp2
);
9842 store_reg(s
, rd
, tmp
);
9844 imm
= ((insn
& 0x04000000) >> 15)
9845 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
9846 if (insn
& (1 << 22)) {
9847 /* 16-bit immediate. */
9848 imm
|= (insn
>> 4) & 0xf000;
9849 if (insn
& (1 << 23)) {
9851 tmp
= load_reg(s
, rd
);
9852 tcg_gen_ext16u_i32(tmp
, tmp
);
9853 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
9856 tmp
= tcg_temp_new_i32();
9857 tcg_gen_movi_i32(tmp
, imm
);
9860 /* Add/sub 12-bit immediate. */
9862 offset
= s
->pc
& ~(uint32_t)3;
9863 if (insn
& (1 << 23))
9867 tmp
= tcg_temp_new_i32();
9868 tcg_gen_movi_i32(tmp
, offset
);
9870 tmp
= load_reg(s
, rn
);
9871 if (insn
& (1 << 23))
9872 tcg_gen_subi_i32(tmp
, tmp
, imm
);
9874 tcg_gen_addi_i32(tmp
, tmp
, imm
);
9877 store_reg(s
, rd
, tmp
);
9880 int shifter_out
= 0;
9881 /* modified 12-bit immediate. */
9882 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
9883 imm
= (insn
& 0xff);
9886 /* Nothing to do. */
9888 case 1: /* 00XY00XY */
9891 case 2: /* XY00XY00 */
9895 case 3: /* XYXYXYXY */
9899 default: /* Rotated constant. */
9900 shift
= (shift
<< 1) | (imm
>> 7);
9902 imm
= imm
<< (32 - shift
);
9906 tmp2
= tcg_temp_new_i32();
9907 tcg_gen_movi_i32(tmp2
, imm
);
9908 rn
= (insn
>> 16) & 0xf;
9910 tmp
= tcg_temp_new_i32();
9911 tcg_gen_movi_i32(tmp
, 0);
9913 tmp
= load_reg(s
, rn
);
9915 op
= (insn
>> 21) & 0xf;
9916 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
9917 shifter_out
, tmp
, tmp2
))
9919 tcg_temp_free_i32(tmp2
);
9920 rd
= (insn
>> 8) & 0xf;
9922 store_reg(s
, rd
, tmp
);
9924 tcg_temp_free_i32(tmp
);
9929 case 12: /* Load/store single data item. */
9934 if ((insn
& 0x01100000) == 0x01000000) {
9935 if (disas_neon_ls_insn(env
, s
, insn
))
9939 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
9941 if (!(insn
& (1 << 20))) {
9945 /* Byte or halfword load space with dest == r15 : memory hints.
9946 * Catch them early so we don't emit pointless addressing code.
9947 * This space is a mix of:
9948 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
9949 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
9951 * unallocated hints, which must be treated as NOPs
9952 * UNPREDICTABLE space, which we NOP or UNDEF depending on
9953 * which is easiest for the decoding logic
9954 * Some space which must UNDEF
9956 int op1
= (insn
>> 23) & 3;
9957 int op2
= (insn
>> 6) & 0x3f;
9962 /* UNPREDICTABLE, unallocated hint or
9963 * PLD/PLDW/PLI (literal)
9968 return 0; /* PLD/PLDW/PLI or unallocated hint */
9970 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
9971 return 0; /* PLD/PLDW/PLI or unallocated hint */
9973 /* UNDEF space, or an UNPREDICTABLE */
9977 memidx
= get_mem_index(s
);
9979 addr
= tcg_temp_new_i32();
9981 /* s->pc has already been incremented by 4. */
9982 imm
= s
->pc
& 0xfffffffc;
9983 if (insn
& (1 << 23))
9984 imm
+= insn
& 0xfff;
9986 imm
-= insn
& 0xfff;
9987 tcg_gen_movi_i32(addr
, imm
);
9989 addr
= load_reg(s
, rn
);
9990 if (insn
& (1 << 23)) {
9991 /* Positive offset. */
9993 tcg_gen_addi_i32(addr
, addr
, imm
);
9996 switch ((insn
>> 8) & 0xf) {
9997 case 0x0: /* Shifted Register. */
9998 shift
= (insn
>> 4) & 0xf;
10000 tcg_temp_free_i32(addr
);
10003 tmp
= load_reg(s
, rm
);
10005 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10006 tcg_gen_add_i32(addr
, addr
, tmp
);
10007 tcg_temp_free_i32(tmp
);
10009 case 0xc: /* Negative offset. */
10010 tcg_gen_addi_i32(addr
, addr
, -imm
);
10012 case 0xe: /* User privilege. */
10013 tcg_gen_addi_i32(addr
, addr
, imm
);
10014 memidx
= MMU_USER_IDX
;
10016 case 0x9: /* Post-decrement. */
10018 /* Fall through. */
10019 case 0xb: /* Post-increment. */
10023 case 0xd: /* Pre-decrement. */
10025 /* Fall through. */
10026 case 0xf: /* Pre-increment. */
10027 tcg_gen_addi_i32(addr
, addr
, imm
);
10031 tcg_temp_free_i32(addr
);
10036 if (insn
& (1 << 20)) {
10038 tmp
= tcg_temp_new_i32();
10041 gen_aa32_ld8u(tmp
, addr
, memidx
);
10044 gen_aa32_ld8s(tmp
, addr
, memidx
);
10047 gen_aa32_ld16u(tmp
, addr
, memidx
);
10050 gen_aa32_ld16s(tmp
, addr
, memidx
);
10053 gen_aa32_ld32u(tmp
, addr
, memidx
);
10056 tcg_temp_free_i32(tmp
);
10057 tcg_temp_free_i32(addr
);
10063 store_reg(s
, rs
, tmp
);
10067 tmp
= load_reg(s
, rs
);
10070 gen_aa32_st8(tmp
, addr
, memidx
);
10073 gen_aa32_st16(tmp
, addr
, memidx
);
10076 gen_aa32_st32(tmp
, addr
, memidx
);
10079 tcg_temp_free_i32(tmp
);
10080 tcg_temp_free_i32(addr
);
10083 tcg_temp_free_i32(tmp
);
10086 tcg_gen_addi_i32(addr
, addr
, imm
);
10088 store_reg(s
, rn
, addr
);
10090 tcg_temp_free_i32(addr
);
10102 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
10104 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
10111 if (s
->condexec_mask
) {
10112 cond
= s
->condexec_cond
;
10113 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
10114 s
->condlabel
= gen_new_label();
10115 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
10120 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
10123 switch (insn
>> 12) {
10127 op
= (insn
>> 11) & 3;
10130 rn
= (insn
>> 3) & 7;
10131 tmp
= load_reg(s
, rn
);
10132 if (insn
& (1 << 10)) {
10134 tmp2
= tcg_temp_new_i32();
10135 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
10138 rm
= (insn
>> 6) & 7;
10139 tmp2
= load_reg(s
, rm
);
10141 if (insn
& (1 << 9)) {
10142 if (s
->condexec_mask
)
10143 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10145 gen_sub_CC(tmp
, tmp
, tmp2
);
10147 if (s
->condexec_mask
)
10148 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10150 gen_add_CC(tmp
, tmp
, tmp2
);
10152 tcg_temp_free_i32(tmp2
);
10153 store_reg(s
, rd
, tmp
);
10155 /* shift immediate */
10156 rm
= (insn
>> 3) & 7;
10157 shift
= (insn
>> 6) & 0x1f;
10158 tmp
= load_reg(s
, rm
);
10159 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
10160 if (!s
->condexec_mask
)
10162 store_reg(s
, rd
, tmp
);
10166 /* arithmetic large immediate */
10167 op
= (insn
>> 11) & 3;
10168 rd
= (insn
>> 8) & 0x7;
10169 if (op
== 0) { /* mov */
10170 tmp
= tcg_temp_new_i32();
10171 tcg_gen_movi_i32(tmp
, insn
& 0xff);
10172 if (!s
->condexec_mask
)
10174 store_reg(s
, rd
, tmp
);
10176 tmp
= load_reg(s
, rd
);
10177 tmp2
= tcg_temp_new_i32();
10178 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
10181 gen_sub_CC(tmp
, tmp
, tmp2
);
10182 tcg_temp_free_i32(tmp
);
10183 tcg_temp_free_i32(tmp2
);
10186 if (s
->condexec_mask
)
10187 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10189 gen_add_CC(tmp
, tmp
, tmp2
);
10190 tcg_temp_free_i32(tmp2
);
10191 store_reg(s
, rd
, tmp
);
10194 if (s
->condexec_mask
)
10195 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10197 gen_sub_CC(tmp
, tmp
, tmp2
);
10198 tcg_temp_free_i32(tmp2
);
10199 store_reg(s
, rd
, tmp
);
10205 if (insn
& (1 << 11)) {
10206 rd
= (insn
>> 8) & 7;
10207 /* load pc-relative. Bit 1 of PC is ignored. */
10208 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
10209 val
&= ~(uint32_t)2;
10210 addr
= tcg_temp_new_i32();
10211 tcg_gen_movi_i32(addr
, val
);
10212 tmp
= tcg_temp_new_i32();
10213 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10214 tcg_temp_free_i32(addr
);
10215 store_reg(s
, rd
, tmp
);
10218 if (insn
& (1 << 10)) {
10219 /* data processing extended or blx */
10220 rd
= (insn
& 7) | ((insn
>> 4) & 8);
10221 rm
= (insn
>> 3) & 0xf;
10222 op
= (insn
>> 8) & 3;
10225 tmp
= load_reg(s
, rd
);
10226 tmp2
= load_reg(s
, rm
);
10227 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10228 tcg_temp_free_i32(tmp2
);
10229 store_reg(s
, rd
, tmp
);
10232 tmp
= load_reg(s
, rd
);
10233 tmp2
= load_reg(s
, rm
);
10234 gen_sub_CC(tmp
, tmp
, tmp2
);
10235 tcg_temp_free_i32(tmp2
);
10236 tcg_temp_free_i32(tmp
);
10238 case 2: /* mov/cpy */
10239 tmp
= load_reg(s
, rm
);
10240 store_reg(s
, rd
, tmp
);
10242 case 3:/* branch [and link] exchange thumb register */
10243 tmp
= load_reg(s
, rm
);
10244 if (insn
& (1 << 7)) {
10246 val
= (uint32_t)s
->pc
| 1;
10247 tmp2
= tcg_temp_new_i32();
10248 tcg_gen_movi_i32(tmp2
, val
);
10249 store_reg(s
, 14, tmp2
);
10251 /* already thumb, no need to check */
10258 /* data processing register */
10260 rm
= (insn
>> 3) & 7;
10261 op
= (insn
>> 6) & 0xf;
10262 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
10263 /* the shift/rotate ops want the operands backwards */
10272 if (op
== 9) { /* neg */
10273 tmp
= tcg_temp_new_i32();
10274 tcg_gen_movi_i32(tmp
, 0);
10275 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
10276 tmp
= load_reg(s
, rd
);
10278 TCGV_UNUSED_I32(tmp
);
10281 tmp2
= load_reg(s
, rm
);
10283 case 0x0: /* and */
10284 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
10285 if (!s
->condexec_mask
)
10288 case 0x1: /* eor */
10289 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
10290 if (!s
->condexec_mask
)
10293 case 0x2: /* lsl */
10294 if (s
->condexec_mask
) {
10295 gen_shl(tmp2
, tmp2
, tmp
);
10297 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10298 gen_logic_CC(tmp2
);
10301 case 0x3: /* lsr */
10302 if (s
->condexec_mask
) {
10303 gen_shr(tmp2
, tmp2
, tmp
);
10305 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10306 gen_logic_CC(tmp2
);
10309 case 0x4: /* asr */
10310 if (s
->condexec_mask
) {
10311 gen_sar(tmp2
, tmp2
, tmp
);
10313 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10314 gen_logic_CC(tmp2
);
10317 case 0x5: /* adc */
10318 if (s
->condexec_mask
) {
10319 gen_adc(tmp
, tmp2
);
10321 gen_adc_CC(tmp
, tmp
, tmp2
);
10324 case 0x6: /* sbc */
10325 if (s
->condexec_mask
) {
10326 gen_sub_carry(tmp
, tmp
, tmp2
);
10328 gen_sbc_CC(tmp
, tmp
, tmp2
);
10331 case 0x7: /* ror */
10332 if (s
->condexec_mask
) {
10333 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
10334 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
10336 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10337 gen_logic_CC(tmp2
);
10340 case 0x8: /* tst */
10341 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
10345 case 0x9: /* neg */
10346 if (s
->condexec_mask
)
10347 tcg_gen_neg_i32(tmp
, tmp2
);
10349 gen_sub_CC(tmp
, tmp
, tmp2
);
10351 case 0xa: /* cmp */
10352 gen_sub_CC(tmp
, tmp
, tmp2
);
10355 case 0xb: /* cmn */
10356 gen_add_CC(tmp
, tmp
, tmp2
);
10359 case 0xc: /* orr */
10360 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
10361 if (!s
->condexec_mask
)
10364 case 0xd: /* mul */
10365 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
10366 if (!s
->condexec_mask
)
10369 case 0xe: /* bic */
10370 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
10371 if (!s
->condexec_mask
)
10374 case 0xf: /* mvn */
10375 tcg_gen_not_i32(tmp2
, tmp2
);
10376 if (!s
->condexec_mask
)
10377 gen_logic_CC(tmp2
);
10384 store_reg(s
, rm
, tmp2
);
10386 tcg_temp_free_i32(tmp
);
10388 store_reg(s
, rd
, tmp
);
10389 tcg_temp_free_i32(tmp2
);
10392 tcg_temp_free_i32(tmp
);
10393 tcg_temp_free_i32(tmp2
);
10398 /* load/store register offset. */
10400 rn
= (insn
>> 3) & 7;
10401 rm
= (insn
>> 6) & 7;
10402 op
= (insn
>> 9) & 7;
10403 addr
= load_reg(s
, rn
);
10404 tmp
= load_reg(s
, rm
);
10405 tcg_gen_add_i32(addr
, addr
, tmp
);
10406 tcg_temp_free_i32(tmp
);
10408 if (op
< 3) { /* store */
10409 tmp
= load_reg(s
, rd
);
10411 tmp
= tcg_temp_new_i32();
10416 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10419 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
10422 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
10424 case 3: /* ldrsb */
10425 gen_aa32_ld8s(tmp
, addr
, get_mem_index(s
));
10428 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10431 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
10434 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
10436 case 7: /* ldrsh */
10437 gen_aa32_ld16s(tmp
, addr
, get_mem_index(s
));
10440 if (op
>= 3) { /* load */
10441 store_reg(s
, rd
, tmp
);
10443 tcg_temp_free_i32(tmp
);
10445 tcg_temp_free_i32(addr
);
10449 /* load/store word immediate offset */
10451 rn
= (insn
>> 3) & 7;
10452 addr
= load_reg(s
, rn
);
10453 val
= (insn
>> 4) & 0x7c;
10454 tcg_gen_addi_i32(addr
, addr
, val
);
10456 if (insn
& (1 << 11)) {
10458 tmp
= tcg_temp_new_i32();
10459 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10460 store_reg(s
, rd
, tmp
);
10463 tmp
= load_reg(s
, rd
);
10464 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10465 tcg_temp_free_i32(tmp
);
10467 tcg_temp_free_i32(addr
);
10471 /* load/store byte immediate offset */
10473 rn
= (insn
>> 3) & 7;
10474 addr
= load_reg(s
, rn
);
10475 val
= (insn
>> 6) & 0x1f;
10476 tcg_gen_addi_i32(addr
, addr
, val
);
10478 if (insn
& (1 << 11)) {
10480 tmp
= tcg_temp_new_i32();
10481 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
10482 store_reg(s
, rd
, tmp
);
10485 tmp
= load_reg(s
, rd
);
10486 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
10487 tcg_temp_free_i32(tmp
);
10489 tcg_temp_free_i32(addr
);
10493 /* load/store halfword immediate offset */
10495 rn
= (insn
>> 3) & 7;
10496 addr
= load_reg(s
, rn
);
10497 val
= (insn
>> 5) & 0x3e;
10498 tcg_gen_addi_i32(addr
, addr
, val
);
10500 if (insn
& (1 << 11)) {
10502 tmp
= tcg_temp_new_i32();
10503 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
10504 store_reg(s
, rd
, tmp
);
10507 tmp
= load_reg(s
, rd
);
10508 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
10509 tcg_temp_free_i32(tmp
);
10511 tcg_temp_free_i32(addr
);
10515 /* load/store from stack */
10516 rd
= (insn
>> 8) & 7;
10517 addr
= load_reg(s
, 13);
10518 val
= (insn
& 0xff) * 4;
10519 tcg_gen_addi_i32(addr
, addr
, val
);
10521 if (insn
& (1 << 11)) {
10523 tmp
= tcg_temp_new_i32();
10524 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10525 store_reg(s
, rd
, tmp
);
10528 tmp
= load_reg(s
, rd
);
10529 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10530 tcg_temp_free_i32(tmp
);
10532 tcg_temp_free_i32(addr
);
10536 /* add to high reg */
10537 rd
= (insn
>> 8) & 7;
10538 if (insn
& (1 << 11)) {
10540 tmp
= load_reg(s
, 13);
10542 /* PC. bit 1 is ignored. */
10543 tmp
= tcg_temp_new_i32();
10544 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
10546 val
= (insn
& 0xff) * 4;
10547 tcg_gen_addi_i32(tmp
, tmp
, val
);
10548 store_reg(s
, rd
, tmp
);
10553 op
= (insn
>> 8) & 0xf;
10556 /* adjust stack pointer */
10557 tmp
= load_reg(s
, 13);
10558 val
= (insn
& 0x7f) * 4;
10559 if (insn
& (1 << 7))
10560 val
= -(int32_t)val
;
10561 tcg_gen_addi_i32(tmp
, tmp
, val
);
10562 store_reg(s
, 13, tmp
);
10565 case 2: /* sign/zero extend. */
10568 rm
= (insn
>> 3) & 7;
10569 tmp
= load_reg(s
, rm
);
10570 switch ((insn
>> 6) & 3) {
10571 case 0: gen_sxth(tmp
); break;
10572 case 1: gen_sxtb(tmp
); break;
10573 case 2: gen_uxth(tmp
); break;
10574 case 3: gen_uxtb(tmp
); break;
10576 store_reg(s
, rd
, tmp
);
10578 case 4: case 5: case 0xc: case 0xd:
10580 addr
= load_reg(s
, 13);
10581 if (insn
& (1 << 8))
10585 for (i
= 0; i
< 8; i
++) {
10586 if (insn
& (1 << i
))
10589 if ((insn
& (1 << 11)) == 0) {
10590 tcg_gen_addi_i32(addr
, addr
, -offset
);
10592 for (i
= 0; i
< 8; i
++) {
10593 if (insn
& (1 << i
)) {
10594 if (insn
& (1 << 11)) {
10596 tmp
= tcg_temp_new_i32();
10597 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10598 store_reg(s
, i
, tmp
);
10601 tmp
= load_reg(s
, i
);
10602 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10603 tcg_temp_free_i32(tmp
);
10605 /* advance to the next address. */
10606 tcg_gen_addi_i32(addr
, addr
, 4);
10609 TCGV_UNUSED_I32(tmp
);
10610 if (insn
& (1 << 8)) {
10611 if (insn
& (1 << 11)) {
10613 tmp
= tcg_temp_new_i32();
10614 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10615 /* don't set the pc until the rest of the instruction
10619 tmp
= load_reg(s
, 14);
10620 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10621 tcg_temp_free_i32(tmp
);
10623 tcg_gen_addi_i32(addr
, addr
, 4);
10625 if ((insn
& (1 << 11)) == 0) {
10626 tcg_gen_addi_i32(addr
, addr
, -offset
);
10628 /* write back the new stack pointer */
10629 store_reg(s
, 13, addr
);
10630 /* set the new PC value */
10631 if ((insn
& 0x0900) == 0x0900) {
10632 store_reg_from_load(env
, s
, 15, tmp
);
10636 case 1: case 3: case 9: case 11: /* czb */
10638 tmp
= load_reg(s
, rm
);
10639 s
->condlabel
= gen_new_label();
10641 if (insn
& (1 << 11))
10642 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
10644 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
10645 tcg_temp_free_i32(tmp
);
10646 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
10647 val
= (uint32_t)s
->pc
+ 2;
10652 case 15: /* IT, nop-hint. */
10653 if ((insn
& 0xf) == 0) {
10654 gen_nop_hint(s
, (insn
>> 4) & 0xf);
10658 s
->condexec_cond
= (insn
>> 4) & 0xe;
10659 s
->condexec_mask
= insn
& 0x1f;
10660 /* No actual code generated for this insn, just setup state. */
10663 case 0xe: /* bkpt */
10665 int imm8
= extract32(insn
, 0, 8);
10667 gen_exception_insn(s
, 2, EXCP_BKPT
, syn_aa32_bkpt(imm8
, true));
10671 case 0xa: /* rev */
10673 rn
= (insn
>> 3) & 0x7;
10675 tmp
= load_reg(s
, rn
);
10676 switch ((insn
>> 6) & 3) {
10677 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
10678 case 1: gen_rev16(tmp
); break;
10679 case 3: gen_revsh(tmp
); break;
10680 default: goto illegal_op
;
10682 store_reg(s
, rd
, tmp
);
10686 switch ((insn
>> 5) & 7) {
10690 if (((insn
>> 3) & 1) != s
->bswap_code
) {
10691 /* Dynamic endianness switching not implemented. */
10692 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
10703 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
10706 addr
= tcg_const_i32(19);
10707 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10708 tcg_temp_free_i32(addr
);
10712 addr
= tcg_const_i32(16);
10713 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10714 tcg_temp_free_i32(addr
);
10716 tcg_temp_free_i32(tmp
);
10719 if (insn
& (1 << 4)) {
10720 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
10724 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
10739 /* load/store multiple */
10740 TCGv_i32 loaded_var
;
10741 TCGV_UNUSED_I32(loaded_var
);
10742 rn
= (insn
>> 8) & 0x7;
10743 addr
= load_reg(s
, rn
);
10744 for (i
= 0; i
< 8; i
++) {
10745 if (insn
& (1 << i
)) {
10746 if (insn
& (1 << 11)) {
10748 tmp
= tcg_temp_new_i32();
10749 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10753 store_reg(s
, i
, tmp
);
10757 tmp
= load_reg(s
, i
);
10758 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10759 tcg_temp_free_i32(tmp
);
10761 /* advance to the next address */
10762 tcg_gen_addi_i32(addr
, addr
, 4);
10765 if ((insn
& (1 << rn
)) == 0) {
10766 /* base reg not in list: base register writeback */
10767 store_reg(s
, rn
, addr
);
10769 /* base reg in list: if load, complete it now */
10770 if (insn
& (1 << 11)) {
10771 store_reg(s
, rn
, loaded_var
);
10773 tcg_temp_free_i32(addr
);
10778 /* conditional branch or swi */
10779 cond
= (insn
>> 8) & 0xf;
10785 gen_set_pc_im(s
, s
->pc
);
10786 s
->svc_imm
= extract32(insn
, 0, 8);
10787 s
->is_jmp
= DISAS_SWI
;
10790 /* generate a conditional jump to next instruction */
10791 s
->condlabel
= gen_new_label();
10792 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
10795 /* jump to the offset */
10796 val
= (uint32_t)s
->pc
+ 2;
10797 offset
= ((int32_t)insn
<< 24) >> 24;
10798 val
+= offset
<< 1;
10803 if (insn
& (1 << 11)) {
10804 if (disas_thumb2_insn(env
, s
, insn
))
10808 /* unconditional branch */
10809 val
= (uint32_t)s
->pc
;
10810 offset
= ((int32_t)insn
<< 21) >> 21;
10811 val
+= (offset
<< 1) + 2;
10816 if (disas_thumb2_insn(env
, s
, insn
))
10822 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized());
10826 gen_exception_insn(s
, 2, EXCP_UDEF
, syn_uncategorized());
10829 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
10830 basic block 'tb'. If search_pc is TRUE, also generate PC
10831 information for each intermediate instruction. */
10832 static inline void gen_intermediate_code_internal(ARMCPU
*cpu
,
10833 TranslationBlock
*tb
,
10836 CPUState
*cs
= CPU(cpu
);
10837 CPUARMState
*env
= &cpu
->env
;
10838 DisasContext dc1
, *dc
= &dc1
;
10840 uint16_t *gen_opc_end
;
10842 target_ulong pc_start
;
10843 target_ulong next_page_start
;
10847 /* generate intermediate code */
10849 /* The A64 decoder has its own top level loop, because it doesn't need
10850 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
10852 if (ARM_TBFLAG_AARCH64_STATE(tb
->flags
)) {
10853 gen_intermediate_code_internal_a64(cpu
, tb
, search_pc
);
10861 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
10863 dc
->is_jmp
= DISAS_NEXT
;
10865 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
10869 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
10870 dc
->bswap_code
= ARM_TBFLAG_BSWAP_CODE(tb
->flags
);
10871 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
10872 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
10873 #if !defined(CONFIG_USER_ONLY)
10874 dc
->user
= (ARM_TBFLAG_PRIV(tb
->flags
) == 0);
10876 dc
->cpacr_fpen
= ARM_TBFLAG_CPACR_FPEN(tb
->flags
);
10877 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
10878 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
10879 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
10880 dc
->cp_regs
= cpu
->cp_regs
;
10881 dc
->current_pl
= arm_current_pl(env
);
10882 dc
->features
= env
->features
;
10884 cpu_F0s
= tcg_temp_new_i32();
10885 cpu_F1s
= tcg_temp_new_i32();
10886 cpu_F0d
= tcg_temp_new_i64();
10887 cpu_F1d
= tcg_temp_new_i64();
10890 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
10891 cpu_M0
= tcg_temp_new_i64();
10892 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
10895 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
10896 if (max_insns
== 0)
10897 max_insns
= CF_COUNT_MASK
;
10901 tcg_clear_temp_count();
10903 /* A note on handling of the condexec (IT) bits:
10905 * We want to avoid the overhead of having to write the updated condexec
10906 * bits back to the CPUARMState for every instruction in an IT block. So:
10907 * (1) if the condexec bits are not already zero then we write
10908 * zero back into the CPUARMState now. This avoids complications trying
10909 * to do it at the end of the block. (For example if we don't do this
10910 * it's hard to identify whether we can safely skip writing condexec
10911 * at the end of the TB, which we definitely want to do for the case
10912 * where a TB doesn't do anything with the IT state at all.)
10913 * (2) if we are going to leave the TB then we call gen_set_condexec()
10914 * which will write the correct value into CPUARMState if zero is wrong.
10915 * This is done both for leaving the TB at the end, and for leaving
10916 * it because of an exception we know will happen, which is done in
10917 * gen_exception_insn(). The latter is necessary because we need to
10918 * leave the TB with the PC/IT state just prior to execution of the
10919 * instruction which caused the exception.
10920 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
10921 * then the CPUARMState will be wrong and we need to reset it.
10922 * This is handled in the same way as restoration of the
10923 * PC in these situations: we will be called again with search_pc=1
10924 * and generate a mapping of the condexec bits for each PC in
10925 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
10926 * this to restore the condexec bits.
10928 * Note that there are no instructions which can read the condexec
10929 * bits, and none which can write non-static values to them, so
10930 * we don't need to care about whether CPUARMState is correct in the
10934 /* Reset the conditional execution bits immediately. This avoids
10935 complications trying to do it at the end of the block. */
10936 if (dc
->condexec_mask
|| dc
->condexec_cond
)
10938 TCGv_i32 tmp
= tcg_temp_new_i32();
10939 tcg_gen_movi_i32(tmp
, 0);
10940 store_cpu_field(tmp
, condexec_bits
);
10943 #ifdef CONFIG_USER_ONLY
10944 /* Intercept jump to the magic kernel page. */
10945 if (dc
->pc
>= 0xffff0000) {
10946 /* We always get here via a jump, so know we are not in a
10947 conditional execution block. */
10948 gen_exception_internal(EXCP_KERNEL_TRAP
);
10949 dc
->is_jmp
= DISAS_UPDATE
;
10953 if (dc
->pc
>= 0xfffffff0 && IS_M(env
)) {
10954 /* We always get here via a jump, so know we are not in a
10955 conditional execution block. */
10956 gen_exception_internal(EXCP_EXCEPTION_EXIT
);
10957 dc
->is_jmp
= DISAS_UPDATE
;
10962 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
10963 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
10964 if (bp
->pc
== dc
->pc
) {
10965 gen_exception_internal_insn(dc
, 0, EXCP_DEBUG
);
10966 /* Advance PC so that clearing the breakpoint will
10967 invalidate this TB. */
10969 goto done_generating
;
10974 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
10978 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
10980 tcg_ctx
.gen_opc_pc
[lj
] = dc
->pc
;
10981 gen_opc_condexec_bits
[lj
] = (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1);
10982 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
10983 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
10986 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
10989 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
10990 tcg_gen_debug_insn_start(dc
->pc
);
10994 disas_thumb_insn(env
, dc
);
10995 if (dc
->condexec_mask
) {
10996 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
10997 | ((dc
->condexec_mask
>> 4) & 1);
10998 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
10999 if (dc
->condexec_mask
== 0) {
11000 dc
->condexec_cond
= 0;
11004 disas_arm_insn(env
, dc
);
11007 if (dc
->condjmp
&& !dc
->is_jmp
) {
11008 gen_set_label(dc
->condlabel
);
11012 if (tcg_check_temp_count()) {
11013 fprintf(stderr
, "TCG temporary leak before "TARGET_FMT_lx
"\n",
11017 /* Translation stops when a conditional branch is encountered.
11018 * Otherwise the subsequent code could get translated several times.
11019 * Also stop translation when a page boundary is reached. This
11020 * ensures prefetch aborts occur at the right place. */
11022 } while (!dc
->is_jmp
&& tcg_ctx
.gen_opc_ptr
< gen_opc_end
&&
11023 !cs
->singlestep_enabled
&&
11025 dc
->pc
< next_page_start
&&
11026 num_insns
< max_insns
);
11028 if (tb
->cflags
& CF_LAST_IO
) {
11030 /* FIXME: This can theoretically happen with self-modifying
11032 cpu_abort(cs
, "IO on conditional branch instruction");
11037 /* At this stage dc->condjmp will only be set when the skipped
11038 instruction was a conditional branch or trap, and the PC has
11039 already been written. */
11040 if (unlikely(cs
->singlestep_enabled
)) {
11041 /* Make sure the pc is updated, and raise a debug exception. */
11043 gen_set_condexec(dc
);
11044 if (dc
->is_jmp
== DISAS_SWI
) {
11045 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
));
11047 gen_exception_internal(EXCP_DEBUG
);
11049 gen_set_label(dc
->condlabel
);
11051 if (dc
->condjmp
|| !dc
->is_jmp
) {
11052 gen_set_pc_im(dc
, dc
->pc
);
11055 gen_set_condexec(dc
);
11056 if (dc
->is_jmp
== DISAS_SWI
&& !dc
->condjmp
) {
11057 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
));
11059 /* FIXME: Single stepping a WFI insn will not halt
11061 gen_exception_internal(EXCP_DEBUG
);
11064 /* While branches must always occur at the end of an IT block,
11065 there are a few other things that can cause us to terminate
11066 the TB in the middle of an IT block:
11067 - Exception generating instructions (bkpt, swi, undefined).
11069 - Hardware watchpoints.
11070 Hardware breakpoints have already been handled and skip this code.
11072 gen_set_condexec(dc
);
11073 switch(dc
->is_jmp
) {
11075 gen_goto_tb(dc
, 1, dc
->pc
);
11080 /* indicate that the hash table must be used to find the next TB */
11081 tcg_gen_exit_tb(0);
11083 case DISAS_TB_JUMP
:
11084 /* nothing more to generate */
11087 gen_helper_wfi(cpu_env
);
11090 gen_helper_wfe(cpu_env
);
11093 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
));
11097 gen_set_label(dc
->condlabel
);
11098 gen_set_condexec(dc
);
11099 gen_goto_tb(dc
, 1, dc
->pc
);
11105 gen_tb_end(tb
, num_insns
);
11106 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
11109 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
11110 qemu_log("----------------\n");
11111 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
11112 log_target_disas(env
, pc_start
, dc
->pc
- pc_start
,
11113 dc
->thumb
| (dc
->bswap_code
<< 1));
11118 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
11121 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
11123 tb
->size
= dc
->pc
- pc_start
;
11124 tb
->icount
= num_insns
;
11128 void gen_intermediate_code(CPUARMState
*env
, TranslationBlock
*tb
)
11130 gen_intermediate_code_internal(arm_env_get_cpu(env
), tb
, false);
11133 void gen_intermediate_code_pc(CPUARMState
*env
, TranslationBlock
*tb
)
11135 gen_intermediate_code_internal(arm_env_get_cpu(env
), tb
, true);
11138 static const char *cpu_mode_names
[16] = {
11139 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
11140 "???", "???", "hyp", "und", "???", "???", "???", "sys"
11143 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
11146 ARMCPU
*cpu
= ARM_CPU(cs
);
11147 CPUARMState
*env
= &cpu
->env
;
11152 aarch64_cpu_dump_state(cs
, f
, cpu_fprintf
, flags
);
11156 for(i
=0;i
<16;i
++) {
11157 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
11159 cpu_fprintf(f
, "\n");
11161 cpu_fprintf(f
, " ");
11163 psr
= cpsr_read(env
);
11164 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%d\n",
11166 psr
& (1 << 31) ? 'N' : '-',
11167 psr
& (1 << 30) ? 'Z' : '-',
11168 psr
& (1 << 29) ? 'C' : '-',
11169 psr
& (1 << 28) ? 'V' : '-',
11170 psr
& CPSR_T
? 'T' : 'A',
11171 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
11173 if (flags
& CPU_DUMP_FPU
) {
11174 int numvfpregs
= 0;
11175 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
11178 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
11181 for (i
= 0; i
< numvfpregs
; i
++) {
11182 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
11183 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
11184 i
* 2, (uint32_t)v
,
11185 i
* 2 + 1, (uint32_t)(v
>> 32),
11188 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
11192 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
, int pc_pos
)
11195 env
->pc
= tcg_ctx
.gen_opc_pc
[pc_pos
];
11196 env
->condexec_bits
= 0;
11198 env
->regs
[15] = tcg_ctx
.gen_opc_pc
[pc_pos
];
11199 env
->condexec_bits
= gen_opc_condexec_bits
[pc_pos
];