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 #include "trace-tcg.h"
41 #define ENABLE_ARCH_4T arm_feature(env, ARM_FEATURE_V4T)
42 #define ENABLE_ARCH_5 arm_feature(env, ARM_FEATURE_V5)
43 /* currently all emulated v5 cores are also v5TE, so don't bother */
44 #define ENABLE_ARCH_5TE arm_feature(env, ARM_FEATURE_V5)
45 #define ENABLE_ARCH_5J 0
46 #define ENABLE_ARCH_6 arm_feature(env, ARM_FEATURE_V6)
47 #define ENABLE_ARCH_6K arm_feature(env, ARM_FEATURE_V6K)
48 #define ENABLE_ARCH_6T2 arm_feature(env, ARM_FEATURE_THUMB2)
49 #define ENABLE_ARCH_7 arm_feature(env, ARM_FEATURE_V7)
50 #define ENABLE_ARCH_8 arm_feature(env, ARM_FEATURE_V8)
52 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
54 #include "translate.h"
55 static uint32_t gen_opc_condexec_bits
[OPC_BUF_SIZE
];
57 #if defined(CONFIG_USER_ONLY)
60 #define IS_USER(s) (s->user)
64 /* We reuse the same 64-bit temporaries for efficiency. */
65 static TCGv_i64 cpu_V0
, cpu_V1
, cpu_M0
;
66 static TCGv_i32 cpu_R
[16];
67 static TCGv_i32 cpu_CF
, cpu_NF
, cpu_VF
, cpu_ZF
;
68 static TCGv_i64 cpu_exclusive_addr
;
69 static TCGv_i64 cpu_exclusive_val
;
70 #ifdef CONFIG_USER_ONLY
71 static TCGv_i64 cpu_exclusive_test
;
72 static TCGv_i32 cpu_exclusive_info
;
75 /* FIXME: These should be removed. */
76 static TCGv_i32 cpu_F0s
, cpu_F1s
;
77 static TCGv_i64 cpu_F0d
, cpu_F1d
;
79 #include "exec/gen-icount.h"
81 static const char *regnames
[] =
82 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
83 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
85 /* initialize TCG globals. */
86 void arm_translate_init(void)
90 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
92 for (i
= 0; i
< 16; i
++) {
93 cpu_R
[i
] = tcg_global_mem_new_i32(TCG_AREG0
,
94 offsetof(CPUARMState
, regs
[i
]),
97 cpu_CF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, CF
), "CF");
98 cpu_NF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, NF
), "NF");
99 cpu_VF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, VF
), "VF");
100 cpu_ZF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, ZF
), "ZF");
102 cpu_exclusive_addr
= tcg_global_mem_new_i64(TCG_AREG0
,
103 offsetof(CPUARMState
, exclusive_addr
), "exclusive_addr");
104 cpu_exclusive_val
= tcg_global_mem_new_i64(TCG_AREG0
,
105 offsetof(CPUARMState
, exclusive_val
), "exclusive_val");
106 #ifdef CONFIG_USER_ONLY
107 cpu_exclusive_test
= tcg_global_mem_new_i64(TCG_AREG0
,
108 offsetof(CPUARMState
, exclusive_test
), "exclusive_test");
109 cpu_exclusive_info
= tcg_global_mem_new_i32(TCG_AREG0
,
110 offsetof(CPUARMState
, exclusive_info
), "exclusive_info");
113 a64_translate_init();
116 static inline TCGv_i32
load_cpu_offset(int offset
)
118 TCGv_i32 tmp
= tcg_temp_new_i32();
119 tcg_gen_ld_i32(tmp
, cpu_env
, offset
);
123 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
125 static inline void store_cpu_offset(TCGv_i32 var
, int offset
)
127 tcg_gen_st_i32(var
, cpu_env
, offset
);
128 tcg_temp_free_i32(var
);
131 #define store_cpu_field(var, name) \
132 store_cpu_offset(var, offsetof(CPUARMState, name))
134 /* Set a variable to the value of a CPU register. */
135 static void load_reg_var(DisasContext
*s
, TCGv_i32 var
, int reg
)
139 /* normally, since we updated PC, we need only to add one insn */
141 addr
= (long)s
->pc
+ 2;
143 addr
= (long)s
->pc
+ 4;
144 tcg_gen_movi_i32(var
, addr
);
146 tcg_gen_mov_i32(var
, cpu_R
[reg
]);
150 /* Create a new temporary and set it to the value of a CPU register. */
151 static inline TCGv_i32
load_reg(DisasContext
*s
, int reg
)
153 TCGv_i32 tmp
= tcg_temp_new_i32();
154 load_reg_var(s
, tmp
, reg
);
158 /* Set a CPU register. The source must be a temporary and will be
160 static void store_reg(DisasContext
*s
, int reg
, TCGv_i32 var
)
163 tcg_gen_andi_i32(var
, var
, ~1);
164 s
->is_jmp
= DISAS_JUMP
;
166 tcg_gen_mov_i32(cpu_R
[reg
], var
);
167 tcg_temp_free_i32(var
);
170 /* Value extensions. */
171 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
172 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
173 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
174 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
176 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
177 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
180 static inline void gen_set_cpsr(TCGv_i32 var
, uint32_t mask
)
182 TCGv_i32 tmp_mask
= tcg_const_i32(mask
);
183 gen_helper_cpsr_write(cpu_env
, var
, tmp_mask
);
184 tcg_temp_free_i32(tmp_mask
);
186 /* Set NZCV flags from the high 4 bits of var. */
187 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
189 static void gen_exception_internal(int excp
)
191 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
193 assert(excp_is_internal(excp
));
194 gen_helper_exception_internal(cpu_env
, tcg_excp
);
195 tcg_temp_free_i32(tcg_excp
);
198 static void gen_exception(int excp
, uint32_t syndrome
)
200 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
201 TCGv_i32 tcg_syn
= tcg_const_i32(syndrome
);
203 gen_helper_exception_with_syndrome(cpu_env
, tcg_excp
, tcg_syn
);
204 tcg_temp_free_i32(tcg_syn
);
205 tcg_temp_free_i32(tcg_excp
);
208 static void gen_ss_advance(DisasContext
*s
)
210 /* If the singlestep state is Active-not-pending, advance to
215 gen_helper_clear_pstate_ss(cpu_env
);
219 static void gen_step_complete_exception(DisasContext
*s
)
221 /* We just completed step of an insn. Move from Active-not-pending
222 * to Active-pending, and then also take the swstep exception.
223 * This corresponds to making the (IMPDEF) choice to prioritize
224 * swstep exceptions over asynchronous exceptions taken to an exception
225 * level where debug is disabled. This choice has the advantage that
226 * we do not need to maintain internal state corresponding to the
227 * ISV/EX syndrome bits between completion of the step and generation
228 * of the exception, and our syndrome information is always correct.
231 gen_exception(EXCP_UDEF
, syn_swstep(s
->ss_same_el
, 1, s
->is_ldex
));
232 s
->is_jmp
= DISAS_EXC
;
235 static void gen_smul_dual(TCGv_i32 a
, TCGv_i32 b
)
237 TCGv_i32 tmp1
= tcg_temp_new_i32();
238 TCGv_i32 tmp2
= tcg_temp_new_i32();
239 tcg_gen_ext16s_i32(tmp1
, a
);
240 tcg_gen_ext16s_i32(tmp2
, b
);
241 tcg_gen_mul_i32(tmp1
, tmp1
, tmp2
);
242 tcg_temp_free_i32(tmp2
);
243 tcg_gen_sari_i32(a
, a
, 16);
244 tcg_gen_sari_i32(b
, b
, 16);
245 tcg_gen_mul_i32(b
, b
, a
);
246 tcg_gen_mov_i32(a
, tmp1
);
247 tcg_temp_free_i32(tmp1
);
250 /* Byteswap each halfword. */
251 static void gen_rev16(TCGv_i32 var
)
253 TCGv_i32 tmp
= tcg_temp_new_i32();
254 tcg_gen_shri_i32(tmp
, var
, 8);
255 tcg_gen_andi_i32(tmp
, tmp
, 0x00ff00ff);
256 tcg_gen_shli_i32(var
, var
, 8);
257 tcg_gen_andi_i32(var
, var
, 0xff00ff00);
258 tcg_gen_or_i32(var
, var
, tmp
);
259 tcg_temp_free_i32(tmp
);
262 /* Byteswap low halfword and sign extend. */
263 static void gen_revsh(TCGv_i32 var
)
265 tcg_gen_ext16u_i32(var
, var
);
266 tcg_gen_bswap16_i32(var
, var
);
267 tcg_gen_ext16s_i32(var
, var
);
270 /* Unsigned bitfield extract. */
271 static void gen_ubfx(TCGv_i32 var
, int shift
, uint32_t mask
)
274 tcg_gen_shri_i32(var
, var
, shift
);
275 tcg_gen_andi_i32(var
, var
, mask
);
278 /* Signed bitfield extract. */
279 static void gen_sbfx(TCGv_i32 var
, int shift
, int width
)
284 tcg_gen_sari_i32(var
, var
, shift
);
285 if (shift
+ width
< 32) {
286 signbit
= 1u << (width
- 1);
287 tcg_gen_andi_i32(var
, var
, (1u << width
) - 1);
288 tcg_gen_xori_i32(var
, var
, signbit
);
289 tcg_gen_subi_i32(var
, var
, signbit
);
293 /* Return (b << 32) + a. Mark inputs as dead */
294 static TCGv_i64
gen_addq_msw(TCGv_i64 a
, TCGv_i32 b
)
296 TCGv_i64 tmp64
= tcg_temp_new_i64();
298 tcg_gen_extu_i32_i64(tmp64
, b
);
299 tcg_temp_free_i32(b
);
300 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
301 tcg_gen_add_i64(a
, tmp64
, a
);
303 tcg_temp_free_i64(tmp64
);
307 /* Return (b << 32) - a. Mark inputs as dead. */
308 static TCGv_i64
gen_subq_msw(TCGv_i64 a
, TCGv_i32 b
)
310 TCGv_i64 tmp64
= tcg_temp_new_i64();
312 tcg_gen_extu_i32_i64(tmp64
, b
);
313 tcg_temp_free_i32(b
);
314 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
315 tcg_gen_sub_i64(a
, tmp64
, a
);
317 tcg_temp_free_i64(tmp64
);
321 /* 32x32->64 multiply. Marks inputs as dead. */
322 static TCGv_i64
gen_mulu_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
324 TCGv_i32 lo
= tcg_temp_new_i32();
325 TCGv_i32 hi
= tcg_temp_new_i32();
328 tcg_gen_mulu2_i32(lo
, hi
, a
, b
);
329 tcg_temp_free_i32(a
);
330 tcg_temp_free_i32(b
);
332 ret
= tcg_temp_new_i64();
333 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
334 tcg_temp_free_i32(lo
);
335 tcg_temp_free_i32(hi
);
340 static TCGv_i64
gen_muls_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
342 TCGv_i32 lo
= tcg_temp_new_i32();
343 TCGv_i32 hi
= tcg_temp_new_i32();
346 tcg_gen_muls2_i32(lo
, hi
, a
, b
);
347 tcg_temp_free_i32(a
);
348 tcg_temp_free_i32(b
);
350 ret
= tcg_temp_new_i64();
351 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
352 tcg_temp_free_i32(lo
);
353 tcg_temp_free_i32(hi
);
358 /* Swap low and high halfwords. */
359 static void gen_swap_half(TCGv_i32 var
)
361 TCGv_i32 tmp
= tcg_temp_new_i32();
362 tcg_gen_shri_i32(tmp
, var
, 16);
363 tcg_gen_shli_i32(var
, var
, 16);
364 tcg_gen_or_i32(var
, var
, tmp
);
365 tcg_temp_free_i32(tmp
);
368 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
369 tmp = (t0 ^ t1) & 0x8000;
372 t0 = (t0 + t1) ^ tmp;
375 static void gen_add16(TCGv_i32 t0
, TCGv_i32 t1
)
377 TCGv_i32 tmp
= tcg_temp_new_i32();
378 tcg_gen_xor_i32(tmp
, t0
, t1
);
379 tcg_gen_andi_i32(tmp
, tmp
, 0x8000);
380 tcg_gen_andi_i32(t0
, t0
, ~0x8000);
381 tcg_gen_andi_i32(t1
, t1
, ~0x8000);
382 tcg_gen_add_i32(t0
, t0
, t1
);
383 tcg_gen_xor_i32(t0
, t0
, tmp
);
384 tcg_temp_free_i32(tmp
);
385 tcg_temp_free_i32(t1
);
388 /* Set CF to the top bit of var. */
389 static void gen_set_CF_bit31(TCGv_i32 var
)
391 tcg_gen_shri_i32(cpu_CF
, var
, 31);
394 /* Set N and Z flags from var. */
395 static inline void gen_logic_CC(TCGv_i32 var
)
397 tcg_gen_mov_i32(cpu_NF
, var
);
398 tcg_gen_mov_i32(cpu_ZF
, var
);
402 static void gen_adc(TCGv_i32 t0
, TCGv_i32 t1
)
404 tcg_gen_add_i32(t0
, t0
, t1
);
405 tcg_gen_add_i32(t0
, t0
, cpu_CF
);
408 /* dest = T0 + T1 + CF. */
409 static void gen_add_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
411 tcg_gen_add_i32(dest
, t0
, t1
);
412 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
415 /* dest = T0 - T1 + CF - 1. */
416 static void gen_sub_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
418 tcg_gen_sub_i32(dest
, t0
, t1
);
419 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
420 tcg_gen_subi_i32(dest
, dest
, 1);
423 /* dest = T0 + T1. Compute C, N, V and Z flags */
424 static void gen_add_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
426 TCGv_i32 tmp
= tcg_temp_new_i32();
427 tcg_gen_movi_i32(tmp
, 0);
428 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, t1
, tmp
);
429 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
430 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
431 tcg_gen_xor_i32(tmp
, t0
, t1
);
432 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
433 tcg_temp_free_i32(tmp
);
434 tcg_gen_mov_i32(dest
, cpu_NF
);
437 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
438 static void gen_adc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
440 TCGv_i32 tmp
= tcg_temp_new_i32();
441 if (TCG_TARGET_HAS_add2_i32
) {
442 tcg_gen_movi_i32(tmp
, 0);
443 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, cpu_CF
, tmp
);
444 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, cpu_NF
, cpu_CF
, t1
, tmp
);
446 TCGv_i64 q0
= tcg_temp_new_i64();
447 TCGv_i64 q1
= tcg_temp_new_i64();
448 tcg_gen_extu_i32_i64(q0
, t0
);
449 tcg_gen_extu_i32_i64(q1
, t1
);
450 tcg_gen_add_i64(q0
, q0
, q1
);
451 tcg_gen_extu_i32_i64(q1
, cpu_CF
);
452 tcg_gen_add_i64(q0
, q0
, q1
);
453 tcg_gen_extr_i64_i32(cpu_NF
, cpu_CF
, q0
);
454 tcg_temp_free_i64(q0
);
455 tcg_temp_free_i64(q1
);
457 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
458 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
459 tcg_gen_xor_i32(tmp
, t0
, t1
);
460 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
461 tcg_temp_free_i32(tmp
);
462 tcg_gen_mov_i32(dest
, cpu_NF
);
465 /* dest = T0 - T1. Compute C, N, V and Z flags */
466 static void gen_sub_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
469 tcg_gen_sub_i32(cpu_NF
, t0
, t1
);
470 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
471 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_CF
, t0
, t1
);
472 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
473 tmp
= tcg_temp_new_i32();
474 tcg_gen_xor_i32(tmp
, t0
, t1
);
475 tcg_gen_and_i32(cpu_VF
, cpu_VF
, tmp
);
476 tcg_temp_free_i32(tmp
);
477 tcg_gen_mov_i32(dest
, cpu_NF
);
480 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
481 static void gen_sbc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
483 TCGv_i32 tmp
= tcg_temp_new_i32();
484 tcg_gen_not_i32(tmp
, t1
);
485 gen_adc_CC(dest
, t0
, tmp
);
486 tcg_temp_free_i32(tmp
);
489 #define GEN_SHIFT(name) \
490 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
492 TCGv_i32 tmp1, tmp2, tmp3; \
493 tmp1 = tcg_temp_new_i32(); \
494 tcg_gen_andi_i32(tmp1, t1, 0xff); \
495 tmp2 = tcg_const_i32(0); \
496 tmp3 = tcg_const_i32(0x1f); \
497 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
498 tcg_temp_free_i32(tmp3); \
499 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
500 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
501 tcg_temp_free_i32(tmp2); \
502 tcg_temp_free_i32(tmp1); \
508 static void gen_sar(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
511 tmp1
= tcg_temp_new_i32();
512 tcg_gen_andi_i32(tmp1
, t1
, 0xff);
513 tmp2
= tcg_const_i32(0x1f);
514 tcg_gen_movcond_i32(TCG_COND_GTU
, tmp1
, tmp1
, tmp2
, tmp2
, tmp1
);
515 tcg_temp_free_i32(tmp2
);
516 tcg_gen_sar_i32(dest
, t0
, tmp1
);
517 tcg_temp_free_i32(tmp1
);
520 static void tcg_gen_abs_i32(TCGv_i32 dest
, TCGv_i32 src
)
522 TCGv_i32 c0
= tcg_const_i32(0);
523 TCGv_i32 tmp
= tcg_temp_new_i32();
524 tcg_gen_neg_i32(tmp
, src
);
525 tcg_gen_movcond_i32(TCG_COND_GT
, dest
, src
, c0
, src
, tmp
);
526 tcg_temp_free_i32(c0
);
527 tcg_temp_free_i32(tmp
);
530 static void shifter_out_im(TCGv_i32 var
, int shift
)
533 tcg_gen_andi_i32(cpu_CF
, var
, 1);
535 tcg_gen_shri_i32(cpu_CF
, var
, shift
);
537 tcg_gen_andi_i32(cpu_CF
, cpu_CF
, 1);
542 /* Shift by immediate. Includes special handling for shift == 0. */
543 static inline void gen_arm_shift_im(TCGv_i32 var
, int shiftop
,
544 int shift
, int flags
)
550 shifter_out_im(var
, 32 - shift
);
551 tcg_gen_shli_i32(var
, var
, shift
);
557 tcg_gen_shri_i32(cpu_CF
, var
, 31);
559 tcg_gen_movi_i32(var
, 0);
562 shifter_out_im(var
, shift
- 1);
563 tcg_gen_shri_i32(var
, var
, shift
);
570 shifter_out_im(var
, shift
- 1);
573 tcg_gen_sari_i32(var
, var
, shift
);
575 case 3: /* ROR/RRX */
578 shifter_out_im(var
, shift
- 1);
579 tcg_gen_rotri_i32(var
, var
, shift
); break;
581 TCGv_i32 tmp
= tcg_temp_new_i32();
582 tcg_gen_shli_i32(tmp
, cpu_CF
, 31);
584 shifter_out_im(var
, 0);
585 tcg_gen_shri_i32(var
, var
, 1);
586 tcg_gen_or_i32(var
, var
, tmp
);
587 tcg_temp_free_i32(tmp
);
592 static inline void gen_arm_shift_reg(TCGv_i32 var
, int shiftop
,
593 TCGv_i32 shift
, int flags
)
597 case 0: gen_helper_shl_cc(var
, cpu_env
, var
, shift
); break;
598 case 1: gen_helper_shr_cc(var
, cpu_env
, var
, shift
); break;
599 case 2: gen_helper_sar_cc(var
, cpu_env
, var
, shift
); break;
600 case 3: gen_helper_ror_cc(var
, cpu_env
, var
, shift
); break;
605 gen_shl(var
, var
, shift
);
608 gen_shr(var
, var
, shift
);
611 gen_sar(var
, var
, shift
);
613 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
614 tcg_gen_rotr_i32(var
, var
, shift
); break;
617 tcg_temp_free_i32(shift
);
620 #define PAS_OP(pfx) \
622 case 0: gen_pas_helper(glue(pfx,add16)); break; \
623 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
624 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
625 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
626 case 4: gen_pas_helper(glue(pfx,add8)); break; \
627 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
629 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
634 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
636 tmp
= tcg_temp_new_ptr();
637 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
639 tcg_temp_free_ptr(tmp
);
642 tmp
= tcg_temp_new_ptr();
643 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
645 tcg_temp_free_ptr(tmp
);
647 #undef gen_pas_helper
648 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
661 #undef gen_pas_helper
666 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
667 #define PAS_OP(pfx) \
669 case 0: gen_pas_helper(glue(pfx,add8)); break; \
670 case 1: gen_pas_helper(glue(pfx,add16)); break; \
671 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
672 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
673 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
674 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
676 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
681 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
683 tmp
= tcg_temp_new_ptr();
684 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
686 tcg_temp_free_ptr(tmp
);
689 tmp
= tcg_temp_new_ptr();
690 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
692 tcg_temp_free_ptr(tmp
);
694 #undef gen_pas_helper
695 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
708 #undef gen_pas_helper
714 * generate a conditional branch based on ARM condition code cc.
715 * This is common between ARM and Aarch64 targets.
717 void arm_gen_test_cc(int cc
, int label
)
724 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
727 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_ZF
, 0, label
);
730 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_CF
, 0, label
);
733 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, label
);
736 tcg_gen_brcondi_i32(TCG_COND_LT
, cpu_NF
, 0, label
);
739 tcg_gen_brcondi_i32(TCG_COND_GE
, cpu_NF
, 0, label
);
742 tcg_gen_brcondi_i32(TCG_COND_LT
, cpu_VF
, 0, label
);
745 tcg_gen_brcondi_i32(TCG_COND_GE
, cpu_VF
, 0, label
);
747 case 8: /* hi: C && !Z */
748 inv
= gen_new_label();
749 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, inv
);
750 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_ZF
, 0, label
);
753 case 9: /* ls: !C || Z */
754 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, label
);
755 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
757 case 10: /* ge: N == V -> N ^ V == 0 */
758 tmp
= tcg_temp_new_i32();
759 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
760 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
761 tcg_temp_free_i32(tmp
);
763 case 11: /* lt: N != V -> N ^ V != 0 */
764 tmp
= tcg_temp_new_i32();
765 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
766 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
767 tcg_temp_free_i32(tmp
);
769 case 12: /* gt: !Z && N == V */
770 inv
= gen_new_label();
771 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, inv
);
772 tmp
= tcg_temp_new_i32();
773 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
774 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
775 tcg_temp_free_i32(tmp
);
778 case 13: /* le: Z || N != V */
779 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
780 tmp
= tcg_temp_new_i32();
781 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
782 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
783 tcg_temp_free_i32(tmp
);
786 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
791 static const uint8_t table_logic_cc
[16] = {
810 /* Set PC and Thumb state from an immediate address. */
811 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
815 s
->is_jmp
= DISAS_UPDATE
;
816 if (s
->thumb
!= (addr
& 1)) {
817 tmp
= tcg_temp_new_i32();
818 tcg_gen_movi_i32(tmp
, addr
& 1);
819 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUARMState
, thumb
));
820 tcg_temp_free_i32(tmp
);
822 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
825 /* Set PC and Thumb state from var. var is marked as dead. */
826 static inline void gen_bx(DisasContext
*s
, TCGv_i32 var
)
828 s
->is_jmp
= DISAS_UPDATE
;
829 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
830 tcg_gen_andi_i32(var
, var
, 1);
831 store_cpu_field(var
, thumb
);
834 /* Variant of store_reg which uses branch&exchange logic when storing
835 to r15 in ARM architecture v7 and above. The source must be a temporary
836 and will be marked as dead. */
837 static inline void store_reg_bx(CPUARMState
*env
, DisasContext
*s
,
838 int reg
, TCGv_i32 var
)
840 if (reg
== 15 && ENABLE_ARCH_7
) {
843 store_reg(s
, reg
, var
);
847 /* Variant of store_reg which uses branch&exchange logic when storing
848 * to r15 in ARM architecture v5T and above. This is used for storing
849 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
850 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
851 static inline void store_reg_from_load(CPUARMState
*env
, DisasContext
*s
,
852 int reg
, TCGv_i32 var
)
854 if (reg
== 15 && ENABLE_ARCH_5
) {
857 store_reg(s
, reg
, var
);
861 /* Abstractions of "generate code to do a guest load/store for
862 * AArch32", where a vaddr is always 32 bits (and is zero
863 * extended if we're a 64 bit core) and data is also
864 * 32 bits unless specifically doing a 64 bit access.
865 * These functions work like tcg_gen_qemu_{ld,st}* except
866 * that the address argument is TCGv_i32 rather than TCGv.
868 #if TARGET_LONG_BITS == 32
870 #define DO_GEN_LD(SUFF, OPC) \
871 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
873 tcg_gen_qemu_ld_i32(val, addr, index, OPC); \
876 #define DO_GEN_ST(SUFF, OPC) \
877 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
879 tcg_gen_qemu_st_i32(val, addr, index, OPC); \
882 static inline void gen_aa32_ld64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
884 tcg_gen_qemu_ld_i64(val
, addr
, index
, MO_TEQ
);
887 static inline void gen_aa32_st64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
889 tcg_gen_qemu_st_i64(val
, addr
, index
, MO_TEQ
);
894 #define DO_GEN_LD(SUFF, OPC) \
895 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
897 TCGv addr64 = tcg_temp_new(); \
898 tcg_gen_extu_i32_i64(addr64, addr); \
899 tcg_gen_qemu_ld_i32(val, addr64, index, OPC); \
900 tcg_temp_free(addr64); \
903 #define DO_GEN_ST(SUFF, OPC) \
904 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
906 TCGv addr64 = tcg_temp_new(); \
907 tcg_gen_extu_i32_i64(addr64, addr); \
908 tcg_gen_qemu_st_i32(val, addr64, index, OPC); \
909 tcg_temp_free(addr64); \
912 static inline void gen_aa32_ld64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
914 TCGv addr64
= tcg_temp_new();
915 tcg_gen_extu_i32_i64(addr64
, addr
);
916 tcg_gen_qemu_ld_i64(val
, addr64
, index
, MO_TEQ
);
917 tcg_temp_free(addr64
);
920 static inline void gen_aa32_st64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
922 TCGv addr64
= tcg_temp_new();
923 tcg_gen_extu_i32_i64(addr64
, addr
);
924 tcg_gen_qemu_st_i64(val
, addr64
, index
, MO_TEQ
);
925 tcg_temp_free(addr64
);
932 DO_GEN_LD(16s
, MO_TESW
)
933 DO_GEN_LD(16u, MO_TEUW
)
934 DO_GEN_LD(32u, MO_TEUL
)
936 DO_GEN_ST(16, MO_TEUW
)
937 DO_GEN_ST(32, MO_TEUL
)
939 static inline void gen_set_pc_im(DisasContext
*s
, target_ulong val
)
941 tcg_gen_movi_i32(cpu_R
[15], val
);
945 gen_set_condexec (DisasContext
*s
)
947 if (s
->condexec_mask
) {
948 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
949 TCGv_i32 tmp
= tcg_temp_new_i32();
950 tcg_gen_movi_i32(tmp
, val
);
951 store_cpu_field(tmp
, condexec_bits
);
955 static void gen_exception_internal_insn(DisasContext
*s
, int offset
, int excp
)
958 gen_set_pc_im(s
, s
->pc
- offset
);
959 gen_exception_internal(excp
);
960 s
->is_jmp
= DISAS_JUMP
;
963 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
, int syn
)
966 gen_set_pc_im(s
, s
->pc
- offset
);
967 gen_exception(excp
, syn
);
968 s
->is_jmp
= DISAS_JUMP
;
971 /* Force a TB lookup after an instruction that changes the CPU state. */
972 static inline void gen_lookup_tb(DisasContext
*s
)
974 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
975 s
->is_jmp
= DISAS_UPDATE
;
978 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
981 int val
, rm
, shift
, shiftop
;
984 if (!(insn
& (1 << 25))) {
987 if (!(insn
& (1 << 23)))
990 tcg_gen_addi_i32(var
, var
, val
);
994 shift
= (insn
>> 7) & 0x1f;
995 shiftop
= (insn
>> 5) & 3;
996 offset
= load_reg(s
, rm
);
997 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
998 if (!(insn
& (1 << 23)))
999 tcg_gen_sub_i32(var
, var
, offset
);
1001 tcg_gen_add_i32(var
, var
, offset
);
1002 tcg_temp_free_i32(offset
);
1006 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
1007 int extra
, TCGv_i32 var
)
1012 if (insn
& (1 << 22)) {
1014 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
1015 if (!(insn
& (1 << 23)))
1019 tcg_gen_addi_i32(var
, var
, val
);
1023 tcg_gen_addi_i32(var
, var
, extra
);
1025 offset
= load_reg(s
, rm
);
1026 if (!(insn
& (1 << 23)))
1027 tcg_gen_sub_i32(var
, var
, offset
);
1029 tcg_gen_add_i32(var
, var
, offset
);
1030 tcg_temp_free_i32(offset
);
1034 static TCGv_ptr
get_fpstatus_ptr(int neon
)
1036 TCGv_ptr statusptr
= tcg_temp_new_ptr();
1039 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
1041 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
1043 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
1047 #define VFP_OP2(name) \
1048 static inline void gen_vfp_##name(int dp) \
1050 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1052 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1054 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1056 tcg_temp_free_ptr(fpst); \
1066 static inline void gen_vfp_F1_mul(int dp
)
1068 /* Like gen_vfp_mul() but put result in F1 */
1069 TCGv_ptr fpst
= get_fpstatus_ptr(0);
1071 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
1073 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
1075 tcg_temp_free_ptr(fpst
);
1078 static inline void gen_vfp_F1_neg(int dp
)
1080 /* Like gen_vfp_neg() but put result in F1 */
1082 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
1084 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
1088 static inline void gen_vfp_abs(int dp
)
1091 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
1093 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
1096 static inline void gen_vfp_neg(int dp
)
1099 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
1101 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
1104 static inline void gen_vfp_sqrt(int dp
)
1107 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
1109 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
1112 static inline void gen_vfp_cmp(int dp
)
1115 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
1117 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
1120 static inline void gen_vfp_cmpe(int dp
)
1123 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
1125 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
1128 static inline void gen_vfp_F1_ld0(int dp
)
1131 tcg_gen_movi_i64(cpu_F1d
, 0);
1133 tcg_gen_movi_i32(cpu_F1s
, 0);
1136 #define VFP_GEN_ITOF(name) \
1137 static inline void gen_vfp_##name(int dp, int neon) \
1139 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1141 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1143 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1145 tcg_temp_free_ptr(statusptr); \
1152 #define VFP_GEN_FTOI(name) \
1153 static inline void gen_vfp_##name(int dp, int neon) \
1155 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1157 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1159 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1161 tcg_temp_free_ptr(statusptr); \
1170 #define VFP_GEN_FIX(name, round) \
1171 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1173 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1174 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1176 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1179 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1182 tcg_temp_free_i32(tmp_shift); \
1183 tcg_temp_free_ptr(statusptr); \
1185 VFP_GEN_FIX(tosh
, _round_to_zero
)
1186 VFP_GEN_FIX(tosl
, _round_to_zero
)
1187 VFP_GEN_FIX(touh
, _round_to_zero
)
1188 VFP_GEN_FIX(toul
, _round_to_zero
)
1195 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1198 gen_aa32_ld64(cpu_F0d
, addr
, get_mem_index(s
));
1200 gen_aa32_ld32u(cpu_F0s
, addr
, get_mem_index(s
));
1204 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1207 gen_aa32_st64(cpu_F0d
, addr
, get_mem_index(s
));
1209 gen_aa32_st32(cpu_F0s
, addr
, get_mem_index(s
));
1214 vfp_reg_offset (int dp
, int reg
)
1217 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1219 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1220 + offsetof(CPU_DoubleU
, l
.upper
);
1222 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1223 + offsetof(CPU_DoubleU
, l
.lower
);
1227 /* Return the offset of a 32-bit piece of a NEON register.
1228 zero is the least significant end of the register. */
1230 neon_reg_offset (int reg
, int n
)
1234 return vfp_reg_offset(0, sreg
);
1237 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1239 TCGv_i32 tmp
= tcg_temp_new_i32();
1240 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1244 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1246 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1247 tcg_temp_free_i32(var
);
1250 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1252 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1255 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1257 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1260 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1261 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1262 #define tcg_gen_st_f32 tcg_gen_st_i32
1263 #define tcg_gen_st_f64 tcg_gen_st_i64
1265 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1268 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1270 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1273 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1276 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1278 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1281 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1284 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1286 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1289 #define ARM_CP_RW_BIT (1 << 20)
1291 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1293 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1296 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1298 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1301 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1303 TCGv_i32 var
= tcg_temp_new_i32();
1304 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1308 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1310 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1311 tcg_temp_free_i32(var
);
1314 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1316 iwmmxt_store_reg(cpu_M0
, rn
);
1319 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1321 iwmmxt_load_reg(cpu_M0
, rn
);
1324 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1326 iwmmxt_load_reg(cpu_V1
, rn
);
1327 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1330 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1332 iwmmxt_load_reg(cpu_V1
, rn
);
1333 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1336 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1338 iwmmxt_load_reg(cpu_V1
, rn
);
1339 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1342 #define IWMMXT_OP(name) \
1343 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1345 iwmmxt_load_reg(cpu_V1, rn); \
1346 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1349 #define IWMMXT_OP_ENV(name) \
1350 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1352 iwmmxt_load_reg(cpu_V1, rn); \
1353 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1356 #define IWMMXT_OP_ENV_SIZE(name) \
1357 IWMMXT_OP_ENV(name##b) \
1358 IWMMXT_OP_ENV(name##w) \
1359 IWMMXT_OP_ENV(name##l)
1361 #define IWMMXT_OP_ENV1(name) \
1362 static inline void gen_op_iwmmxt_##name##_M0(void) \
1364 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1378 IWMMXT_OP_ENV_SIZE(unpackl
)
1379 IWMMXT_OP_ENV_SIZE(unpackh
)
1381 IWMMXT_OP_ENV1(unpacklub
)
1382 IWMMXT_OP_ENV1(unpackluw
)
1383 IWMMXT_OP_ENV1(unpacklul
)
1384 IWMMXT_OP_ENV1(unpackhub
)
1385 IWMMXT_OP_ENV1(unpackhuw
)
1386 IWMMXT_OP_ENV1(unpackhul
)
1387 IWMMXT_OP_ENV1(unpacklsb
)
1388 IWMMXT_OP_ENV1(unpacklsw
)
1389 IWMMXT_OP_ENV1(unpacklsl
)
1390 IWMMXT_OP_ENV1(unpackhsb
)
1391 IWMMXT_OP_ENV1(unpackhsw
)
1392 IWMMXT_OP_ENV1(unpackhsl
)
1394 IWMMXT_OP_ENV_SIZE(cmpeq
)
1395 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1396 IWMMXT_OP_ENV_SIZE(cmpgts
)
1398 IWMMXT_OP_ENV_SIZE(mins
)
1399 IWMMXT_OP_ENV_SIZE(minu
)
1400 IWMMXT_OP_ENV_SIZE(maxs
)
1401 IWMMXT_OP_ENV_SIZE(maxu
)
1403 IWMMXT_OP_ENV_SIZE(subn
)
1404 IWMMXT_OP_ENV_SIZE(addn
)
1405 IWMMXT_OP_ENV_SIZE(subu
)
1406 IWMMXT_OP_ENV_SIZE(addu
)
1407 IWMMXT_OP_ENV_SIZE(subs
)
1408 IWMMXT_OP_ENV_SIZE(adds
)
1410 IWMMXT_OP_ENV(avgb0
)
1411 IWMMXT_OP_ENV(avgb1
)
1412 IWMMXT_OP_ENV(avgw0
)
1413 IWMMXT_OP_ENV(avgw1
)
1415 IWMMXT_OP_ENV(packuw
)
1416 IWMMXT_OP_ENV(packul
)
1417 IWMMXT_OP_ENV(packuq
)
1418 IWMMXT_OP_ENV(packsw
)
1419 IWMMXT_OP_ENV(packsl
)
1420 IWMMXT_OP_ENV(packsq
)
1422 static void gen_op_iwmmxt_set_mup(void)
1425 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1426 tcg_gen_ori_i32(tmp
, tmp
, 2);
1427 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1430 static void gen_op_iwmmxt_set_cup(void)
1433 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1434 tcg_gen_ori_i32(tmp
, tmp
, 1);
1435 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1438 static void gen_op_iwmmxt_setpsr_nz(void)
1440 TCGv_i32 tmp
= tcg_temp_new_i32();
1441 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1442 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1445 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1447 iwmmxt_load_reg(cpu_V1
, rn
);
1448 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1449 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1452 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1459 rd
= (insn
>> 16) & 0xf;
1460 tmp
= load_reg(s
, rd
);
1462 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1463 if (insn
& (1 << 24)) {
1465 if (insn
& (1 << 23))
1466 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1468 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1469 tcg_gen_mov_i32(dest
, tmp
);
1470 if (insn
& (1 << 21))
1471 store_reg(s
, rd
, tmp
);
1473 tcg_temp_free_i32(tmp
);
1474 } else if (insn
& (1 << 21)) {
1476 tcg_gen_mov_i32(dest
, tmp
);
1477 if (insn
& (1 << 23))
1478 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1480 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1481 store_reg(s
, rd
, tmp
);
1482 } else if (!(insn
& (1 << 23)))
1487 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1489 int rd
= (insn
>> 0) & 0xf;
1492 if (insn
& (1 << 8)) {
1493 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1496 tmp
= iwmmxt_load_creg(rd
);
1499 tmp
= tcg_temp_new_i32();
1500 iwmmxt_load_reg(cpu_V0
, rd
);
1501 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
1503 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1504 tcg_gen_mov_i32(dest
, tmp
);
1505 tcg_temp_free_i32(tmp
);
1509 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1510 (ie. an undefined instruction). */
1511 static int disas_iwmmxt_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
1514 int rdhi
, rdlo
, rd0
, rd1
, i
;
1516 TCGv_i32 tmp
, tmp2
, tmp3
;
1518 if ((insn
& 0x0e000e00) == 0x0c000000) {
1519 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1521 rdlo
= (insn
>> 12) & 0xf;
1522 rdhi
= (insn
>> 16) & 0xf;
1523 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1524 iwmmxt_load_reg(cpu_V0
, wrd
);
1525 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1526 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1527 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1528 } else { /* TMCRR */
1529 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1530 iwmmxt_store_reg(cpu_V0
, wrd
);
1531 gen_op_iwmmxt_set_mup();
1536 wrd
= (insn
>> 12) & 0xf;
1537 addr
= tcg_temp_new_i32();
1538 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1539 tcg_temp_free_i32(addr
);
1542 if (insn
& ARM_CP_RW_BIT
) {
1543 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1544 tmp
= tcg_temp_new_i32();
1545 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
1546 iwmmxt_store_creg(wrd
, tmp
);
1549 if (insn
& (1 << 8)) {
1550 if (insn
& (1 << 22)) { /* WLDRD */
1551 gen_aa32_ld64(cpu_M0
, addr
, get_mem_index(s
));
1553 } else { /* WLDRW wRd */
1554 tmp
= tcg_temp_new_i32();
1555 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
1558 tmp
= tcg_temp_new_i32();
1559 if (insn
& (1 << 22)) { /* WLDRH */
1560 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
1561 } else { /* WLDRB */
1562 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
1566 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1567 tcg_temp_free_i32(tmp
);
1569 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1572 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1573 tmp
= iwmmxt_load_creg(wrd
);
1574 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
1576 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1577 tmp
= tcg_temp_new_i32();
1578 if (insn
& (1 << 8)) {
1579 if (insn
& (1 << 22)) { /* WSTRD */
1580 gen_aa32_st64(cpu_M0
, addr
, get_mem_index(s
));
1581 } else { /* WSTRW wRd */
1582 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1583 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
1586 if (insn
& (1 << 22)) { /* WSTRH */
1587 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1588 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
1589 } else { /* WSTRB */
1590 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1591 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
1595 tcg_temp_free_i32(tmp
);
1597 tcg_temp_free_i32(addr
);
1601 if ((insn
& 0x0f000000) != 0x0e000000)
1604 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1605 case 0x000: /* WOR */
1606 wrd
= (insn
>> 12) & 0xf;
1607 rd0
= (insn
>> 0) & 0xf;
1608 rd1
= (insn
>> 16) & 0xf;
1609 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1610 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1611 gen_op_iwmmxt_setpsr_nz();
1612 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1613 gen_op_iwmmxt_set_mup();
1614 gen_op_iwmmxt_set_cup();
1616 case 0x011: /* TMCR */
1619 rd
= (insn
>> 12) & 0xf;
1620 wrd
= (insn
>> 16) & 0xf;
1622 case ARM_IWMMXT_wCID
:
1623 case ARM_IWMMXT_wCASF
:
1625 case ARM_IWMMXT_wCon
:
1626 gen_op_iwmmxt_set_cup();
1628 case ARM_IWMMXT_wCSSF
:
1629 tmp
= iwmmxt_load_creg(wrd
);
1630 tmp2
= load_reg(s
, rd
);
1631 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1632 tcg_temp_free_i32(tmp2
);
1633 iwmmxt_store_creg(wrd
, tmp
);
1635 case ARM_IWMMXT_wCGR0
:
1636 case ARM_IWMMXT_wCGR1
:
1637 case ARM_IWMMXT_wCGR2
:
1638 case ARM_IWMMXT_wCGR3
:
1639 gen_op_iwmmxt_set_cup();
1640 tmp
= load_reg(s
, rd
);
1641 iwmmxt_store_creg(wrd
, tmp
);
1647 case 0x100: /* WXOR */
1648 wrd
= (insn
>> 12) & 0xf;
1649 rd0
= (insn
>> 0) & 0xf;
1650 rd1
= (insn
>> 16) & 0xf;
1651 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1652 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1653 gen_op_iwmmxt_setpsr_nz();
1654 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1655 gen_op_iwmmxt_set_mup();
1656 gen_op_iwmmxt_set_cup();
1658 case 0x111: /* TMRC */
1661 rd
= (insn
>> 12) & 0xf;
1662 wrd
= (insn
>> 16) & 0xf;
1663 tmp
= iwmmxt_load_creg(wrd
);
1664 store_reg(s
, rd
, tmp
);
1666 case 0x300: /* WANDN */
1667 wrd
= (insn
>> 12) & 0xf;
1668 rd0
= (insn
>> 0) & 0xf;
1669 rd1
= (insn
>> 16) & 0xf;
1670 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1671 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1672 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1673 gen_op_iwmmxt_setpsr_nz();
1674 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1675 gen_op_iwmmxt_set_mup();
1676 gen_op_iwmmxt_set_cup();
1678 case 0x200: /* WAND */
1679 wrd
= (insn
>> 12) & 0xf;
1680 rd0
= (insn
>> 0) & 0xf;
1681 rd1
= (insn
>> 16) & 0xf;
1682 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1683 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1684 gen_op_iwmmxt_setpsr_nz();
1685 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1686 gen_op_iwmmxt_set_mup();
1687 gen_op_iwmmxt_set_cup();
1689 case 0x810: case 0xa10: /* WMADD */
1690 wrd
= (insn
>> 12) & 0xf;
1691 rd0
= (insn
>> 0) & 0xf;
1692 rd1
= (insn
>> 16) & 0xf;
1693 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1694 if (insn
& (1 << 21))
1695 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1697 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1698 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1699 gen_op_iwmmxt_set_mup();
1701 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1702 wrd
= (insn
>> 12) & 0xf;
1703 rd0
= (insn
>> 16) & 0xf;
1704 rd1
= (insn
>> 0) & 0xf;
1705 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1706 switch ((insn
>> 22) & 3) {
1708 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1711 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1714 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1719 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1720 gen_op_iwmmxt_set_mup();
1721 gen_op_iwmmxt_set_cup();
1723 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1724 wrd
= (insn
>> 12) & 0xf;
1725 rd0
= (insn
>> 16) & 0xf;
1726 rd1
= (insn
>> 0) & 0xf;
1727 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1728 switch ((insn
>> 22) & 3) {
1730 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1733 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1736 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1741 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1742 gen_op_iwmmxt_set_mup();
1743 gen_op_iwmmxt_set_cup();
1745 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1746 wrd
= (insn
>> 12) & 0xf;
1747 rd0
= (insn
>> 16) & 0xf;
1748 rd1
= (insn
>> 0) & 0xf;
1749 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1750 if (insn
& (1 << 22))
1751 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1753 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1754 if (!(insn
& (1 << 20)))
1755 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1756 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1757 gen_op_iwmmxt_set_mup();
1759 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1760 wrd
= (insn
>> 12) & 0xf;
1761 rd0
= (insn
>> 16) & 0xf;
1762 rd1
= (insn
>> 0) & 0xf;
1763 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1764 if (insn
& (1 << 21)) {
1765 if (insn
& (1 << 20))
1766 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1768 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1770 if (insn
& (1 << 20))
1771 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1773 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1775 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1776 gen_op_iwmmxt_set_mup();
1778 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1779 wrd
= (insn
>> 12) & 0xf;
1780 rd0
= (insn
>> 16) & 0xf;
1781 rd1
= (insn
>> 0) & 0xf;
1782 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1783 if (insn
& (1 << 21))
1784 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1786 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1787 if (!(insn
& (1 << 20))) {
1788 iwmmxt_load_reg(cpu_V1
, wrd
);
1789 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1791 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1792 gen_op_iwmmxt_set_mup();
1794 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1795 wrd
= (insn
>> 12) & 0xf;
1796 rd0
= (insn
>> 16) & 0xf;
1797 rd1
= (insn
>> 0) & 0xf;
1798 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1799 switch ((insn
>> 22) & 3) {
1801 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
1804 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1807 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
1812 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1813 gen_op_iwmmxt_set_mup();
1814 gen_op_iwmmxt_set_cup();
1816 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1817 wrd
= (insn
>> 12) & 0xf;
1818 rd0
= (insn
>> 16) & 0xf;
1819 rd1
= (insn
>> 0) & 0xf;
1820 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1821 if (insn
& (1 << 22)) {
1822 if (insn
& (1 << 20))
1823 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1825 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1827 if (insn
& (1 << 20))
1828 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1830 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
1832 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1833 gen_op_iwmmxt_set_mup();
1834 gen_op_iwmmxt_set_cup();
1836 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1837 wrd
= (insn
>> 12) & 0xf;
1838 rd0
= (insn
>> 16) & 0xf;
1839 rd1
= (insn
>> 0) & 0xf;
1840 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1841 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
1842 tcg_gen_andi_i32(tmp
, tmp
, 7);
1843 iwmmxt_load_reg(cpu_V1
, rd1
);
1844 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
1845 tcg_temp_free_i32(tmp
);
1846 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1847 gen_op_iwmmxt_set_mup();
1849 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1850 if (((insn
>> 6) & 3) == 3)
1852 rd
= (insn
>> 12) & 0xf;
1853 wrd
= (insn
>> 16) & 0xf;
1854 tmp
= load_reg(s
, rd
);
1855 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1856 switch ((insn
>> 6) & 3) {
1858 tmp2
= tcg_const_i32(0xff);
1859 tmp3
= tcg_const_i32((insn
& 7) << 3);
1862 tmp2
= tcg_const_i32(0xffff);
1863 tmp3
= tcg_const_i32((insn
& 3) << 4);
1866 tmp2
= tcg_const_i32(0xffffffff);
1867 tmp3
= tcg_const_i32((insn
& 1) << 5);
1870 TCGV_UNUSED_I32(tmp2
);
1871 TCGV_UNUSED_I32(tmp3
);
1873 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
1874 tcg_temp_free_i32(tmp3
);
1875 tcg_temp_free_i32(tmp2
);
1876 tcg_temp_free_i32(tmp
);
1877 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1878 gen_op_iwmmxt_set_mup();
1880 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1881 rd
= (insn
>> 12) & 0xf;
1882 wrd
= (insn
>> 16) & 0xf;
1883 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
1885 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1886 tmp
= tcg_temp_new_i32();
1887 switch ((insn
>> 22) & 3) {
1889 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
1890 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1892 tcg_gen_ext8s_i32(tmp
, tmp
);
1894 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
1898 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
1899 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1901 tcg_gen_ext16s_i32(tmp
, tmp
);
1903 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
1907 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
1908 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1911 store_reg(s
, rd
, tmp
);
1913 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1914 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1916 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1917 switch ((insn
>> 22) & 3) {
1919 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
1922 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
1925 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
1928 tcg_gen_shli_i32(tmp
, tmp
, 28);
1930 tcg_temp_free_i32(tmp
);
1932 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1933 if (((insn
>> 6) & 3) == 3)
1935 rd
= (insn
>> 12) & 0xf;
1936 wrd
= (insn
>> 16) & 0xf;
1937 tmp
= load_reg(s
, rd
);
1938 switch ((insn
>> 6) & 3) {
1940 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
1943 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
1946 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
1949 tcg_temp_free_i32(tmp
);
1950 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1951 gen_op_iwmmxt_set_mup();
1953 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1954 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1956 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1957 tmp2
= tcg_temp_new_i32();
1958 tcg_gen_mov_i32(tmp2
, tmp
);
1959 switch ((insn
>> 22) & 3) {
1961 for (i
= 0; i
< 7; i
++) {
1962 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1963 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1967 for (i
= 0; i
< 3; i
++) {
1968 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1969 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1973 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1974 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1978 tcg_temp_free_i32(tmp2
);
1979 tcg_temp_free_i32(tmp
);
1981 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1982 wrd
= (insn
>> 12) & 0xf;
1983 rd0
= (insn
>> 16) & 0xf;
1984 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1985 switch ((insn
>> 22) & 3) {
1987 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
1990 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
1993 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
1998 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1999 gen_op_iwmmxt_set_mup();
2001 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2002 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2004 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2005 tmp2
= tcg_temp_new_i32();
2006 tcg_gen_mov_i32(tmp2
, tmp
);
2007 switch ((insn
>> 22) & 3) {
2009 for (i
= 0; i
< 7; i
++) {
2010 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2011 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2015 for (i
= 0; i
< 3; i
++) {
2016 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2017 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2021 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2022 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2026 tcg_temp_free_i32(tmp2
);
2027 tcg_temp_free_i32(tmp
);
2029 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2030 rd
= (insn
>> 12) & 0xf;
2031 rd0
= (insn
>> 16) & 0xf;
2032 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
2034 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2035 tmp
= tcg_temp_new_i32();
2036 switch ((insn
>> 22) & 3) {
2038 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
2041 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
2044 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
2047 store_reg(s
, rd
, tmp
);
2049 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2050 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2051 wrd
= (insn
>> 12) & 0xf;
2052 rd0
= (insn
>> 16) & 0xf;
2053 rd1
= (insn
>> 0) & 0xf;
2054 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2055 switch ((insn
>> 22) & 3) {
2057 if (insn
& (1 << 21))
2058 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
2060 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
2063 if (insn
& (1 << 21))
2064 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2066 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2069 if (insn
& (1 << 21))
2070 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2072 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2077 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2078 gen_op_iwmmxt_set_mup();
2079 gen_op_iwmmxt_set_cup();
2081 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2082 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2083 wrd
= (insn
>> 12) & 0xf;
2084 rd0
= (insn
>> 16) & 0xf;
2085 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2086 switch ((insn
>> 22) & 3) {
2088 if (insn
& (1 << 21))
2089 gen_op_iwmmxt_unpacklsb_M0();
2091 gen_op_iwmmxt_unpacklub_M0();
2094 if (insn
& (1 << 21))
2095 gen_op_iwmmxt_unpacklsw_M0();
2097 gen_op_iwmmxt_unpackluw_M0();
2100 if (insn
& (1 << 21))
2101 gen_op_iwmmxt_unpacklsl_M0();
2103 gen_op_iwmmxt_unpacklul_M0();
2108 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2109 gen_op_iwmmxt_set_mup();
2110 gen_op_iwmmxt_set_cup();
2112 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2113 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2114 wrd
= (insn
>> 12) & 0xf;
2115 rd0
= (insn
>> 16) & 0xf;
2116 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2117 switch ((insn
>> 22) & 3) {
2119 if (insn
& (1 << 21))
2120 gen_op_iwmmxt_unpackhsb_M0();
2122 gen_op_iwmmxt_unpackhub_M0();
2125 if (insn
& (1 << 21))
2126 gen_op_iwmmxt_unpackhsw_M0();
2128 gen_op_iwmmxt_unpackhuw_M0();
2131 if (insn
& (1 << 21))
2132 gen_op_iwmmxt_unpackhsl_M0();
2134 gen_op_iwmmxt_unpackhul_M0();
2139 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2140 gen_op_iwmmxt_set_mup();
2141 gen_op_iwmmxt_set_cup();
2143 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2144 case 0x214: case 0x614: case 0xa14: case 0xe14:
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_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2160 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2163 gen_helper_iwmmxt_srlq(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 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2172 case 0x014: case 0x414: case 0x814: case 0xc14:
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_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2188 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2191 gen_helper_iwmmxt_sraq(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 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2200 case 0x114: case 0x514: case 0x914: case 0xd14:
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 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2208 tcg_temp_free_i32(tmp
);
2211 switch ((insn
>> 22) & 3) {
2213 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2216 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2219 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2222 tcg_temp_free_i32(tmp
);
2223 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2224 gen_op_iwmmxt_set_mup();
2225 gen_op_iwmmxt_set_cup();
2227 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2228 case 0x314: case 0x714: case 0xb14: case 0xf14:
2229 if (((insn
>> 22) & 3) == 0)
2231 wrd
= (insn
>> 12) & 0xf;
2232 rd0
= (insn
>> 16) & 0xf;
2233 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2234 tmp
= tcg_temp_new_i32();
2235 switch ((insn
>> 22) & 3) {
2237 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2238 tcg_temp_free_i32(tmp
);
2241 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2244 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2245 tcg_temp_free_i32(tmp
);
2248 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2251 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2252 tcg_temp_free_i32(tmp
);
2255 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2258 tcg_temp_free_i32(tmp
);
2259 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2260 gen_op_iwmmxt_set_mup();
2261 gen_op_iwmmxt_set_cup();
2263 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2264 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2265 wrd
= (insn
>> 12) & 0xf;
2266 rd0
= (insn
>> 16) & 0xf;
2267 rd1
= (insn
>> 0) & 0xf;
2268 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2269 switch ((insn
>> 22) & 3) {
2271 if (insn
& (1 << 21))
2272 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2274 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2277 if (insn
& (1 << 21))
2278 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2280 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2283 if (insn
& (1 << 21))
2284 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2286 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2291 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2292 gen_op_iwmmxt_set_mup();
2294 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2295 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2296 wrd
= (insn
>> 12) & 0xf;
2297 rd0
= (insn
>> 16) & 0xf;
2298 rd1
= (insn
>> 0) & 0xf;
2299 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2300 switch ((insn
>> 22) & 3) {
2302 if (insn
& (1 << 21))
2303 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2305 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2308 if (insn
& (1 << 21))
2309 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2311 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2314 if (insn
& (1 << 21))
2315 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2317 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2322 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2323 gen_op_iwmmxt_set_mup();
2325 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2326 case 0x402: case 0x502: case 0x602: case 0x702:
2327 wrd
= (insn
>> 12) & 0xf;
2328 rd0
= (insn
>> 16) & 0xf;
2329 rd1
= (insn
>> 0) & 0xf;
2330 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2331 tmp
= tcg_const_i32((insn
>> 20) & 3);
2332 iwmmxt_load_reg(cpu_V1
, rd1
);
2333 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2334 tcg_temp_free_i32(tmp
);
2335 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2336 gen_op_iwmmxt_set_mup();
2338 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2339 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2340 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2341 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2342 wrd
= (insn
>> 12) & 0xf;
2343 rd0
= (insn
>> 16) & 0xf;
2344 rd1
= (insn
>> 0) & 0xf;
2345 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2346 switch ((insn
>> 20) & 0xf) {
2348 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2351 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2354 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2357 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2360 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2363 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2366 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2369 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2372 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2377 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2378 gen_op_iwmmxt_set_mup();
2379 gen_op_iwmmxt_set_cup();
2381 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2382 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2383 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2384 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2385 wrd
= (insn
>> 12) & 0xf;
2386 rd0
= (insn
>> 16) & 0xf;
2387 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2388 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2389 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2390 tcg_temp_free_i32(tmp
);
2391 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2392 gen_op_iwmmxt_set_mup();
2393 gen_op_iwmmxt_set_cup();
2395 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2396 case 0x418: case 0x518: case 0x618: case 0x718:
2397 case 0x818: case 0x918: case 0xa18: case 0xb18:
2398 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2399 wrd
= (insn
>> 12) & 0xf;
2400 rd0
= (insn
>> 16) & 0xf;
2401 rd1
= (insn
>> 0) & 0xf;
2402 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2403 switch ((insn
>> 20) & 0xf) {
2405 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2408 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2411 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2414 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2417 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2420 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2423 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2426 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2429 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2434 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2435 gen_op_iwmmxt_set_mup();
2436 gen_op_iwmmxt_set_cup();
2438 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2439 case 0x408: case 0x508: case 0x608: case 0x708:
2440 case 0x808: case 0x908: case 0xa08: case 0xb08:
2441 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2442 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2444 wrd
= (insn
>> 12) & 0xf;
2445 rd0
= (insn
>> 16) & 0xf;
2446 rd1
= (insn
>> 0) & 0xf;
2447 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2448 switch ((insn
>> 22) & 3) {
2450 if (insn
& (1 << 21))
2451 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2453 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2456 if (insn
& (1 << 21))
2457 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2459 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2462 if (insn
& (1 << 21))
2463 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2465 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2468 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2469 gen_op_iwmmxt_set_mup();
2470 gen_op_iwmmxt_set_cup();
2472 case 0x201: case 0x203: case 0x205: case 0x207:
2473 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2474 case 0x211: case 0x213: case 0x215: case 0x217:
2475 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2476 wrd
= (insn
>> 5) & 0xf;
2477 rd0
= (insn
>> 12) & 0xf;
2478 rd1
= (insn
>> 0) & 0xf;
2479 if (rd0
== 0xf || rd1
== 0xf)
2481 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2482 tmp
= load_reg(s
, rd0
);
2483 tmp2
= load_reg(s
, rd1
);
2484 switch ((insn
>> 16) & 0xf) {
2485 case 0x0: /* TMIA */
2486 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2488 case 0x8: /* TMIAPH */
2489 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2491 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2492 if (insn
& (1 << 16))
2493 tcg_gen_shri_i32(tmp
, tmp
, 16);
2494 if (insn
& (1 << 17))
2495 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2496 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2499 tcg_temp_free_i32(tmp2
);
2500 tcg_temp_free_i32(tmp
);
2503 tcg_temp_free_i32(tmp2
);
2504 tcg_temp_free_i32(tmp
);
2505 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2506 gen_op_iwmmxt_set_mup();
2515 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2516 (ie. an undefined instruction). */
2517 static int disas_dsp_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
2519 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2522 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2523 /* Multiply with Internal Accumulate Format */
2524 rd0
= (insn
>> 12) & 0xf;
2526 acc
= (insn
>> 5) & 7;
2531 tmp
= load_reg(s
, rd0
);
2532 tmp2
= load_reg(s
, rd1
);
2533 switch ((insn
>> 16) & 0xf) {
2535 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2537 case 0x8: /* MIAPH */
2538 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2540 case 0xc: /* MIABB */
2541 case 0xd: /* MIABT */
2542 case 0xe: /* MIATB */
2543 case 0xf: /* MIATT */
2544 if (insn
& (1 << 16))
2545 tcg_gen_shri_i32(tmp
, tmp
, 16);
2546 if (insn
& (1 << 17))
2547 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2548 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2553 tcg_temp_free_i32(tmp2
);
2554 tcg_temp_free_i32(tmp
);
2556 gen_op_iwmmxt_movq_wRn_M0(acc
);
2560 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2561 /* Internal Accumulator Access Format */
2562 rdhi
= (insn
>> 16) & 0xf;
2563 rdlo
= (insn
>> 12) & 0xf;
2569 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2570 iwmmxt_load_reg(cpu_V0
, acc
);
2571 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2572 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2573 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2574 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2576 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2577 iwmmxt_store_reg(cpu_V0
, acc
);
2585 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2586 #define VFP_SREG(insn, bigbit, smallbit) \
2587 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2588 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2589 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2590 reg = (((insn) >> (bigbit)) & 0x0f) \
2591 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2593 if (insn & (1 << (smallbit))) \
2595 reg = ((insn) >> (bigbit)) & 0x0f; \
2598 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2599 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2600 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2601 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2602 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2603 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2605 /* Move between integer and VFP cores. */
2606 static TCGv_i32
gen_vfp_mrs(void)
2608 TCGv_i32 tmp
= tcg_temp_new_i32();
2609 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2613 static void gen_vfp_msr(TCGv_i32 tmp
)
2615 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2616 tcg_temp_free_i32(tmp
);
2619 static void gen_neon_dup_u8(TCGv_i32 var
, int shift
)
2621 TCGv_i32 tmp
= tcg_temp_new_i32();
2623 tcg_gen_shri_i32(var
, var
, shift
);
2624 tcg_gen_ext8u_i32(var
, var
);
2625 tcg_gen_shli_i32(tmp
, var
, 8);
2626 tcg_gen_or_i32(var
, var
, tmp
);
2627 tcg_gen_shli_i32(tmp
, var
, 16);
2628 tcg_gen_or_i32(var
, var
, tmp
);
2629 tcg_temp_free_i32(tmp
);
2632 static void gen_neon_dup_low16(TCGv_i32 var
)
2634 TCGv_i32 tmp
= tcg_temp_new_i32();
2635 tcg_gen_ext16u_i32(var
, var
);
2636 tcg_gen_shli_i32(tmp
, var
, 16);
2637 tcg_gen_or_i32(var
, var
, tmp
);
2638 tcg_temp_free_i32(tmp
);
2641 static void gen_neon_dup_high16(TCGv_i32 var
)
2643 TCGv_i32 tmp
= tcg_temp_new_i32();
2644 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2645 tcg_gen_shri_i32(tmp
, var
, 16);
2646 tcg_gen_or_i32(var
, var
, tmp
);
2647 tcg_temp_free_i32(tmp
);
2650 static TCGv_i32
gen_load_and_replicate(DisasContext
*s
, TCGv_i32 addr
, int size
)
2652 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2653 TCGv_i32 tmp
= tcg_temp_new_i32();
2656 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
2657 gen_neon_dup_u8(tmp
, 0);
2660 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
2661 gen_neon_dup_low16(tmp
);
2664 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
2666 default: /* Avoid compiler warnings. */
2672 static int handle_vsel(uint32_t insn
, uint32_t rd
, uint32_t rn
, uint32_t rm
,
2675 uint32_t cc
= extract32(insn
, 20, 2);
2678 TCGv_i64 frn
, frm
, dest
;
2679 TCGv_i64 tmp
, zero
, zf
, nf
, vf
;
2681 zero
= tcg_const_i64(0);
2683 frn
= tcg_temp_new_i64();
2684 frm
= tcg_temp_new_i64();
2685 dest
= tcg_temp_new_i64();
2687 zf
= tcg_temp_new_i64();
2688 nf
= tcg_temp_new_i64();
2689 vf
= tcg_temp_new_i64();
2691 tcg_gen_extu_i32_i64(zf
, cpu_ZF
);
2692 tcg_gen_ext_i32_i64(nf
, cpu_NF
);
2693 tcg_gen_ext_i32_i64(vf
, cpu_VF
);
2695 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2696 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2699 tcg_gen_movcond_i64(TCG_COND_EQ
, dest
, zf
, zero
,
2703 tcg_gen_movcond_i64(TCG_COND_LT
, dest
, vf
, zero
,
2706 case 2: /* ge: N == V -> N ^ V == 0 */
2707 tmp
= tcg_temp_new_i64();
2708 tcg_gen_xor_i64(tmp
, vf
, nf
);
2709 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2711 tcg_temp_free_i64(tmp
);
2713 case 3: /* gt: !Z && N == V */
2714 tcg_gen_movcond_i64(TCG_COND_NE
, dest
, zf
, zero
,
2716 tmp
= tcg_temp_new_i64();
2717 tcg_gen_xor_i64(tmp
, vf
, nf
);
2718 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2720 tcg_temp_free_i64(tmp
);
2723 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2724 tcg_temp_free_i64(frn
);
2725 tcg_temp_free_i64(frm
);
2726 tcg_temp_free_i64(dest
);
2728 tcg_temp_free_i64(zf
);
2729 tcg_temp_free_i64(nf
);
2730 tcg_temp_free_i64(vf
);
2732 tcg_temp_free_i64(zero
);
2734 TCGv_i32 frn
, frm
, dest
;
2737 zero
= tcg_const_i32(0);
2739 frn
= tcg_temp_new_i32();
2740 frm
= tcg_temp_new_i32();
2741 dest
= tcg_temp_new_i32();
2742 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2743 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2746 tcg_gen_movcond_i32(TCG_COND_EQ
, dest
, cpu_ZF
, zero
,
2750 tcg_gen_movcond_i32(TCG_COND_LT
, dest
, cpu_VF
, zero
,
2753 case 2: /* ge: N == V -> N ^ V == 0 */
2754 tmp
= tcg_temp_new_i32();
2755 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2756 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2758 tcg_temp_free_i32(tmp
);
2760 case 3: /* gt: !Z && N == V */
2761 tcg_gen_movcond_i32(TCG_COND_NE
, dest
, cpu_ZF
, zero
,
2763 tmp
= tcg_temp_new_i32();
2764 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2765 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2767 tcg_temp_free_i32(tmp
);
2770 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2771 tcg_temp_free_i32(frn
);
2772 tcg_temp_free_i32(frm
);
2773 tcg_temp_free_i32(dest
);
2775 tcg_temp_free_i32(zero
);
2781 static int handle_vminmaxnm(uint32_t insn
, uint32_t rd
, uint32_t rn
,
2782 uint32_t rm
, uint32_t dp
)
2784 uint32_t vmin
= extract32(insn
, 6, 1);
2785 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2788 TCGv_i64 frn
, frm
, dest
;
2790 frn
= tcg_temp_new_i64();
2791 frm
= tcg_temp_new_i64();
2792 dest
= tcg_temp_new_i64();
2794 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2795 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2797 gen_helper_vfp_minnumd(dest
, frn
, frm
, fpst
);
2799 gen_helper_vfp_maxnumd(dest
, frn
, frm
, fpst
);
2801 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2802 tcg_temp_free_i64(frn
);
2803 tcg_temp_free_i64(frm
);
2804 tcg_temp_free_i64(dest
);
2806 TCGv_i32 frn
, frm
, dest
;
2808 frn
= tcg_temp_new_i32();
2809 frm
= tcg_temp_new_i32();
2810 dest
= tcg_temp_new_i32();
2812 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2813 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2815 gen_helper_vfp_minnums(dest
, frn
, frm
, fpst
);
2817 gen_helper_vfp_maxnums(dest
, frn
, frm
, fpst
);
2819 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2820 tcg_temp_free_i32(frn
);
2821 tcg_temp_free_i32(frm
);
2822 tcg_temp_free_i32(dest
);
2825 tcg_temp_free_ptr(fpst
);
2829 static int handle_vrint(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
2832 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2835 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
2836 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2841 tcg_op
= tcg_temp_new_i64();
2842 tcg_res
= tcg_temp_new_i64();
2843 tcg_gen_ld_f64(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
2844 gen_helper_rintd(tcg_res
, tcg_op
, fpst
);
2845 tcg_gen_st_f64(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
2846 tcg_temp_free_i64(tcg_op
);
2847 tcg_temp_free_i64(tcg_res
);
2851 tcg_op
= tcg_temp_new_i32();
2852 tcg_res
= tcg_temp_new_i32();
2853 tcg_gen_ld_f32(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
2854 gen_helper_rints(tcg_res
, tcg_op
, fpst
);
2855 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
2856 tcg_temp_free_i32(tcg_op
);
2857 tcg_temp_free_i32(tcg_res
);
2860 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2861 tcg_temp_free_i32(tcg_rmode
);
2863 tcg_temp_free_ptr(fpst
);
2867 static int handle_vcvt(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
2870 bool is_signed
= extract32(insn
, 7, 1);
2871 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2872 TCGv_i32 tcg_rmode
, tcg_shift
;
2874 tcg_shift
= tcg_const_i32(0);
2876 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
2877 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2880 TCGv_i64 tcg_double
, tcg_res
;
2882 /* Rd is encoded as a single precision register even when the source
2883 * is double precision.
2885 rd
= ((rd
<< 1) & 0x1e) | ((rd
>> 4) & 0x1);
2886 tcg_double
= tcg_temp_new_i64();
2887 tcg_res
= tcg_temp_new_i64();
2888 tcg_tmp
= tcg_temp_new_i32();
2889 tcg_gen_ld_f64(tcg_double
, cpu_env
, vfp_reg_offset(1, rm
));
2891 gen_helper_vfp_tosld(tcg_res
, tcg_double
, tcg_shift
, fpst
);
2893 gen_helper_vfp_tould(tcg_res
, tcg_double
, tcg_shift
, fpst
);
2895 tcg_gen_trunc_i64_i32(tcg_tmp
, tcg_res
);
2896 tcg_gen_st_f32(tcg_tmp
, cpu_env
, vfp_reg_offset(0, rd
));
2897 tcg_temp_free_i32(tcg_tmp
);
2898 tcg_temp_free_i64(tcg_res
);
2899 tcg_temp_free_i64(tcg_double
);
2901 TCGv_i32 tcg_single
, tcg_res
;
2902 tcg_single
= tcg_temp_new_i32();
2903 tcg_res
= tcg_temp_new_i32();
2904 tcg_gen_ld_f32(tcg_single
, cpu_env
, vfp_reg_offset(0, rm
));
2906 gen_helper_vfp_tosls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
2908 gen_helper_vfp_touls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
2910 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(0, rd
));
2911 tcg_temp_free_i32(tcg_res
);
2912 tcg_temp_free_i32(tcg_single
);
2915 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2916 tcg_temp_free_i32(tcg_rmode
);
2918 tcg_temp_free_i32(tcg_shift
);
2920 tcg_temp_free_ptr(fpst
);
2925 /* Table for converting the most common AArch32 encoding of
2926 * rounding mode to arm_fprounding order (which matches the
2927 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
2929 static const uint8_t fp_decode_rm
[] = {
2936 static int disas_vfp_v8_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
2938 uint32_t rd
, rn
, rm
, dp
= extract32(insn
, 8, 1);
2940 if (!arm_feature(env
, ARM_FEATURE_V8
)) {
2945 VFP_DREG_D(rd
, insn
);
2946 VFP_DREG_N(rn
, insn
);
2947 VFP_DREG_M(rm
, insn
);
2949 rd
= VFP_SREG_D(insn
);
2950 rn
= VFP_SREG_N(insn
);
2951 rm
= VFP_SREG_M(insn
);
2954 if ((insn
& 0x0f800e50) == 0x0e000a00) {
2955 return handle_vsel(insn
, rd
, rn
, rm
, dp
);
2956 } else if ((insn
& 0x0fb00e10) == 0x0e800a00) {
2957 return handle_vminmaxnm(insn
, rd
, rn
, rm
, dp
);
2958 } else if ((insn
& 0x0fbc0ed0) == 0x0eb80a40) {
2959 /* VRINTA, VRINTN, VRINTP, VRINTM */
2960 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
2961 return handle_vrint(insn
, rd
, rm
, dp
, rounding
);
2962 } else if ((insn
& 0x0fbc0e50) == 0x0ebc0a40) {
2963 /* VCVTA, VCVTN, VCVTP, VCVTM */
2964 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
2965 return handle_vcvt(insn
, rd
, rm
, dp
, rounding
);
2970 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
2971 (ie. an undefined instruction). */
2972 static int disas_vfp_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
2974 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
2980 if (!arm_feature(env
, ARM_FEATURE_VFP
))
2983 /* FIXME: this access check should not take precedence over UNDEF
2984 * for invalid encodings; we will generate incorrect syndrome information
2985 * for attempts to execute invalid vfp/neon encodings with FP disabled.
2987 if (!s
->cpacr_fpen
) {
2988 gen_exception_insn(s
, 4, EXCP_UDEF
,
2989 syn_fp_access_trap(1, 0xe, s
->thumb
));
2993 if (!s
->vfp_enabled
) {
2994 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2995 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
2997 rn
= (insn
>> 16) & 0xf;
2998 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
&& rn
!= ARM_VFP_MVFR2
2999 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
) {
3004 if (extract32(insn
, 28, 4) == 0xf) {
3005 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3006 * only used in v8 and above.
3008 return disas_vfp_v8_insn(env
, s
, insn
);
3011 dp
= ((insn
& 0xf00) == 0xb00);
3012 switch ((insn
>> 24) & 0xf) {
3014 if (insn
& (1 << 4)) {
3015 /* single register transfer */
3016 rd
= (insn
>> 12) & 0xf;
3021 VFP_DREG_N(rn
, insn
);
3024 if (insn
& 0x00c00060
3025 && !arm_feature(env
, ARM_FEATURE_NEON
))
3028 pass
= (insn
>> 21) & 1;
3029 if (insn
& (1 << 22)) {
3031 offset
= ((insn
>> 5) & 3) * 8;
3032 } else if (insn
& (1 << 5)) {
3034 offset
= (insn
& (1 << 6)) ? 16 : 0;
3039 if (insn
& ARM_CP_RW_BIT
) {
3041 tmp
= neon_load_reg(rn
, pass
);
3045 tcg_gen_shri_i32(tmp
, tmp
, offset
);
3046 if (insn
& (1 << 23))
3052 if (insn
& (1 << 23)) {
3054 tcg_gen_shri_i32(tmp
, tmp
, 16);
3060 tcg_gen_sari_i32(tmp
, tmp
, 16);
3069 store_reg(s
, rd
, tmp
);
3072 tmp
= load_reg(s
, rd
);
3073 if (insn
& (1 << 23)) {
3076 gen_neon_dup_u8(tmp
, 0);
3077 } else if (size
== 1) {
3078 gen_neon_dup_low16(tmp
);
3080 for (n
= 0; n
<= pass
* 2; n
++) {
3081 tmp2
= tcg_temp_new_i32();
3082 tcg_gen_mov_i32(tmp2
, tmp
);
3083 neon_store_reg(rn
, n
, tmp2
);
3085 neon_store_reg(rn
, n
, tmp
);
3090 tmp2
= neon_load_reg(rn
, pass
);
3091 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 8);
3092 tcg_temp_free_i32(tmp2
);
3095 tmp2
= neon_load_reg(rn
, pass
);
3096 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 16);
3097 tcg_temp_free_i32(tmp2
);
3102 neon_store_reg(rn
, pass
, tmp
);
3106 if ((insn
& 0x6f) != 0x00)
3108 rn
= VFP_SREG_N(insn
);
3109 if (insn
& ARM_CP_RW_BIT
) {
3111 if (insn
& (1 << 21)) {
3112 /* system register */
3117 /* VFP2 allows access to FSID from userspace.
3118 VFP3 restricts all id registers to privileged
3121 && arm_feature(env
, ARM_FEATURE_VFP3
))
3123 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3128 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3130 case ARM_VFP_FPINST
:
3131 case ARM_VFP_FPINST2
:
3132 /* Not present in VFP3. */
3134 || arm_feature(env
, ARM_FEATURE_VFP3
))
3136 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3140 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
3141 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
3143 tmp
= tcg_temp_new_i32();
3144 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
3148 if (!arm_feature(env
, ARM_FEATURE_V8
)) {
3155 || !arm_feature(env
, ARM_FEATURE_MVFR
))
3157 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3163 gen_mov_F0_vreg(0, rn
);
3164 tmp
= gen_vfp_mrs();
3167 /* Set the 4 flag bits in the CPSR. */
3169 tcg_temp_free_i32(tmp
);
3171 store_reg(s
, rd
, tmp
);
3175 if (insn
& (1 << 21)) {
3177 /* system register */
3182 /* Writes are ignored. */
3185 tmp
= load_reg(s
, rd
);
3186 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
3187 tcg_temp_free_i32(tmp
);
3193 /* TODO: VFP subarchitecture support.
3194 * For now, keep the EN bit only */
3195 tmp
= load_reg(s
, rd
);
3196 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
3197 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3200 case ARM_VFP_FPINST
:
3201 case ARM_VFP_FPINST2
:
3202 tmp
= load_reg(s
, rd
);
3203 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3209 tmp
= load_reg(s
, rd
);
3211 gen_mov_vreg_F0(0, rn
);
3216 /* data processing */
3217 /* The opcode is in bits 23, 21, 20 and 6. */
3218 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
3222 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
3224 /* rn is register number */
3225 VFP_DREG_N(rn
, insn
);
3228 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18) ||
3229 ((rn
& 0x1e) == 0x6))) {
3230 /* Integer or single/half precision destination. */
3231 rd
= VFP_SREG_D(insn
);
3233 VFP_DREG_D(rd
, insn
);
3236 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14) ||
3237 ((rn
& 0x1e) == 0x4))) {
3238 /* VCVT from int or half precision is always from S reg
3239 * regardless of dp bit. VCVT with immediate frac_bits
3240 * has same format as SREG_M.
3242 rm
= VFP_SREG_M(insn
);
3244 VFP_DREG_M(rm
, insn
);
3247 rn
= VFP_SREG_N(insn
);
3248 if (op
== 15 && rn
== 15) {
3249 /* Double precision destination. */
3250 VFP_DREG_D(rd
, insn
);
3252 rd
= VFP_SREG_D(insn
);
3254 /* NB that we implicitly rely on the encoding for the frac_bits
3255 * in VCVT of fixed to float being the same as that of an SREG_M
3257 rm
= VFP_SREG_M(insn
);
3260 veclen
= s
->vec_len
;
3261 if (op
== 15 && rn
> 3)
3264 /* Shut up compiler warnings. */
3275 /* Figure out what type of vector operation this is. */
3276 if ((rd
& bank_mask
) == 0) {
3281 delta_d
= (s
->vec_stride
>> 1) + 1;
3283 delta_d
= s
->vec_stride
+ 1;
3285 if ((rm
& bank_mask
) == 0) {
3286 /* mixed scalar/vector */
3295 /* Load the initial operands. */
3300 /* Integer source */
3301 gen_mov_F0_vreg(0, rm
);
3306 gen_mov_F0_vreg(dp
, rd
);
3307 gen_mov_F1_vreg(dp
, rm
);
3311 /* Compare with zero */
3312 gen_mov_F0_vreg(dp
, rd
);
3323 /* Source and destination the same. */
3324 gen_mov_F0_vreg(dp
, rd
);
3330 /* VCVTB, VCVTT: only present with the halfprec extension
3331 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3332 * (we choose to UNDEF)
3334 if ((dp
&& !arm_feature(env
, ARM_FEATURE_V8
)) ||
3335 !arm_feature(env
, ARM_FEATURE_VFP_FP16
)) {
3338 if (!extract32(rn
, 1, 1)) {
3339 /* Half precision source. */
3340 gen_mov_F0_vreg(0, rm
);
3343 /* Otherwise fall through */
3345 /* One source operand. */
3346 gen_mov_F0_vreg(dp
, rm
);
3350 /* Two source operands. */
3351 gen_mov_F0_vreg(dp
, rn
);
3352 gen_mov_F1_vreg(dp
, rm
);
3356 /* Perform the calculation. */
3358 case 0: /* VMLA: fd + (fn * fm) */
3359 /* Note that order of inputs to the add matters for NaNs */
3361 gen_mov_F0_vreg(dp
, rd
);
3364 case 1: /* VMLS: fd + -(fn * fm) */
3367 gen_mov_F0_vreg(dp
, rd
);
3370 case 2: /* VNMLS: -fd + (fn * fm) */
3371 /* Note that it isn't valid to replace (-A + B) with (B - A)
3372 * or similar plausible looking simplifications
3373 * because this will give wrong results for NaNs.
3376 gen_mov_F0_vreg(dp
, rd
);
3380 case 3: /* VNMLA: -fd + -(fn * fm) */
3383 gen_mov_F0_vreg(dp
, rd
);
3387 case 4: /* mul: fn * fm */
3390 case 5: /* nmul: -(fn * fm) */
3394 case 6: /* add: fn + fm */
3397 case 7: /* sub: fn - fm */
3400 case 8: /* div: fn / fm */
3403 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3404 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3405 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3406 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3407 /* These are fused multiply-add, and must be done as one
3408 * floating point operation with no rounding between the
3409 * multiplication and addition steps.
3410 * NB that doing the negations here as separate steps is
3411 * correct : an input NaN should come out with its sign bit
3412 * flipped if it is a negated-input.
3414 if (!arm_feature(env
, ARM_FEATURE_VFP4
)) {
3422 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3424 frd
= tcg_temp_new_i64();
3425 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3428 gen_helper_vfp_negd(frd
, frd
);
3430 fpst
= get_fpstatus_ptr(0);
3431 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3432 cpu_F1d
, frd
, fpst
);
3433 tcg_temp_free_ptr(fpst
);
3434 tcg_temp_free_i64(frd
);
3440 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3442 frd
= tcg_temp_new_i32();
3443 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3445 gen_helper_vfp_negs(frd
, frd
);
3447 fpst
= get_fpstatus_ptr(0);
3448 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3449 cpu_F1s
, frd
, fpst
);
3450 tcg_temp_free_ptr(fpst
);
3451 tcg_temp_free_i32(frd
);
3454 case 14: /* fconst */
3455 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3458 n
= (insn
<< 12) & 0x80000000;
3459 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3466 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3473 tcg_gen_movi_i32(cpu_F0s
, n
);
3476 case 15: /* extension space */
3490 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3491 tmp
= gen_vfp_mrs();
3492 tcg_gen_ext16u_i32(tmp
, tmp
);
3494 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3497 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3500 tcg_temp_free_i32(tmp
);
3502 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3503 tmp
= gen_vfp_mrs();
3504 tcg_gen_shri_i32(tmp
, tmp
, 16);
3506 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3509 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3512 tcg_temp_free_i32(tmp
);
3514 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3515 tmp
= tcg_temp_new_i32();
3517 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3520 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3523 gen_mov_F0_vreg(0, rd
);
3524 tmp2
= gen_vfp_mrs();
3525 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3526 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3527 tcg_temp_free_i32(tmp2
);
3530 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3531 tmp
= tcg_temp_new_i32();
3533 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3536 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3539 tcg_gen_shli_i32(tmp
, tmp
, 16);
3540 gen_mov_F0_vreg(0, rd
);
3541 tmp2
= gen_vfp_mrs();
3542 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3543 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3544 tcg_temp_free_i32(tmp2
);
3556 case 11: /* cmpez */
3560 case 12: /* vrintr */
3562 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3564 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3566 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3568 tcg_temp_free_ptr(fpst
);
3571 case 13: /* vrintz */
3573 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3575 tcg_rmode
= tcg_const_i32(float_round_to_zero
);
3576 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3578 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3580 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3582 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3583 tcg_temp_free_i32(tcg_rmode
);
3584 tcg_temp_free_ptr(fpst
);
3587 case 14: /* vrintx */
3589 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3591 gen_helper_rintd_exact(cpu_F0d
, cpu_F0d
, fpst
);
3593 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpst
);
3595 tcg_temp_free_ptr(fpst
);
3598 case 15: /* single<->double conversion */
3600 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3602 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3604 case 16: /* fuito */
3605 gen_vfp_uito(dp
, 0);
3607 case 17: /* fsito */
3608 gen_vfp_sito(dp
, 0);
3610 case 20: /* fshto */
3611 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3613 gen_vfp_shto(dp
, 16 - rm
, 0);
3615 case 21: /* fslto */
3616 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3618 gen_vfp_slto(dp
, 32 - rm
, 0);
3620 case 22: /* fuhto */
3621 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3623 gen_vfp_uhto(dp
, 16 - rm
, 0);
3625 case 23: /* fulto */
3626 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3628 gen_vfp_ulto(dp
, 32 - rm
, 0);
3630 case 24: /* ftoui */
3631 gen_vfp_toui(dp
, 0);
3633 case 25: /* ftouiz */
3634 gen_vfp_touiz(dp
, 0);
3636 case 26: /* ftosi */
3637 gen_vfp_tosi(dp
, 0);
3639 case 27: /* ftosiz */
3640 gen_vfp_tosiz(dp
, 0);
3642 case 28: /* ftosh */
3643 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3645 gen_vfp_tosh(dp
, 16 - rm
, 0);
3647 case 29: /* ftosl */
3648 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3650 gen_vfp_tosl(dp
, 32 - rm
, 0);
3652 case 30: /* ftouh */
3653 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3655 gen_vfp_touh(dp
, 16 - rm
, 0);
3657 case 31: /* ftoul */
3658 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3660 gen_vfp_toul(dp
, 32 - rm
, 0);
3662 default: /* undefined */
3666 default: /* undefined */
3670 /* Write back the result. */
3671 if (op
== 15 && (rn
>= 8 && rn
<= 11)) {
3672 /* Comparison, do nothing. */
3673 } else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18 ||
3674 (rn
& 0x1e) == 0x6)) {
3675 /* VCVT double to int: always integer result.
3676 * VCVT double to half precision is always a single
3679 gen_mov_vreg_F0(0, rd
);
3680 } else if (op
== 15 && rn
== 15) {
3682 gen_mov_vreg_F0(!dp
, rd
);
3684 gen_mov_vreg_F0(dp
, rd
);
3687 /* break out of the loop if we have finished */
3691 if (op
== 15 && delta_m
== 0) {
3692 /* single source one-many */
3694 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3696 gen_mov_vreg_F0(dp
, rd
);
3700 /* Setup the next operands. */
3702 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3706 /* One source operand. */
3707 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3709 gen_mov_F0_vreg(dp
, rm
);
3711 /* Two source operands. */
3712 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3714 gen_mov_F0_vreg(dp
, rn
);
3716 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3718 gen_mov_F1_vreg(dp
, rm
);
3726 if ((insn
& 0x03e00000) == 0x00400000) {
3727 /* two-register transfer */
3728 rn
= (insn
>> 16) & 0xf;
3729 rd
= (insn
>> 12) & 0xf;
3731 VFP_DREG_M(rm
, insn
);
3733 rm
= VFP_SREG_M(insn
);
3736 if (insn
& ARM_CP_RW_BIT
) {
3739 gen_mov_F0_vreg(0, rm
* 2);
3740 tmp
= gen_vfp_mrs();
3741 store_reg(s
, rd
, tmp
);
3742 gen_mov_F0_vreg(0, rm
* 2 + 1);
3743 tmp
= gen_vfp_mrs();
3744 store_reg(s
, rn
, tmp
);
3746 gen_mov_F0_vreg(0, rm
);
3747 tmp
= gen_vfp_mrs();
3748 store_reg(s
, rd
, tmp
);
3749 gen_mov_F0_vreg(0, rm
+ 1);
3750 tmp
= gen_vfp_mrs();
3751 store_reg(s
, rn
, tmp
);
3756 tmp
= load_reg(s
, rd
);
3758 gen_mov_vreg_F0(0, rm
* 2);
3759 tmp
= load_reg(s
, rn
);
3761 gen_mov_vreg_F0(0, rm
* 2 + 1);
3763 tmp
= load_reg(s
, rd
);
3765 gen_mov_vreg_F0(0, rm
);
3766 tmp
= load_reg(s
, rn
);
3768 gen_mov_vreg_F0(0, rm
+ 1);
3773 rn
= (insn
>> 16) & 0xf;
3775 VFP_DREG_D(rd
, insn
);
3777 rd
= VFP_SREG_D(insn
);
3778 if ((insn
& 0x01200000) == 0x01000000) {
3779 /* Single load/store */
3780 offset
= (insn
& 0xff) << 2;
3781 if ((insn
& (1 << 23)) == 0)
3783 if (s
->thumb
&& rn
== 15) {
3784 /* This is actually UNPREDICTABLE */
3785 addr
= tcg_temp_new_i32();
3786 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3788 addr
= load_reg(s
, rn
);
3790 tcg_gen_addi_i32(addr
, addr
, offset
);
3791 if (insn
& (1 << 20)) {
3792 gen_vfp_ld(s
, dp
, addr
);
3793 gen_mov_vreg_F0(dp
, rd
);
3795 gen_mov_F0_vreg(dp
, rd
);
3796 gen_vfp_st(s
, dp
, addr
);
3798 tcg_temp_free_i32(addr
);
3800 /* load/store multiple */
3801 int w
= insn
& (1 << 21);
3803 n
= (insn
>> 1) & 0x7f;
3807 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
3808 /* P == U , W == 1 => UNDEF */
3811 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
3812 /* UNPREDICTABLE cases for bad immediates: we choose to
3813 * UNDEF to avoid generating huge numbers of TCG ops
3817 if (rn
== 15 && w
) {
3818 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3822 if (s
->thumb
&& rn
== 15) {
3823 /* This is actually UNPREDICTABLE */
3824 addr
= tcg_temp_new_i32();
3825 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3827 addr
= load_reg(s
, rn
);
3829 if (insn
& (1 << 24)) /* pre-decrement */
3830 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
3836 for (i
= 0; i
< n
; i
++) {
3837 if (insn
& ARM_CP_RW_BIT
) {
3839 gen_vfp_ld(s
, dp
, addr
);
3840 gen_mov_vreg_F0(dp
, rd
+ i
);
3843 gen_mov_F0_vreg(dp
, rd
+ i
);
3844 gen_vfp_st(s
, dp
, addr
);
3846 tcg_gen_addi_i32(addr
, addr
, offset
);
3850 if (insn
& (1 << 24))
3851 offset
= -offset
* n
;
3852 else if (dp
&& (insn
& 1))
3858 tcg_gen_addi_i32(addr
, addr
, offset
);
3859 store_reg(s
, rn
, addr
);
3861 tcg_temp_free_i32(addr
);
3867 /* Should never happen. */
3873 static inline void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
3875 TranslationBlock
*tb
;
3878 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
3880 gen_set_pc_im(s
, dest
);
3881 tcg_gen_exit_tb((uintptr_t)tb
+ n
);
3883 gen_set_pc_im(s
, dest
);
3888 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
3890 if (unlikely(s
->singlestep_enabled
|| s
->ss_active
)) {
3891 /* An indirect jump so that we still trigger the debug exception. */
3896 gen_goto_tb(s
, 0, dest
);
3897 s
->is_jmp
= DISAS_TB_JUMP
;
3901 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
3904 tcg_gen_sari_i32(t0
, t0
, 16);
3908 tcg_gen_sari_i32(t1
, t1
, 16);
3911 tcg_gen_mul_i32(t0
, t0
, t1
);
3914 /* Return the mask of PSR bits set by a MSR instruction. */
3915 static uint32_t msr_mask(CPUARMState
*env
, DisasContext
*s
, int flags
, int spsr
) {
3919 if (flags
& (1 << 0))
3921 if (flags
& (1 << 1))
3923 if (flags
& (1 << 2))
3925 if (flags
& (1 << 3))
3928 /* Mask out undefined bits. */
3929 mask
&= ~CPSR_RESERVED
;
3930 if (!arm_feature(env
, ARM_FEATURE_V4T
))
3932 if (!arm_feature(env
, ARM_FEATURE_V5
))
3933 mask
&= ~CPSR_Q
; /* V5TE in reality*/
3934 if (!arm_feature(env
, ARM_FEATURE_V6
))
3935 mask
&= ~(CPSR_E
| CPSR_GE
);
3936 if (!arm_feature(env
, ARM_FEATURE_THUMB2
))
3938 /* Mask out execution state and reserved bits. */
3940 mask
&= ~(CPSR_EXEC
| CPSR_RESERVED
);
3942 /* Mask out privileged bits. */
3948 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3949 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
3953 /* ??? This is also undefined in system mode. */
3957 tmp
= load_cpu_field(spsr
);
3958 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
3959 tcg_gen_andi_i32(t0
, t0
, mask
);
3960 tcg_gen_or_i32(tmp
, tmp
, t0
);
3961 store_cpu_field(tmp
, spsr
);
3963 gen_set_cpsr(t0
, mask
);
3965 tcg_temp_free_i32(t0
);
3970 /* Returns nonzero if access to the PSR is not permitted. */
3971 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
3974 tmp
= tcg_temp_new_i32();
3975 tcg_gen_movi_i32(tmp
, val
);
3976 return gen_set_psr(s
, mask
, spsr
, tmp
);
3979 /* Generate an old-style exception return. Marks pc as dead. */
3980 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
3983 store_reg(s
, 15, pc
);
3984 tmp
= load_cpu_field(spsr
);
3985 gen_set_cpsr(tmp
, CPSR_ERET_MASK
);
3986 tcg_temp_free_i32(tmp
);
3987 s
->is_jmp
= DISAS_UPDATE
;
3990 /* Generate a v6 exception return. Marks both values as dead. */
3991 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
3993 gen_set_cpsr(cpsr
, CPSR_ERET_MASK
);
3994 tcg_temp_free_i32(cpsr
);
3995 store_reg(s
, 15, pc
);
3996 s
->is_jmp
= DISAS_UPDATE
;
3999 static void gen_nop_hint(DisasContext
*s
, int val
)
4003 gen_set_pc_im(s
, s
->pc
);
4004 s
->is_jmp
= DISAS_WFI
;
4007 gen_set_pc_im(s
, s
->pc
);
4008 s
->is_jmp
= DISAS_WFE
;
4012 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4018 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4020 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4023 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
4024 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
4025 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
4030 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4033 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
4034 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
4035 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
4040 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4041 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4042 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4043 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4044 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4046 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4047 switch ((size << 1) | u) { \
4049 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4052 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4055 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4058 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4061 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4064 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4066 default: return 1; \
4069 #define GEN_NEON_INTEGER_OP(name) do { \
4070 switch ((size << 1) | u) { \
4072 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4075 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4078 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4081 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4084 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4087 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4089 default: return 1; \
4092 static TCGv_i32
neon_load_scratch(int scratch
)
4094 TCGv_i32 tmp
= tcg_temp_new_i32();
4095 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4099 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
4101 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4102 tcg_temp_free_i32(var
);
4105 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
4109 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
4111 gen_neon_dup_high16(tmp
);
4113 gen_neon_dup_low16(tmp
);
4116 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
4121 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
4124 if (!q
&& size
== 2) {
4127 tmp
= tcg_const_i32(rd
);
4128 tmp2
= tcg_const_i32(rm
);
4132 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
4135 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
4138 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
4146 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
4149 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
4155 tcg_temp_free_i32(tmp
);
4156 tcg_temp_free_i32(tmp2
);
4160 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
4163 if (!q
&& size
== 2) {
4166 tmp
= tcg_const_i32(rd
);
4167 tmp2
= tcg_const_i32(rm
);
4171 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
4174 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
4177 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
4185 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
4188 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
4194 tcg_temp_free_i32(tmp
);
4195 tcg_temp_free_i32(tmp2
);
4199 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
4203 rd
= tcg_temp_new_i32();
4204 tmp
= tcg_temp_new_i32();
4206 tcg_gen_shli_i32(rd
, t0
, 8);
4207 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
4208 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
4209 tcg_gen_or_i32(rd
, rd
, tmp
);
4211 tcg_gen_shri_i32(t1
, t1
, 8);
4212 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
4213 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
4214 tcg_gen_or_i32(t1
, t1
, tmp
);
4215 tcg_gen_mov_i32(t0
, rd
);
4217 tcg_temp_free_i32(tmp
);
4218 tcg_temp_free_i32(rd
);
4221 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
4225 rd
= tcg_temp_new_i32();
4226 tmp
= tcg_temp_new_i32();
4228 tcg_gen_shli_i32(rd
, t0
, 16);
4229 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
4230 tcg_gen_or_i32(rd
, rd
, tmp
);
4231 tcg_gen_shri_i32(t1
, t1
, 16);
4232 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
4233 tcg_gen_or_i32(t1
, t1
, tmp
);
4234 tcg_gen_mov_i32(t0
, rd
);
4236 tcg_temp_free_i32(tmp
);
4237 tcg_temp_free_i32(rd
);
4245 } neon_ls_element_type
[11] = {
4259 /* Translate a NEON load/store element instruction. Return nonzero if the
4260 instruction is invalid. */
4261 static int disas_neon_ls_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
4280 /* FIXME: this access check should not take precedence over UNDEF
4281 * for invalid encodings; we will generate incorrect syndrome information
4282 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4284 if (!s
->cpacr_fpen
) {
4285 gen_exception_insn(s
, 4, EXCP_UDEF
,
4286 syn_fp_access_trap(1, 0xe, s
->thumb
));
4290 if (!s
->vfp_enabled
)
4292 VFP_DREG_D(rd
, insn
);
4293 rn
= (insn
>> 16) & 0xf;
4295 load
= (insn
& (1 << 21)) != 0;
4296 if ((insn
& (1 << 23)) == 0) {
4297 /* Load store all elements. */
4298 op
= (insn
>> 8) & 0xf;
4299 size
= (insn
>> 6) & 3;
4302 /* Catch UNDEF cases for bad values of align field */
4305 if (((insn
>> 5) & 1) == 1) {
4310 if (((insn
>> 4) & 3) == 3) {
4317 nregs
= neon_ls_element_type
[op
].nregs
;
4318 interleave
= neon_ls_element_type
[op
].interleave
;
4319 spacing
= neon_ls_element_type
[op
].spacing
;
4320 if (size
== 3 && (interleave
| spacing
) != 1)
4322 addr
= tcg_temp_new_i32();
4323 load_reg_var(s
, addr
, rn
);
4324 stride
= (1 << size
) * interleave
;
4325 for (reg
= 0; reg
< nregs
; reg
++) {
4326 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
4327 load_reg_var(s
, addr
, rn
);
4328 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
4329 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
4330 load_reg_var(s
, addr
, rn
);
4331 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4334 tmp64
= tcg_temp_new_i64();
4336 gen_aa32_ld64(tmp64
, addr
, get_mem_index(s
));
4337 neon_store_reg64(tmp64
, rd
);
4339 neon_load_reg64(tmp64
, rd
);
4340 gen_aa32_st64(tmp64
, addr
, get_mem_index(s
));
4342 tcg_temp_free_i64(tmp64
);
4343 tcg_gen_addi_i32(addr
, addr
, stride
);
4345 for (pass
= 0; pass
< 2; pass
++) {
4348 tmp
= tcg_temp_new_i32();
4349 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
4350 neon_store_reg(rd
, pass
, tmp
);
4352 tmp
= neon_load_reg(rd
, pass
);
4353 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
4354 tcg_temp_free_i32(tmp
);
4356 tcg_gen_addi_i32(addr
, addr
, stride
);
4357 } else if (size
== 1) {
4359 tmp
= tcg_temp_new_i32();
4360 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
4361 tcg_gen_addi_i32(addr
, addr
, stride
);
4362 tmp2
= tcg_temp_new_i32();
4363 gen_aa32_ld16u(tmp2
, addr
, get_mem_index(s
));
4364 tcg_gen_addi_i32(addr
, addr
, stride
);
4365 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
4366 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4367 tcg_temp_free_i32(tmp2
);
4368 neon_store_reg(rd
, pass
, tmp
);
4370 tmp
= neon_load_reg(rd
, pass
);
4371 tmp2
= tcg_temp_new_i32();
4372 tcg_gen_shri_i32(tmp2
, tmp
, 16);
4373 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
4374 tcg_temp_free_i32(tmp
);
4375 tcg_gen_addi_i32(addr
, addr
, stride
);
4376 gen_aa32_st16(tmp2
, addr
, get_mem_index(s
));
4377 tcg_temp_free_i32(tmp2
);
4378 tcg_gen_addi_i32(addr
, addr
, stride
);
4380 } else /* size == 0 */ {
4382 TCGV_UNUSED_I32(tmp2
);
4383 for (n
= 0; n
< 4; n
++) {
4384 tmp
= tcg_temp_new_i32();
4385 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
4386 tcg_gen_addi_i32(addr
, addr
, stride
);
4390 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
4391 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
4392 tcg_temp_free_i32(tmp
);
4395 neon_store_reg(rd
, pass
, tmp2
);
4397 tmp2
= neon_load_reg(rd
, pass
);
4398 for (n
= 0; n
< 4; n
++) {
4399 tmp
= tcg_temp_new_i32();
4401 tcg_gen_mov_i32(tmp
, tmp2
);
4403 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
4405 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
4406 tcg_temp_free_i32(tmp
);
4407 tcg_gen_addi_i32(addr
, addr
, stride
);
4409 tcg_temp_free_i32(tmp2
);
4416 tcg_temp_free_i32(addr
);
4419 size
= (insn
>> 10) & 3;
4421 /* Load single element to all lanes. */
4422 int a
= (insn
>> 4) & 1;
4426 size
= (insn
>> 6) & 3;
4427 nregs
= ((insn
>> 8) & 3) + 1;
4430 if (nregs
!= 4 || a
== 0) {
4433 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4436 if (nregs
== 1 && a
== 1 && size
== 0) {
4439 if (nregs
== 3 && a
== 1) {
4442 addr
= tcg_temp_new_i32();
4443 load_reg_var(s
, addr
, rn
);
4445 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4446 tmp
= gen_load_and_replicate(s
, addr
, size
);
4447 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4448 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4449 if (insn
& (1 << 5)) {
4450 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
4451 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
4453 tcg_temp_free_i32(tmp
);
4455 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4456 stride
= (insn
& (1 << 5)) ? 2 : 1;
4457 for (reg
= 0; reg
< nregs
; reg
++) {
4458 tmp
= gen_load_and_replicate(s
, addr
, size
);
4459 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4460 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4461 tcg_temp_free_i32(tmp
);
4462 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4466 tcg_temp_free_i32(addr
);
4467 stride
= (1 << size
) * nregs
;
4469 /* Single element. */
4470 int idx
= (insn
>> 4) & 0xf;
4471 pass
= (insn
>> 7) & 1;
4474 shift
= ((insn
>> 5) & 3) * 8;
4478 shift
= ((insn
>> 6) & 1) * 16;
4479 stride
= (insn
& (1 << 5)) ? 2 : 1;
4483 stride
= (insn
& (1 << 6)) ? 2 : 1;
4488 nregs
= ((insn
>> 8) & 3) + 1;
4489 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4492 if (((idx
& (1 << size
)) != 0) ||
4493 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
4498 if ((idx
& 1) != 0) {
4503 if (size
== 2 && (idx
& 2) != 0) {
4508 if ((size
== 2) && ((idx
& 3) == 3)) {
4515 if ((rd
+ stride
* (nregs
- 1)) > 31) {
4516 /* Attempts to write off the end of the register file
4517 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4518 * the neon_load_reg() would write off the end of the array.
4522 addr
= tcg_temp_new_i32();
4523 load_reg_var(s
, addr
, rn
);
4524 for (reg
= 0; reg
< nregs
; reg
++) {
4526 tmp
= tcg_temp_new_i32();
4529 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
4532 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
4535 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
4537 default: /* Avoid compiler warnings. */
4541 tmp2
= neon_load_reg(rd
, pass
);
4542 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
4543 shift
, size
? 16 : 8);
4544 tcg_temp_free_i32(tmp2
);
4546 neon_store_reg(rd
, pass
, tmp
);
4547 } else { /* Store */
4548 tmp
= neon_load_reg(rd
, pass
);
4550 tcg_gen_shri_i32(tmp
, tmp
, shift
);
4553 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
4556 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
4559 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
4562 tcg_temp_free_i32(tmp
);
4565 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4567 tcg_temp_free_i32(addr
);
4568 stride
= nregs
* (1 << size
);
4574 base
= load_reg(s
, rn
);
4576 tcg_gen_addi_i32(base
, base
, stride
);
4579 index
= load_reg(s
, rm
);
4580 tcg_gen_add_i32(base
, base
, index
);
4581 tcg_temp_free_i32(index
);
4583 store_reg(s
, rn
, base
);
4588 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4589 static void gen_neon_bsl(TCGv_i32 dest
, TCGv_i32 t
, TCGv_i32 f
, TCGv_i32 c
)
4591 tcg_gen_and_i32(t
, t
, c
);
4592 tcg_gen_andc_i32(f
, f
, c
);
4593 tcg_gen_or_i32(dest
, t
, f
);
4596 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4599 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4600 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4601 case 2: tcg_gen_trunc_i64_i32(dest
, src
); break;
4606 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4609 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4610 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4611 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
4616 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4619 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
4620 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
4621 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
4626 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4629 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
4630 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
4631 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
4636 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
4642 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
4643 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
4648 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
4649 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
4656 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
4657 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
4662 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
4663 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
4670 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
4674 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
4675 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
4676 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
4681 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
4682 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
4683 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
4687 tcg_temp_free_i32(src
);
4690 static inline void gen_neon_addl(int size
)
4693 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
4694 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
4695 case 2: tcg_gen_add_i64(CPU_V001
); break;
4700 static inline void gen_neon_subl(int size
)
4703 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
4704 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
4705 case 2: tcg_gen_sub_i64(CPU_V001
); break;
4710 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
4713 case 0: gen_helper_neon_negl_u16(var
, var
); break;
4714 case 1: gen_helper_neon_negl_u32(var
, var
); break;
4716 tcg_gen_neg_i64(var
, var
);
4722 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
4725 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
4726 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
4731 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
4736 switch ((size
<< 1) | u
) {
4737 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
4738 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
4739 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
4740 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
4742 tmp
= gen_muls_i64_i32(a
, b
);
4743 tcg_gen_mov_i64(dest
, tmp
);
4744 tcg_temp_free_i64(tmp
);
4747 tmp
= gen_mulu_i64_i32(a
, b
);
4748 tcg_gen_mov_i64(dest
, tmp
);
4749 tcg_temp_free_i64(tmp
);
4754 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4755 Don't forget to clean them now. */
4757 tcg_temp_free_i32(a
);
4758 tcg_temp_free_i32(b
);
4762 static void gen_neon_narrow_op(int op
, int u
, int size
,
4763 TCGv_i32 dest
, TCGv_i64 src
)
4767 gen_neon_unarrow_sats(size
, dest
, src
);
4769 gen_neon_narrow(size
, dest
, src
);
4773 gen_neon_narrow_satu(size
, dest
, src
);
4775 gen_neon_narrow_sats(size
, dest
, src
);
4780 /* Symbolic constants for op fields for Neon 3-register same-length.
4781 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4784 #define NEON_3R_VHADD 0
4785 #define NEON_3R_VQADD 1
4786 #define NEON_3R_VRHADD 2
4787 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4788 #define NEON_3R_VHSUB 4
4789 #define NEON_3R_VQSUB 5
4790 #define NEON_3R_VCGT 6
4791 #define NEON_3R_VCGE 7
4792 #define NEON_3R_VSHL 8
4793 #define NEON_3R_VQSHL 9
4794 #define NEON_3R_VRSHL 10
4795 #define NEON_3R_VQRSHL 11
4796 #define NEON_3R_VMAX 12
4797 #define NEON_3R_VMIN 13
4798 #define NEON_3R_VABD 14
4799 #define NEON_3R_VABA 15
4800 #define NEON_3R_VADD_VSUB 16
4801 #define NEON_3R_VTST_VCEQ 17
4802 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4803 #define NEON_3R_VMUL 19
4804 #define NEON_3R_VPMAX 20
4805 #define NEON_3R_VPMIN 21
4806 #define NEON_3R_VQDMULH_VQRDMULH 22
4807 #define NEON_3R_VPADD 23
4808 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
4809 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4810 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4811 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4812 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4813 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4814 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4815 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4817 static const uint8_t neon_3r_sizes
[] = {
4818 [NEON_3R_VHADD
] = 0x7,
4819 [NEON_3R_VQADD
] = 0xf,
4820 [NEON_3R_VRHADD
] = 0x7,
4821 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
4822 [NEON_3R_VHSUB
] = 0x7,
4823 [NEON_3R_VQSUB
] = 0xf,
4824 [NEON_3R_VCGT
] = 0x7,
4825 [NEON_3R_VCGE
] = 0x7,
4826 [NEON_3R_VSHL
] = 0xf,
4827 [NEON_3R_VQSHL
] = 0xf,
4828 [NEON_3R_VRSHL
] = 0xf,
4829 [NEON_3R_VQRSHL
] = 0xf,
4830 [NEON_3R_VMAX
] = 0x7,
4831 [NEON_3R_VMIN
] = 0x7,
4832 [NEON_3R_VABD
] = 0x7,
4833 [NEON_3R_VABA
] = 0x7,
4834 [NEON_3R_VADD_VSUB
] = 0xf,
4835 [NEON_3R_VTST_VCEQ
] = 0x7,
4836 [NEON_3R_VML
] = 0x7,
4837 [NEON_3R_VMUL
] = 0x7,
4838 [NEON_3R_VPMAX
] = 0x7,
4839 [NEON_3R_VPMIN
] = 0x7,
4840 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
4841 [NEON_3R_VPADD
] = 0x7,
4842 [NEON_3R_SHA
] = 0xf, /* size field encodes op type */
4843 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
4844 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
4845 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
4846 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
4847 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
4848 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
4849 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
4852 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4853 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4856 #define NEON_2RM_VREV64 0
4857 #define NEON_2RM_VREV32 1
4858 #define NEON_2RM_VREV16 2
4859 #define NEON_2RM_VPADDL 4
4860 #define NEON_2RM_VPADDL_U 5
4861 #define NEON_2RM_AESE 6 /* Includes AESD */
4862 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4863 #define NEON_2RM_VCLS 8
4864 #define NEON_2RM_VCLZ 9
4865 #define NEON_2RM_VCNT 10
4866 #define NEON_2RM_VMVN 11
4867 #define NEON_2RM_VPADAL 12
4868 #define NEON_2RM_VPADAL_U 13
4869 #define NEON_2RM_VQABS 14
4870 #define NEON_2RM_VQNEG 15
4871 #define NEON_2RM_VCGT0 16
4872 #define NEON_2RM_VCGE0 17
4873 #define NEON_2RM_VCEQ0 18
4874 #define NEON_2RM_VCLE0 19
4875 #define NEON_2RM_VCLT0 20
4876 #define NEON_2RM_SHA1H 21
4877 #define NEON_2RM_VABS 22
4878 #define NEON_2RM_VNEG 23
4879 #define NEON_2RM_VCGT0_F 24
4880 #define NEON_2RM_VCGE0_F 25
4881 #define NEON_2RM_VCEQ0_F 26
4882 #define NEON_2RM_VCLE0_F 27
4883 #define NEON_2RM_VCLT0_F 28
4884 #define NEON_2RM_VABS_F 30
4885 #define NEON_2RM_VNEG_F 31
4886 #define NEON_2RM_VSWP 32
4887 #define NEON_2RM_VTRN 33
4888 #define NEON_2RM_VUZP 34
4889 #define NEON_2RM_VZIP 35
4890 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4891 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4892 #define NEON_2RM_VSHLL 38
4893 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
4894 #define NEON_2RM_VRINTN 40
4895 #define NEON_2RM_VRINTX 41
4896 #define NEON_2RM_VRINTA 42
4897 #define NEON_2RM_VRINTZ 43
4898 #define NEON_2RM_VCVT_F16_F32 44
4899 #define NEON_2RM_VRINTM 45
4900 #define NEON_2RM_VCVT_F32_F16 46
4901 #define NEON_2RM_VRINTP 47
4902 #define NEON_2RM_VCVTAU 48
4903 #define NEON_2RM_VCVTAS 49
4904 #define NEON_2RM_VCVTNU 50
4905 #define NEON_2RM_VCVTNS 51
4906 #define NEON_2RM_VCVTPU 52
4907 #define NEON_2RM_VCVTPS 53
4908 #define NEON_2RM_VCVTMU 54
4909 #define NEON_2RM_VCVTMS 55
4910 #define NEON_2RM_VRECPE 56
4911 #define NEON_2RM_VRSQRTE 57
4912 #define NEON_2RM_VRECPE_F 58
4913 #define NEON_2RM_VRSQRTE_F 59
4914 #define NEON_2RM_VCVT_FS 60
4915 #define NEON_2RM_VCVT_FU 61
4916 #define NEON_2RM_VCVT_SF 62
4917 #define NEON_2RM_VCVT_UF 63
4919 static int neon_2rm_is_float_op(int op
)
4921 /* Return true if this neon 2reg-misc op is float-to-float */
4922 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
4923 (op
>= NEON_2RM_VRINTN
&& op
<= NEON_2RM_VRINTZ
) ||
4924 op
== NEON_2RM_VRINTM
||
4925 (op
>= NEON_2RM_VRINTP
&& op
<= NEON_2RM_VCVTMS
) ||
4926 op
>= NEON_2RM_VRECPE_F
);
4929 /* Each entry in this array has bit n set if the insn allows
4930 * size value n (otherwise it will UNDEF). Since unallocated
4931 * op values will have no bits set they always UNDEF.
4933 static const uint8_t neon_2rm_sizes
[] = {
4934 [NEON_2RM_VREV64
] = 0x7,
4935 [NEON_2RM_VREV32
] = 0x3,
4936 [NEON_2RM_VREV16
] = 0x1,
4937 [NEON_2RM_VPADDL
] = 0x7,
4938 [NEON_2RM_VPADDL_U
] = 0x7,
4939 [NEON_2RM_AESE
] = 0x1,
4940 [NEON_2RM_AESMC
] = 0x1,
4941 [NEON_2RM_VCLS
] = 0x7,
4942 [NEON_2RM_VCLZ
] = 0x7,
4943 [NEON_2RM_VCNT
] = 0x1,
4944 [NEON_2RM_VMVN
] = 0x1,
4945 [NEON_2RM_VPADAL
] = 0x7,
4946 [NEON_2RM_VPADAL_U
] = 0x7,
4947 [NEON_2RM_VQABS
] = 0x7,
4948 [NEON_2RM_VQNEG
] = 0x7,
4949 [NEON_2RM_VCGT0
] = 0x7,
4950 [NEON_2RM_VCGE0
] = 0x7,
4951 [NEON_2RM_VCEQ0
] = 0x7,
4952 [NEON_2RM_VCLE0
] = 0x7,
4953 [NEON_2RM_VCLT0
] = 0x7,
4954 [NEON_2RM_SHA1H
] = 0x4,
4955 [NEON_2RM_VABS
] = 0x7,
4956 [NEON_2RM_VNEG
] = 0x7,
4957 [NEON_2RM_VCGT0_F
] = 0x4,
4958 [NEON_2RM_VCGE0_F
] = 0x4,
4959 [NEON_2RM_VCEQ0_F
] = 0x4,
4960 [NEON_2RM_VCLE0_F
] = 0x4,
4961 [NEON_2RM_VCLT0_F
] = 0x4,
4962 [NEON_2RM_VABS_F
] = 0x4,
4963 [NEON_2RM_VNEG_F
] = 0x4,
4964 [NEON_2RM_VSWP
] = 0x1,
4965 [NEON_2RM_VTRN
] = 0x7,
4966 [NEON_2RM_VUZP
] = 0x7,
4967 [NEON_2RM_VZIP
] = 0x7,
4968 [NEON_2RM_VMOVN
] = 0x7,
4969 [NEON_2RM_VQMOVN
] = 0x7,
4970 [NEON_2RM_VSHLL
] = 0x7,
4971 [NEON_2RM_SHA1SU1
] = 0x4,
4972 [NEON_2RM_VRINTN
] = 0x4,
4973 [NEON_2RM_VRINTX
] = 0x4,
4974 [NEON_2RM_VRINTA
] = 0x4,
4975 [NEON_2RM_VRINTZ
] = 0x4,
4976 [NEON_2RM_VCVT_F16_F32
] = 0x2,
4977 [NEON_2RM_VRINTM
] = 0x4,
4978 [NEON_2RM_VCVT_F32_F16
] = 0x2,
4979 [NEON_2RM_VRINTP
] = 0x4,
4980 [NEON_2RM_VCVTAU
] = 0x4,
4981 [NEON_2RM_VCVTAS
] = 0x4,
4982 [NEON_2RM_VCVTNU
] = 0x4,
4983 [NEON_2RM_VCVTNS
] = 0x4,
4984 [NEON_2RM_VCVTPU
] = 0x4,
4985 [NEON_2RM_VCVTPS
] = 0x4,
4986 [NEON_2RM_VCVTMU
] = 0x4,
4987 [NEON_2RM_VCVTMS
] = 0x4,
4988 [NEON_2RM_VRECPE
] = 0x4,
4989 [NEON_2RM_VRSQRTE
] = 0x4,
4990 [NEON_2RM_VRECPE_F
] = 0x4,
4991 [NEON_2RM_VRSQRTE_F
] = 0x4,
4992 [NEON_2RM_VCVT_FS
] = 0x4,
4993 [NEON_2RM_VCVT_FU
] = 0x4,
4994 [NEON_2RM_VCVT_SF
] = 0x4,
4995 [NEON_2RM_VCVT_UF
] = 0x4,
4998 /* Translate a NEON data processing instruction. Return nonzero if the
4999 instruction is invalid.
5000 We process data in a mixture of 32-bit and 64-bit chunks.
5001 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5003 static int disas_neon_data_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
5015 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
5018 /* FIXME: this access check should not take precedence over UNDEF
5019 * for invalid encodings; we will generate incorrect syndrome information
5020 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5022 if (!s
->cpacr_fpen
) {
5023 gen_exception_insn(s
, 4, EXCP_UDEF
,
5024 syn_fp_access_trap(1, 0xe, s
->thumb
));
5028 if (!s
->vfp_enabled
)
5030 q
= (insn
& (1 << 6)) != 0;
5031 u
= (insn
>> 24) & 1;
5032 VFP_DREG_D(rd
, insn
);
5033 VFP_DREG_N(rn
, insn
);
5034 VFP_DREG_M(rm
, insn
);
5035 size
= (insn
>> 20) & 3;
5036 if ((insn
& (1 << 23)) == 0) {
5037 /* Three register same length. */
5038 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
5039 /* Catch invalid op and bad size combinations: UNDEF */
5040 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
5043 /* All insns of this form UNDEF for either this condition or the
5044 * superset of cases "Q==1"; we catch the latter later.
5046 if (q
&& ((rd
| rn
| rm
) & 1)) {
5050 * The SHA-1/SHA-256 3-register instructions require special treatment
5051 * here, as their size field is overloaded as an op type selector, and
5052 * they all consume their input in a single pass.
5054 if (op
== NEON_3R_SHA
) {
5058 if (!u
) { /* SHA-1 */
5059 if (!arm_feature(env
, ARM_FEATURE_V8_SHA1
)) {
5062 tmp
= tcg_const_i32(rd
);
5063 tmp2
= tcg_const_i32(rn
);
5064 tmp3
= tcg_const_i32(rm
);
5065 tmp4
= tcg_const_i32(size
);
5066 gen_helper_crypto_sha1_3reg(cpu_env
, tmp
, tmp2
, tmp3
, tmp4
);
5067 tcg_temp_free_i32(tmp4
);
5068 } else { /* SHA-256 */
5069 if (!arm_feature(env
, ARM_FEATURE_V8_SHA256
) || size
== 3) {
5072 tmp
= tcg_const_i32(rd
);
5073 tmp2
= tcg_const_i32(rn
);
5074 tmp3
= tcg_const_i32(rm
);
5077 gen_helper_crypto_sha256h(cpu_env
, tmp
, tmp2
, tmp3
);
5080 gen_helper_crypto_sha256h2(cpu_env
, tmp
, tmp2
, tmp3
);
5083 gen_helper_crypto_sha256su1(cpu_env
, tmp
, tmp2
, tmp3
);
5087 tcg_temp_free_i32(tmp
);
5088 tcg_temp_free_i32(tmp2
);
5089 tcg_temp_free_i32(tmp3
);
5092 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
5093 /* 64-bit element instructions. */
5094 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5095 neon_load_reg64(cpu_V0
, rn
+ pass
);
5096 neon_load_reg64(cpu_V1
, rm
+ pass
);
5100 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
5103 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
5109 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
5112 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
5118 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5120 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5125 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5128 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5134 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5136 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5139 case NEON_3R_VQRSHL
:
5141 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
5144 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
5148 case NEON_3R_VADD_VSUB
:
5150 tcg_gen_sub_i64(CPU_V001
);
5152 tcg_gen_add_i64(CPU_V001
);
5158 neon_store_reg64(cpu_V0
, rd
+ pass
);
5167 case NEON_3R_VQRSHL
:
5170 /* Shift instruction operands are reversed. */
5185 case NEON_3R_FLOAT_ARITH
:
5186 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
5188 case NEON_3R_FLOAT_MINMAX
:
5189 pairwise
= u
; /* if VPMIN/VPMAX (float) */
5191 case NEON_3R_FLOAT_CMP
:
5193 /* no encoding for U=0 C=1x */
5197 case NEON_3R_FLOAT_ACMP
:
5202 case NEON_3R_FLOAT_MISC
:
5203 /* VMAXNM/VMINNM in ARMv8 */
5204 if (u
&& !arm_feature(env
, ARM_FEATURE_V8
)) {
5209 if (u
&& (size
!= 0)) {
5210 /* UNDEF on invalid size for polynomial subcase */
5215 if (!arm_feature(env
, ARM_FEATURE_VFP4
) || u
) {
5223 if (pairwise
&& q
) {
5224 /* All the pairwise insns UNDEF if Q is set */
5228 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5233 tmp
= neon_load_reg(rn
, 0);
5234 tmp2
= neon_load_reg(rn
, 1);
5236 tmp
= neon_load_reg(rm
, 0);
5237 tmp2
= neon_load_reg(rm
, 1);
5241 tmp
= neon_load_reg(rn
, pass
);
5242 tmp2
= neon_load_reg(rm
, pass
);
5246 GEN_NEON_INTEGER_OP(hadd
);
5249 GEN_NEON_INTEGER_OP_ENV(qadd
);
5251 case NEON_3R_VRHADD
:
5252 GEN_NEON_INTEGER_OP(rhadd
);
5254 case NEON_3R_LOGIC
: /* Logic ops. */
5255 switch ((u
<< 2) | size
) {
5257 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
5260 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
5263 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5266 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
5269 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
5272 tmp3
= neon_load_reg(rd
, pass
);
5273 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
5274 tcg_temp_free_i32(tmp3
);
5277 tmp3
= neon_load_reg(rd
, pass
);
5278 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
5279 tcg_temp_free_i32(tmp3
);
5282 tmp3
= neon_load_reg(rd
, pass
);
5283 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
5284 tcg_temp_free_i32(tmp3
);
5289 GEN_NEON_INTEGER_OP(hsub
);
5292 GEN_NEON_INTEGER_OP_ENV(qsub
);
5295 GEN_NEON_INTEGER_OP(cgt
);
5298 GEN_NEON_INTEGER_OP(cge
);
5301 GEN_NEON_INTEGER_OP(shl
);
5304 GEN_NEON_INTEGER_OP_ENV(qshl
);
5307 GEN_NEON_INTEGER_OP(rshl
);
5309 case NEON_3R_VQRSHL
:
5310 GEN_NEON_INTEGER_OP_ENV(qrshl
);
5313 GEN_NEON_INTEGER_OP(max
);
5316 GEN_NEON_INTEGER_OP(min
);
5319 GEN_NEON_INTEGER_OP(abd
);
5322 GEN_NEON_INTEGER_OP(abd
);
5323 tcg_temp_free_i32(tmp2
);
5324 tmp2
= neon_load_reg(rd
, pass
);
5325 gen_neon_add(size
, tmp
, tmp2
);
5327 case NEON_3R_VADD_VSUB
:
5328 if (!u
) { /* VADD */
5329 gen_neon_add(size
, tmp
, tmp2
);
5332 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
5333 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
5334 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
5339 case NEON_3R_VTST_VCEQ
:
5340 if (!u
) { /* VTST */
5342 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
5343 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
5344 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
5349 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
5350 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
5351 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
5356 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
5358 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5359 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5360 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5363 tcg_temp_free_i32(tmp2
);
5364 tmp2
= neon_load_reg(rd
, pass
);
5366 gen_neon_rsb(size
, tmp
, tmp2
);
5368 gen_neon_add(size
, tmp
, tmp2
);
5372 if (u
) { /* polynomial */
5373 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
5374 } else { /* Integer */
5376 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5377 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5378 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5384 GEN_NEON_INTEGER_OP(pmax
);
5387 GEN_NEON_INTEGER_OP(pmin
);
5389 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
5390 if (!u
) { /* VQDMULH */
5393 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5396 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5400 } else { /* VQRDMULH */
5403 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5406 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5414 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
5415 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
5416 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
5420 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
5422 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5423 switch ((u
<< 2) | size
) {
5426 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5429 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
5432 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
5437 tcg_temp_free_ptr(fpstatus
);
5440 case NEON_3R_FLOAT_MULTIPLY
:
5442 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5443 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5445 tcg_temp_free_i32(tmp2
);
5446 tmp2
= neon_load_reg(rd
, pass
);
5448 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5450 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5453 tcg_temp_free_ptr(fpstatus
);
5456 case NEON_3R_FLOAT_CMP
:
5458 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5460 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
5463 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5465 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5468 tcg_temp_free_ptr(fpstatus
);
5471 case NEON_3R_FLOAT_ACMP
:
5473 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5475 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5477 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5479 tcg_temp_free_ptr(fpstatus
);
5482 case NEON_3R_FLOAT_MINMAX
:
5484 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5486 gen_helper_vfp_maxs(tmp
, tmp
, tmp2
, fpstatus
);
5488 gen_helper_vfp_mins(tmp
, tmp
, tmp2
, fpstatus
);
5490 tcg_temp_free_ptr(fpstatus
);
5493 case NEON_3R_FLOAT_MISC
:
5496 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5498 gen_helper_vfp_maxnums(tmp
, tmp
, tmp2
, fpstatus
);
5500 gen_helper_vfp_minnums(tmp
, tmp
, tmp2
, fpstatus
);
5502 tcg_temp_free_ptr(fpstatus
);
5505 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
5507 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
5513 /* VFMA, VFMS: fused multiply-add */
5514 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5515 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
5518 gen_helper_vfp_negs(tmp
, tmp
);
5520 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
5521 tcg_temp_free_i32(tmp3
);
5522 tcg_temp_free_ptr(fpstatus
);
5528 tcg_temp_free_i32(tmp2
);
5530 /* Save the result. For elementwise operations we can put it
5531 straight into the destination register. For pairwise operations
5532 we have to be careful to avoid clobbering the source operands. */
5533 if (pairwise
&& rd
== rm
) {
5534 neon_store_scratch(pass
, tmp
);
5536 neon_store_reg(rd
, pass
, tmp
);
5540 if (pairwise
&& rd
== rm
) {
5541 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5542 tmp
= neon_load_scratch(pass
);
5543 neon_store_reg(rd
, pass
, tmp
);
5546 /* End of 3 register same size operations. */
5547 } else if (insn
& (1 << 4)) {
5548 if ((insn
& 0x00380080) != 0) {
5549 /* Two registers and shift. */
5550 op
= (insn
>> 8) & 0xf;
5551 if (insn
& (1 << 7)) {
5559 while ((insn
& (1 << (size
+ 19))) == 0)
5562 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
5563 /* To avoid excessive duplication of ops we implement shift
5564 by immediate using the variable shift operations. */
5566 /* Shift by immediate:
5567 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5568 if (q
&& ((rd
| rm
) & 1)) {
5571 if (!u
&& (op
== 4 || op
== 6)) {
5574 /* Right shifts are encoded as N - shift, where N is the
5575 element size in bits. */
5577 shift
= shift
- (1 << (size
+ 3));
5585 imm
= (uint8_t) shift
;
5590 imm
= (uint16_t) shift
;
5601 for (pass
= 0; pass
< count
; pass
++) {
5603 neon_load_reg64(cpu_V0
, rm
+ pass
);
5604 tcg_gen_movi_i64(cpu_V1
, imm
);
5609 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5611 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5616 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5618 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5621 case 5: /* VSHL, VSLI */
5622 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5624 case 6: /* VQSHLU */
5625 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
5630 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5633 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5638 if (op
== 1 || op
== 3) {
5640 neon_load_reg64(cpu_V1
, rd
+ pass
);
5641 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5642 } else if (op
== 4 || (op
== 5 && u
)) {
5644 neon_load_reg64(cpu_V1
, rd
+ pass
);
5646 if (shift
< -63 || shift
> 63) {
5650 mask
= 0xffffffffffffffffull
>> -shift
;
5652 mask
= 0xffffffffffffffffull
<< shift
;
5655 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
5656 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5658 neon_store_reg64(cpu_V0
, rd
+ pass
);
5659 } else { /* size < 3 */
5660 /* Operands in T0 and T1. */
5661 tmp
= neon_load_reg(rm
, pass
);
5662 tmp2
= tcg_temp_new_i32();
5663 tcg_gen_movi_i32(tmp2
, imm
);
5667 GEN_NEON_INTEGER_OP(shl
);
5671 GEN_NEON_INTEGER_OP(rshl
);
5674 case 5: /* VSHL, VSLI */
5676 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
5677 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
5678 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
5682 case 6: /* VQSHLU */
5685 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
5689 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
5693 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
5701 GEN_NEON_INTEGER_OP_ENV(qshl
);
5704 tcg_temp_free_i32(tmp2
);
5706 if (op
== 1 || op
== 3) {
5708 tmp2
= neon_load_reg(rd
, pass
);
5709 gen_neon_add(size
, tmp
, tmp2
);
5710 tcg_temp_free_i32(tmp2
);
5711 } else if (op
== 4 || (op
== 5 && u
)) {
5716 mask
= 0xff >> -shift
;
5718 mask
= (uint8_t)(0xff << shift
);
5724 mask
= 0xffff >> -shift
;
5726 mask
= (uint16_t)(0xffff << shift
);
5730 if (shift
< -31 || shift
> 31) {
5734 mask
= 0xffffffffu
>> -shift
;
5736 mask
= 0xffffffffu
<< shift
;
5742 tmp2
= neon_load_reg(rd
, pass
);
5743 tcg_gen_andi_i32(tmp
, tmp
, mask
);
5744 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
5745 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5746 tcg_temp_free_i32(tmp2
);
5748 neon_store_reg(rd
, pass
, tmp
);
5751 } else if (op
< 10) {
5752 /* Shift by immediate and narrow:
5753 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5754 int input_unsigned
= (op
== 8) ? !u
: u
;
5758 shift
= shift
- (1 << (size
+ 3));
5761 tmp64
= tcg_const_i64(shift
);
5762 neon_load_reg64(cpu_V0
, rm
);
5763 neon_load_reg64(cpu_V1
, rm
+ 1);
5764 for (pass
= 0; pass
< 2; pass
++) {
5772 if (input_unsigned
) {
5773 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
5775 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
5778 if (input_unsigned
) {
5779 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
5781 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
5784 tmp
= tcg_temp_new_i32();
5785 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5786 neon_store_reg(rd
, pass
, tmp
);
5788 tcg_temp_free_i64(tmp64
);
5791 imm
= (uint16_t)shift
;
5795 imm
= (uint32_t)shift
;
5797 tmp2
= tcg_const_i32(imm
);
5798 tmp4
= neon_load_reg(rm
+ 1, 0);
5799 tmp5
= neon_load_reg(rm
+ 1, 1);
5800 for (pass
= 0; pass
< 2; pass
++) {
5802 tmp
= neon_load_reg(rm
, 0);
5806 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
5809 tmp3
= neon_load_reg(rm
, 1);
5813 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
5815 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
5816 tcg_temp_free_i32(tmp
);
5817 tcg_temp_free_i32(tmp3
);
5818 tmp
= tcg_temp_new_i32();
5819 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5820 neon_store_reg(rd
, pass
, tmp
);
5822 tcg_temp_free_i32(tmp2
);
5824 } else if (op
== 10) {
5826 if (q
|| (rd
& 1)) {
5829 tmp
= neon_load_reg(rm
, 0);
5830 tmp2
= neon_load_reg(rm
, 1);
5831 for (pass
= 0; pass
< 2; pass
++) {
5835 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5838 /* The shift is less than the width of the source
5839 type, so we can just shift the whole register. */
5840 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
5841 /* Widen the result of shift: we need to clear
5842 * the potential overflow bits resulting from
5843 * left bits of the narrow input appearing as
5844 * right bits of left the neighbour narrow
5846 if (size
< 2 || !u
) {
5849 imm
= (0xffu
>> (8 - shift
));
5851 } else if (size
== 1) {
5852 imm
= 0xffff >> (16 - shift
);
5855 imm
= 0xffffffff >> (32 - shift
);
5858 imm64
= imm
| (((uint64_t)imm
) << 32);
5862 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
5865 neon_store_reg64(cpu_V0
, rd
+ pass
);
5867 } else if (op
>= 14) {
5868 /* VCVT fixed-point. */
5869 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
5872 /* We have already masked out the must-be-1 top bit of imm6,
5873 * hence this 32-shift where the ARM ARM has 64-imm6.
5876 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5877 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
5880 gen_vfp_ulto(0, shift
, 1);
5882 gen_vfp_slto(0, shift
, 1);
5885 gen_vfp_toul(0, shift
, 1);
5887 gen_vfp_tosl(0, shift
, 1);
5889 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
5894 } else { /* (insn & 0x00380080) == 0 */
5896 if (q
&& (rd
& 1)) {
5900 op
= (insn
>> 8) & 0xf;
5901 /* One register and immediate. */
5902 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
5903 invert
= (insn
& (1 << 5)) != 0;
5904 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5905 * We choose to not special-case this and will behave as if a
5906 * valid constant encoding of 0 had been given.
5925 imm
= (imm
<< 8) | (imm
<< 24);
5928 imm
= (imm
<< 8) | 0xff;
5931 imm
= (imm
<< 16) | 0xffff;
5934 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
5942 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
5943 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
5949 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5950 if (op
& 1 && op
< 12) {
5951 tmp
= neon_load_reg(rd
, pass
);
5953 /* The immediate value has already been inverted, so
5955 tcg_gen_andi_i32(tmp
, tmp
, imm
);
5957 tcg_gen_ori_i32(tmp
, tmp
, imm
);
5961 tmp
= tcg_temp_new_i32();
5962 if (op
== 14 && invert
) {
5966 for (n
= 0; n
< 4; n
++) {
5967 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
5968 val
|= 0xff << (n
* 8);
5970 tcg_gen_movi_i32(tmp
, val
);
5972 tcg_gen_movi_i32(tmp
, imm
);
5975 neon_store_reg(rd
, pass
, tmp
);
5978 } else { /* (insn & 0x00800010 == 0x00800000) */
5980 op
= (insn
>> 8) & 0xf;
5981 if ((insn
& (1 << 6)) == 0) {
5982 /* Three registers of different lengths. */
5986 /* undefreq: bit 0 : UNDEF if size == 0
5987 * bit 1 : UNDEF if size == 1
5988 * bit 2 : UNDEF if size == 2
5989 * bit 3 : UNDEF if U == 1
5990 * Note that [2:0] set implies 'always UNDEF'
5993 /* prewiden, src1_wide, src2_wide, undefreq */
5994 static const int neon_3reg_wide
[16][4] = {
5995 {1, 0, 0, 0}, /* VADDL */
5996 {1, 1, 0, 0}, /* VADDW */
5997 {1, 0, 0, 0}, /* VSUBL */
5998 {1, 1, 0, 0}, /* VSUBW */
5999 {0, 1, 1, 0}, /* VADDHN */
6000 {0, 0, 0, 0}, /* VABAL */
6001 {0, 1, 1, 0}, /* VSUBHN */
6002 {0, 0, 0, 0}, /* VABDL */
6003 {0, 0, 0, 0}, /* VMLAL */
6004 {0, 0, 0, 9}, /* VQDMLAL */
6005 {0, 0, 0, 0}, /* VMLSL */
6006 {0, 0, 0, 9}, /* VQDMLSL */
6007 {0, 0, 0, 0}, /* Integer VMULL */
6008 {0, 0, 0, 1}, /* VQDMULL */
6009 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6010 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6013 prewiden
= neon_3reg_wide
[op
][0];
6014 src1_wide
= neon_3reg_wide
[op
][1];
6015 src2_wide
= neon_3reg_wide
[op
][2];
6016 undefreq
= neon_3reg_wide
[op
][3];
6018 if ((undefreq
& (1 << size
)) ||
6019 ((undefreq
& 8) && u
)) {
6022 if ((src1_wide
&& (rn
& 1)) ||
6023 (src2_wide
&& (rm
& 1)) ||
6024 (!src2_wide
&& (rd
& 1))) {
6028 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6029 * outside the loop below as it only performs a single pass.
6031 if (op
== 14 && size
== 2) {
6032 TCGv_i64 tcg_rn
, tcg_rm
, tcg_rd
;
6034 if (!arm_feature(env
, ARM_FEATURE_V8_PMULL
)) {
6037 tcg_rn
= tcg_temp_new_i64();
6038 tcg_rm
= tcg_temp_new_i64();
6039 tcg_rd
= tcg_temp_new_i64();
6040 neon_load_reg64(tcg_rn
, rn
);
6041 neon_load_reg64(tcg_rm
, rm
);
6042 gen_helper_neon_pmull_64_lo(tcg_rd
, tcg_rn
, tcg_rm
);
6043 neon_store_reg64(tcg_rd
, rd
);
6044 gen_helper_neon_pmull_64_hi(tcg_rd
, tcg_rn
, tcg_rm
);
6045 neon_store_reg64(tcg_rd
, rd
+ 1);
6046 tcg_temp_free_i64(tcg_rn
);
6047 tcg_temp_free_i64(tcg_rm
);
6048 tcg_temp_free_i64(tcg_rd
);
6052 /* Avoid overlapping operands. Wide source operands are
6053 always aligned so will never overlap with wide
6054 destinations in problematic ways. */
6055 if (rd
== rm
&& !src2_wide
) {
6056 tmp
= neon_load_reg(rm
, 1);
6057 neon_store_scratch(2, tmp
);
6058 } else if (rd
== rn
&& !src1_wide
) {
6059 tmp
= neon_load_reg(rn
, 1);
6060 neon_store_scratch(2, tmp
);
6062 TCGV_UNUSED_I32(tmp3
);
6063 for (pass
= 0; pass
< 2; pass
++) {
6065 neon_load_reg64(cpu_V0
, rn
+ pass
);
6066 TCGV_UNUSED_I32(tmp
);
6068 if (pass
== 1 && rd
== rn
) {
6069 tmp
= neon_load_scratch(2);
6071 tmp
= neon_load_reg(rn
, pass
);
6074 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6078 neon_load_reg64(cpu_V1
, rm
+ pass
);
6079 TCGV_UNUSED_I32(tmp2
);
6081 if (pass
== 1 && rd
== rm
) {
6082 tmp2
= neon_load_scratch(2);
6084 tmp2
= neon_load_reg(rm
, pass
);
6087 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
6091 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6092 gen_neon_addl(size
);
6094 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6095 gen_neon_subl(size
);
6097 case 5: case 7: /* VABAL, VABDL */
6098 switch ((size
<< 1) | u
) {
6100 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
6103 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
6106 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
6109 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
6112 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
6115 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
6119 tcg_temp_free_i32(tmp2
);
6120 tcg_temp_free_i32(tmp
);
6122 case 8: case 9: case 10: case 11: case 12: case 13:
6123 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6124 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6126 case 14: /* Polynomial VMULL */
6127 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
6128 tcg_temp_free_i32(tmp2
);
6129 tcg_temp_free_i32(tmp
);
6131 default: /* 15 is RESERVED: caught earlier */
6136 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6137 neon_store_reg64(cpu_V0
, rd
+ pass
);
6138 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
6140 neon_load_reg64(cpu_V1
, rd
+ pass
);
6142 case 10: /* VMLSL */
6143 gen_neon_negl(cpu_V0
, size
);
6145 case 5: case 8: /* VABAL, VMLAL */
6146 gen_neon_addl(size
);
6148 case 9: case 11: /* VQDMLAL, VQDMLSL */
6149 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6151 gen_neon_negl(cpu_V0
, size
);
6153 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6158 neon_store_reg64(cpu_V0
, rd
+ pass
);
6159 } else if (op
== 4 || op
== 6) {
6160 /* Narrowing operation. */
6161 tmp
= tcg_temp_new_i32();
6165 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
6168 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
6171 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6172 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
6179 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
6182 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
6185 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
6186 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6187 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
6195 neon_store_reg(rd
, 0, tmp3
);
6196 neon_store_reg(rd
, 1, tmp
);
6199 /* Write back the result. */
6200 neon_store_reg64(cpu_V0
, rd
+ pass
);
6204 /* Two registers and a scalar. NB that for ops of this form
6205 * the ARM ARM labels bit 24 as Q, but it is in our variable
6212 case 1: /* Float VMLA scalar */
6213 case 5: /* Floating point VMLS scalar */
6214 case 9: /* Floating point VMUL scalar */
6219 case 0: /* Integer VMLA scalar */
6220 case 4: /* Integer VMLS scalar */
6221 case 8: /* Integer VMUL scalar */
6222 case 12: /* VQDMULH scalar */
6223 case 13: /* VQRDMULH scalar */
6224 if (u
&& ((rd
| rn
) & 1)) {
6227 tmp
= neon_get_scalar(size
, rm
);
6228 neon_store_scratch(0, tmp
);
6229 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6230 tmp
= neon_load_scratch(0);
6231 tmp2
= neon_load_reg(rn
, pass
);
6234 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6236 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6238 } else if (op
== 13) {
6240 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6242 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6244 } else if (op
& 1) {
6245 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6246 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6247 tcg_temp_free_ptr(fpstatus
);
6250 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6251 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6252 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6256 tcg_temp_free_i32(tmp2
);
6259 tmp2
= neon_load_reg(rd
, pass
);
6262 gen_neon_add(size
, tmp
, tmp2
);
6266 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6267 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6268 tcg_temp_free_ptr(fpstatus
);
6272 gen_neon_rsb(size
, tmp
, tmp2
);
6276 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6277 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6278 tcg_temp_free_ptr(fpstatus
);
6284 tcg_temp_free_i32(tmp2
);
6286 neon_store_reg(rd
, pass
, tmp
);
6289 case 3: /* VQDMLAL scalar */
6290 case 7: /* VQDMLSL scalar */
6291 case 11: /* VQDMULL scalar */
6296 case 2: /* VMLAL sclar */
6297 case 6: /* VMLSL scalar */
6298 case 10: /* VMULL scalar */
6302 tmp2
= neon_get_scalar(size
, rm
);
6303 /* We need a copy of tmp2 because gen_neon_mull
6304 * deletes it during pass 0. */
6305 tmp4
= tcg_temp_new_i32();
6306 tcg_gen_mov_i32(tmp4
, tmp2
);
6307 tmp3
= neon_load_reg(rn
, 1);
6309 for (pass
= 0; pass
< 2; pass
++) {
6311 tmp
= neon_load_reg(rn
, 0);
6316 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6318 neon_load_reg64(cpu_V1
, rd
+ pass
);
6322 gen_neon_negl(cpu_V0
, size
);
6325 gen_neon_addl(size
);
6328 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6330 gen_neon_negl(cpu_V0
, size
);
6332 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6338 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6343 neon_store_reg64(cpu_V0
, rd
+ pass
);
6348 default: /* 14 and 15 are RESERVED */
6352 } else { /* size == 3 */
6355 imm
= (insn
>> 8) & 0xf;
6360 if (q
&& ((rd
| rn
| rm
) & 1)) {
6365 neon_load_reg64(cpu_V0
, rn
);
6367 neon_load_reg64(cpu_V1
, rn
+ 1);
6369 } else if (imm
== 8) {
6370 neon_load_reg64(cpu_V0
, rn
+ 1);
6372 neon_load_reg64(cpu_V1
, rm
);
6375 tmp64
= tcg_temp_new_i64();
6377 neon_load_reg64(cpu_V0
, rn
);
6378 neon_load_reg64(tmp64
, rn
+ 1);
6380 neon_load_reg64(cpu_V0
, rn
+ 1);
6381 neon_load_reg64(tmp64
, rm
);
6383 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
6384 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
6385 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6387 neon_load_reg64(cpu_V1
, rm
);
6389 neon_load_reg64(cpu_V1
, rm
+ 1);
6392 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6393 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
6394 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
6395 tcg_temp_free_i64(tmp64
);
6398 neon_load_reg64(cpu_V0
, rn
);
6399 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
6400 neon_load_reg64(cpu_V1
, rm
);
6401 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6402 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6404 neon_store_reg64(cpu_V0
, rd
);
6406 neon_store_reg64(cpu_V1
, rd
+ 1);
6408 } else if ((insn
& (1 << 11)) == 0) {
6409 /* Two register misc. */
6410 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
6411 size
= (insn
>> 18) & 3;
6412 /* UNDEF for unknown op values and bad op-size combinations */
6413 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
6416 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
6417 q
&& ((rm
| rd
) & 1)) {
6421 case NEON_2RM_VREV64
:
6422 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
6423 tmp
= neon_load_reg(rm
, pass
* 2);
6424 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
6426 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6427 case 1: gen_swap_half(tmp
); break;
6428 case 2: /* no-op */ break;
6431 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
6433 neon_store_reg(rd
, pass
* 2, tmp2
);
6436 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
6437 case 1: gen_swap_half(tmp2
); break;
6440 neon_store_reg(rd
, pass
* 2, tmp2
);
6444 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
6445 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
6446 for (pass
= 0; pass
< q
+ 1; pass
++) {
6447 tmp
= neon_load_reg(rm
, pass
* 2);
6448 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
6449 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
6450 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
6452 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
6453 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
6454 case 2: tcg_gen_add_i64(CPU_V001
); break;
6457 if (op
>= NEON_2RM_VPADAL
) {
6459 neon_load_reg64(cpu_V1
, rd
+ pass
);
6460 gen_neon_addl(size
);
6462 neon_store_reg64(cpu_V0
, rd
+ pass
);
6468 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
6469 tmp
= neon_load_reg(rm
, n
);
6470 tmp2
= neon_load_reg(rd
, n
+ 1);
6471 neon_store_reg(rm
, n
, tmp2
);
6472 neon_store_reg(rd
, n
+ 1, tmp
);
6479 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
6484 if (gen_neon_zip(rd
, rm
, size
, q
)) {
6488 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
6489 /* also VQMOVUN; op field and mnemonics don't line up */
6493 TCGV_UNUSED_I32(tmp2
);
6494 for (pass
= 0; pass
< 2; pass
++) {
6495 neon_load_reg64(cpu_V0
, rm
+ pass
);
6496 tmp
= tcg_temp_new_i32();
6497 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
6502 neon_store_reg(rd
, 0, tmp2
);
6503 neon_store_reg(rd
, 1, tmp
);
6507 case NEON_2RM_VSHLL
:
6508 if (q
|| (rd
& 1)) {
6511 tmp
= neon_load_reg(rm
, 0);
6512 tmp2
= neon_load_reg(rm
, 1);
6513 for (pass
= 0; pass
< 2; pass
++) {
6516 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
6517 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
6518 neon_store_reg64(cpu_V0
, rd
+ pass
);
6521 case NEON_2RM_VCVT_F16_F32
:
6522 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
6526 tmp
= tcg_temp_new_i32();
6527 tmp2
= tcg_temp_new_i32();
6528 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
6529 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6530 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
6531 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6532 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6533 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6534 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
6535 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6536 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
6537 neon_store_reg(rd
, 0, tmp2
);
6538 tmp2
= tcg_temp_new_i32();
6539 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6540 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6541 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6542 neon_store_reg(rd
, 1, tmp2
);
6543 tcg_temp_free_i32(tmp
);
6545 case NEON_2RM_VCVT_F32_F16
:
6546 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
6550 tmp3
= tcg_temp_new_i32();
6551 tmp
= neon_load_reg(rm
, 0);
6552 tmp2
= neon_load_reg(rm
, 1);
6553 tcg_gen_ext16u_i32(tmp3
, tmp
);
6554 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6555 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
6556 tcg_gen_shri_i32(tmp3
, tmp
, 16);
6557 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6558 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
6559 tcg_temp_free_i32(tmp
);
6560 tcg_gen_ext16u_i32(tmp3
, tmp2
);
6561 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6562 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
6563 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
6564 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6565 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
6566 tcg_temp_free_i32(tmp2
);
6567 tcg_temp_free_i32(tmp3
);
6569 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
6570 if (!arm_feature(env
, ARM_FEATURE_V8_AES
)
6571 || ((rm
| rd
) & 1)) {
6574 tmp
= tcg_const_i32(rd
);
6575 tmp2
= tcg_const_i32(rm
);
6577 /* Bit 6 is the lowest opcode bit; it distinguishes between
6578 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6580 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
6582 if (op
== NEON_2RM_AESE
) {
6583 gen_helper_crypto_aese(cpu_env
, tmp
, tmp2
, tmp3
);
6585 gen_helper_crypto_aesmc(cpu_env
, tmp
, tmp2
, tmp3
);
6587 tcg_temp_free_i32(tmp
);
6588 tcg_temp_free_i32(tmp2
);
6589 tcg_temp_free_i32(tmp3
);
6591 case NEON_2RM_SHA1H
:
6592 if (!arm_feature(env
, ARM_FEATURE_V8_SHA1
)
6593 || ((rm
| rd
) & 1)) {
6596 tmp
= tcg_const_i32(rd
);
6597 tmp2
= tcg_const_i32(rm
);
6599 gen_helper_crypto_sha1h(cpu_env
, tmp
, tmp2
);
6601 tcg_temp_free_i32(tmp
);
6602 tcg_temp_free_i32(tmp2
);
6604 case NEON_2RM_SHA1SU1
:
6605 if ((rm
| rd
) & 1) {
6608 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6610 if (!arm_feature(env
, ARM_FEATURE_V8_SHA256
)) {
6613 } else if (!arm_feature(env
, ARM_FEATURE_V8_SHA1
)) {
6616 tmp
= tcg_const_i32(rd
);
6617 tmp2
= tcg_const_i32(rm
);
6619 gen_helper_crypto_sha256su0(cpu_env
, tmp
, tmp2
);
6621 gen_helper_crypto_sha1su1(cpu_env
, tmp
, tmp2
);
6623 tcg_temp_free_i32(tmp
);
6624 tcg_temp_free_i32(tmp2
);
6628 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6629 if (neon_2rm_is_float_op(op
)) {
6630 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
6631 neon_reg_offset(rm
, pass
));
6632 TCGV_UNUSED_I32(tmp
);
6634 tmp
= neon_load_reg(rm
, pass
);
6637 case NEON_2RM_VREV32
:
6639 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6640 case 1: gen_swap_half(tmp
); break;
6644 case NEON_2RM_VREV16
:
6649 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
6650 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
6651 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
6657 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
6658 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
6659 case 2: gen_helper_clz(tmp
, tmp
); break;
6664 gen_helper_neon_cnt_u8(tmp
, tmp
);
6667 tcg_gen_not_i32(tmp
, tmp
);
6669 case NEON_2RM_VQABS
:
6672 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
6675 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
6678 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
6683 case NEON_2RM_VQNEG
:
6686 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
6689 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
6692 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
6697 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
6698 tmp2
= tcg_const_i32(0);
6700 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
6701 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
6702 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
6705 tcg_temp_free_i32(tmp2
);
6706 if (op
== NEON_2RM_VCLE0
) {
6707 tcg_gen_not_i32(tmp
, tmp
);
6710 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
6711 tmp2
= tcg_const_i32(0);
6713 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
6714 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
6715 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
6718 tcg_temp_free_i32(tmp2
);
6719 if (op
== NEON_2RM_VCLT0
) {
6720 tcg_gen_not_i32(tmp
, tmp
);
6723 case NEON_2RM_VCEQ0
:
6724 tmp2
= tcg_const_i32(0);
6726 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
6727 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
6728 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
6731 tcg_temp_free_i32(tmp2
);
6735 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
6736 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
6737 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
6742 tmp2
= tcg_const_i32(0);
6743 gen_neon_rsb(size
, tmp
, tmp2
);
6744 tcg_temp_free_i32(tmp2
);
6746 case NEON_2RM_VCGT0_F
:
6748 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6749 tmp2
= tcg_const_i32(0);
6750 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6751 tcg_temp_free_i32(tmp2
);
6752 tcg_temp_free_ptr(fpstatus
);
6755 case NEON_2RM_VCGE0_F
:
6757 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6758 tmp2
= tcg_const_i32(0);
6759 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6760 tcg_temp_free_i32(tmp2
);
6761 tcg_temp_free_ptr(fpstatus
);
6764 case NEON_2RM_VCEQ0_F
:
6766 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6767 tmp2
= tcg_const_i32(0);
6768 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6769 tcg_temp_free_i32(tmp2
);
6770 tcg_temp_free_ptr(fpstatus
);
6773 case NEON_2RM_VCLE0_F
:
6775 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6776 tmp2
= tcg_const_i32(0);
6777 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
6778 tcg_temp_free_i32(tmp2
);
6779 tcg_temp_free_ptr(fpstatus
);
6782 case NEON_2RM_VCLT0_F
:
6784 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6785 tmp2
= tcg_const_i32(0);
6786 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
6787 tcg_temp_free_i32(tmp2
);
6788 tcg_temp_free_ptr(fpstatus
);
6791 case NEON_2RM_VABS_F
:
6794 case NEON_2RM_VNEG_F
:
6798 tmp2
= neon_load_reg(rd
, pass
);
6799 neon_store_reg(rm
, pass
, tmp2
);
6802 tmp2
= neon_load_reg(rd
, pass
);
6804 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
6805 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
6808 neon_store_reg(rm
, pass
, tmp2
);
6810 case NEON_2RM_VRINTN
:
6811 case NEON_2RM_VRINTA
:
6812 case NEON_2RM_VRINTM
:
6813 case NEON_2RM_VRINTP
:
6814 case NEON_2RM_VRINTZ
:
6817 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6820 if (op
== NEON_2RM_VRINTZ
) {
6821 rmode
= FPROUNDING_ZERO
;
6823 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
6826 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
6827 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6829 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpstatus
);
6830 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6832 tcg_temp_free_ptr(fpstatus
);
6833 tcg_temp_free_i32(tcg_rmode
);
6836 case NEON_2RM_VRINTX
:
6838 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6839 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpstatus
);
6840 tcg_temp_free_ptr(fpstatus
);
6843 case NEON_2RM_VCVTAU
:
6844 case NEON_2RM_VCVTAS
:
6845 case NEON_2RM_VCVTNU
:
6846 case NEON_2RM_VCVTNS
:
6847 case NEON_2RM_VCVTPU
:
6848 case NEON_2RM_VCVTPS
:
6849 case NEON_2RM_VCVTMU
:
6850 case NEON_2RM_VCVTMS
:
6852 bool is_signed
= !extract32(insn
, 7, 1);
6853 TCGv_ptr fpst
= get_fpstatus_ptr(1);
6854 TCGv_i32 tcg_rmode
, tcg_shift
;
6855 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
6857 tcg_shift
= tcg_const_i32(0);
6858 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
6859 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6863 gen_helper_vfp_tosls(cpu_F0s
, cpu_F0s
,
6866 gen_helper_vfp_touls(cpu_F0s
, cpu_F0s
,
6870 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6872 tcg_temp_free_i32(tcg_rmode
);
6873 tcg_temp_free_i32(tcg_shift
);
6874 tcg_temp_free_ptr(fpst
);
6877 case NEON_2RM_VRECPE
:
6879 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6880 gen_helper_recpe_u32(tmp
, tmp
, fpstatus
);
6881 tcg_temp_free_ptr(fpstatus
);
6884 case NEON_2RM_VRSQRTE
:
6886 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6887 gen_helper_rsqrte_u32(tmp
, tmp
, fpstatus
);
6888 tcg_temp_free_ptr(fpstatus
);
6891 case NEON_2RM_VRECPE_F
:
6893 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6894 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
6895 tcg_temp_free_ptr(fpstatus
);
6898 case NEON_2RM_VRSQRTE_F
:
6900 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6901 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
6902 tcg_temp_free_ptr(fpstatus
);
6905 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
6908 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
6911 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
6912 gen_vfp_tosiz(0, 1);
6914 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
6915 gen_vfp_touiz(0, 1);
6918 /* Reserved op values were caught by the
6919 * neon_2rm_sizes[] check earlier.
6923 if (neon_2rm_is_float_op(op
)) {
6924 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
6925 neon_reg_offset(rd
, pass
));
6927 neon_store_reg(rd
, pass
, tmp
);
6932 } else if ((insn
& (1 << 10)) == 0) {
6934 int n
= ((insn
>> 8) & 3) + 1;
6935 if ((rn
+ n
) > 32) {
6936 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6937 * helper function running off the end of the register file.
6942 if (insn
& (1 << 6)) {
6943 tmp
= neon_load_reg(rd
, 0);
6945 tmp
= tcg_temp_new_i32();
6946 tcg_gen_movi_i32(tmp
, 0);
6948 tmp2
= neon_load_reg(rm
, 0);
6949 tmp4
= tcg_const_i32(rn
);
6950 tmp5
= tcg_const_i32(n
);
6951 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
6952 tcg_temp_free_i32(tmp
);
6953 if (insn
& (1 << 6)) {
6954 tmp
= neon_load_reg(rd
, 1);
6956 tmp
= tcg_temp_new_i32();
6957 tcg_gen_movi_i32(tmp
, 0);
6959 tmp3
= neon_load_reg(rm
, 1);
6960 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
6961 tcg_temp_free_i32(tmp5
);
6962 tcg_temp_free_i32(tmp4
);
6963 neon_store_reg(rd
, 0, tmp2
);
6964 neon_store_reg(rd
, 1, tmp3
);
6965 tcg_temp_free_i32(tmp
);
6966 } else if ((insn
& 0x380) == 0) {
6968 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
6971 if (insn
& (1 << 19)) {
6972 tmp
= neon_load_reg(rm
, 1);
6974 tmp
= neon_load_reg(rm
, 0);
6976 if (insn
& (1 << 16)) {
6977 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
6978 } else if (insn
& (1 << 17)) {
6979 if ((insn
>> 18) & 1)
6980 gen_neon_dup_high16(tmp
);
6982 gen_neon_dup_low16(tmp
);
6984 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6985 tmp2
= tcg_temp_new_i32();
6986 tcg_gen_mov_i32(tmp2
, tmp
);
6987 neon_store_reg(rd
, pass
, tmp2
);
6989 tcg_temp_free_i32(tmp
);
6998 static int disas_coproc_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
7000 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
7001 const ARMCPRegInfo
*ri
;
7003 cpnum
= (insn
>> 8) & 0xf;
7004 if (arm_feature(env
, ARM_FEATURE_XSCALE
)
7005 && ((env
->cp15
.c15_cpar
^ 0x3fff) & (1 << cpnum
)))
7008 /* First check for coprocessor space used for actual instructions */
7012 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
7013 return disas_iwmmxt_insn(env
, s
, insn
);
7014 } else if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
7015 return disas_dsp_insn(env
, s
, insn
);
7022 /* Otherwise treat as a generic register access */
7023 is64
= (insn
& (1 << 25)) == 0;
7024 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
7032 opc1
= (insn
>> 4) & 0xf;
7034 rt2
= (insn
>> 16) & 0xf;
7036 crn
= (insn
>> 16) & 0xf;
7037 opc1
= (insn
>> 21) & 7;
7038 opc2
= (insn
>> 5) & 7;
7041 isread
= (insn
>> 20) & 1;
7042 rt
= (insn
>> 12) & 0xf;
7044 ri
= get_arm_cp_reginfo(s
->cp_regs
,
7045 ENCODE_CP_REG(cpnum
, is64
, crn
, crm
, opc1
, opc2
));
7047 /* Check access permissions */
7048 if (!cp_access_ok(s
->current_pl
, ri
, isread
)) {
7053 /* Emit code to perform further access permissions checks at
7054 * runtime; this may result in an exception.
7060 /* Note that since we are an implementation which takes an
7061 * exception on a trapped conditional instruction only if the
7062 * instruction passes its condition code check, we can take
7063 * advantage of the clause in the ARM ARM that allows us to set
7064 * the COND field in the instruction to 0xE in all cases.
7065 * We could fish the actual condition out of the insn (ARM)
7066 * or the condexec bits (Thumb) but it isn't necessary.
7071 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7074 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7075 rt
, isread
, s
->thumb
);
7080 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7083 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7084 rt
, isread
, s
->thumb
);
7088 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7089 * so this can only happen if this is an ARMv7 or earlier CPU,
7090 * in which case the syndrome information won't actually be
7093 assert(!arm_feature(env
, ARM_FEATURE_V8
));
7094 syndrome
= syn_uncategorized();
7098 gen_set_pc_im(s
, s
->pc
);
7099 tmpptr
= tcg_const_ptr(ri
);
7100 tcg_syn
= tcg_const_i32(syndrome
);
7101 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
);
7102 tcg_temp_free_ptr(tmpptr
);
7103 tcg_temp_free_i32(tcg_syn
);
7106 /* Handle special cases first */
7107 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
7114 gen_set_pc_im(s
, s
->pc
);
7115 s
->is_jmp
= DISAS_WFI
;
7121 if (use_icount
&& (ri
->type
& ARM_CP_IO
)) {
7130 if (ri
->type
& ARM_CP_CONST
) {
7131 tmp64
= tcg_const_i64(ri
->resetvalue
);
7132 } else if (ri
->readfn
) {
7134 tmp64
= tcg_temp_new_i64();
7135 tmpptr
= tcg_const_ptr(ri
);
7136 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
7137 tcg_temp_free_ptr(tmpptr
);
7139 tmp64
= tcg_temp_new_i64();
7140 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7142 tmp
= tcg_temp_new_i32();
7143 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7144 store_reg(s
, rt
, tmp
);
7145 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7146 tmp
= tcg_temp_new_i32();
7147 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7148 tcg_temp_free_i64(tmp64
);
7149 store_reg(s
, rt2
, tmp
);
7152 if (ri
->type
& ARM_CP_CONST
) {
7153 tmp
= tcg_const_i32(ri
->resetvalue
);
7154 } else if (ri
->readfn
) {
7156 tmp
= tcg_temp_new_i32();
7157 tmpptr
= tcg_const_ptr(ri
);
7158 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
7159 tcg_temp_free_ptr(tmpptr
);
7161 tmp
= load_cpu_offset(ri
->fieldoffset
);
7164 /* Destination register of r15 for 32 bit loads sets
7165 * the condition codes from the high 4 bits of the value
7168 tcg_temp_free_i32(tmp
);
7170 store_reg(s
, rt
, tmp
);
7175 if (ri
->type
& ARM_CP_CONST
) {
7176 /* If not forbidden by access permissions, treat as WI */
7181 TCGv_i32 tmplo
, tmphi
;
7182 TCGv_i64 tmp64
= tcg_temp_new_i64();
7183 tmplo
= load_reg(s
, rt
);
7184 tmphi
= load_reg(s
, rt2
);
7185 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
7186 tcg_temp_free_i32(tmplo
);
7187 tcg_temp_free_i32(tmphi
);
7189 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
7190 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
7191 tcg_temp_free_ptr(tmpptr
);
7193 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7195 tcg_temp_free_i64(tmp64
);
7200 tmp
= load_reg(s
, rt
);
7201 tmpptr
= tcg_const_ptr(ri
);
7202 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
7203 tcg_temp_free_ptr(tmpptr
);
7204 tcg_temp_free_i32(tmp
);
7206 TCGv_i32 tmp
= load_reg(s
, rt
);
7207 store_cpu_offset(tmp
, ri
->fieldoffset
);
7212 if (use_icount
&& (ri
->type
& ARM_CP_IO
)) {
7213 /* I/O operations must end the TB here (whether read or write) */
7216 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
7217 /* We default to ending the TB on a coprocessor register write,
7218 * but allow this to be suppressed by the register definition
7219 * (usually only necessary to work around guest bugs).
7227 /* Unknown register; this might be a guest error or a QEMU
7228 * unimplemented feature.
7231 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7232 "64 bit system register cp:%d opc1: %d crm:%d\n",
7233 isread
? "read" : "write", cpnum
, opc1
, crm
);
7235 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7236 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d\n",
7237 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
);
7244 /* Store a 64-bit value to a register pair. Clobbers val. */
7245 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
7248 tmp
= tcg_temp_new_i32();
7249 tcg_gen_trunc_i64_i32(tmp
, val
);
7250 store_reg(s
, rlow
, tmp
);
7251 tmp
= tcg_temp_new_i32();
7252 tcg_gen_shri_i64(val
, val
, 32);
7253 tcg_gen_trunc_i64_i32(tmp
, val
);
7254 store_reg(s
, rhigh
, tmp
);
7257 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7258 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
7263 /* Load value and extend to 64 bits. */
7264 tmp
= tcg_temp_new_i64();
7265 tmp2
= load_reg(s
, rlow
);
7266 tcg_gen_extu_i32_i64(tmp
, tmp2
);
7267 tcg_temp_free_i32(tmp2
);
7268 tcg_gen_add_i64(val
, val
, tmp
);
7269 tcg_temp_free_i64(tmp
);
7272 /* load and add a 64-bit value from a register pair. */
7273 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
7279 /* Load 64-bit value rd:rn. */
7280 tmpl
= load_reg(s
, rlow
);
7281 tmph
= load_reg(s
, rhigh
);
7282 tmp
= tcg_temp_new_i64();
7283 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
7284 tcg_temp_free_i32(tmpl
);
7285 tcg_temp_free_i32(tmph
);
7286 tcg_gen_add_i64(val
, val
, tmp
);
7287 tcg_temp_free_i64(tmp
);
7290 /* Set N and Z flags from hi|lo. */
7291 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
7293 tcg_gen_mov_i32(cpu_NF
, hi
);
7294 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
7297 /* Load/Store exclusive instructions are implemented by remembering
7298 the value/address loaded, and seeing if these are the same
7299 when the store is performed. This should be sufficient to implement
7300 the architecturally mandated semantics, and avoids having to monitor
7303 In system emulation mode only one CPU will be running at once, so
7304 this sequence is effectively atomic. In user emulation mode we
7305 throw an exception and handle the atomic operation elsewhere. */
7306 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
7307 TCGv_i32 addr
, int size
)
7309 TCGv_i32 tmp
= tcg_temp_new_i32();
7315 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
7318 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
7322 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
7329 TCGv_i32 tmp2
= tcg_temp_new_i32();
7330 TCGv_i32 tmp3
= tcg_temp_new_i32();
7332 tcg_gen_addi_i32(tmp2
, addr
, 4);
7333 gen_aa32_ld32u(tmp3
, tmp2
, get_mem_index(s
));
7334 tcg_temp_free_i32(tmp2
);
7335 tcg_gen_concat_i32_i64(cpu_exclusive_val
, tmp
, tmp3
);
7336 store_reg(s
, rt2
, tmp3
);
7338 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
7341 store_reg(s
, rt
, tmp
);
7342 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
7345 static void gen_clrex(DisasContext
*s
)
7347 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7350 #ifdef CONFIG_USER_ONLY
7351 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7352 TCGv_i32 addr
, int size
)
7354 tcg_gen_extu_i32_i64(cpu_exclusive_test
, addr
);
7355 tcg_gen_movi_i32(cpu_exclusive_info
,
7356 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
7357 gen_exception_internal_insn(s
, 4, EXCP_STREX
);
7360 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7361 TCGv_i32 addr
, int size
)
7364 TCGv_i64 val64
, extaddr
;
7368 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7374 fail_label
= gen_new_label();
7375 done_label
= gen_new_label();
7376 extaddr
= tcg_temp_new_i64();
7377 tcg_gen_extu_i32_i64(extaddr
, addr
);
7378 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
7379 tcg_temp_free_i64(extaddr
);
7381 tmp
= tcg_temp_new_i32();
7384 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
7387 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
7391 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
7397 val64
= tcg_temp_new_i64();
7399 TCGv_i32 tmp2
= tcg_temp_new_i32();
7400 TCGv_i32 tmp3
= tcg_temp_new_i32();
7401 tcg_gen_addi_i32(tmp2
, addr
, 4);
7402 gen_aa32_ld32u(tmp3
, tmp2
, get_mem_index(s
));
7403 tcg_temp_free_i32(tmp2
);
7404 tcg_gen_concat_i32_i64(val64
, tmp
, tmp3
);
7405 tcg_temp_free_i32(tmp3
);
7407 tcg_gen_extu_i32_i64(val64
, tmp
);
7409 tcg_temp_free_i32(tmp
);
7411 tcg_gen_brcond_i64(TCG_COND_NE
, val64
, cpu_exclusive_val
, fail_label
);
7412 tcg_temp_free_i64(val64
);
7414 tmp
= load_reg(s
, rt
);
7417 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
7420 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
7424 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7429 tcg_temp_free_i32(tmp
);
7431 tcg_gen_addi_i32(addr
, addr
, 4);
7432 tmp
= load_reg(s
, rt2
);
7433 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7434 tcg_temp_free_i32(tmp
);
7436 tcg_gen_movi_i32(cpu_R
[rd
], 0);
7437 tcg_gen_br(done_label
);
7438 gen_set_label(fail_label
);
7439 tcg_gen_movi_i32(cpu_R
[rd
], 1);
7440 gen_set_label(done_label
);
7441 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7448 * @mode: mode field from insn (which stack to store to)
7449 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7450 * @writeback: true if writeback bit set
7452 * Generate code for the SRS (Store Return State) insn.
7454 static void gen_srs(DisasContext
*s
,
7455 uint32_t mode
, uint32_t amode
, bool writeback
)
7458 TCGv_i32 addr
= tcg_temp_new_i32();
7459 TCGv_i32 tmp
= tcg_const_i32(mode
);
7460 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
7461 tcg_temp_free_i32(tmp
);
7478 tcg_gen_addi_i32(addr
, addr
, offset
);
7479 tmp
= load_reg(s
, 14);
7480 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7481 tcg_temp_free_i32(tmp
);
7482 tmp
= load_cpu_field(spsr
);
7483 tcg_gen_addi_i32(addr
, addr
, 4);
7484 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7485 tcg_temp_free_i32(tmp
);
7503 tcg_gen_addi_i32(addr
, addr
, offset
);
7504 tmp
= tcg_const_i32(mode
);
7505 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
7506 tcg_temp_free_i32(tmp
);
7508 tcg_temp_free_i32(addr
);
7511 static void disas_arm_insn(CPUARMState
* env
, DisasContext
*s
)
7513 unsigned int cond
, insn
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
7520 insn
= arm_ldl_code(env
, s
->pc
, s
->bswap_code
);
7523 /* M variants do not implement ARM mode. */
7528 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7529 * choose to UNDEF. In ARMv5 and above the space is used
7530 * for miscellaneous unconditional instructions.
7534 /* Unconditional instructions. */
7535 if (((insn
>> 25) & 7) == 1) {
7536 /* NEON Data processing. */
7537 if (!arm_feature(env
, ARM_FEATURE_NEON
))
7540 if (disas_neon_data_insn(env
, s
, insn
))
7544 if ((insn
& 0x0f100000) == 0x04000000) {
7545 /* NEON load/store. */
7546 if (!arm_feature(env
, ARM_FEATURE_NEON
))
7549 if (disas_neon_ls_insn(env
, s
, insn
))
7553 if ((insn
& 0x0f000e10) == 0x0e000a00) {
7555 if (disas_vfp_insn(env
, s
, insn
)) {
7560 if (((insn
& 0x0f30f000) == 0x0510f000) ||
7561 ((insn
& 0x0f30f010) == 0x0710f000)) {
7562 if ((insn
& (1 << 22)) == 0) {
7564 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
7568 /* Otherwise PLD; v5TE+ */
7572 if (((insn
& 0x0f70f000) == 0x0450f000) ||
7573 ((insn
& 0x0f70f010) == 0x0650f000)) {
7575 return; /* PLI; V7 */
7577 if (((insn
& 0x0f700000) == 0x04100000) ||
7578 ((insn
& 0x0f700010) == 0x06100000)) {
7579 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
7582 return; /* v7MP: Unallocated memory hint: must NOP */
7585 if ((insn
& 0x0ffffdff) == 0x01010000) {
7588 if (((insn
>> 9) & 1) != s
->bswap_code
) {
7589 /* Dynamic endianness switching not implemented. */
7590 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
7594 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
7595 switch ((insn
>> 4) & 0xf) {
7604 /* We don't emulate caches so these are a no-op. */
7609 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
7615 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
7617 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
7623 rn
= (insn
>> 16) & 0xf;
7624 addr
= load_reg(s
, rn
);
7625 i
= (insn
>> 23) & 3;
7627 case 0: offset
= -4; break; /* DA */
7628 case 1: offset
= 0; break; /* IA */
7629 case 2: offset
= -8; break; /* DB */
7630 case 3: offset
= 4; break; /* IB */
7634 tcg_gen_addi_i32(addr
, addr
, offset
);
7635 /* Load PC into tmp and CPSR into tmp2. */
7636 tmp
= tcg_temp_new_i32();
7637 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
7638 tcg_gen_addi_i32(addr
, addr
, 4);
7639 tmp2
= tcg_temp_new_i32();
7640 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
7641 if (insn
& (1 << 21)) {
7642 /* Base writeback. */
7644 case 0: offset
= -8; break;
7645 case 1: offset
= 4; break;
7646 case 2: offset
= -4; break;
7647 case 3: offset
= 0; break;
7651 tcg_gen_addi_i32(addr
, addr
, offset
);
7652 store_reg(s
, rn
, addr
);
7654 tcg_temp_free_i32(addr
);
7656 gen_rfe(s
, tmp
, tmp2
);
7658 } else if ((insn
& 0x0e000000) == 0x0a000000) {
7659 /* branch link and change to thumb (blx <offset>) */
7662 val
= (uint32_t)s
->pc
;
7663 tmp
= tcg_temp_new_i32();
7664 tcg_gen_movi_i32(tmp
, val
);
7665 store_reg(s
, 14, tmp
);
7666 /* Sign-extend the 24-bit offset */
7667 offset
= (((int32_t)insn
) << 8) >> 8;
7668 /* offset * 4 + bit24 * 2 + (thumb bit) */
7669 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
7670 /* pipeline offset */
7672 /* protected by ARCH(5); above, near the start of uncond block */
7675 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
7676 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
7677 /* iWMMXt register transfer. */
7678 if (env
->cp15
.c15_cpar
& (1 << 1))
7679 if (!disas_iwmmxt_insn(env
, s
, insn
))
7682 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
7683 /* Coprocessor double register transfer. */
7685 } else if ((insn
& 0x0f000010) == 0x0e000010) {
7686 /* Additional coprocessor register transfer. */
7687 } else if ((insn
& 0x0ff10020) == 0x01000000) {
7690 /* cps (privileged) */
7694 if (insn
& (1 << 19)) {
7695 if (insn
& (1 << 8))
7697 if (insn
& (1 << 7))
7699 if (insn
& (1 << 6))
7701 if (insn
& (1 << 18))
7704 if (insn
& (1 << 17)) {
7706 val
|= (insn
& 0x1f);
7709 gen_set_psr_im(s
, mask
, 0, val
);
7716 /* if not always execute, we generate a conditional jump to
7718 s
->condlabel
= gen_new_label();
7719 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
7722 if ((insn
& 0x0f900000) == 0x03000000) {
7723 if ((insn
& (1 << 21)) == 0) {
7725 rd
= (insn
>> 12) & 0xf;
7726 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
7727 if ((insn
& (1 << 22)) == 0) {
7729 tmp
= tcg_temp_new_i32();
7730 tcg_gen_movi_i32(tmp
, val
);
7733 tmp
= load_reg(s
, rd
);
7734 tcg_gen_ext16u_i32(tmp
, tmp
);
7735 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
7737 store_reg(s
, rd
, tmp
);
7739 if (((insn
>> 12) & 0xf) != 0xf)
7741 if (((insn
>> 16) & 0xf) == 0) {
7742 gen_nop_hint(s
, insn
& 0xff);
7744 /* CPSR = immediate */
7746 shift
= ((insn
>> 8) & 0xf) * 2;
7748 val
= (val
>> shift
) | (val
<< (32 - shift
));
7749 i
= ((insn
& (1 << 22)) != 0);
7750 if (gen_set_psr_im(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, val
))
7754 } else if ((insn
& 0x0f900000) == 0x01000000
7755 && (insn
& 0x00000090) != 0x00000090) {
7756 /* miscellaneous instructions */
7757 op1
= (insn
>> 21) & 3;
7758 sh
= (insn
>> 4) & 0xf;
7761 case 0x0: /* move program status register */
7764 tmp
= load_reg(s
, rm
);
7765 i
= ((op1
& 2) != 0);
7766 if (gen_set_psr(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
7770 rd
= (insn
>> 12) & 0xf;
7774 tmp
= load_cpu_field(spsr
);
7776 tmp
= tcg_temp_new_i32();
7777 gen_helper_cpsr_read(tmp
, cpu_env
);
7779 store_reg(s
, rd
, tmp
);
7784 /* branch/exchange thumb (bx). */
7786 tmp
= load_reg(s
, rm
);
7788 } else if (op1
== 3) {
7791 rd
= (insn
>> 12) & 0xf;
7792 tmp
= load_reg(s
, rm
);
7793 gen_helper_clz(tmp
, tmp
);
7794 store_reg(s
, rd
, tmp
);
7802 /* Trivial implementation equivalent to bx. */
7803 tmp
= load_reg(s
, rm
);
7814 /* branch link/exchange thumb (blx) */
7815 tmp
= load_reg(s
, rm
);
7816 tmp2
= tcg_temp_new_i32();
7817 tcg_gen_movi_i32(tmp2
, s
->pc
);
7818 store_reg(s
, 14, tmp2
);
7824 uint32_t c
= extract32(insn
, 8, 4);
7826 /* Check this CPU supports ARMv8 CRC instructions.
7827 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
7828 * Bits 8, 10 and 11 should be zero.
7830 if (!arm_feature(env
, ARM_FEATURE_CRC
) || op1
== 0x3 ||
7835 rn
= extract32(insn
, 16, 4);
7836 rd
= extract32(insn
, 12, 4);
7838 tmp
= load_reg(s
, rn
);
7839 tmp2
= load_reg(s
, rm
);
7841 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
7842 } else if (op1
== 1) {
7843 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
7845 tmp3
= tcg_const_i32(1 << op1
);
7847 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
7849 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
7851 tcg_temp_free_i32(tmp2
);
7852 tcg_temp_free_i32(tmp3
);
7853 store_reg(s
, rd
, tmp
);
7856 case 0x5: /* saturating add/subtract */
7858 rd
= (insn
>> 12) & 0xf;
7859 rn
= (insn
>> 16) & 0xf;
7860 tmp
= load_reg(s
, rm
);
7861 tmp2
= load_reg(s
, rn
);
7863 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
7865 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
7867 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
7868 tcg_temp_free_i32(tmp2
);
7869 store_reg(s
, rd
, tmp
);
7873 int imm16
= extract32(insn
, 0, 4) | (extract32(insn
, 8, 12) << 4);
7874 /* SMC instruction (op1 == 3)
7875 and undefined instructions (op1 == 0 || op1 == 2)
7882 gen_exception_insn(s
, 4, EXCP_BKPT
, syn_aa32_bkpt(imm16
, false));
7885 case 0x8: /* signed multiply */
7890 rs
= (insn
>> 8) & 0xf;
7891 rn
= (insn
>> 12) & 0xf;
7892 rd
= (insn
>> 16) & 0xf;
7894 /* (32 * 16) >> 16 */
7895 tmp
= load_reg(s
, rm
);
7896 tmp2
= load_reg(s
, rs
);
7898 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
7901 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7902 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
7903 tmp
= tcg_temp_new_i32();
7904 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7905 tcg_temp_free_i64(tmp64
);
7906 if ((sh
& 2) == 0) {
7907 tmp2
= load_reg(s
, rn
);
7908 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7909 tcg_temp_free_i32(tmp2
);
7911 store_reg(s
, rd
, tmp
);
7914 tmp
= load_reg(s
, rm
);
7915 tmp2
= load_reg(s
, rs
);
7916 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
7917 tcg_temp_free_i32(tmp2
);
7919 tmp64
= tcg_temp_new_i64();
7920 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7921 tcg_temp_free_i32(tmp
);
7922 gen_addq(s
, tmp64
, rn
, rd
);
7923 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7924 tcg_temp_free_i64(tmp64
);
7927 tmp2
= load_reg(s
, rn
);
7928 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7929 tcg_temp_free_i32(tmp2
);
7931 store_reg(s
, rd
, tmp
);
7938 } else if (((insn
& 0x0e000000) == 0 &&
7939 (insn
& 0x00000090) != 0x90) ||
7940 ((insn
& 0x0e000000) == (1 << 25))) {
7941 int set_cc
, logic_cc
, shiftop
;
7943 op1
= (insn
>> 21) & 0xf;
7944 set_cc
= (insn
>> 20) & 1;
7945 logic_cc
= table_logic_cc
[op1
] & set_cc
;
7947 /* data processing instruction */
7948 if (insn
& (1 << 25)) {
7949 /* immediate operand */
7951 shift
= ((insn
>> 8) & 0xf) * 2;
7953 val
= (val
>> shift
) | (val
<< (32 - shift
));
7955 tmp2
= tcg_temp_new_i32();
7956 tcg_gen_movi_i32(tmp2
, val
);
7957 if (logic_cc
&& shift
) {
7958 gen_set_CF_bit31(tmp2
);
7963 tmp2
= load_reg(s
, rm
);
7964 shiftop
= (insn
>> 5) & 3;
7965 if (!(insn
& (1 << 4))) {
7966 shift
= (insn
>> 7) & 0x1f;
7967 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
7969 rs
= (insn
>> 8) & 0xf;
7970 tmp
= load_reg(s
, rs
);
7971 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
7974 if (op1
!= 0x0f && op1
!= 0x0d) {
7975 rn
= (insn
>> 16) & 0xf;
7976 tmp
= load_reg(s
, rn
);
7978 TCGV_UNUSED_I32(tmp
);
7980 rd
= (insn
>> 12) & 0xf;
7983 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
7987 store_reg_bx(env
, s
, rd
, tmp
);
7990 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
7994 store_reg_bx(env
, s
, rd
, tmp
);
7997 if (set_cc
&& rd
== 15) {
7998 /* SUBS r15, ... is used for exception return. */
8002 gen_sub_CC(tmp
, tmp
, tmp2
);
8003 gen_exception_return(s
, tmp
);
8006 gen_sub_CC(tmp
, tmp
, tmp2
);
8008 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8010 store_reg_bx(env
, s
, rd
, tmp
);
8015 gen_sub_CC(tmp
, tmp2
, tmp
);
8017 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8019 store_reg_bx(env
, s
, rd
, tmp
);
8023 gen_add_CC(tmp
, tmp
, tmp2
);
8025 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8027 store_reg_bx(env
, s
, rd
, tmp
);
8031 gen_adc_CC(tmp
, tmp
, tmp2
);
8033 gen_add_carry(tmp
, tmp
, tmp2
);
8035 store_reg_bx(env
, s
, rd
, tmp
);
8039 gen_sbc_CC(tmp
, tmp
, tmp2
);
8041 gen_sub_carry(tmp
, tmp
, tmp2
);
8043 store_reg_bx(env
, s
, rd
, tmp
);
8047 gen_sbc_CC(tmp
, tmp2
, tmp
);
8049 gen_sub_carry(tmp
, tmp2
, tmp
);
8051 store_reg_bx(env
, s
, rd
, tmp
);
8055 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8058 tcg_temp_free_i32(tmp
);
8062 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8065 tcg_temp_free_i32(tmp
);
8069 gen_sub_CC(tmp
, tmp
, tmp2
);
8071 tcg_temp_free_i32(tmp
);
8075 gen_add_CC(tmp
, tmp
, tmp2
);
8077 tcg_temp_free_i32(tmp
);
8080 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8084 store_reg_bx(env
, s
, rd
, tmp
);
8087 if (logic_cc
&& rd
== 15) {
8088 /* MOVS r15, ... is used for exception return. */
8092 gen_exception_return(s
, tmp2
);
8097 store_reg_bx(env
, s
, rd
, tmp2
);
8101 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
8105 store_reg_bx(env
, s
, rd
, tmp
);
8109 tcg_gen_not_i32(tmp2
, tmp2
);
8113 store_reg_bx(env
, s
, rd
, tmp2
);
8116 if (op1
!= 0x0f && op1
!= 0x0d) {
8117 tcg_temp_free_i32(tmp2
);
8120 /* other instructions */
8121 op1
= (insn
>> 24) & 0xf;
8125 /* multiplies, extra load/stores */
8126 sh
= (insn
>> 5) & 3;
8129 rd
= (insn
>> 16) & 0xf;
8130 rn
= (insn
>> 12) & 0xf;
8131 rs
= (insn
>> 8) & 0xf;
8133 op1
= (insn
>> 20) & 0xf;
8135 case 0: case 1: case 2: case 3: case 6:
8137 tmp
= load_reg(s
, rs
);
8138 tmp2
= load_reg(s
, rm
);
8139 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8140 tcg_temp_free_i32(tmp2
);
8141 if (insn
& (1 << 22)) {
8142 /* Subtract (mls) */
8144 tmp2
= load_reg(s
, rn
);
8145 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8146 tcg_temp_free_i32(tmp2
);
8147 } else if (insn
& (1 << 21)) {
8149 tmp2
= load_reg(s
, rn
);
8150 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8151 tcg_temp_free_i32(tmp2
);
8153 if (insn
& (1 << 20))
8155 store_reg(s
, rd
, tmp
);
8158 /* 64 bit mul double accumulate (UMAAL) */
8160 tmp
= load_reg(s
, rs
);
8161 tmp2
= load_reg(s
, rm
);
8162 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8163 gen_addq_lo(s
, tmp64
, rn
);
8164 gen_addq_lo(s
, tmp64
, rd
);
8165 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8166 tcg_temp_free_i64(tmp64
);
8168 case 8: case 9: case 10: case 11:
8169 case 12: case 13: case 14: case 15:
8170 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8171 tmp
= load_reg(s
, rs
);
8172 tmp2
= load_reg(s
, rm
);
8173 if (insn
& (1 << 22)) {
8174 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
8176 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
8178 if (insn
& (1 << 21)) { /* mult accumulate */
8179 TCGv_i32 al
= load_reg(s
, rn
);
8180 TCGv_i32 ah
= load_reg(s
, rd
);
8181 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
8182 tcg_temp_free_i32(al
);
8183 tcg_temp_free_i32(ah
);
8185 if (insn
& (1 << 20)) {
8186 gen_logicq_cc(tmp
, tmp2
);
8188 store_reg(s
, rn
, tmp
);
8189 store_reg(s
, rd
, tmp2
);
8195 rn
= (insn
>> 16) & 0xf;
8196 rd
= (insn
>> 12) & 0xf;
8197 if (insn
& (1 << 23)) {
8198 /* load/store exclusive */
8199 int op2
= (insn
>> 8) & 3;
8200 op1
= (insn
>> 21) & 0x3;
8203 case 0: /* lda/stl */
8209 case 1: /* reserved */
8211 case 2: /* ldaex/stlex */
8214 case 3: /* ldrex/strex */
8223 addr
= tcg_temp_local_new_i32();
8224 load_reg_var(s
, addr
, rn
);
8226 /* Since the emulation does not have barriers,
8227 the acquire/release semantics need no special
8230 if (insn
& (1 << 20)) {
8231 tmp
= tcg_temp_new_i32();
8234 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8237 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
8240 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
8245 store_reg(s
, rd
, tmp
);
8248 tmp
= load_reg(s
, rm
);
8251 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8254 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
8257 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
8262 tcg_temp_free_i32(tmp
);
8264 } else if (insn
& (1 << 20)) {
8267 gen_load_exclusive(s
, rd
, 15, addr
, 2);
8269 case 1: /* ldrexd */
8270 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
8272 case 2: /* ldrexb */
8273 gen_load_exclusive(s
, rd
, 15, addr
, 0);
8275 case 3: /* ldrexh */
8276 gen_load_exclusive(s
, rd
, 15, addr
, 1);
8285 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
8287 case 1: /* strexd */
8288 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
8290 case 2: /* strexb */
8291 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
8293 case 3: /* strexh */
8294 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
8300 tcg_temp_free_i32(addr
);
8302 /* SWP instruction */
8305 /* ??? This is not really atomic. However we know
8306 we never have multiple CPUs running in parallel,
8307 so it is good enough. */
8308 addr
= load_reg(s
, rn
);
8309 tmp
= load_reg(s
, rm
);
8310 tmp2
= tcg_temp_new_i32();
8311 if (insn
& (1 << 22)) {
8312 gen_aa32_ld8u(tmp2
, addr
, get_mem_index(s
));
8313 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
8315 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
8316 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8318 tcg_temp_free_i32(tmp
);
8319 tcg_temp_free_i32(addr
);
8320 store_reg(s
, rd
, tmp2
);
8326 /* Misc load/store */
8327 rn
= (insn
>> 16) & 0xf;
8328 rd
= (insn
>> 12) & 0xf;
8329 addr
= load_reg(s
, rn
);
8330 if (insn
& (1 << 24))
8331 gen_add_datah_offset(s
, insn
, 0, addr
);
8333 if (insn
& (1 << 20)) {
8335 tmp
= tcg_temp_new_i32();
8338 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
8341 gen_aa32_ld8s(tmp
, addr
, get_mem_index(s
));
8345 gen_aa32_ld16s(tmp
, addr
, get_mem_index(s
));
8349 } else if (sh
& 2) {
8354 tmp
= load_reg(s
, rd
);
8355 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8356 tcg_temp_free_i32(tmp
);
8357 tcg_gen_addi_i32(addr
, addr
, 4);
8358 tmp
= load_reg(s
, rd
+ 1);
8359 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8360 tcg_temp_free_i32(tmp
);
8364 tmp
= tcg_temp_new_i32();
8365 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8366 store_reg(s
, rd
, tmp
);
8367 tcg_gen_addi_i32(addr
, addr
, 4);
8368 tmp
= tcg_temp_new_i32();
8369 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8373 address_offset
= -4;
8376 tmp
= load_reg(s
, rd
);
8377 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
8378 tcg_temp_free_i32(tmp
);
8381 /* Perform base writeback before the loaded value to
8382 ensure correct behavior with overlapping index registers.
8383 ldrd with base writeback is is undefined if the
8384 destination and index registers overlap. */
8385 if (!(insn
& (1 << 24))) {
8386 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
8387 store_reg(s
, rn
, addr
);
8388 } else if (insn
& (1 << 21)) {
8390 tcg_gen_addi_i32(addr
, addr
, address_offset
);
8391 store_reg(s
, rn
, addr
);
8393 tcg_temp_free_i32(addr
);
8396 /* Complete the load. */
8397 store_reg(s
, rd
, tmp
);
8406 if (insn
& (1 << 4)) {
8408 /* Armv6 Media instructions. */
8410 rn
= (insn
>> 16) & 0xf;
8411 rd
= (insn
>> 12) & 0xf;
8412 rs
= (insn
>> 8) & 0xf;
8413 switch ((insn
>> 23) & 3) {
8414 case 0: /* Parallel add/subtract. */
8415 op1
= (insn
>> 20) & 7;
8416 tmp
= load_reg(s
, rn
);
8417 tmp2
= load_reg(s
, rm
);
8418 sh
= (insn
>> 5) & 7;
8419 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
8421 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
8422 tcg_temp_free_i32(tmp2
);
8423 store_reg(s
, rd
, tmp
);
8426 if ((insn
& 0x00700020) == 0) {
8427 /* Halfword pack. */
8428 tmp
= load_reg(s
, rn
);
8429 tmp2
= load_reg(s
, rm
);
8430 shift
= (insn
>> 7) & 0x1f;
8431 if (insn
& (1 << 6)) {
8435 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8436 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8437 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8441 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8442 tcg_gen_ext16u_i32(tmp
, tmp
);
8443 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8445 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8446 tcg_temp_free_i32(tmp2
);
8447 store_reg(s
, rd
, tmp
);
8448 } else if ((insn
& 0x00200020) == 0x00200000) {
8450 tmp
= load_reg(s
, rm
);
8451 shift
= (insn
>> 7) & 0x1f;
8452 if (insn
& (1 << 6)) {
8455 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8457 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8459 sh
= (insn
>> 16) & 0x1f;
8460 tmp2
= tcg_const_i32(sh
);
8461 if (insn
& (1 << 22))
8462 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
8464 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
8465 tcg_temp_free_i32(tmp2
);
8466 store_reg(s
, rd
, tmp
);
8467 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
8469 tmp
= load_reg(s
, rm
);
8470 sh
= (insn
>> 16) & 0x1f;
8471 tmp2
= tcg_const_i32(sh
);
8472 if (insn
& (1 << 22))
8473 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
8475 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
8476 tcg_temp_free_i32(tmp2
);
8477 store_reg(s
, rd
, tmp
);
8478 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
8480 tmp
= load_reg(s
, rn
);
8481 tmp2
= load_reg(s
, rm
);
8482 tmp3
= tcg_temp_new_i32();
8483 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
8484 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
8485 tcg_temp_free_i32(tmp3
);
8486 tcg_temp_free_i32(tmp2
);
8487 store_reg(s
, rd
, tmp
);
8488 } else if ((insn
& 0x000003e0) == 0x00000060) {
8489 tmp
= load_reg(s
, rm
);
8490 shift
= (insn
>> 10) & 3;
8491 /* ??? In many cases it's not necessary to do a
8492 rotate, a shift is sufficient. */
8494 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
8495 op1
= (insn
>> 20) & 7;
8497 case 0: gen_sxtb16(tmp
); break;
8498 case 2: gen_sxtb(tmp
); break;
8499 case 3: gen_sxth(tmp
); break;
8500 case 4: gen_uxtb16(tmp
); break;
8501 case 6: gen_uxtb(tmp
); break;
8502 case 7: gen_uxth(tmp
); break;
8503 default: goto illegal_op
;
8506 tmp2
= load_reg(s
, rn
);
8507 if ((op1
& 3) == 0) {
8508 gen_add16(tmp
, tmp2
);
8510 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8511 tcg_temp_free_i32(tmp2
);
8514 store_reg(s
, rd
, tmp
);
8515 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
8517 tmp
= load_reg(s
, rm
);
8518 if (insn
& (1 << 22)) {
8519 if (insn
& (1 << 7)) {
8523 gen_helper_rbit(tmp
, tmp
);
8526 if (insn
& (1 << 7))
8529 tcg_gen_bswap32_i32(tmp
, tmp
);
8531 store_reg(s
, rd
, tmp
);
8536 case 2: /* Multiplies (Type 3). */
8537 switch ((insn
>> 20) & 0x7) {
8539 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
8540 /* op2 not 00x or 11x : UNDEF */
8543 /* Signed multiply most significant [accumulate].
8544 (SMMUL, SMMLA, SMMLS) */
8545 tmp
= load_reg(s
, rm
);
8546 tmp2
= load_reg(s
, rs
);
8547 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8550 tmp
= load_reg(s
, rd
);
8551 if (insn
& (1 << 6)) {
8552 tmp64
= gen_subq_msw(tmp64
, tmp
);
8554 tmp64
= gen_addq_msw(tmp64
, tmp
);
8557 if (insn
& (1 << 5)) {
8558 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
8560 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
8561 tmp
= tcg_temp_new_i32();
8562 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8563 tcg_temp_free_i64(tmp64
);
8564 store_reg(s
, rn
, tmp
);
8568 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8569 if (insn
& (1 << 7)) {
8572 tmp
= load_reg(s
, rm
);
8573 tmp2
= load_reg(s
, rs
);
8574 if (insn
& (1 << 5))
8575 gen_swap_half(tmp2
);
8576 gen_smul_dual(tmp
, tmp2
);
8577 if (insn
& (1 << 22)) {
8578 /* smlald, smlsld */
8581 tmp64
= tcg_temp_new_i64();
8582 tmp64_2
= tcg_temp_new_i64();
8583 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8584 tcg_gen_ext_i32_i64(tmp64_2
, tmp2
);
8585 tcg_temp_free_i32(tmp
);
8586 tcg_temp_free_i32(tmp2
);
8587 if (insn
& (1 << 6)) {
8588 tcg_gen_sub_i64(tmp64
, tmp64
, tmp64_2
);
8590 tcg_gen_add_i64(tmp64
, tmp64
, tmp64_2
);
8592 tcg_temp_free_i64(tmp64_2
);
8593 gen_addq(s
, tmp64
, rd
, rn
);
8594 gen_storeq_reg(s
, rd
, rn
, tmp64
);
8595 tcg_temp_free_i64(tmp64
);
8597 /* smuad, smusd, smlad, smlsd */
8598 if (insn
& (1 << 6)) {
8599 /* This subtraction cannot overflow. */
8600 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8602 /* This addition cannot overflow 32 bits;
8603 * however it may overflow considered as a
8604 * signed operation, in which case we must set
8607 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8609 tcg_temp_free_i32(tmp2
);
8612 tmp2
= load_reg(s
, rd
);
8613 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8614 tcg_temp_free_i32(tmp2
);
8616 store_reg(s
, rn
, tmp
);
8622 if (!arm_feature(env
, ARM_FEATURE_ARM_DIV
)) {
8625 if (((insn
>> 5) & 7) || (rd
!= 15)) {
8628 tmp
= load_reg(s
, rm
);
8629 tmp2
= load_reg(s
, rs
);
8630 if (insn
& (1 << 21)) {
8631 gen_helper_udiv(tmp
, tmp
, tmp2
);
8633 gen_helper_sdiv(tmp
, tmp
, tmp2
);
8635 tcg_temp_free_i32(tmp2
);
8636 store_reg(s
, rn
, tmp
);
8643 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
8645 case 0: /* Unsigned sum of absolute differences. */
8647 tmp
= load_reg(s
, rm
);
8648 tmp2
= load_reg(s
, rs
);
8649 gen_helper_usad8(tmp
, tmp
, tmp2
);
8650 tcg_temp_free_i32(tmp2
);
8652 tmp2
= load_reg(s
, rd
);
8653 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8654 tcg_temp_free_i32(tmp2
);
8656 store_reg(s
, rn
, tmp
);
8658 case 0x20: case 0x24: case 0x28: case 0x2c:
8659 /* Bitfield insert/clear. */
8661 shift
= (insn
>> 7) & 0x1f;
8662 i
= (insn
>> 16) & 0x1f;
8665 tmp
= tcg_temp_new_i32();
8666 tcg_gen_movi_i32(tmp
, 0);
8668 tmp
= load_reg(s
, rm
);
8671 tmp2
= load_reg(s
, rd
);
8672 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
8673 tcg_temp_free_i32(tmp2
);
8675 store_reg(s
, rd
, tmp
);
8677 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8678 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8680 tmp
= load_reg(s
, rm
);
8681 shift
= (insn
>> 7) & 0x1f;
8682 i
= ((insn
>> 16) & 0x1f) + 1;
8687 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
8689 gen_sbfx(tmp
, shift
, i
);
8692 store_reg(s
, rd
, tmp
);
8702 /* Check for undefined extension instructions
8703 * per the ARM Bible IE:
8704 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8706 sh
= (0xf << 20) | (0xf << 4);
8707 if (op1
== 0x7 && ((insn
& sh
) == sh
))
8711 /* load/store byte/word */
8712 rn
= (insn
>> 16) & 0xf;
8713 rd
= (insn
>> 12) & 0xf;
8714 tmp2
= load_reg(s
, rn
);
8715 if ((insn
& 0x01200000) == 0x00200000) {
8719 i
= get_mem_index(s
);
8721 if (insn
& (1 << 24))
8722 gen_add_data_offset(s
, insn
, tmp2
);
8723 if (insn
& (1 << 20)) {
8725 tmp
= tcg_temp_new_i32();
8726 if (insn
& (1 << 22)) {
8727 gen_aa32_ld8u(tmp
, tmp2
, i
);
8729 gen_aa32_ld32u(tmp
, tmp2
, i
);
8733 tmp
= load_reg(s
, rd
);
8734 if (insn
& (1 << 22)) {
8735 gen_aa32_st8(tmp
, tmp2
, i
);
8737 gen_aa32_st32(tmp
, tmp2
, i
);
8739 tcg_temp_free_i32(tmp
);
8741 if (!(insn
& (1 << 24))) {
8742 gen_add_data_offset(s
, insn
, tmp2
);
8743 store_reg(s
, rn
, tmp2
);
8744 } else if (insn
& (1 << 21)) {
8745 store_reg(s
, rn
, tmp2
);
8747 tcg_temp_free_i32(tmp2
);
8749 if (insn
& (1 << 20)) {
8750 /* Complete the load. */
8751 store_reg_from_load(env
, s
, rd
, tmp
);
8757 int j
, n
, user
, loaded_base
;
8758 TCGv_i32 loaded_var
;
8759 /* load/store multiple words */
8760 /* XXX: store correct base if write back */
8762 if (insn
& (1 << 22)) {
8764 goto illegal_op
; /* only usable in supervisor mode */
8766 if ((insn
& (1 << 15)) == 0)
8769 rn
= (insn
>> 16) & 0xf;
8770 addr
= load_reg(s
, rn
);
8772 /* compute total size */
8774 TCGV_UNUSED_I32(loaded_var
);
8777 if (insn
& (1 << i
))
8780 /* XXX: test invalid n == 0 case ? */
8781 if (insn
& (1 << 23)) {
8782 if (insn
& (1 << 24)) {
8784 tcg_gen_addi_i32(addr
, addr
, 4);
8786 /* post increment */
8789 if (insn
& (1 << 24)) {
8791 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
8793 /* post decrement */
8795 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
8800 if (insn
& (1 << i
)) {
8801 if (insn
& (1 << 20)) {
8803 tmp
= tcg_temp_new_i32();
8804 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8806 tmp2
= tcg_const_i32(i
);
8807 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
8808 tcg_temp_free_i32(tmp2
);
8809 tcg_temp_free_i32(tmp
);
8810 } else if (i
== rn
) {
8814 store_reg_from_load(env
, s
, i
, tmp
);
8819 /* special case: r15 = PC + 8 */
8820 val
= (long)s
->pc
+ 4;
8821 tmp
= tcg_temp_new_i32();
8822 tcg_gen_movi_i32(tmp
, val
);
8824 tmp
= tcg_temp_new_i32();
8825 tmp2
= tcg_const_i32(i
);
8826 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
8827 tcg_temp_free_i32(tmp2
);
8829 tmp
= load_reg(s
, i
);
8831 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8832 tcg_temp_free_i32(tmp
);
8835 /* no need to add after the last transfer */
8837 tcg_gen_addi_i32(addr
, addr
, 4);
8840 if (insn
& (1 << 21)) {
8842 if (insn
& (1 << 23)) {
8843 if (insn
& (1 << 24)) {
8846 /* post increment */
8847 tcg_gen_addi_i32(addr
, addr
, 4);
8850 if (insn
& (1 << 24)) {
8853 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
8855 /* post decrement */
8856 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
8859 store_reg(s
, rn
, addr
);
8861 tcg_temp_free_i32(addr
);
8864 store_reg(s
, rn
, loaded_var
);
8866 if ((insn
& (1 << 22)) && !user
) {
8867 /* Restore CPSR from SPSR. */
8868 tmp
= load_cpu_field(spsr
);
8869 gen_set_cpsr(tmp
, CPSR_ERET_MASK
);
8870 tcg_temp_free_i32(tmp
);
8871 s
->is_jmp
= DISAS_UPDATE
;
8880 /* branch (and link) */
8881 val
= (int32_t)s
->pc
;
8882 if (insn
& (1 << 24)) {
8883 tmp
= tcg_temp_new_i32();
8884 tcg_gen_movi_i32(tmp
, val
);
8885 store_reg(s
, 14, tmp
);
8887 offset
= sextract32(insn
<< 2, 0, 26);
8895 if (((insn
>> 8) & 0xe) == 10) {
8897 if (disas_vfp_insn(env
, s
, insn
)) {
8900 } else if (disas_coproc_insn(env
, s
, insn
)) {
8907 gen_set_pc_im(s
, s
->pc
);
8908 s
->svc_imm
= extract32(insn
, 0, 24);
8909 s
->is_jmp
= DISAS_SWI
;
8913 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized());
8919 /* Return true if this is a Thumb-2 logical op. */
8921 thumb2_logic_op(int op
)
8926 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
8927 then set condition code flags based on the result of the operation.
8928 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8929 to the high bit of T1.
8930 Returns zero if the opcode is valid. */
8933 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
8934 TCGv_i32 t0
, TCGv_i32 t1
)
8941 tcg_gen_and_i32(t0
, t0
, t1
);
8945 tcg_gen_andc_i32(t0
, t0
, t1
);
8949 tcg_gen_or_i32(t0
, t0
, t1
);
8953 tcg_gen_orc_i32(t0
, t0
, t1
);
8957 tcg_gen_xor_i32(t0
, t0
, t1
);
8962 gen_add_CC(t0
, t0
, t1
);
8964 tcg_gen_add_i32(t0
, t0
, t1
);
8968 gen_adc_CC(t0
, t0
, t1
);
8974 gen_sbc_CC(t0
, t0
, t1
);
8976 gen_sub_carry(t0
, t0
, t1
);
8981 gen_sub_CC(t0
, t0
, t1
);
8983 tcg_gen_sub_i32(t0
, t0
, t1
);
8987 gen_sub_CC(t0
, t1
, t0
);
8989 tcg_gen_sub_i32(t0
, t1
, t0
);
8991 default: /* 5, 6, 7, 9, 12, 15. */
8997 gen_set_CF_bit31(t1
);
9002 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
9004 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
9006 uint32_t insn
, imm
, shift
, offset
;
9007 uint32_t rd
, rn
, rm
, rs
;
9018 if (!(arm_feature(env
, ARM_FEATURE_THUMB2
)
9019 || arm_feature (env
, ARM_FEATURE_M
))) {
9020 /* Thumb-1 cores may need to treat bl and blx as a pair of
9021 16-bit instructions to get correct prefetch abort behavior. */
9023 if ((insn
& (1 << 12)) == 0) {
9025 /* Second half of blx. */
9026 offset
= ((insn
& 0x7ff) << 1);
9027 tmp
= load_reg(s
, 14);
9028 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9029 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
9031 tmp2
= tcg_temp_new_i32();
9032 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9033 store_reg(s
, 14, tmp2
);
9037 if (insn
& (1 << 11)) {
9038 /* Second half of bl. */
9039 offset
= ((insn
& 0x7ff) << 1) | 1;
9040 tmp
= load_reg(s
, 14);
9041 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9043 tmp2
= tcg_temp_new_i32();
9044 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9045 store_reg(s
, 14, tmp2
);
9049 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
9050 /* Instruction spans a page boundary. Implement it as two
9051 16-bit instructions in case the second half causes an
9053 offset
= ((int32_t)insn
<< 21) >> 9;
9054 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
9057 /* Fall through to 32-bit decode. */
9060 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
9062 insn
|= (uint32_t)insn_hw1
<< 16;
9064 if ((insn
& 0xf800e800) != 0xf000e800) {
9068 rn
= (insn
>> 16) & 0xf;
9069 rs
= (insn
>> 12) & 0xf;
9070 rd
= (insn
>> 8) & 0xf;
9072 switch ((insn
>> 25) & 0xf) {
9073 case 0: case 1: case 2: case 3:
9074 /* 16-bit instructions. Should never happen. */
9077 if (insn
& (1 << 22)) {
9078 /* Other load/store, table branch. */
9079 if (insn
& 0x01200000) {
9080 /* Load/store doubleword. */
9082 addr
= tcg_temp_new_i32();
9083 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
9085 addr
= load_reg(s
, rn
);
9087 offset
= (insn
& 0xff) * 4;
9088 if ((insn
& (1 << 23)) == 0)
9090 if (insn
& (1 << 24)) {
9091 tcg_gen_addi_i32(addr
, addr
, offset
);
9094 if (insn
& (1 << 20)) {
9096 tmp
= tcg_temp_new_i32();
9097 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9098 store_reg(s
, rs
, tmp
);
9099 tcg_gen_addi_i32(addr
, addr
, 4);
9100 tmp
= tcg_temp_new_i32();
9101 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9102 store_reg(s
, rd
, tmp
);
9105 tmp
= load_reg(s
, rs
);
9106 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9107 tcg_temp_free_i32(tmp
);
9108 tcg_gen_addi_i32(addr
, addr
, 4);
9109 tmp
= load_reg(s
, rd
);
9110 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9111 tcg_temp_free_i32(tmp
);
9113 if (insn
& (1 << 21)) {
9114 /* Base writeback. */
9117 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
9118 store_reg(s
, rn
, addr
);
9120 tcg_temp_free_i32(addr
);
9122 } else if ((insn
& (1 << 23)) == 0) {
9123 /* Load/store exclusive word. */
9124 addr
= tcg_temp_local_new_i32();
9125 load_reg_var(s
, addr
, rn
);
9126 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
9127 if (insn
& (1 << 20)) {
9128 gen_load_exclusive(s
, rs
, 15, addr
, 2);
9130 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
9132 tcg_temp_free_i32(addr
);
9133 } else if ((insn
& (7 << 5)) == 0) {
9136 addr
= tcg_temp_new_i32();
9137 tcg_gen_movi_i32(addr
, s
->pc
);
9139 addr
= load_reg(s
, rn
);
9141 tmp
= load_reg(s
, rm
);
9142 tcg_gen_add_i32(addr
, addr
, tmp
);
9143 if (insn
& (1 << 4)) {
9145 tcg_gen_add_i32(addr
, addr
, tmp
);
9146 tcg_temp_free_i32(tmp
);
9147 tmp
= tcg_temp_new_i32();
9148 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
9150 tcg_temp_free_i32(tmp
);
9151 tmp
= tcg_temp_new_i32();
9152 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
9154 tcg_temp_free_i32(addr
);
9155 tcg_gen_shli_i32(tmp
, tmp
, 1);
9156 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
9157 store_reg(s
, 15, tmp
);
9159 int op2
= (insn
>> 6) & 0x3;
9160 op
= (insn
>> 4) & 0x3;
9165 /* Load/store exclusive byte/halfword/doubleword */
9172 /* Load-acquire/store-release */
9178 /* Load-acquire/store-release exclusive */
9182 addr
= tcg_temp_local_new_i32();
9183 load_reg_var(s
, addr
, rn
);
9185 if (insn
& (1 << 20)) {
9186 tmp
= tcg_temp_new_i32();
9189 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
9192 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
9195 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9200 store_reg(s
, rs
, tmp
);
9202 tmp
= load_reg(s
, rs
);
9205 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
9208 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
9211 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9216 tcg_temp_free_i32(tmp
);
9218 } else if (insn
& (1 << 20)) {
9219 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
9221 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
9223 tcg_temp_free_i32(addr
);
9226 /* Load/store multiple, RFE, SRS. */
9227 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
9228 /* RFE, SRS: not available in user mode or on M profile */
9229 if (IS_USER(s
) || IS_M(env
)) {
9232 if (insn
& (1 << 20)) {
9234 addr
= load_reg(s
, rn
);
9235 if ((insn
& (1 << 24)) == 0)
9236 tcg_gen_addi_i32(addr
, addr
, -8);
9237 /* Load PC into tmp and CPSR into tmp2. */
9238 tmp
= tcg_temp_new_i32();
9239 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9240 tcg_gen_addi_i32(addr
, addr
, 4);
9241 tmp2
= tcg_temp_new_i32();
9242 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
9243 if (insn
& (1 << 21)) {
9244 /* Base writeback. */
9245 if (insn
& (1 << 24)) {
9246 tcg_gen_addi_i32(addr
, addr
, 4);
9248 tcg_gen_addi_i32(addr
, addr
, -4);
9250 store_reg(s
, rn
, addr
);
9252 tcg_temp_free_i32(addr
);
9254 gen_rfe(s
, tmp
, tmp2
);
9257 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
9261 int i
, loaded_base
= 0;
9262 TCGv_i32 loaded_var
;
9263 /* Load/store multiple. */
9264 addr
= load_reg(s
, rn
);
9266 for (i
= 0; i
< 16; i
++) {
9267 if (insn
& (1 << i
))
9270 if (insn
& (1 << 24)) {
9271 tcg_gen_addi_i32(addr
, addr
, -offset
);
9274 TCGV_UNUSED_I32(loaded_var
);
9275 for (i
= 0; i
< 16; i
++) {
9276 if ((insn
& (1 << i
)) == 0)
9278 if (insn
& (1 << 20)) {
9280 tmp
= tcg_temp_new_i32();
9281 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9284 } else if (i
== rn
) {
9288 store_reg(s
, i
, tmp
);
9292 tmp
= load_reg(s
, i
);
9293 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9294 tcg_temp_free_i32(tmp
);
9296 tcg_gen_addi_i32(addr
, addr
, 4);
9299 store_reg(s
, rn
, loaded_var
);
9301 if (insn
& (1 << 21)) {
9302 /* Base register writeback. */
9303 if (insn
& (1 << 24)) {
9304 tcg_gen_addi_i32(addr
, addr
, -offset
);
9306 /* Fault if writeback register is in register list. */
9307 if (insn
& (1 << rn
))
9309 store_reg(s
, rn
, addr
);
9311 tcg_temp_free_i32(addr
);
9318 op
= (insn
>> 21) & 0xf;
9320 /* Halfword pack. */
9321 tmp
= load_reg(s
, rn
);
9322 tmp2
= load_reg(s
, rm
);
9323 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
9324 if (insn
& (1 << 5)) {
9328 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9329 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9330 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9334 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9335 tcg_gen_ext16u_i32(tmp
, tmp
);
9336 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9338 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9339 tcg_temp_free_i32(tmp2
);
9340 store_reg(s
, rd
, tmp
);
9342 /* Data processing register constant shift. */
9344 tmp
= tcg_temp_new_i32();
9345 tcg_gen_movi_i32(tmp
, 0);
9347 tmp
= load_reg(s
, rn
);
9349 tmp2
= load_reg(s
, rm
);
9351 shiftop
= (insn
>> 4) & 3;
9352 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
9353 conds
= (insn
& (1 << 20)) != 0;
9354 logic_cc
= (conds
&& thumb2_logic_op(op
));
9355 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
9356 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
9358 tcg_temp_free_i32(tmp2
);
9360 store_reg(s
, rd
, tmp
);
9362 tcg_temp_free_i32(tmp
);
9366 case 13: /* Misc data processing. */
9367 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
9368 if (op
< 4 && (insn
& 0xf000) != 0xf000)
9371 case 0: /* Register controlled shift. */
9372 tmp
= load_reg(s
, rn
);
9373 tmp2
= load_reg(s
, rm
);
9374 if ((insn
& 0x70) != 0)
9376 op
= (insn
>> 21) & 3;
9377 logic_cc
= (insn
& (1 << 20)) != 0;
9378 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
9381 store_reg_bx(env
, s
, rd
, tmp
);
9383 case 1: /* Sign/zero extend. */
9384 tmp
= load_reg(s
, rm
);
9385 shift
= (insn
>> 4) & 3;
9386 /* ??? In many cases it's not necessary to do a
9387 rotate, a shift is sufficient. */
9389 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9390 op
= (insn
>> 20) & 7;
9392 case 0: gen_sxth(tmp
); break;
9393 case 1: gen_uxth(tmp
); break;
9394 case 2: gen_sxtb16(tmp
); break;
9395 case 3: gen_uxtb16(tmp
); break;
9396 case 4: gen_sxtb(tmp
); break;
9397 case 5: gen_uxtb(tmp
); break;
9398 default: goto illegal_op
;
9401 tmp2
= load_reg(s
, rn
);
9402 if ((op
>> 1) == 1) {
9403 gen_add16(tmp
, tmp2
);
9405 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9406 tcg_temp_free_i32(tmp2
);
9409 store_reg(s
, rd
, tmp
);
9411 case 2: /* SIMD add/subtract. */
9412 op
= (insn
>> 20) & 7;
9413 shift
= (insn
>> 4) & 7;
9414 if ((op
& 3) == 3 || (shift
& 3) == 3)
9416 tmp
= load_reg(s
, rn
);
9417 tmp2
= load_reg(s
, rm
);
9418 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
9419 tcg_temp_free_i32(tmp2
);
9420 store_reg(s
, rd
, tmp
);
9422 case 3: /* Other data processing. */
9423 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
9425 /* Saturating add/subtract. */
9426 tmp
= load_reg(s
, rn
);
9427 tmp2
= load_reg(s
, rm
);
9429 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
9431 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
9433 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
9434 tcg_temp_free_i32(tmp2
);
9436 tmp
= load_reg(s
, rn
);
9438 case 0x0a: /* rbit */
9439 gen_helper_rbit(tmp
, tmp
);
9441 case 0x08: /* rev */
9442 tcg_gen_bswap32_i32(tmp
, tmp
);
9444 case 0x09: /* rev16 */
9447 case 0x0b: /* revsh */
9450 case 0x10: /* sel */
9451 tmp2
= load_reg(s
, rm
);
9452 tmp3
= tcg_temp_new_i32();
9453 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
9454 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
9455 tcg_temp_free_i32(tmp3
);
9456 tcg_temp_free_i32(tmp2
);
9458 case 0x18: /* clz */
9459 gen_helper_clz(tmp
, tmp
);
9469 uint32_t sz
= op
& 0x3;
9470 uint32_t c
= op
& 0x8;
9472 if (!arm_feature(env
, ARM_FEATURE_CRC
)) {
9476 tmp2
= load_reg(s
, rm
);
9478 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
9479 } else if (sz
== 1) {
9480 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
9482 tmp3
= tcg_const_i32(1 << sz
);
9484 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
9486 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
9488 tcg_temp_free_i32(tmp2
);
9489 tcg_temp_free_i32(tmp3
);
9496 store_reg(s
, rd
, tmp
);
9498 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
9499 op
= (insn
>> 4) & 0xf;
9500 tmp
= load_reg(s
, rn
);
9501 tmp2
= load_reg(s
, rm
);
9502 switch ((insn
>> 20) & 7) {
9503 case 0: /* 32 x 32 -> 32 */
9504 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
9505 tcg_temp_free_i32(tmp2
);
9507 tmp2
= load_reg(s
, rs
);
9509 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
9511 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9512 tcg_temp_free_i32(tmp2
);
9515 case 1: /* 16 x 16 -> 32 */
9516 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
9517 tcg_temp_free_i32(tmp2
);
9519 tmp2
= load_reg(s
, rs
);
9520 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9521 tcg_temp_free_i32(tmp2
);
9524 case 2: /* Dual multiply add. */
9525 case 4: /* Dual multiply subtract. */
9527 gen_swap_half(tmp2
);
9528 gen_smul_dual(tmp
, tmp2
);
9529 if (insn
& (1 << 22)) {
9530 /* This subtraction cannot overflow. */
9531 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9533 /* This addition cannot overflow 32 bits;
9534 * however it may overflow considered as a signed
9535 * operation, in which case we must set the Q flag.
9537 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9539 tcg_temp_free_i32(tmp2
);
9542 tmp2
= load_reg(s
, rs
);
9543 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9544 tcg_temp_free_i32(tmp2
);
9547 case 3: /* 32 * 16 -> 32msb */
9549 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
9552 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9553 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
9554 tmp
= tcg_temp_new_i32();
9555 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
9556 tcg_temp_free_i64(tmp64
);
9559 tmp2
= load_reg(s
, rs
);
9560 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9561 tcg_temp_free_i32(tmp2
);
9564 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9565 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9567 tmp
= load_reg(s
, rs
);
9568 if (insn
& (1 << 20)) {
9569 tmp64
= gen_addq_msw(tmp64
, tmp
);
9571 tmp64
= gen_subq_msw(tmp64
, tmp
);
9574 if (insn
& (1 << 4)) {
9575 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
9577 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
9578 tmp
= tcg_temp_new_i32();
9579 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
9580 tcg_temp_free_i64(tmp64
);
9582 case 7: /* Unsigned sum of absolute differences. */
9583 gen_helper_usad8(tmp
, tmp
, tmp2
);
9584 tcg_temp_free_i32(tmp2
);
9586 tmp2
= load_reg(s
, rs
);
9587 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9588 tcg_temp_free_i32(tmp2
);
9592 store_reg(s
, rd
, tmp
);
9594 case 6: case 7: /* 64-bit multiply, Divide. */
9595 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
9596 tmp
= load_reg(s
, rn
);
9597 tmp2
= load_reg(s
, rm
);
9598 if ((op
& 0x50) == 0x10) {
9600 if (!arm_feature(env
, ARM_FEATURE_THUMB_DIV
)) {
9604 gen_helper_udiv(tmp
, tmp
, tmp2
);
9606 gen_helper_sdiv(tmp
, tmp
, tmp2
);
9607 tcg_temp_free_i32(tmp2
);
9608 store_reg(s
, rd
, tmp
);
9609 } else if ((op
& 0xe) == 0xc) {
9610 /* Dual multiply accumulate long. */
9612 gen_swap_half(tmp2
);
9613 gen_smul_dual(tmp
, tmp2
);
9615 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9617 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9619 tcg_temp_free_i32(tmp2
);
9621 tmp64
= tcg_temp_new_i64();
9622 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9623 tcg_temp_free_i32(tmp
);
9624 gen_addq(s
, tmp64
, rs
, rd
);
9625 gen_storeq_reg(s
, rs
, rd
, tmp64
);
9626 tcg_temp_free_i64(tmp64
);
9629 /* Unsigned 64-bit multiply */
9630 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
9634 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
9635 tcg_temp_free_i32(tmp2
);
9636 tmp64
= tcg_temp_new_i64();
9637 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9638 tcg_temp_free_i32(tmp
);
9640 /* Signed 64-bit multiply */
9641 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9646 gen_addq_lo(s
, tmp64
, rs
);
9647 gen_addq_lo(s
, tmp64
, rd
);
9648 } else if (op
& 0x40) {
9649 /* 64-bit accumulate. */
9650 gen_addq(s
, tmp64
, rs
, rd
);
9652 gen_storeq_reg(s
, rs
, rd
, tmp64
);
9653 tcg_temp_free_i64(tmp64
);
9658 case 6: case 7: case 14: case 15:
9660 if (((insn
>> 24) & 3) == 3) {
9661 /* Translate into the equivalent ARM encoding. */
9662 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
9663 if (disas_neon_data_insn(env
, s
, insn
))
9665 } else if (((insn
>> 8) & 0xe) == 10) {
9666 if (disas_vfp_insn(env
, s
, insn
)) {
9670 if (insn
& (1 << 28))
9672 if (disas_coproc_insn (env
, s
, insn
))
9676 case 8: case 9: case 10: case 11:
9677 if (insn
& (1 << 15)) {
9678 /* Branches, misc control. */
9679 if (insn
& 0x5000) {
9680 /* Unconditional branch. */
9681 /* signextend(hw1[10:0]) -> offset[:12]. */
9682 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
9683 /* hw1[10:0] -> offset[11:1]. */
9684 offset
|= (insn
& 0x7ff) << 1;
9685 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9686 offset[24:22] already have the same value because of the
9687 sign extension above. */
9688 offset
^= ((~insn
) & (1 << 13)) << 10;
9689 offset
^= ((~insn
) & (1 << 11)) << 11;
9691 if (insn
& (1 << 14)) {
9692 /* Branch and link. */
9693 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
9697 if (insn
& (1 << 12)) {
9702 offset
&= ~(uint32_t)2;
9703 /* thumb2 bx, no need to check */
9704 gen_bx_im(s
, offset
);
9706 } else if (((insn
>> 23) & 7) == 7) {
9708 if (insn
& (1 << 13))
9711 if (insn
& (1 << 26)) {
9712 /* Secure monitor call (v6Z) */
9713 qemu_log_mask(LOG_UNIMP
,
9714 "arm: unimplemented secure monitor call\n");
9715 goto illegal_op
; /* not implemented. */
9717 op
= (insn
>> 20) & 7;
9719 case 0: /* msr cpsr. */
9721 tmp
= load_reg(s
, rn
);
9722 addr
= tcg_const_i32(insn
& 0xff);
9723 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9724 tcg_temp_free_i32(addr
);
9725 tcg_temp_free_i32(tmp
);
9730 case 1: /* msr spsr. */
9733 tmp
= load_reg(s
, rn
);
9735 msr_mask(env
, s
, (insn
>> 8) & 0xf, op
== 1),
9739 case 2: /* cps, nop-hint. */
9740 if (((insn
>> 8) & 7) == 0) {
9741 gen_nop_hint(s
, insn
& 0xff);
9743 /* Implemented as NOP in user mode. */
9748 if (insn
& (1 << 10)) {
9749 if (insn
& (1 << 7))
9751 if (insn
& (1 << 6))
9753 if (insn
& (1 << 5))
9755 if (insn
& (1 << 9))
9756 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
9758 if (insn
& (1 << 8)) {
9760 imm
|= (insn
& 0x1f);
9763 gen_set_psr_im(s
, offset
, 0, imm
);
9766 case 3: /* Special control operations. */
9768 op
= (insn
>> 4) & 0xf;
9776 /* These execute as NOPs. */
9783 /* Trivial implementation equivalent to bx. */
9784 tmp
= load_reg(s
, rn
);
9787 case 5: /* Exception return. */
9791 if (rn
!= 14 || rd
!= 15) {
9794 tmp
= load_reg(s
, rn
);
9795 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
9796 gen_exception_return(s
, tmp
);
9798 case 6: /* mrs cpsr. */
9799 tmp
= tcg_temp_new_i32();
9801 addr
= tcg_const_i32(insn
& 0xff);
9802 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
9803 tcg_temp_free_i32(addr
);
9805 gen_helper_cpsr_read(tmp
, cpu_env
);
9807 store_reg(s
, rd
, tmp
);
9809 case 7: /* mrs spsr. */
9810 /* Not accessible in user mode. */
9811 if (IS_USER(s
) || IS_M(env
))
9813 tmp
= load_cpu_field(spsr
);
9814 store_reg(s
, rd
, tmp
);
9819 /* Conditional branch. */
9820 op
= (insn
>> 22) & 0xf;
9821 /* Generate a conditional jump to next instruction. */
9822 s
->condlabel
= gen_new_label();
9823 arm_gen_test_cc(op
^ 1, s
->condlabel
);
9826 /* offset[11:1] = insn[10:0] */
9827 offset
= (insn
& 0x7ff) << 1;
9828 /* offset[17:12] = insn[21:16]. */
9829 offset
|= (insn
& 0x003f0000) >> 4;
9830 /* offset[31:20] = insn[26]. */
9831 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
9832 /* offset[18] = insn[13]. */
9833 offset
|= (insn
& (1 << 13)) << 5;
9834 /* offset[19] = insn[11]. */
9835 offset
|= (insn
& (1 << 11)) << 8;
9837 /* jump to the offset */
9838 gen_jmp(s
, s
->pc
+ offset
);
9841 /* Data processing immediate. */
9842 if (insn
& (1 << 25)) {
9843 if (insn
& (1 << 24)) {
9844 if (insn
& (1 << 20))
9846 /* Bitfield/Saturate. */
9847 op
= (insn
>> 21) & 7;
9849 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
9851 tmp
= tcg_temp_new_i32();
9852 tcg_gen_movi_i32(tmp
, 0);
9854 tmp
= load_reg(s
, rn
);
9857 case 2: /* Signed bitfield extract. */
9859 if (shift
+ imm
> 32)
9862 gen_sbfx(tmp
, shift
, imm
);
9864 case 6: /* Unsigned bitfield extract. */
9866 if (shift
+ imm
> 32)
9869 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
9871 case 3: /* Bitfield insert/clear. */
9874 imm
= imm
+ 1 - shift
;
9876 tmp2
= load_reg(s
, rd
);
9877 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
9878 tcg_temp_free_i32(tmp2
);
9883 default: /* Saturate. */
9886 tcg_gen_sari_i32(tmp
, tmp
, shift
);
9888 tcg_gen_shli_i32(tmp
, tmp
, shift
);
9890 tmp2
= tcg_const_i32(imm
);
9893 if ((op
& 1) && shift
== 0)
9894 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
9896 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
9899 if ((op
& 1) && shift
== 0)
9900 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
9902 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
9904 tcg_temp_free_i32(tmp2
);
9907 store_reg(s
, rd
, tmp
);
9909 imm
= ((insn
& 0x04000000) >> 15)
9910 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
9911 if (insn
& (1 << 22)) {
9912 /* 16-bit immediate. */
9913 imm
|= (insn
>> 4) & 0xf000;
9914 if (insn
& (1 << 23)) {
9916 tmp
= load_reg(s
, rd
);
9917 tcg_gen_ext16u_i32(tmp
, tmp
);
9918 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
9921 tmp
= tcg_temp_new_i32();
9922 tcg_gen_movi_i32(tmp
, imm
);
9925 /* Add/sub 12-bit immediate. */
9927 offset
= s
->pc
& ~(uint32_t)3;
9928 if (insn
& (1 << 23))
9932 tmp
= tcg_temp_new_i32();
9933 tcg_gen_movi_i32(tmp
, offset
);
9935 tmp
= load_reg(s
, rn
);
9936 if (insn
& (1 << 23))
9937 tcg_gen_subi_i32(tmp
, tmp
, imm
);
9939 tcg_gen_addi_i32(tmp
, tmp
, imm
);
9942 store_reg(s
, rd
, tmp
);
9945 int shifter_out
= 0;
9946 /* modified 12-bit immediate. */
9947 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
9948 imm
= (insn
& 0xff);
9951 /* Nothing to do. */
9953 case 1: /* 00XY00XY */
9956 case 2: /* XY00XY00 */
9960 case 3: /* XYXYXYXY */
9964 default: /* Rotated constant. */
9965 shift
= (shift
<< 1) | (imm
>> 7);
9967 imm
= imm
<< (32 - shift
);
9971 tmp2
= tcg_temp_new_i32();
9972 tcg_gen_movi_i32(tmp2
, imm
);
9973 rn
= (insn
>> 16) & 0xf;
9975 tmp
= tcg_temp_new_i32();
9976 tcg_gen_movi_i32(tmp
, 0);
9978 tmp
= load_reg(s
, rn
);
9980 op
= (insn
>> 21) & 0xf;
9981 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
9982 shifter_out
, tmp
, tmp2
))
9984 tcg_temp_free_i32(tmp2
);
9985 rd
= (insn
>> 8) & 0xf;
9987 store_reg(s
, rd
, tmp
);
9989 tcg_temp_free_i32(tmp
);
9994 case 12: /* Load/store single data item. */
9999 if ((insn
& 0x01100000) == 0x01000000) {
10000 if (disas_neon_ls_insn(env
, s
, insn
))
10004 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
10006 if (!(insn
& (1 << 20))) {
10010 /* Byte or halfword load space with dest == r15 : memory hints.
10011 * Catch them early so we don't emit pointless addressing code.
10012 * This space is a mix of:
10013 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10014 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10016 * unallocated hints, which must be treated as NOPs
10017 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10018 * which is easiest for the decoding logic
10019 * Some space which must UNDEF
10021 int op1
= (insn
>> 23) & 3;
10022 int op2
= (insn
>> 6) & 0x3f;
10027 /* UNPREDICTABLE, unallocated hint or
10028 * PLD/PLDW/PLI (literal)
10033 return 0; /* PLD/PLDW/PLI or unallocated hint */
10035 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
10036 return 0; /* PLD/PLDW/PLI or unallocated hint */
10038 /* UNDEF space, or an UNPREDICTABLE */
10042 memidx
= get_mem_index(s
);
10044 addr
= tcg_temp_new_i32();
10046 /* s->pc has already been incremented by 4. */
10047 imm
= s
->pc
& 0xfffffffc;
10048 if (insn
& (1 << 23))
10049 imm
+= insn
& 0xfff;
10051 imm
-= insn
& 0xfff;
10052 tcg_gen_movi_i32(addr
, imm
);
10054 addr
= load_reg(s
, rn
);
10055 if (insn
& (1 << 23)) {
10056 /* Positive offset. */
10057 imm
= insn
& 0xfff;
10058 tcg_gen_addi_i32(addr
, addr
, imm
);
10061 switch ((insn
>> 8) & 0xf) {
10062 case 0x0: /* Shifted Register. */
10063 shift
= (insn
>> 4) & 0xf;
10065 tcg_temp_free_i32(addr
);
10068 tmp
= load_reg(s
, rm
);
10070 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10071 tcg_gen_add_i32(addr
, addr
, tmp
);
10072 tcg_temp_free_i32(tmp
);
10074 case 0xc: /* Negative offset. */
10075 tcg_gen_addi_i32(addr
, addr
, -imm
);
10077 case 0xe: /* User privilege. */
10078 tcg_gen_addi_i32(addr
, addr
, imm
);
10079 memidx
= MMU_USER_IDX
;
10081 case 0x9: /* Post-decrement. */
10083 /* Fall through. */
10084 case 0xb: /* Post-increment. */
10088 case 0xd: /* Pre-decrement. */
10090 /* Fall through. */
10091 case 0xf: /* Pre-increment. */
10092 tcg_gen_addi_i32(addr
, addr
, imm
);
10096 tcg_temp_free_i32(addr
);
10101 if (insn
& (1 << 20)) {
10103 tmp
= tcg_temp_new_i32();
10106 gen_aa32_ld8u(tmp
, addr
, memidx
);
10109 gen_aa32_ld8s(tmp
, addr
, memidx
);
10112 gen_aa32_ld16u(tmp
, addr
, memidx
);
10115 gen_aa32_ld16s(tmp
, addr
, memidx
);
10118 gen_aa32_ld32u(tmp
, addr
, memidx
);
10121 tcg_temp_free_i32(tmp
);
10122 tcg_temp_free_i32(addr
);
10128 store_reg(s
, rs
, tmp
);
10132 tmp
= load_reg(s
, rs
);
10135 gen_aa32_st8(tmp
, addr
, memidx
);
10138 gen_aa32_st16(tmp
, addr
, memidx
);
10141 gen_aa32_st32(tmp
, addr
, memidx
);
10144 tcg_temp_free_i32(tmp
);
10145 tcg_temp_free_i32(addr
);
10148 tcg_temp_free_i32(tmp
);
10151 tcg_gen_addi_i32(addr
, addr
, imm
);
10153 store_reg(s
, rn
, addr
);
10155 tcg_temp_free_i32(addr
);
10167 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
10169 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
10176 if (s
->condexec_mask
) {
10177 cond
= s
->condexec_cond
;
10178 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
10179 s
->condlabel
= gen_new_label();
10180 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
10185 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
10188 switch (insn
>> 12) {
10192 op
= (insn
>> 11) & 3;
10195 rn
= (insn
>> 3) & 7;
10196 tmp
= load_reg(s
, rn
);
10197 if (insn
& (1 << 10)) {
10199 tmp2
= tcg_temp_new_i32();
10200 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
10203 rm
= (insn
>> 6) & 7;
10204 tmp2
= load_reg(s
, rm
);
10206 if (insn
& (1 << 9)) {
10207 if (s
->condexec_mask
)
10208 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10210 gen_sub_CC(tmp
, tmp
, tmp2
);
10212 if (s
->condexec_mask
)
10213 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10215 gen_add_CC(tmp
, tmp
, tmp2
);
10217 tcg_temp_free_i32(tmp2
);
10218 store_reg(s
, rd
, tmp
);
10220 /* shift immediate */
10221 rm
= (insn
>> 3) & 7;
10222 shift
= (insn
>> 6) & 0x1f;
10223 tmp
= load_reg(s
, rm
);
10224 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
10225 if (!s
->condexec_mask
)
10227 store_reg(s
, rd
, tmp
);
10231 /* arithmetic large immediate */
10232 op
= (insn
>> 11) & 3;
10233 rd
= (insn
>> 8) & 0x7;
10234 if (op
== 0) { /* mov */
10235 tmp
= tcg_temp_new_i32();
10236 tcg_gen_movi_i32(tmp
, insn
& 0xff);
10237 if (!s
->condexec_mask
)
10239 store_reg(s
, rd
, tmp
);
10241 tmp
= load_reg(s
, rd
);
10242 tmp2
= tcg_temp_new_i32();
10243 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
10246 gen_sub_CC(tmp
, tmp
, tmp2
);
10247 tcg_temp_free_i32(tmp
);
10248 tcg_temp_free_i32(tmp2
);
10251 if (s
->condexec_mask
)
10252 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10254 gen_add_CC(tmp
, tmp
, tmp2
);
10255 tcg_temp_free_i32(tmp2
);
10256 store_reg(s
, rd
, tmp
);
10259 if (s
->condexec_mask
)
10260 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10262 gen_sub_CC(tmp
, tmp
, tmp2
);
10263 tcg_temp_free_i32(tmp2
);
10264 store_reg(s
, rd
, tmp
);
10270 if (insn
& (1 << 11)) {
10271 rd
= (insn
>> 8) & 7;
10272 /* load pc-relative. Bit 1 of PC is ignored. */
10273 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
10274 val
&= ~(uint32_t)2;
10275 addr
= tcg_temp_new_i32();
10276 tcg_gen_movi_i32(addr
, val
);
10277 tmp
= tcg_temp_new_i32();
10278 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10279 tcg_temp_free_i32(addr
);
10280 store_reg(s
, rd
, tmp
);
10283 if (insn
& (1 << 10)) {
10284 /* data processing extended or blx */
10285 rd
= (insn
& 7) | ((insn
>> 4) & 8);
10286 rm
= (insn
>> 3) & 0xf;
10287 op
= (insn
>> 8) & 3;
10290 tmp
= load_reg(s
, rd
);
10291 tmp2
= load_reg(s
, rm
);
10292 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10293 tcg_temp_free_i32(tmp2
);
10294 store_reg(s
, rd
, tmp
);
10297 tmp
= load_reg(s
, rd
);
10298 tmp2
= load_reg(s
, rm
);
10299 gen_sub_CC(tmp
, tmp
, tmp2
);
10300 tcg_temp_free_i32(tmp2
);
10301 tcg_temp_free_i32(tmp
);
10303 case 2: /* mov/cpy */
10304 tmp
= load_reg(s
, rm
);
10305 store_reg(s
, rd
, tmp
);
10307 case 3:/* branch [and link] exchange thumb register */
10308 tmp
= load_reg(s
, rm
);
10309 if (insn
& (1 << 7)) {
10311 val
= (uint32_t)s
->pc
| 1;
10312 tmp2
= tcg_temp_new_i32();
10313 tcg_gen_movi_i32(tmp2
, val
);
10314 store_reg(s
, 14, tmp2
);
10316 /* already thumb, no need to check */
10323 /* data processing register */
10325 rm
= (insn
>> 3) & 7;
10326 op
= (insn
>> 6) & 0xf;
10327 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
10328 /* the shift/rotate ops want the operands backwards */
10337 if (op
== 9) { /* neg */
10338 tmp
= tcg_temp_new_i32();
10339 tcg_gen_movi_i32(tmp
, 0);
10340 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
10341 tmp
= load_reg(s
, rd
);
10343 TCGV_UNUSED_I32(tmp
);
10346 tmp2
= load_reg(s
, rm
);
10348 case 0x0: /* and */
10349 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
10350 if (!s
->condexec_mask
)
10353 case 0x1: /* eor */
10354 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
10355 if (!s
->condexec_mask
)
10358 case 0x2: /* lsl */
10359 if (s
->condexec_mask
) {
10360 gen_shl(tmp2
, tmp2
, tmp
);
10362 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10363 gen_logic_CC(tmp2
);
10366 case 0x3: /* lsr */
10367 if (s
->condexec_mask
) {
10368 gen_shr(tmp2
, tmp2
, tmp
);
10370 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10371 gen_logic_CC(tmp2
);
10374 case 0x4: /* asr */
10375 if (s
->condexec_mask
) {
10376 gen_sar(tmp2
, tmp2
, tmp
);
10378 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10379 gen_logic_CC(tmp2
);
10382 case 0x5: /* adc */
10383 if (s
->condexec_mask
) {
10384 gen_adc(tmp
, tmp2
);
10386 gen_adc_CC(tmp
, tmp
, tmp2
);
10389 case 0x6: /* sbc */
10390 if (s
->condexec_mask
) {
10391 gen_sub_carry(tmp
, tmp
, tmp2
);
10393 gen_sbc_CC(tmp
, tmp
, tmp2
);
10396 case 0x7: /* ror */
10397 if (s
->condexec_mask
) {
10398 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
10399 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
10401 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10402 gen_logic_CC(tmp2
);
10405 case 0x8: /* tst */
10406 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
10410 case 0x9: /* neg */
10411 if (s
->condexec_mask
)
10412 tcg_gen_neg_i32(tmp
, tmp2
);
10414 gen_sub_CC(tmp
, tmp
, tmp2
);
10416 case 0xa: /* cmp */
10417 gen_sub_CC(tmp
, tmp
, tmp2
);
10420 case 0xb: /* cmn */
10421 gen_add_CC(tmp
, tmp
, tmp2
);
10424 case 0xc: /* orr */
10425 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
10426 if (!s
->condexec_mask
)
10429 case 0xd: /* mul */
10430 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
10431 if (!s
->condexec_mask
)
10434 case 0xe: /* bic */
10435 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
10436 if (!s
->condexec_mask
)
10439 case 0xf: /* mvn */
10440 tcg_gen_not_i32(tmp2
, tmp2
);
10441 if (!s
->condexec_mask
)
10442 gen_logic_CC(tmp2
);
10449 store_reg(s
, rm
, tmp2
);
10451 tcg_temp_free_i32(tmp
);
10453 store_reg(s
, rd
, tmp
);
10454 tcg_temp_free_i32(tmp2
);
10457 tcg_temp_free_i32(tmp
);
10458 tcg_temp_free_i32(tmp2
);
10463 /* load/store register offset. */
10465 rn
= (insn
>> 3) & 7;
10466 rm
= (insn
>> 6) & 7;
10467 op
= (insn
>> 9) & 7;
10468 addr
= load_reg(s
, rn
);
10469 tmp
= load_reg(s
, rm
);
10470 tcg_gen_add_i32(addr
, addr
, tmp
);
10471 tcg_temp_free_i32(tmp
);
10473 if (op
< 3) { /* store */
10474 tmp
= load_reg(s
, rd
);
10476 tmp
= tcg_temp_new_i32();
10481 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10484 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
10487 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
10489 case 3: /* ldrsb */
10490 gen_aa32_ld8s(tmp
, addr
, get_mem_index(s
));
10493 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10496 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
10499 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
10501 case 7: /* ldrsh */
10502 gen_aa32_ld16s(tmp
, addr
, get_mem_index(s
));
10505 if (op
>= 3) { /* load */
10506 store_reg(s
, rd
, tmp
);
10508 tcg_temp_free_i32(tmp
);
10510 tcg_temp_free_i32(addr
);
10514 /* load/store word immediate offset */
10516 rn
= (insn
>> 3) & 7;
10517 addr
= load_reg(s
, rn
);
10518 val
= (insn
>> 4) & 0x7c;
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 /* load/store byte immediate offset */
10538 rn
= (insn
>> 3) & 7;
10539 addr
= load_reg(s
, rn
);
10540 val
= (insn
>> 6) & 0x1f;
10541 tcg_gen_addi_i32(addr
, addr
, val
);
10543 if (insn
& (1 << 11)) {
10545 tmp
= tcg_temp_new_i32();
10546 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
10547 store_reg(s
, rd
, tmp
);
10550 tmp
= load_reg(s
, rd
);
10551 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
10552 tcg_temp_free_i32(tmp
);
10554 tcg_temp_free_i32(addr
);
10558 /* load/store halfword immediate offset */
10560 rn
= (insn
>> 3) & 7;
10561 addr
= load_reg(s
, rn
);
10562 val
= (insn
>> 5) & 0x3e;
10563 tcg_gen_addi_i32(addr
, addr
, val
);
10565 if (insn
& (1 << 11)) {
10567 tmp
= tcg_temp_new_i32();
10568 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
10569 store_reg(s
, rd
, tmp
);
10572 tmp
= load_reg(s
, rd
);
10573 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
10574 tcg_temp_free_i32(tmp
);
10576 tcg_temp_free_i32(addr
);
10580 /* load/store from stack */
10581 rd
= (insn
>> 8) & 7;
10582 addr
= load_reg(s
, 13);
10583 val
= (insn
& 0xff) * 4;
10584 tcg_gen_addi_i32(addr
, addr
, val
);
10586 if (insn
& (1 << 11)) {
10588 tmp
= tcg_temp_new_i32();
10589 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10590 store_reg(s
, rd
, tmp
);
10593 tmp
= load_reg(s
, rd
);
10594 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10595 tcg_temp_free_i32(tmp
);
10597 tcg_temp_free_i32(addr
);
10601 /* add to high reg */
10602 rd
= (insn
>> 8) & 7;
10603 if (insn
& (1 << 11)) {
10605 tmp
= load_reg(s
, 13);
10607 /* PC. bit 1 is ignored. */
10608 tmp
= tcg_temp_new_i32();
10609 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
10611 val
= (insn
& 0xff) * 4;
10612 tcg_gen_addi_i32(tmp
, tmp
, val
);
10613 store_reg(s
, rd
, tmp
);
10618 op
= (insn
>> 8) & 0xf;
10621 /* adjust stack pointer */
10622 tmp
= load_reg(s
, 13);
10623 val
= (insn
& 0x7f) * 4;
10624 if (insn
& (1 << 7))
10625 val
= -(int32_t)val
;
10626 tcg_gen_addi_i32(tmp
, tmp
, val
);
10627 store_reg(s
, 13, tmp
);
10630 case 2: /* sign/zero extend. */
10633 rm
= (insn
>> 3) & 7;
10634 tmp
= load_reg(s
, rm
);
10635 switch ((insn
>> 6) & 3) {
10636 case 0: gen_sxth(tmp
); break;
10637 case 1: gen_sxtb(tmp
); break;
10638 case 2: gen_uxth(tmp
); break;
10639 case 3: gen_uxtb(tmp
); break;
10641 store_reg(s
, rd
, tmp
);
10643 case 4: case 5: case 0xc: case 0xd:
10645 addr
= load_reg(s
, 13);
10646 if (insn
& (1 << 8))
10650 for (i
= 0; i
< 8; i
++) {
10651 if (insn
& (1 << i
))
10654 if ((insn
& (1 << 11)) == 0) {
10655 tcg_gen_addi_i32(addr
, addr
, -offset
);
10657 for (i
= 0; i
< 8; i
++) {
10658 if (insn
& (1 << i
)) {
10659 if (insn
& (1 << 11)) {
10661 tmp
= tcg_temp_new_i32();
10662 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10663 store_reg(s
, i
, tmp
);
10666 tmp
= load_reg(s
, i
);
10667 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10668 tcg_temp_free_i32(tmp
);
10670 /* advance to the next address. */
10671 tcg_gen_addi_i32(addr
, addr
, 4);
10674 TCGV_UNUSED_I32(tmp
);
10675 if (insn
& (1 << 8)) {
10676 if (insn
& (1 << 11)) {
10678 tmp
= tcg_temp_new_i32();
10679 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10680 /* don't set the pc until the rest of the instruction
10684 tmp
= load_reg(s
, 14);
10685 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10686 tcg_temp_free_i32(tmp
);
10688 tcg_gen_addi_i32(addr
, addr
, 4);
10690 if ((insn
& (1 << 11)) == 0) {
10691 tcg_gen_addi_i32(addr
, addr
, -offset
);
10693 /* write back the new stack pointer */
10694 store_reg(s
, 13, addr
);
10695 /* set the new PC value */
10696 if ((insn
& 0x0900) == 0x0900) {
10697 store_reg_from_load(env
, s
, 15, tmp
);
10701 case 1: case 3: case 9: case 11: /* czb */
10703 tmp
= load_reg(s
, rm
);
10704 s
->condlabel
= gen_new_label();
10706 if (insn
& (1 << 11))
10707 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
10709 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
10710 tcg_temp_free_i32(tmp
);
10711 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
10712 val
= (uint32_t)s
->pc
+ 2;
10717 case 15: /* IT, nop-hint. */
10718 if ((insn
& 0xf) == 0) {
10719 gen_nop_hint(s
, (insn
>> 4) & 0xf);
10723 s
->condexec_cond
= (insn
>> 4) & 0xe;
10724 s
->condexec_mask
= insn
& 0x1f;
10725 /* No actual code generated for this insn, just setup state. */
10728 case 0xe: /* bkpt */
10730 int imm8
= extract32(insn
, 0, 8);
10732 gen_exception_insn(s
, 2, EXCP_BKPT
, syn_aa32_bkpt(imm8
, true));
10736 case 0xa: /* rev */
10738 rn
= (insn
>> 3) & 0x7;
10740 tmp
= load_reg(s
, rn
);
10741 switch ((insn
>> 6) & 3) {
10742 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
10743 case 1: gen_rev16(tmp
); break;
10744 case 3: gen_revsh(tmp
); break;
10745 default: goto illegal_op
;
10747 store_reg(s
, rd
, tmp
);
10751 switch ((insn
>> 5) & 7) {
10755 if (((insn
>> 3) & 1) != s
->bswap_code
) {
10756 /* Dynamic endianness switching not implemented. */
10757 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
10768 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
10771 addr
= tcg_const_i32(19);
10772 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10773 tcg_temp_free_i32(addr
);
10777 addr
= tcg_const_i32(16);
10778 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10779 tcg_temp_free_i32(addr
);
10781 tcg_temp_free_i32(tmp
);
10784 if (insn
& (1 << 4)) {
10785 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
10789 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
10804 /* load/store multiple */
10805 TCGv_i32 loaded_var
;
10806 TCGV_UNUSED_I32(loaded_var
);
10807 rn
= (insn
>> 8) & 0x7;
10808 addr
= load_reg(s
, rn
);
10809 for (i
= 0; i
< 8; i
++) {
10810 if (insn
& (1 << i
)) {
10811 if (insn
& (1 << 11)) {
10813 tmp
= tcg_temp_new_i32();
10814 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10818 store_reg(s
, i
, tmp
);
10822 tmp
= load_reg(s
, i
);
10823 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10824 tcg_temp_free_i32(tmp
);
10826 /* advance to the next address */
10827 tcg_gen_addi_i32(addr
, addr
, 4);
10830 if ((insn
& (1 << rn
)) == 0) {
10831 /* base reg not in list: base register writeback */
10832 store_reg(s
, rn
, addr
);
10834 /* base reg in list: if load, complete it now */
10835 if (insn
& (1 << 11)) {
10836 store_reg(s
, rn
, loaded_var
);
10838 tcg_temp_free_i32(addr
);
10843 /* conditional branch or swi */
10844 cond
= (insn
>> 8) & 0xf;
10850 gen_set_pc_im(s
, s
->pc
);
10851 s
->svc_imm
= extract32(insn
, 0, 8);
10852 s
->is_jmp
= DISAS_SWI
;
10855 /* generate a conditional jump to next instruction */
10856 s
->condlabel
= gen_new_label();
10857 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
10860 /* jump to the offset */
10861 val
= (uint32_t)s
->pc
+ 2;
10862 offset
= ((int32_t)insn
<< 24) >> 24;
10863 val
+= offset
<< 1;
10868 if (insn
& (1 << 11)) {
10869 if (disas_thumb2_insn(env
, s
, insn
))
10873 /* unconditional branch */
10874 val
= (uint32_t)s
->pc
;
10875 offset
= ((int32_t)insn
<< 21) >> 21;
10876 val
+= (offset
<< 1) + 2;
10881 if (disas_thumb2_insn(env
, s
, insn
))
10887 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized());
10891 gen_exception_insn(s
, 2, EXCP_UDEF
, syn_uncategorized());
10894 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
10895 basic block 'tb'. If search_pc is TRUE, also generate PC
10896 information for each intermediate instruction. */
10897 static inline void gen_intermediate_code_internal(ARMCPU
*cpu
,
10898 TranslationBlock
*tb
,
10901 CPUState
*cs
= CPU(cpu
);
10902 CPUARMState
*env
= &cpu
->env
;
10903 DisasContext dc1
, *dc
= &dc1
;
10905 uint16_t *gen_opc_end
;
10907 target_ulong pc_start
;
10908 target_ulong next_page_start
;
10912 /* generate intermediate code */
10914 /* The A64 decoder has its own top level loop, because it doesn't need
10915 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
10917 if (ARM_TBFLAG_AARCH64_STATE(tb
->flags
)) {
10918 gen_intermediate_code_internal_a64(cpu
, tb
, search_pc
);
10926 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
10928 dc
->is_jmp
= DISAS_NEXT
;
10930 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
10934 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
10935 dc
->bswap_code
= ARM_TBFLAG_BSWAP_CODE(tb
->flags
);
10936 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
10937 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
10938 #if !defined(CONFIG_USER_ONLY)
10939 dc
->user
= (ARM_TBFLAG_PRIV(tb
->flags
) == 0);
10941 dc
->cpacr_fpen
= ARM_TBFLAG_CPACR_FPEN(tb
->flags
);
10942 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
10943 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
10944 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
10945 dc
->cp_regs
= cpu
->cp_regs
;
10946 dc
->current_pl
= arm_current_pl(env
);
10947 dc
->features
= env
->features
;
10949 /* Single step state. The code-generation logic here is:
10951 * generate code with no special handling for single-stepping (except
10952 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
10953 * this happens anyway because those changes are all system register or
10955 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
10956 * emit code for one insn
10957 * emit code to clear PSTATE.SS
10958 * emit code to generate software step exception for completed step
10959 * end TB (as usual for having generated an exception)
10960 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
10961 * emit code to generate a software step exception
10964 dc
->ss_active
= ARM_TBFLAG_SS_ACTIVE(tb
->flags
);
10965 dc
->pstate_ss
= ARM_TBFLAG_PSTATE_SS(tb
->flags
);
10966 dc
->is_ldex
= false;
10967 dc
->ss_same_el
= false; /* Can't be true since EL_d must be AArch64 */
10969 cpu_F0s
= tcg_temp_new_i32();
10970 cpu_F1s
= tcg_temp_new_i32();
10971 cpu_F0d
= tcg_temp_new_i64();
10972 cpu_F1d
= tcg_temp_new_i64();
10975 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
10976 cpu_M0
= tcg_temp_new_i64();
10977 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
10980 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
10981 if (max_insns
== 0)
10982 max_insns
= CF_COUNT_MASK
;
10986 tcg_clear_temp_count();
10988 /* A note on handling of the condexec (IT) bits:
10990 * We want to avoid the overhead of having to write the updated condexec
10991 * bits back to the CPUARMState for every instruction in an IT block. So:
10992 * (1) if the condexec bits are not already zero then we write
10993 * zero back into the CPUARMState now. This avoids complications trying
10994 * to do it at the end of the block. (For example if we don't do this
10995 * it's hard to identify whether we can safely skip writing condexec
10996 * at the end of the TB, which we definitely want to do for the case
10997 * where a TB doesn't do anything with the IT state at all.)
10998 * (2) if we are going to leave the TB then we call gen_set_condexec()
10999 * which will write the correct value into CPUARMState if zero is wrong.
11000 * This is done both for leaving the TB at the end, and for leaving
11001 * it because of an exception we know will happen, which is done in
11002 * gen_exception_insn(). The latter is necessary because we need to
11003 * leave the TB with the PC/IT state just prior to execution of the
11004 * instruction which caused the exception.
11005 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11006 * then the CPUARMState will be wrong and we need to reset it.
11007 * This is handled in the same way as restoration of the
11008 * PC in these situations: we will be called again with search_pc=1
11009 * and generate a mapping of the condexec bits for each PC in
11010 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
11011 * this to restore the condexec bits.
11013 * Note that there are no instructions which can read the condexec
11014 * bits, and none which can write non-static values to them, so
11015 * we don't need to care about whether CPUARMState is correct in the
11019 /* Reset the conditional execution bits immediately. This avoids
11020 complications trying to do it at the end of the block. */
11021 if (dc
->condexec_mask
|| dc
->condexec_cond
)
11023 TCGv_i32 tmp
= tcg_temp_new_i32();
11024 tcg_gen_movi_i32(tmp
, 0);
11025 store_cpu_field(tmp
, condexec_bits
);
11028 #ifdef CONFIG_USER_ONLY
11029 /* Intercept jump to the magic kernel page. */
11030 if (dc
->pc
>= 0xffff0000) {
11031 /* We always get here via a jump, so know we are not in a
11032 conditional execution block. */
11033 gen_exception_internal(EXCP_KERNEL_TRAP
);
11034 dc
->is_jmp
= DISAS_UPDATE
;
11038 if (dc
->pc
>= 0xfffffff0 && IS_M(env
)) {
11039 /* We always get here via a jump, so know we are not in a
11040 conditional execution block. */
11041 gen_exception_internal(EXCP_EXCEPTION_EXIT
);
11042 dc
->is_jmp
= DISAS_UPDATE
;
11047 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
11048 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
11049 if (bp
->pc
== dc
->pc
) {
11050 gen_exception_internal_insn(dc
, 0, EXCP_DEBUG
);
11051 /* Advance PC so that clearing the breakpoint will
11052 invalidate this TB. */
11054 goto done_generating
;
11059 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
11063 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
11065 tcg_ctx
.gen_opc_pc
[lj
] = dc
->pc
;
11066 gen_opc_condexec_bits
[lj
] = (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1);
11067 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
11068 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
11071 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
11074 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
11075 tcg_gen_debug_insn_start(dc
->pc
);
11078 if (dc
->ss_active
&& !dc
->pstate_ss
) {
11079 /* Singlestep state is Active-pending.
11080 * If we're in this state at the start of a TB then either
11081 * a) we just took an exception to an EL which is being debugged
11082 * and this is the first insn in the exception handler
11083 * b) debug exceptions were masked and we just unmasked them
11084 * without changing EL (eg by clearing PSTATE.D)
11085 * In either case we're going to take a swstep exception in the
11086 * "did not step an insn" case, and so the syndrome ISV and EX
11087 * bits should be zero.
11089 assert(num_insns
== 0);
11090 gen_exception(EXCP_UDEF
, syn_swstep(dc
->ss_same_el
, 0, 0));
11091 goto done_generating
;
11095 disas_thumb_insn(env
, dc
);
11096 if (dc
->condexec_mask
) {
11097 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
11098 | ((dc
->condexec_mask
>> 4) & 1);
11099 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
11100 if (dc
->condexec_mask
== 0) {
11101 dc
->condexec_cond
= 0;
11105 disas_arm_insn(env
, dc
);
11108 if (dc
->condjmp
&& !dc
->is_jmp
) {
11109 gen_set_label(dc
->condlabel
);
11113 if (tcg_check_temp_count()) {
11114 fprintf(stderr
, "TCG temporary leak before "TARGET_FMT_lx
"\n",
11118 /* Translation stops when a conditional branch is encountered.
11119 * Otherwise the subsequent code could get translated several times.
11120 * Also stop translation when a page boundary is reached. This
11121 * ensures prefetch aborts occur at the right place. */
11123 } while (!dc
->is_jmp
&& tcg_ctx
.gen_opc_ptr
< gen_opc_end
&&
11124 !cs
->singlestep_enabled
&&
11127 dc
->pc
< next_page_start
&&
11128 num_insns
< max_insns
);
11130 if (tb
->cflags
& CF_LAST_IO
) {
11132 /* FIXME: This can theoretically happen with self-modifying
11134 cpu_abort(cs
, "IO on conditional branch instruction");
11139 /* At this stage dc->condjmp will only be set when the skipped
11140 instruction was a conditional branch or trap, and the PC has
11141 already been written. */
11142 if (unlikely(cs
->singlestep_enabled
|| dc
->ss_active
)) {
11143 /* Make sure the pc is updated, and raise a debug exception. */
11145 gen_set_condexec(dc
);
11146 if (dc
->is_jmp
== DISAS_SWI
) {
11147 gen_ss_advance(dc
);
11148 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
));
11149 } else if (dc
->ss_active
) {
11150 gen_step_complete_exception(dc
);
11152 gen_exception_internal(EXCP_DEBUG
);
11154 gen_set_label(dc
->condlabel
);
11156 if (dc
->condjmp
|| !dc
->is_jmp
) {
11157 gen_set_pc_im(dc
, dc
->pc
);
11160 gen_set_condexec(dc
);
11161 if (dc
->is_jmp
== DISAS_SWI
&& !dc
->condjmp
) {
11162 gen_ss_advance(dc
);
11163 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
));
11164 } else if (dc
->ss_active
) {
11165 gen_step_complete_exception(dc
);
11167 /* FIXME: Single stepping a WFI insn will not halt
11169 gen_exception_internal(EXCP_DEBUG
);
11172 /* While branches must always occur at the end of an IT block,
11173 there are a few other things that can cause us to terminate
11174 the TB in the middle of an IT block:
11175 - Exception generating instructions (bkpt, swi, undefined).
11177 - Hardware watchpoints.
11178 Hardware breakpoints have already been handled and skip this code.
11180 gen_set_condexec(dc
);
11181 switch(dc
->is_jmp
) {
11183 gen_goto_tb(dc
, 1, dc
->pc
);
11188 /* indicate that the hash table must be used to find the next TB */
11189 tcg_gen_exit_tb(0);
11191 case DISAS_TB_JUMP
:
11192 /* nothing more to generate */
11195 gen_helper_wfi(cpu_env
);
11198 gen_helper_wfe(cpu_env
);
11201 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
));
11205 gen_set_label(dc
->condlabel
);
11206 gen_set_condexec(dc
);
11207 gen_goto_tb(dc
, 1, dc
->pc
);
11213 gen_tb_end(tb
, num_insns
);
11214 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
11217 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
11218 qemu_log("----------------\n");
11219 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
11220 log_target_disas(env
, pc_start
, dc
->pc
- pc_start
,
11221 dc
->thumb
| (dc
->bswap_code
<< 1));
11226 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
11229 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
11231 tb
->size
= dc
->pc
- pc_start
;
11232 tb
->icount
= num_insns
;
11236 void gen_intermediate_code(CPUARMState
*env
, TranslationBlock
*tb
)
11238 gen_intermediate_code_internal(arm_env_get_cpu(env
), tb
, false);
11241 void gen_intermediate_code_pc(CPUARMState
*env
, TranslationBlock
*tb
)
11243 gen_intermediate_code_internal(arm_env_get_cpu(env
), tb
, true);
11246 static const char *cpu_mode_names
[16] = {
11247 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
11248 "???", "???", "hyp", "und", "???", "???", "???", "sys"
11251 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
11254 ARMCPU
*cpu
= ARM_CPU(cs
);
11255 CPUARMState
*env
= &cpu
->env
;
11260 aarch64_cpu_dump_state(cs
, f
, cpu_fprintf
, flags
);
11264 for(i
=0;i
<16;i
++) {
11265 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
11267 cpu_fprintf(f
, "\n");
11269 cpu_fprintf(f
, " ");
11271 psr
= cpsr_read(env
);
11272 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%d\n",
11274 psr
& (1 << 31) ? 'N' : '-',
11275 psr
& (1 << 30) ? 'Z' : '-',
11276 psr
& (1 << 29) ? 'C' : '-',
11277 psr
& (1 << 28) ? 'V' : '-',
11278 psr
& CPSR_T
? 'T' : 'A',
11279 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
11281 if (flags
& CPU_DUMP_FPU
) {
11282 int numvfpregs
= 0;
11283 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
11286 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
11289 for (i
= 0; i
< numvfpregs
; i
++) {
11290 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
11291 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
11292 i
* 2, (uint32_t)v
,
11293 i
* 2 + 1, (uint32_t)(v
>> 32),
11296 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
11300 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
, int pc_pos
)
11303 env
->pc
= tcg_ctx
.gen_opc_pc
[pc_pos
];
11304 env
->condexec_bits
= 0;
11306 env
->regs
[15] = tcg_ctx
.gen_opc_pc
[pc_pos
];
11307 env
->condexec_bits
= gen_opc_condexec_bits
[pc_pos
];