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;
7005 /* First check for coprocessor space used for XScale/iwMMXt insns */
7006 if (arm_feature(env
, ARM_FEATURE_XSCALE
) && (cpnum
< 2)) {
7007 if (extract32(s
->c15_cpar
, cpnum
, 1) == 0) {
7010 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
7011 return disas_iwmmxt_insn(env
, s
, insn
);
7012 } else if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
7013 return disas_dsp_insn(env
, s
, insn
);
7018 /* Otherwise treat as a generic register access */
7019 is64
= (insn
& (1 << 25)) == 0;
7020 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
7028 opc1
= (insn
>> 4) & 0xf;
7030 rt2
= (insn
>> 16) & 0xf;
7032 crn
= (insn
>> 16) & 0xf;
7033 opc1
= (insn
>> 21) & 7;
7034 opc2
= (insn
>> 5) & 7;
7037 isread
= (insn
>> 20) & 1;
7038 rt
= (insn
>> 12) & 0xf;
7040 ri
= get_arm_cp_reginfo(s
->cp_regs
,
7041 ENCODE_CP_REG(cpnum
, is64
, crn
, crm
, opc1
, opc2
));
7043 /* Check access permissions */
7044 if (!cp_access_ok(s
->current_pl
, ri
, isread
)) {
7049 (arm_feature(env
, ARM_FEATURE_XSCALE
) && cpnum
< 14)) {
7050 /* Emit code to perform further access permissions checks at
7051 * runtime; this may result in an exception.
7052 * Note that on XScale all cp0..c13 registers do an access check
7053 * call in order to handle c15_cpar.
7059 /* Note that since we are an implementation which takes an
7060 * exception on a trapped conditional instruction only if the
7061 * instruction passes its condition code check, we can take
7062 * advantage of the clause in the ARM ARM that allows us to set
7063 * the COND field in the instruction to 0xE in all cases.
7064 * We could fish the actual condition out of the insn (ARM)
7065 * or the condexec bits (Thumb) but it isn't necessary.
7070 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7073 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7074 rt
, isread
, s
->thumb
);
7079 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7082 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7083 rt
, isread
, s
->thumb
);
7087 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7088 * so this can only happen if this is an ARMv7 or earlier CPU,
7089 * in which case the syndrome information won't actually be
7092 assert(!arm_feature(env
, ARM_FEATURE_V8
));
7093 syndrome
= syn_uncategorized();
7097 gen_set_pc_im(s
, s
->pc
);
7098 tmpptr
= tcg_const_ptr(ri
);
7099 tcg_syn
= tcg_const_i32(syndrome
);
7100 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
);
7101 tcg_temp_free_ptr(tmpptr
);
7102 tcg_temp_free_i32(tcg_syn
);
7105 /* Handle special cases first */
7106 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
7113 gen_set_pc_im(s
, s
->pc
);
7114 s
->is_jmp
= DISAS_WFI
;
7120 if (use_icount
&& (ri
->type
& ARM_CP_IO
)) {
7129 if (ri
->type
& ARM_CP_CONST
) {
7130 tmp64
= tcg_const_i64(ri
->resetvalue
);
7131 } else if (ri
->readfn
) {
7133 tmp64
= tcg_temp_new_i64();
7134 tmpptr
= tcg_const_ptr(ri
);
7135 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
7136 tcg_temp_free_ptr(tmpptr
);
7138 tmp64
= tcg_temp_new_i64();
7139 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7141 tmp
= tcg_temp_new_i32();
7142 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7143 store_reg(s
, rt
, tmp
);
7144 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7145 tmp
= tcg_temp_new_i32();
7146 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7147 tcg_temp_free_i64(tmp64
);
7148 store_reg(s
, rt2
, tmp
);
7151 if (ri
->type
& ARM_CP_CONST
) {
7152 tmp
= tcg_const_i32(ri
->resetvalue
);
7153 } else if (ri
->readfn
) {
7155 tmp
= tcg_temp_new_i32();
7156 tmpptr
= tcg_const_ptr(ri
);
7157 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
7158 tcg_temp_free_ptr(tmpptr
);
7160 tmp
= load_cpu_offset(ri
->fieldoffset
);
7163 /* Destination register of r15 for 32 bit loads sets
7164 * the condition codes from the high 4 bits of the value
7167 tcg_temp_free_i32(tmp
);
7169 store_reg(s
, rt
, tmp
);
7174 if (ri
->type
& ARM_CP_CONST
) {
7175 /* If not forbidden by access permissions, treat as WI */
7180 TCGv_i32 tmplo
, tmphi
;
7181 TCGv_i64 tmp64
= tcg_temp_new_i64();
7182 tmplo
= load_reg(s
, rt
);
7183 tmphi
= load_reg(s
, rt2
);
7184 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
7185 tcg_temp_free_i32(tmplo
);
7186 tcg_temp_free_i32(tmphi
);
7188 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
7189 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
7190 tcg_temp_free_ptr(tmpptr
);
7192 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7194 tcg_temp_free_i64(tmp64
);
7199 tmp
= load_reg(s
, rt
);
7200 tmpptr
= tcg_const_ptr(ri
);
7201 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
7202 tcg_temp_free_ptr(tmpptr
);
7203 tcg_temp_free_i32(tmp
);
7205 TCGv_i32 tmp
= load_reg(s
, rt
);
7206 store_cpu_offset(tmp
, ri
->fieldoffset
);
7211 if (use_icount
&& (ri
->type
& ARM_CP_IO
)) {
7212 /* I/O operations must end the TB here (whether read or write) */
7215 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
7216 /* We default to ending the TB on a coprocessor register write,
7217 * but allow this to be suppressed by the register definition
7218 * (usually only necessary to work around guest bugs).
7226 /* Unknown register; this might be a guest error or a QEMU
7227 * unimplemented feature.
7230 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7231 "64 bit system register cp:%d opc1: %d crm:%d\n",
7232 isread
? "read" : "write", cpnum
, opc1
, crm
);
7234 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7235 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d\n",
7236 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
);
7243 /* Store a 64-bit value to a register pair. Clobbers val. */
7244 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
7247 tmp
= tcg_temp_new_i32();
7248 tcg_gen_trunc_i64_i32(tmp
, val
);
7249 store_reg(s
, rlow
, tmp
);
7250 tmp
= tcg_temp_new_i32();
7251 tcg_gen_shri_i64(val
, val
, 32);
7252 tcg_gen_trunc_i64_i32(tmp
, val
);
7253 store_reg(s
, rhigh
, tmp
);
7256 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7257 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
7262 /* Load value and extend to 64 bits. */
7263 tmp
= tcg_temp_new_i64();
7264 tmp2
= load_reg(s
, rlow
);
7265 tcg_gen_extu_i32_i64(tmp
, tmp2
);
7266 tcg_temp_free_i32(tmp2
);
7267 tcg_gen_add_i64(val
, val
, tmp
);
7268 tcg_temp_free_i64(tmp
);
7271 /* load and add a 64-bit value from a register pair. */
7272 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
7278 /* Load 64-bit value rd:rn. */
7279 tmpl
= load_reg(s
, rlow
);
7280 tmph
= load_reg(s
, rhigh
);
7281 tmp
= tcg_temp_new_i64();
7282 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
7283 tcg_temp_free_i32(tmpl
);
7284 tcg_temp_free_i32(tmph
);
7285 tcg_gen_add_i64(val
, val
, tmp
);
7286 tcg_temp_free_i64(tmp
);
7289 /* Set N and Z flags from hi|lo. */
7290 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
7292 tcg_gen_mov_i32(cpu_NF
, hi
);
7293 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
7296 /* Load/Store exclusive instructions are implemented by remembering
7297 the value/address loaded, and seeing if these are the same
7298 when the store is performed. This should be sufficient to implement
7299 the architecturally mandated semantics, and avoids having to monitor
7302 In system emulation mode only one CPU will be running at once, so
7303 this sequence is effectively atomic. In user emulation mode we
7304 throw an exception and handle the atomic operation elsewhere. */
7305 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
7306 TCGv_i32 addr
, int size
)
7308 TCGv_i32 tmp
= tcg_temp_new_i32();
7314 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
7317 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
7321 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
7328 TCGv_i32 tmp2
= tcg_temp_new_i32();
7329 TCGv_i32 tmp3
= tcg_temp_new_i32();
7331 tcg_gen_addi_i32(tmp2
, addr
, 4);
7332 gen_aa32_ld32u(tmp3
, tmp2
, get_mem_index(s
));
7333 tcg_temp_free_i32(tmp2
);
7334 tcg_gen_concat_i32_i64(cpu_exclusive_val
, tmp
, tmp3
);
7335 store_reg(s
, rt2
, tmp3
);
7337 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
7340 store_reg(s
, rt
, tmp
);
7341 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
7344 static void gen_clrex(DisasContext
*s
)
7346 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7349 #ifdef CONFIG_USER_ONLY
7350 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7351 TCGv_i32 addr
, int size
)
7353 tcg_gen_extu_i32_i64(cpu_exclusive_test
, addr
);
7354 tcg_gen_movi_i32(cpu_exclusive_info
,
7355 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
7356 gen_exception_internal_insn(s
, 4, EXCP_STREX
);
7359 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7360 TCGv_i32 addr
, int size
)
7363 TCGv_i64 val64
, extaddr
;
7367 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7373 fail_label
= gen_new_label();
7374 done_label
= gen_new_label();
7375 extaddr
= tcg_temp_new_i64();
7376 tcg_gen_extu_i32_i64(extaddr
, addr
);
7377 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
7378 tcg_temp_free_i64(extaddr
);
7380 tmp
= tcg_temp_new_i32();
7383 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
7386 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
7390 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
7396 val64
= tcg_temp_new_i64();
7398 TCGv_i32 tmp2
= tcg_temp_new_i32();
7399 TCGv_i32 tmp3
= tcg_temp_new_i32();
7400 tcg_gen_addi_i32(tmp2
, addr
, 4);
7401 gen_aa32_ld32u(tmp3
, tmp2
, get_mem_index(s
));
7402 tcg_temp_free_i32(tmp2
);
7403 tcg_gen_concat_i32_i64(val64
, tmp
, tmp3
);
7404 tcg_temp_free_i32(tmp3
);
7406 tcg_gen_extu_i32_i64(val64
, tmp
);
7408 tcg_temp_free_i32(tmp
);
7410 tcg_gen_brcond_i64(TCG_COND_NE
, val64
, cpu_exclusive_val
, fail_label
);
7411 tcg_temp_free_i64(val64
);
7413 tmp
= load_reg(s
, rt
);
7416 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
7419 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
7423 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7428 tcg_temp_free_i32(tmp
);
7430 tcg_gen_addi_i32(addr
, addr
, 4);
7431 tmp
= load_reg(s
, rt2
);
7432 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7433 tcg_temp_free_i32(tmp
);
7435 tcg_gen_movi_i32(cpu_R
[rd
], 0);
7436 tcg_gen_br(done_label
);
7437 gen_set_label(fail_label
);
7438 tcg_gen_movi_i32(cpu_R
[rd
], 1);
7439 gen_set_label(done_label
);
7440 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7447 * @mode: mode field from insn (which stack to store to)
7448 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7449 * @writeback: true if writeback bit set
7451 * Generate code for the SRS (Store Return State) insn.
7453 static void gen_srs(DisasContext
*s
,
7454 uint32_t mode
, uint32_t amode
, bool writeback
)
7457 TCGv_i32 addr
= tcg_temp_new_i32();
7458 TCGv_i32 tmp
= tcg_const_i32(mode
);
7459 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
7460 tcg_temp_free_i32(tmp
);
7477 tcg_gen_addi_i32(addr
, addr
, offset
);
7478 tmp
= load_reg(s
, 14);
7479 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7480 tcg_temp_free_i32(tmp
);
7481 tmp
= load_cpu_field(spsr
);
7482 tcg_gen_addi_i32(addr
, addr
, 4);
7483 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7484 tcg_temp_free_i32(tmp
);
7502 tcg_gen_addi_i32(addr
, addr
, offset
);
7503 tmp
= tcg_const_i32(mode
);
7504 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
7505 tcg_temp_free_i32(tmp
);
7507 tcg_temp_free_i32(addr
);
7510 static void disas_arm_insn(CPUARMState
* env
, DisasContext
*s
)
7512 unsigned int cond
, insn
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
7519 insn
= arm_ldl_code(env
, s
->pc
, s
->bswap_code
);
7522 /* M variants do not implement ARM mode. */
7527 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7528 * choose to UNDEF. In ARMv5 and above the space is used
7529 * for miscellaneous unconditional instructions.
7533 /* Unconditional instructions. */
7534 if (((insn
>> 25) & 7) == 1) {
7535 /* NEON Data processing. */
7536 if (!arm_feature(env
, ARM_FEATURE_NEON
))
7539 if (disas_neon_data_insn(env
, s
, insn
))
7543 if ((insn
& 0x0f100000) == 0x04000000) {
7544 /* NEON load/store. */
7545 if (!arm_feature(env
, ARM_FEATURE_NEON
))
7548 if (disas_neon_ls_insn(env
, s
, insn
))
7552 if ((insn
& 0x0f000e10) == 0x0e000a00) {
7554 if (disas_vfp_insn(env
, s
, insn
)) {
7559 if (((insn
& 0x0f30f000) == 0x0510f000) ||
7560 ((insn
& 0x0f30f010) == 0x0710f000)) {
7561 if ((insn
& (1 << 22)) == 0) {
7563 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
7567 /* Otherwise PLD; v5TE+ */
7571 if (((insn
& 0x0f70f000) == 0x0450f000) ||
7572 ((insn
& 0x0f70f010) == 0x0650f000)) {
7574 return; /* PLI; V7 */
7576 if (((insn
& 0x0f700000) == 0x04100000) ||
7577 ((insn
& 0x0f700010) == 0x06100000)) {
7578 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
7581 return; /* v7MP: Unallocated memory hint: must NOP */
7584 if ((insn
& 0x0ffffdff) == 0x01010000) {
7587 if (((insn
>> 9) & 1) != s
->bswap_code
) {
7588 /* Dynamic endianness switching not implemented. */
7589 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
7593 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
7594 switch ((insn
>> 4) & 0xf) {
7603 /* We don't emulate caches so these are a no-op. */
7608 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
7614 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
7616 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
7622 rn
= (insn
>> 16) & 0xf;
7623 addr
= load_reg(s
, rn
);
7624 i
= (insn
>> 23) & 3;
7626 case 0: offset
= -4; break; /* DA */
7627 case 1: offset
= 0; break; /* IA */
7628 case 2: offset
= -8; break; /* DB */
7629 case 3: offset
= 4; break; /* IB */
7633 tcg_gen_addi_i32(addr
, addr
, offset
);
7634 /* Load PC into tmp and CPSR into tmp2. */
7635 tmp
= tcg_temp_new_i32();
7636 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
7637 tcg_gen_addi_i32(addr
, addr
, 4);
7638 tmp2
= tcg_temp_new_i32();
7639 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
7640 if (insn
& (1 << 21)) {
7641 /* Base writeback. */
7643 case 0: offset
= -8; break;
7644 case 1: offset
= 4; break;
7645 case 2: offset
= -4; break;
7646 case 3: offset
= 0; break;
7650 tcg_gen_addi_i32(addr
, addr
, offset
);
7651 store_reg(s
, rn
, addr
);
7653 tcg_temp_free_i32(addr
);
7655 gen_rfe(s
, tmp
, tmp2
);
7657 } else if ((insn
& 0x0e000000) == 0x0a000000) {
7658 /* branch link and change to thumb (blx <offset>) */
7661 val
= (uint32_t)s
->pc
;
7662 tmp
= tcg_temp_new_i32();
7663 tcg_gen_movi_i32(tmp
, val
);
7664 store_reg(s
, 14, tmp
);
7665 /* Sign-extend the 24-bit offset */
7666 offset
= (((int32_t)insn
) << 8) >> 8;
7667 /* offset * 4 + bit24 * 2 + (thumb bit) */
7668 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
7669 /* pipeline offset */
7671 /* protected by ARCH(5); above, near the start of uncond block */
7674 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
7675 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
7676 /* iWMMXt register transfer. */
7677 if (extract32(s
->c15_cpar
, 1, 1)) {
7678 if (!disas_iwmmxt_insn(env
, s
, insn
)) {
7683 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
7684 /* Coprocessor double register transfer. */
7686 } else if ((insn
& 0x0f000010) == 0x0e000010) {
7687 /* Additional coprocessor register transfer. */
7688 } else if ((insn
& 0x0ff10020) == 0x01000000) {
7691 /* cps (privileged) */
7695 if (insn
& (1 << 19)) {
7696 if (insn
& (1 << 8))
7698 if (insn
& (1 << 7))
7700 if (insn
& (1 << 6))
7702 if (insn
& (1 << 18))
7705 if (insn
& (1 << 17)) {
7707 val
|= (insn
& 0x1f);
7710 gen_set_psr_im(s
, mask
, 0, val
);
7717 /* if not always execute, we generate a conditional jump to
7719 s
->condlabel
= gen_new_label();
7720 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
7723 if ((insn
& 0x0f900000) == 0x03000000) {
7724 if ((insn
& (1 << 21)) == 0) {
7726 rd
= (insn
>> 12) & 0xf;
7727 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
7728 if ((insn
& (1 << 22)) == 0) {
7730 tmp
= tcg_temp_new_i32();
7731 tcg_gen_movi_i32(tmp
, val
);
7734 tmp
= load_reg(s
, rd
);
7735 tcg_gen_ext16u_i32(tmp
, tmp
);
7736 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
7738 store_reg(s
, rd
, tmp
);
7740 if (((insn
>> 12) & 0xf) != 0xf)
7742 if (((insn
>> 16) & 0xf) == 0) {
7743 gen_nop_hint(s
, insn
& 0xff);
7745 /* CPSR = immediate */
7747 shift
= ((insn
>> 8) & 0xf) * 2;
7749 val
= (val
>> shift
) | (val
<< (32 - shift
));
7750 i
= ((insn
& (1 << 22)) != 0);
7751 if (gen_set_psr_im(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, val
))
7755 } else if ((insn
& 0x0f900000) == 0x01000000
7756 && (insn
& 0x00000090) != 0x00000090) {
7757 /* miscellaneous instructions */
7758 op1
= (insn
>> 21) & 3;
7759 sh
= (insn
>> 4) & 0xf;
7762 case 0x0: /* move program status register */
7765 tmp
= load_reg(s
, rm
);
7766 i
= ((op1
& 2) != 0);
7767 if (gen_set_psr(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
7771 rd
= (insn
>> 12) & 0xf;
7775 tmp
= load_cpu_field(spsr
);
7777 tmp
= tcg_temp_new_i32();
7778 gen_helper_cpsr_read(tmp
, cpu_env
);
7780 store_reg(s
, rd
, tmp
);
7785 /* branch/exchange thumb (bx). */
7787 tmp
= load_reg(s
, rm
);
7789 } else if (op1
== 3) {
7792 rd
= (insn
>> 12) & 0xf;
7793 tmp
= load_reg(s
, rm
);
7794 gen_helper_clz(tmp
, tmp
);
7795 store_reg(s
, rd
, tmp
);
7803 /* Trivial implementation equivalent to bx. */
7804 tmp
= load_reg(s
, rm
);
7815 /* branch link/exchange thumb (blx) */
7816 tmp
= load_reg(s
, rm
);
7817 tmp2
= tcg_temp_new_i32();
7818 tcg_gen_movi_i32(tmp2
, s
->pc
);
7819 store_reg(s
, 14, tmp2
);
7825 uint32_t c
= extract32(insn
, 8, 4);
7827 /* Check this CPU supports ARMv8 CRC instructions.
7828 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
7829 * Bits 8, 10 and 11 should be zero.
7831 if (!arm_feature(env
, ARM_FEATURE_CRC
) || op1
== 0x3 ||
7836 rn
= extract32(insn
, 16, 4);
7837 rd
= extract32(insn
, 12, 4);
7839 tmp
= load_reg(s
, rn
);
7840 tmp2
= load_reg(s
, rm
);
7842 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
7843 } else if (op1
== 1) {
7844 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
7846 tmp3
= tcg_const_i32(1 << op1
);
7848 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
7850 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
7852 tcg_temp_free_i32(tmp2
);
7853 tcg_temp_free_i32(tmp3
);
7854 store_reg(s
, rd
, tmp
);
7857 case 0x5: /* saturating add/subtract */
7859 rd
= (insn
>> 12) & 0xf;
7860 rn
= (insn
>> 16) & 0xf;
7861 tmp
= load_reg(s
, rm
);
7862 tmp2
= load_reg(s
, rn
);
7864 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
7866 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
7868 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
7869 tcg_temp_free_i32(tmp2
);
7870 store_reg(s
, rd
, tmp
);
7874 int imm16
= extract32(insn
, 0, 4) | (extract32(insn
, 8, 12) << 4);
7875 /* SMC instruction (op1 == 3)
7876 and undefined instructions (op1 == 0 || op1 == 2)
7883 gen_exception_insn(s
, 4, EXCP_BKPT
, syn_aa32_bkpt(imm16
, false));
7886 case 0x8: /* signed multiply */
7891 rs
= (insn
>> 8) & 0xf;
7892 rn
= (insn
>> 12) & 0xf;
7893 rd
= (insn
>> 16) & 0xf;
7895 /* (32 * 16) >> 16 */
7896 tmp
= load_reg(s
, rm
);
7897 tmp2
= load_reg(s
, rs
);
7899 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
7902 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7903 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
7904 tmp
= tcg_temp_new_i32();
7905 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7906 tcg_temp_free_i64(tmp64
);
7907 if ((sh
& 2) == 0) {
7908 tmp2
= load_reg(s
, rn
);
7909 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7910 tcg_temp_free_i32(tmp2
);
7912 store_reg(s
, rd
, tmp
);
7915 tmp
= load_reg(s
, rm
);
7916 tmp2
= load_reg(s
, rs
);
7917 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
7918 tcg_temp_free_i32(tmp2
);
7920 tmp64
= tcg_temp_new_i64();
7921 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7922 tcg_temp_free_i32(tmp
);
7923 gen_addq(s
, tmp64
, rn
, rd
);
7924 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7925 tcg_temp_free_i64(tmp64
);
7928 tmp2
= load_reg(s
, rn
);
7929 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7930 tcg_temp_free_i32(tmp2
);
7932 store_reg(s
, rd
, tmp
);
7939 } else if (((insn
& 0x0e000000) == 0 &&
7940 (insn
& 0x00000090) != 0x90) ||
7941 ((insn
& 0x0e000000) == (1 << 25))) {
7942 int set_cc
, logic_cc
, shiftop
;
7944 op1
= (insn
>> 21) & 0xf;
7945 set_cc
= (insn
>> 20) & 1;
7946 logic_cc
= table_logic_cc
[op1
] & set_cc
;
7948 /* data processing instruction */
7949 if (insn
& (1 << 25)) {
7950 /* immediate operand */
7952 shift
= ((insn
>> 8) & 0xf) * 2;
7954 val
= (val
>> shift
) | (val
<< (32 - shift
));
7956 tmp2
= tcg_temp_new_i32();
7957 tcg_gen_movi_i32(tmp2
, val
);
7958 if (logic_cc
&& shift
) {
7959 gen_set_CF_bit31(tmp2
);
7964 tmp2
= load_reg(s
, rm
);
7965 shiftop
= (insn
>> 5) & 3;
7966 if (!(insn
& (1 << 4))) {
7967 shift
= (insn
>> 7) & 0x1f;
7968 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
7970 rs
= (insn
>> 8) & 0xf;
7971 tmp
= load_reg(s
, rs
);
7972 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
7975 if (op1
!= 0x0f && op1
!= 0x0d) {
7976 rn
= (insn
>> 16) & 0xf;
7977 tmp
= load_reg(s
, rn
);
7979 TCGV_UNUSED_I32(tmp
);
7981 rd
= (insn
>> 12) & 0xf;
7984 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
7988 store_reg_bx(env
, s
, rd
, tmp
);
7991 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
7995 store_reg_bx(env
, s
, rd
, tmp
);
7998 if (set_cc
&& rd
== 15) {
7999 /* SUBS r15, ... is used for exception return. */
8003 gen_sub_CC(tmp
, tmp
, tmp2
);
8004 gen_exception_return(s
, tmp
);
8007 gen_sub_CC(tmp
, tmp
, tmp2
);
8009 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8011 store_reg_bx(env
, s
, rd
, tmp
);
8016 gen_sub_CC(tmp
, tmp2
, tmp
);
8018 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8020 store_reg_bx(env
, s
, rd
, tmp
);
8024 gen_add_CC(tmp
, tmp
, tmp2
);
8026 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8028 store_reg_bx(env
, s
, rd
, tmp
);
8032 gen_adc_CC(tmp
, tmp
, tmp2
);
8034 gen_add_carry(tmp
, tmp
, tmp2
);
8036 store_reg_bx(env
, s
, rd
, tmp
);
8040 gen_sbc_CC(tmp
, tmp
, tmp2
);
8042 gen_sub_carry(tmp
, tmp
, tmp2
);
8044 store_reg_bx(env
, s
, rd
, tmp
);
8048 gen_sbc_CC(tmp
, tmp2
, tmp
);
8050 gen_sub_carry(tmp
, tmp2
, tmp
);
8052 store_reg_bx(env
, s
, rd
, tmp
);
8056 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8059 tcg_temp_free_i32(tmp
);
8063 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8066 tcg_temp_free_i32(tmp
);
8070 gen_sub_CC(tmp
, tmp
, tmp2
);
8072 tcg_temp_free_i32(tmp
);
8076 gen_add_CC(tmp
, tmp
, tmp2
);
8078 tcg_temp_free_i32(tmp
);
8081 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8085 store_reg_bx(env
, s
, rd
, tmp
);
8088 if (logic_cc
&& rd
== 15) {
8089 /* MOVS r15, ... is used for exception return. */
8093 gen_exception_return(s
, tmp2
);
8098 store_reg_bx(env
, s
, rd
, tmp2
);
8102 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
8106 store_reg_bx(env
, s
, rd
, tmp
);
8110 tcg_gen_not_i32(tmp2
, tmp2
);
8114 store_reg_bx(env
, s
, rd
, tmp2
);
8117 if (op1
!= 0x0f && op1
!= 0x0d) {
8118 tcg_temp_free_i32(tmp2
);
8121 /* other instructions */
8122 op1
= (insn
>> 24) & 0xf;
8126 /* multiplies, extra load/stores */
8127 sh
= (insn
>> 5) & 3;
8130 rd
= (insn
>> 16) & 0xf;
8131 rn
= (insn
>> 12) & 0xf;
8132 rs
= (insn
>> 8) & 0xf;
8134 op1
= (insn
>> 20) & 0xf;
8136 case 0: case 1: case 2: case 3: case 6:
8138 tmp
= load_reg(s
, rs
);
8139 tmp2
= load_reg(s
, rm
);
8140 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8141 tcg_temp_free_i32(tmp2
);
8142 if (insn
& (1 << 22)) {
8143 /* Subtract (mls) */
8145 tmp2
= load_reg(s
, rn
);
8146 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8147 tcg_temp_free_i32(tmp2
);
8148 } else if (insn
& (1 << 21)) {
8150 tmp2
= load_reg(s
, rn
);
8151 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8152 tcg_temp_free_i32(tmp2
);
8154 if (insn
& (1 << 20))
8156 store_reg(s
, rd
, tmp
);
8159 /* 64 bit mul double accumulate (UMAAL) */
8161 tmp
= load_reg(s
, rs
);
8162 tmp2
= load_reg(s
, rm
);
8163 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8164 gen_addq_lo(s
, tmp64
, rn
);
8165 gen_addq_lo(s
, tmp64
, rd
);
8166 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8167 tcg_temp_free_i64(tmp64
);
8169 case 8: case 9: case 10: case 11:
8170 case 12: case 13: case 14: case 15:
8171 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8172 tmp
= load_reg(s
, rs
);
8173 tmp2
= load_reg(s
, rm
);
8174 if (insn
& (1 << 22)) {
8175 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
8177 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
8179 if (insn
& (1 << 21)) { /* mult accumulate */
8180 TCGv_i32 al
= load_reg(s
, rn
);
8181 TCGv_i32 ah
= load_reg(s
, rd
);
8182 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
8183 tcg_temp_free_i32(al
);
8184 tcg_temp_free_i32(ah
);
8186 if (insn
& (1 << 20)) {
8187 gen_logicq_cc(tmp
, tmp2
);
8189 store_reg(s
, rn
, tmp
);
8190 store_reg(s
, rd
, tmp2
);
8196 rn
= (insn
>> 16) & 0xf;
8197 rd
= (insn
>> 12) & 0xf;
8198 if (insn
& (1 << 23)) {
8199 /* load/store exclusive */
8200 int op2
= (insn
>> 8) & 3;
8201 op1
= (insn
>> 21) & 0x3;
8204 case 0: /* lda/stl */
8210 case 1: /* reserved */
8212 case 2: /* ldaex/stlex */
8215 case 3: /* ldrex/strex */
8224 addr
= tcg_temp_local_new_i32();
8225 load_reg_var(s
, addr
, rn
);
8227 /* Since the emulation does not have barriers,
8228 the acquire/release semantics need no special
8231 if (insn
& (1 << 20)) {
8232 tmp
= tcg_temp_new_i32();
8235 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8238 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
8241 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
8246 store_reg(s
, rd
, tmp
);
8249 tmp
= load_reg(s
, rm
);
8252 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8255 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
8258 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
8263 tcg_temp_free_i32(tmp
);
8265 } else if (insn
& (1 << 20)) {
8268 gen_load_exclusive(s
, rd
, 15, addr
, 2);
8270 case 1: /* ldrexd */
8271 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
8273 case 2: /* ldrexb */
8274 gen_load_exclusive(s
, rd
, 15, addr
, 0);
8276 case 3: /* ldrexh */
8277 gen_load_exclusive(s
, rd
, 15, addr
, 1);
8286 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
8288 case 1: /* strexd */
8289 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
8291 case 2: /* strexb */
8292 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
8294 case 3: /* strexh */
8295 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
8301 tcg_temp_free_i32(addr
);
8303 /* SWP instruction */
8306 /* ??? This is not really atomic. However we know
8307 we never have multiple CPUs running in parallel,
8308 so it is good enough. */
8309 addr
= load_reg(s
, rn
);
8310 tmp
= load_reg(s
, rm
);
8311 tmp2
= tcg_temp_new_i32();
8312 if (insn
& (1 << 22)) {
8313 gen_aa32_ld8u(tmp2
, addr
, get_mem_index(s
));
8314 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
8316 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
8317 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8319 tcg_temp_free_i32(tmp
);
8320 tcg_temp_free_i32(addr
);
8321 store_reg(s
, rd
, tmp2
);
8327 /* Misc load/store */
8328 rn
= (insn
>> 16) & 0xf;
8329 rd
= (insn
>> 12) & 0xf;
8330 addr
= load_reg(s
, rn
);
8331 if (insn
& (1 << 24))
8332 gen_add_datah_offset(s
, insn
, 0, addr
);
8334 if (insn
& (1 << 20)) {
8336 tmp
= tcg_temp_new_i32();
8339 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
8342 gen_aa32_ld8s(tmp
, addr
, get_mem_index(s
));
8346 gen_aa32_ld16s(tmp
, addr
, get_mem_index(s
));
8350 } else if (sh
& 2) {
8355 tmp
= load_reg(s
, rd
);
8356 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8357 tcg_temp_free_i32(tmp
);
8358 tcg_gen_addi_i32(addr
, addr
, 4);
8359 tmp
= load_reg(s
, rd
+ 1);
8360 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8361 tcg_temp_free_i32(tmp
);
8365 tmp
= tcg_temp_new_i32();
8366 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8367 store_reg(s
, rd
, tmp
);
8368 tcg_gen_addi_i32(addr
, addr
, 4);
8369 tmp
= tcg_temp_new_i32();
8370 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8374 address_offset
= -4;
8377 tmp
= load_reg(s
, rd
);
8378 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
8379 tcg_temp_free_i32(tmp
);
8382 /* Perform base writeback before the loaded value to
8383 ensure correct behavior with overlapping index registers.
8384 ldrd with base writeback is is undefined if the
8385 destination and index registers overlap. */
8386 if (!(insn
& (1 << 24))) {
8387 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
8388 store_reg(s
, rn
, addr
);
8389 } else if (insn
& (1 << 21)) {
8391 tcg_gen_addi_i32(addr
, addr
, address_offset
);
8392 store_reg(s
, rn
, addr
);
8394 tcg_temp_free_i32(addr
);
8397 /* Complete the load. */
8398 store_reg(s
, rd
, tmp
);
8407 if (insn
& (1 << 4)) {
8409 /* Armv6 Media instructions. */
8411 rn
= (insn
>> 16) & 0xf;
8412 rd
= (insn
>> 12) & 0xf;
8413 rs
= (insn
>> 8) & 0xf;
8414 switch ((insn
>> 23) & 3) {
8415 case 0: /* Parallel add/subtract. */
8416 op1
= (insn
>> 20) & 7;
8417 tmp
= load_reg(s
, rn
);
8418 tmp2
= load_reg(s
, rm
);
8419 sh
= (insn
>> 5) & 7;
8420 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
8422 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
8423 tcg_temp_free_i32(tmp2
);
8424 store_reg(s
, rd
, tmp
);
8427 if ((insn
& 0x00700020) == 0) {
8428 /* Halfword pack. */
8429 tmp
= load_reg(s
, rn
);
8430 tmp2
= load_reg(s
, rm
);
8431 shift
= (insn
>> 7) & 0x1f;
8432 if (insn
& (1 << 6)) {
8436 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8437 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8438 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8442 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8443 tcg_gen_ext16u_i32(tmp
, tmp
);
8444 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8446 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8447 tcg_temp_free_i32(tmp2
);
8448 store_reg(s
, rd
, tmp
);
8449 } else if ((insn
& 0x00200020) == 0x00200000) {
8451 tmp
= load_reg(s
, rm
);
8452 shift
= (insn
>> 7) & 0x1f;
8453 if (insn
& (1 << 6)) {
8456 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8458 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8460 sh
= (insn
>> 16) & 0x1f;
8461 tmp2
= tcg_const_i32(sh
);
8462 if (insn
& (1 << 22))
8463 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
8465 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
8466 tcg_temp_free_i32(tmp2
);
8467 store_reg(s
, rd
, tmp
);
8468 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
8470 tmp
= load_reg(s
, rm
);
8471 sh
= (insn
>> 16) & 0x1f;
8472 tmp2
= tcg_const_i32(sh
);
8473 if (insn
& (1 << 22))
8474 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
8476 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
8477 tcg_temp_free_i32(tmp2
);
8478 store_reg(s
, rd
, tmp
);
8479 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
8481 tmp
= load_reg(s
, rn
);
8482 tmp2
= load_reg(s
, rm
);
8483 tmp3
= tcg_temp_new_i32();
8484 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
8485 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
8486 tcg_temp_free_i32(tmp3
);
8487 tcg_temp_free_i32(tmp2
);
8488 store_reg(s
, rd
, tmp
);
8489 } else if ((insn
& 0x000003e0) == 0x00000060) {
8490 tmp
= load_reg(s
, rm
);
8491 shift
= (insn
>> 10) & 3;
8492 /* ??? In many cases it's not necessary to do a
8493 rotate, a shift is sufficient. */
8495 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
8496 op1
= (insn
>> 20) & 7;
8498 case 0: gen_sxtb16(tmp
); break;
8499 case 2: gen_sxtb(tmp
); break;
8500 case 3: gen_sxth(tmp
); break;
8501 case 4: gen_uxtb16(tmp
); break;
8502 case 6: gen_uxtb(tmp
); break;
8503 case 7: gen_uxth(tmp
); break;
8504 default: goto illegal_op
;
8507 tmp2
= load_reg(s
, rn
);
8508 if ((op1
& 3) == 0) {
8509 gen_add16(tmp
, tmp2
);
8511 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8512 tcg_temp_free_i32(tmp2
);
8515 store_reg(s
, rd
, tmp
);
8516 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
8518 tmp
= load_reg(s
, rm
);
8519 if (insn
& (1 << 22)) {
8520 if (insn
& (1 << 7)) {
8524 gen_helper_rbit(tmp
, tmp
);
8527 if (insn
& (1 << 7))
8530 tcg_gen_bswap32_i32(tmp
, tmp
);
8532 store_reg(s
, rd
, tmp
);
8537 case 2: /* Multiplies (Type 3). */
8538 switch ((insn
>> 20) & 0x7) {
8540 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
8541 /* op2 not 00x or 11x : UNDEF */
8544 /* Signed multiply most significant [accumulate].
8545 (SMMUL, SMMLA, SMMLS) */
8546 tmp
= load_reg(s
, rm
);
8547 tmp2
= load_reg(s
, rs
);
8548 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8551 tmp
= load_reg(s
, rd
);
8552 if (insn
& (1 << 6)) {
8553 tmp64
= gen_subq_msw(tmp64
, tmp
);
8555 tmp64
= gen_addq_msw(tmp64
, tmp
);
8558 if (insn
& (1 << 5)) {
8559 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
8561 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
8562 tmp
= tcg_temp_new_i32();
8563 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8564 tcg_temp_free_i64(tmp64
);
8565 store_reg(s
, rn
, tmp
);
8569 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8570 if (insn
& (1 << 7)) {
8573 tmp
= load_reg(s
, rm
);
8574 tmp2
= load_reg(s
, rs
);
8575 if (insn
& (1 << 5))
8576 gen_swap_half(tmp2
);
8577 gen_smul_dual(tmp
, tmp2
);
8578 if (insn
& (1 << 22)) {
8579 /* smlald, smlsld */
8582 tmp64
= tcg_temp_new_i64();
8583 tmp64_2
= tcg_temp_new_i64();
8584 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8585 tcg_gen_ext_i32_i64(tmp64_2
, tmp2
);
8586 tcg_temp_free_i32(tmp
);
8587 tcg_temp_free_i32(tmp2
);
8588 if (insn
& (1 << 6)) {
8589 tcg_gen_sub_i64(tmp64
, tmp64
, tmp64_2
);
8591 tcg_gen_add_i64(tmp64
, tmp64
, tmp64_2
);
8593 tcg_temp_free_i64(tmp64_2
);
8594 gen_addq(s
, tmp64
, rd
, rn
);
8595 gen_storeq_reg(s
, rd
, rn
, tmp64
);
8596 tcg_temp_free_i64(tmp64
);
8598 /* smuad, smusd, smlad, smlsd */
8599 if (insn
& (1 << 6)) {
8600 /* This subtraction cannot overflow. */
8601 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8603 /* This addition cannot overflow 32 bits;
8604 * however it may overflow considered as a
8605 * signed operation, in which case we must set
8608 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8610 tcg_temp_free_i32(tmp2
);
8613 tmp2
= load_reg(s
, rd
);
8614 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8615 tcg_temp_free_i32(tmp2
);
8617 store_reg(s
, rn
, tmp
);
8623 if (!arm_feature(env
, ARM_FEATURE_ARM_DIV
)) {
8626 if (((insn
>> 5) & 7) || (rd
!= 15)) {
8629 tmp
= load_reg(s
, rm
);
8630 tmp2
= load_reg(s
, rs
);
8631 if (insn
& (1 << 21)) {
8632 gen_helper_udiv(tmp
, tmp
, tmp2
);
8634 gen_helper_sdiv(tmp
, tmp
, tmp2
);
8636 tcg_temp_free_i32(tmp2
);
8637 store_reg(s
, rn
, tmp
);
8644 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
8646 case 0: /* Unsigned sum of absolute differences. */
8648 tmp
= load_reg(s
, rm
);
8649 tmp2
= load_reg(s
, rs
);
8650 gen_helper_usad8(tmp
, tmp
, tmp2
);
8651 tcg_temp_free_i32(tmp2
);
8653 tmp2
= load_reg(s
, rd
);
8654 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8655 tcg_temp_free_i32(tmp2
);
8657 store_reg(s
, rn
, tmp
);
8659 case 0x20: case 0x24: case 0x28: case 0x2c:
8660 /* Bitfield insert/clear. */
8662 shift
= (insn
>> 7) & 0x1f;
8663 i
= (insn
>> 16) & 0x1f;
8666 tmp
= tcg_temp_new_i32();
8667 tcg_gen_movi_i32(tmp
, 0);
8669 tmp
= load_reg(s
, rm
);
8672 tmp2
= load_reg(s
, rd
);
8673 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
8674 tcg_temp_free_i32(tmp2
);
8676 store_reg(s
, rd
, tmp
);
8678 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8679 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8681 tmp
= load_reg(s
, rm
);
8682 shift
= (insn
>> 7) & 0x1f;
8683 i
= ((insn
>> 16) & 0x1f) + 1;
8688 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
8690 gen_sbfx(tmp
, shift
, i
);
8693 store_reg(s
, rd
, tmp
);
8703 /* Check for undefined extension instructions
8704 * per the ARM Bible IE:
8705 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8707 sh
= (0xf << 20) | (0xf << 4);
8708 if (op1
== 0x7 && ((insn
& sh
) == sh
))
8712 /* load/store byte/word */
8713 rn
= (insn
>> 16) & 0xf;
8714 rd
= (insn
>> 12) & 0xf;
8715 tmp2
= load_reg(s
, rn
);
8716 if ((insn
& 0x01200000) == 0x00200000) {
8720 i
= get_mem_index(s
);
8722 if (insn
& (1 << 24))
8723 gen_add_data_offset(s
, insn
, tmp2
);
8724 if (insn
& (1 << 20)) {
8726 tmp
= tcg_temp_new_i32();
8727 if (insn
& (1 << 22)) {
8728 gen_aa32_ld8u(tmp
, tmp2
, i
);
8730 gen_aa32_ld32u(tmp
, tmp2
, i
);
8734 tmp
= load_reg(s
, rd
);
8735 if (insn
& (1 << 22)) {
8736 gen_aa32_st8(tmp
, tmp2
, i
);
8738 gen_aa32_st32(tmp
, tmp2
, i
);
8740 tcg_temp_free_i32(tmp
);
8742 if (!(insn
& (1 << 24))) {
8743 gen_add_data_offset(s
, insn
, tmp2
);
8744 store_reg(s
, rn
, tmp2
);
8745 } else if (insn
& (1 << 21)) {
8746 store_reg(s
, rn
, tmp2
);
8748 tcg_temp_free_i32(tmp2
);
8750 if (insn
& (1 << 20)) {
8751 /* Complete the load. */
8752 store_reg_from_load(env
, s
, rd
, tmp
);
8758 int j
, n
, user
, loaded_base
;
8759 TCGv_i32 loaded_var
;
8760 /* load/store multiple words */
8761 /* XXX: store correct base if write back */
8763 if (insn
& (1 << 22)) {
8765 goto illegal_op
; /* only usable in supervisor mode */
8767 if ((insn
& (1 << 15)) == 0)
8770 rn
= (insn
>> 16) & 0xf;
8771 addr
= load_reg(s
, rn
);
8773 /* compute total size */
8775 TCGV_UNUSED_I32(loaded_var
);
8778 if (insn
& (1 << i
))
8781 /* XXX: test invalid n == 0 case ? */
8782 if (insn
& (1 << 23)) {
8783 if (insn
& (1 << 24)) {
8785 tcg_gen_addi_i32(addr
, addr
, 4);
8787 /* post increment */
8790 if (insn
& (1 << 24)) {
8792 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
8794 /* post decrement */
8796 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
8801 if (insn
& (1 << i
)) {
8802 if (insn
& (1 << 20)) {
8804 tmp
= tcg_temp_new_i32();
8805 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8807 tmp2
= tcg_const_i32(i
);
8808 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
8809 tcg_temp_free_i32(tmp2
);
8810 tcg_temp_free_i32(tmp
);
8811 } else if (i
== rn
) {
8815 store_reg_from_load(env
, s
, i
, tmp
);
8820 /* special case: r15 = PC + 8 */
8821 val
= (long)s
->pc
+ 4;
8822 tmp
= tcg_temp_new_i32();
8823 tcg_gen_movi_i32(tmp
, val
);
8825 tmp
= tcg_temp_new_i32();
8826 tmp2
= tcg_const_i32(i
);
8827 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
8828 tcg_temp_free_i32(tmp2
);
8830 tmp
= load_reg(s
, i
);
8832 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8833 tcg_temp_free_i32(tmp
);
8836 /* no need to add after the last transfer */
8838 tcg_gen_addi_i32(addr
, addr
, 4);
8841 if (insn
& (1 << 21)) {
8843 if (insn
& (1 << 23)) {
8844 if (insn
& (1 << 24)) {
8847 /* post increment */
8848 tcg_gen_addi_i32(addr
, addr
, 4);
8851 if (insn
& (1 << 24)) {
8854 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
8856 /* post decrement */
8857 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
8860 store_reg(s
, rn
, addr
);
8862 tcg_temp_free_i32(addr
);
8865 store_reg(s
, rn
, loaded_var
);
8867 if ((insn
& (1 << 22)) && !user
) {
8868 /* Restore CPSR from SPSR. */
8869 tmp
= load_cpu_field(spsr
);
8870 gen_set_cpsr(tmp
, CPSR_ERET_MASK
);
8871 tcg_temp_free_i32(tmp
);
8872 s
->is_jmp
= DISAS_UPDATE
;
8881 /* branch (and link) */
8882 val
= (int32_t)s
->pc
;
8883 if (insn
& (1 << 24)) {
8884 tmp
= tcg_temp_new_i32();
8885 tcg_gen_movi_i32(tmp
, val
);
8886 store_reg(s
, 14, tmp
);
8888 offset
= sextract32(insn
<< 2, 0, 26);
8896 if (((insn
>> 8) & 0xe) == 10) {
8898 if (disas_vfp_insn(env
, s
, insn
)) {
8901 } else if (disas_coproc_insn(env
, s
, insn
)) {
8908 gen_set_pc_im(s
, s
->pc
);
8909 s
->svc_imm
= extract32(insn
, 0, 24);
8910 s
->is_jmp
= DISAS_SWI
;
8914 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized());
8920 /* Return true if this is a Thumb-2 logical op. */
8922 thumb2_logic_op(int op
)
8927 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
8928 then set condition code flags based on the result of the operation.
8929 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8930 to the high bit of T1.
8931 Returns zero if the opcode is valid. */
8934 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
8935 TCGv_i32 t0
, TCGv_i32 t1
)
8942 tcg_gen_and_i32(t0
, t0
, t1
);
8946 tcg_gen_andc_i32(t0
, t0
, t1
);
8950 tcg_gen_or_i32(t0
, t0
, t1
);
8954 tcg_gen_orc_i32(t0
, t0
, t1
);
8958 tcg_gen_xor_i32(t0
, t0
, t1
);
8963 gen_add_CC(t0
, t0
, t1
);
8965 tcg_gen_add_i32(t0
, t0
, t1
);
8969 gen_adc_CC(t0
, t0
, t1
);
8975 gen_sbc_CC(t0
, t0
, t1
);
8977 gen_sub_carry(t0
, t0
, t1
);
8982 gen_sub_CC(t0
, t0
, t1
);
8984 tcg_gen_sub_i32(t0
, t0
, t1
);
8988 gen_sub_CC(t0
, t1
, t0
);
8990 tcg_gen_sub_i32(t0
, t1
, t0
);
8992 default: /* 5, 6, 7, 9, 12, 15. */
8998 gen_set_CF_bit31(t1
);
9003 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
9005 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
9007 uint32_t insn
, imm
, shift
, offset
;
9008 uint32_t rd
, rn
, rm
, rs
;
9019 if (!(arm_feature(env
, ARM_FEATURE_THUMB2
)
9020 || arm_feature (env
, ARM_FEATURE_M
))) {
9021 /* Thumb-1 cores may need to treat bl and blx as a pair of
9022 16-bit instructions to get correct prefetch abort behavior. */
9024 if ((insn
& (1 << 12)) == 0) {
9026 /* Second half of blx. */
9027 offset
= ((insn
& 0x7ff) << 1);
9028 tmp
= load_reg(s
, 14);
9029 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9030 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
9032 tmp2
= tcg_temp_new_i32();
9033 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9034 store_reg(s
, 14, tmp2
);
9038 if (insn
& (1 << 11)) {
9039 /* Second half of bl. */
9040 offset
= ((insn
& 0x7ff) << 1) | 1;
9041 tmp
= load_reg(s
, 14);
9042 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9044 tmp2
= tcg_temp_new_i32();
9045 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9046 store_reg(s
, 14, tmp2
);
9050 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
9051 /* Instruction spans a page boundary. Implement it as two
9052 16-bit instructions in case the second half causes an
9054 offset
= ((int32_t)insn
<< 21) >> 9;
9055 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
9058 /* Fall through to 32-bit decode. */
9061 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
9063 insn
|= (uint32_t)insn_hw1
<< 16;
9065 if ((insn
& 0xf800e800) != 0xf000e800) {
9069 rn
= (insn
>> 16) & 0xf;
9070 rs
= (insn
>> 12) & 0xf;
9071 rd
= (insn
>> 8) & 0xf;
9073 switch ((insn
>> 25) & 0xf) {
9074 case 0: case 1: case 2: case 3:
9075 /* 16-bit instructions. Should never happen. */
9078 if (insn
& (1 << 22)) {
9079 /* Other load/store, table branch. */
9080 if (insn
& 0x01200000) {
9081 /* Load/store doubleword. */
9083 addr
= tcg_temp_new_i32();
9084 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
9086 addr
= load_reg(s
, rn
);
9088 offset
= (insn
& 0xff) * 4;
9089 if ((insn
& (1 << 23)) == 0)
9091 if (insn
& (1 << 24)) {
9092 tcg_gen_addi_i32(addr
, addr
, offset
);
9095 if (insn
& (1 << 20)) {
9097 tmp
= tcg_temp_new_i32();
9098 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9099 store_reg(s
, rs
, tmp
);
9100 tcg_gen_addi_i32(addr
, addr
, 4);
9101 tmp
= tcg_temp_new_i32();
9102 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9103 store_reg(s
, rd
, tmp
);
9106 tmp
= load_reg(s
, rs
);
9107 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9108 tcg_temp_free_i32(tmp
);
9109 tcg_gen_addi_i32(addr
, addr
, 4);
9110 tmp
= load_reg(s
, rd
);
9111 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9112 tcg_temp_free_i32(tmp
);
9114 if (insn
& (1 << 21)) {
9115 /* Base writeback. */
9118 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
9119 store_reg(s
, rn
, addr
);
9121 tcg_temp_free_i32(addr
);
9123 } else if ((insn
& (1 << 23)) == 0) {
9124 /* Load/store exclusive word. */
9125 addr
= tcg_temp_local_new_i32();
9126 load_reg_var(s
, addr
, rn
);
9127 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
9128 if (insn
& (1 << 20)) {
9129 gen_load_exclusive(s
, rs
, 15, addr
, 2);
9131 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
9133 tcg_temp_free_i32(addr
);
9134 } else if ((insn
& (7 << 5)) == 0) {
9137 addr
= tcg_temp_new_i32();
9138 tcg_gen_movi_i32(addr
, s
->pc
);
9140 addr
= load_reg(s
, rn
);
9142 tmp
= load_reg(s
, rm
);
9143 tcg_gen_add_i32(addr
, addr
, tmp
);
9144 if (insn
& (1 << 4)) {
9146 tcg_gen_add_i32(addr
, addr
, tmp
);
9147 tcg_temp_free_i32(tmp
);
9148 tmp
= tcg_temp_new_i32();
9149 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
9151 tcg_temp_free_i32(tmp
);
9152 tmp
= tcg_temp_new_i32();
9153 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
9155 tcg_temp_free_i32(addr
);
9156 tcg_gen_shli_i32(tmp
, tmp
, 1);
9157 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
9158 store_reg(s
, 15, tmp
);
9160 int op2
= (insn
>> 6) & 0x3;
9161 op
= (insn
>> 4) & 0x3;
9166 /* Load/store exclusive byte/halfword/doubleword */
9173 /* Load-acquire/store-release */
9179 /* Load-acquire/store-release exclusive */
9183 addr
= tcg_temp_local_new_i32();
9184 load_reg_var(s
, addr
, rn
);
9186 if (insn
& (1 << 20)) {
9187 tmp
= tcg_temp_new_i32();
9190 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
9193 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
9196 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9201 store_reg(s
, rs
, tmp
);
9203 tmp
= load_reg(s
, rs
);
9206 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
9209 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
9212 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9217 tcg_temp_free_i32(tmp
);
9219 } else if (insn
& (1 << 20)) {
9220 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
9222 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
9224 tcg_temp_free_i32(addr
);
9227 /* Load/store multiple, RFE, SRS. */
9228 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
9229 /* RFE, SRS: not available in user mode or on M profile */
9230 if (IS_USER(s
) || IS_M(env
)) {
9233 if (insn
& (1 << 20)) {
9235 addr
= load_reg(s
, rn
);
9236 if ((insn
& (1 << 24)) == 0)
9237 tcg_gen_addi_i32(addr
, addr
, -8);
9238 /* Load PC into tmp and CPSR into tmp2. */
9239 tmp
= tcg_temp_new_i32();
9240 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9241 tcg_gen_addi_i32(addr
, addr
, 4);
9242 tmp2
= tcg_temp_new_i32();
9243 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
9244 if (insn
& (1 << 21)) {
9245 /* Base writeback. */
9246 if (insn
& (1 << 24)) {
9247 tcg_gen_addi_i32(addr
, addr
, 4);
9249 tcg_gen_addi_i32(addr
, addr
, -4);
9251 store_reg(s
, rn
, addr
);
9253 tcg_temp_free_i32(addr
);
9255 gen_rfe(s
, tmp
, tmp2
);
9258 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
9262 int i
, loaded_base
= 0;
9263 TCGv_i32 loaded_var
;
9264 /* Load/store multiple. */
9265 addr
= load_reg(s
, rn
);
9267 for (i
= 0; i
< 16; i
++) {
9268 if (insn
& (1 << i
))
9271 if (insn
& (1 << 24)) {
9272 tcg_gen_addi_i32(addr
, addr
, -offset
);
9275 TCGV_UNUSED_I32(loaded_var
);
9276 for (i
= 0; i
< 16; i
++) {
9277 if ((insn
& (1 << i
)) == 0)
9279 if (insn
& (1 << 20)) {
9281 tmp
= tcg_temp_new_i32();
9282 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9285 } else if (i
== rn
) {
9289 store_reg(s
, i
, tmp
);
9293 tmp
= load_reg(s
, i
);
9294 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9295 tcg_temp_free_i32(tmp
);
9297 tcg_gen_addi_i32(addr
, addr
, 4);
9300 store_reg(s
, rn
, loaded_var
);
9302 if (insn
& (1 << 21)) {
9303 /* Base register writeback. */
9304 if (insn
& (1 << 24)) {
9305 tcg_gen_addi_i32(addr
, addr
, -offset
);
9307 /* Fault if writeback register is in register list. */
9308 if (insn
& (1 << rn
))
9310 store_reg(s
, rn
, addr
);
9312 tcg_temp_free_i32(addr
);
9319 op
= (insn
>> 21) & 0xf;
9321 /* Halfword pack. */
9322 tmp
= load_reg(s
, rn
);
9323 tmp2
= load_reg(s
, rm
);
9324 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
9325 if (insn
& (1 << 5)) {
9329 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9330 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9331 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9335 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9336 tcg_gen_ext16u_i32(tmp
, tmp
);
9337 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9339 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9340 tcg_temp_free_i32(tmp2
);
9341 store_reg(s
, rd
, tmp
);
9343 /* Data processing register constant shift. */
9345 tmp
= tcg_temp_new_i32();
9346 tcg_gen_movi_i32(tmp
, 0);
9348 tmp
= load_reg(s
, rn
);
9350 tmp2
= load_reg(s
, rm
);
9352 shiftop
= (insn
>> 4) & 3;
9353 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
9354 conds
= (insn
& (1 << 20)) != 0;
9355 logic_cc
= (conds
&& thumb2_logic_op(op
));
9356 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
9357 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
9359 tcg_temp_free_i32(tmp2
);
9361 store_reg(s
, rd
, tmp
);
9363 tcg_temp_free_i32(tmp
);
9367 case 13: /* Misc data processing. */
9368 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
9369 if (op
< 4 && (insn
& 0xf000) != 0xf000)
9372 case 0: /* Register controlled shift. */
9373 tmp
= load_reg(s
, rn
);
9374 tmp2
= load_reg(s
, rm
);
9375 if ((insn
& 0x70) != 0)
9377 op
= (insn
>> 21) & 3;
9378 logic_cc
= (insn
& (1 << 20)) != 0;
9379 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
9382 store_reg_bx(env
, s
, rd
, tmp
);
9384 case 1: /* Sign/zero extend. */
9385 tmp
= load_reg(s
, rm
);
9386 shift
= (insn
>> 4) & 3;
9387 /* ??? In many cases it's not necessary to do a
9388 rotate, a shift is sufficient. */
9390 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9391 op
= (insn
>> 20) & 7;
9393 case 0: gen_sxth(tmp
); break;
9394 case 1: gen_uxth(tmp
); break;
9395 case 2: gen_sxtb16(tmp
); break;
9396 case 3: gen_uxtb16(tmp
); break;
9397 case 4: gen_sxtb(tmp
); break;
9398 case 5: gen_uxtb(tmp
); break;
9399 default: goto illegal_op
;
9402 tmp2
= load_reg(s
, rn
);
9403 if ((op
>> 1) == 1) {
9404 gen_add16(tmp
, tmp2
);
9406 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9407 tcg_temp_free_i32(tmp2
);
9410 store_reg(s
, rd
, tmp
);
9412 case 2: /* SIMD add/subtract. */
9413 op
= (insn
>> 20) & 7;
9414 shift
= (insn
>> 4) & 7;
9415 if ((op
& 3) == 3 || (shift
& 3) == 3)
9417 tmp
= load_reg(s
, rn
);
9418 tmp2
= load_reg(s
, rm
);
9419 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
9420 tcg_temp_free_i32(tmp2
);
9421 store_reg(s
, rd
, tmp
);
9423 case 3: /* Other data processing. */
9424 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
9426 /* Saturating add/subtract. */
9427 tmp
= load_reg(s
, rn
);
9428 tmp2
= load_reg(s
, rm
);
9430 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
9432 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
9434 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
9435 tcg_temp_free_i32(tmp2
);
9437 tmp
= load_reg(s
, rn
);
9439 case 0x0a: /* rbit */
9440 gen_helper_rbit(tmp
, tmp
);
9442 case 0x08: /* rev */
9443 tcg_gen_bswap32_i32(tmp
, tmp
);
9445 case 0x09: /* rev16 */
9448 case 0x0b: /* revsh */
9451 case 0x10: /* sel */
9452 tmp2
= load_reg(s
, rm
);
9453 tmp3
= tcg_temp_new_i32();
9454 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
9455 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
9456 tcg_temp_free_i32(tmp3
);
9457 tcg_temp_free_i32(tmp2
);
9459 case 0x18: /* clz */
9460 gen_helper_clz(tmp
, tmp
);
9470 uint32_t sz
= op
& 0x3;
9471 uint32_t c
= op
& 0x8;
9473 if (!arm_feature(env
, ARM_FEATURE_CRC
)) {
9477 tmp2
= load_reg(s
, rm
);
9479 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
9480 } else if (sz
== 1) {
9481 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
9483 tmp3
= tcg_const_i32(1 << sz
);
9485 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
9487 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
9489 tcg_temp_free_i32(tmp2
);
9490 tcg_temp_free_i32(tmp3
);
9497 store_reg(s
, rd
, tmp
);
9499 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
9500 op
= (insn
>> 4) & 0xf;
9501 tmp
= load_reg(s
, rn
);
9502 tmp2
= load_reg(s
, rm
);
9503 switch ((insn
>> 20) & 7) {
9504 case 0: /* 32 x 32 -> 32 */
9505 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
9506 tcg_temp_free_i32(tmp2
);
9508 tmp2
= load_reg(s
, rs
);
9510 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
9512 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9513 tcg_temp_free_i32(tmp2
);
9516 case 1: /* 16 x 16 -> 32 */
9517 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
9518 tcg_temp_free_i32(tmp2
);
9520 tmp2
= load_reg(s
, rs
);
9521 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9522 tcg_temp_free_i32(tmp2
);
9525 case 2: /* Dual multiply add. */
9526 case 4: /* Dual multiply subtract. */
9528 gen_swap_half(tmp2
);
9529 gen_smul_dual(tmp
, tmp2
);
9530 if (insn
& (1 << 22)) {
9531 /* This subtraction cannot overflow. */
9532 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9534 /* This addition cannot overflow 32 bits;
9535 * however it may overflow considered as a signed
9536 * operation, in which case we must set the Q flag.
9538 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9540 tcg_temp_free_i32(tmp2
);
9543 tmp2
= load_reg(s
, rs
);
9544 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9545 tcg_temp_free_i32(tmp2
);
9548 case 3: /* 32 * 16 -> 32msb */
9550 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
9553 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9554 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
9555 tmp
= tcg_temp_new_i32();
9556 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
9557 tcg_temp_free_i64(tmp64
);
9560 tmp2
= load_reg(s
, rs
);
9561 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9562 tcg_temp_free_i32(tmp2
);
9565 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9566 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9568 tmp
= load_reg(s
, rs
);
9569 if (insn
& (1 << 20)) {
9570 tmp64
= gen_addq_msw(tmp64
, tmp
);
9572 tmp64
= gen_subq_msw(tmp64
, tmp
);
9575 if (insn
& (1 << 4)) {
9576 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
9578 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
9579 tmp
= tcg_temp_new_i32();
9580 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
9581 tcg_temp_free_i64(tmp64
);
9583 case 7: /* Unsigned sum of absolute differences. */
9584 gen_helper_usad8(tmp
, tmp
, tmp2
);
9585 tcg_temp_free_i32(tmp2
);
9587 tmp2
= load_reg(s
, rs
);
9588 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9589 tcg_temp_free_i32(tmp2
);
9593 store_reg(s
, rd
, tmp
);
9595 case 6: case 7: /* 64-bit multiply, Divide. */
9596 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
9597 tmp
= load_reg(s
, rn
);
9598 tmp2
= load_reg(s
, rm
);
9599 if ((op
& 0x50) == 0x10) {
9601 if (!arm_feature(env
, ARM_FEATURE_THUMB_DIV
)) {
9605 gen_helper_udiv(tmp
, tmp
, tmp2
);
9607 gen_helper_sdiv(tmp
, tmp
, tmp2
);
9608 tcg_temp_free_i32(tmp2
);
9609 store_reg(s
, rd
, tmp
);
9610 } else if ((op
& 0xe) == 0xc) {
9611 /* Dual multiply accumulate long. */
9613 gen_swap_half(tmp2
);
9614 gen_smul_dual(tmp
, tmp2
);
9616 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9618 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9620 tcg_temp_free_i32(tmp2
);
9622 tmp64
= tcg_temp_new_i64();
9623 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9624 tcg_temp_free_i32(tmp
);
9625 gen_addq(s
, tmp64
, rs
, rd
);
9626 gen_storeq_reg(s
, rs
, rd
, tmp64
);
9627 tcg_temp_free_i64(tmp64
);
9630 /* Unsigned 64-bit multiply */
9631 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
9635 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
9636 tcg_temp_free_i32(tmp2
);
9637 tmp64
= tcg_temp_new_i64();
9638 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9639 tcg_temp_free_i32(tmp
);
9641 /* Signed 64-bit multiply */
9642 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9647 gen_addq_lo(s
, tmp64
, rs
);
9648 gen_addq_lo(s
, tmp64
, rd
);
9649 } else if (op
& 0x40) {
9650 /* 64-bit accumulate. */
9651 gen_addq(s
, tmp64
, rs
, rd
);
9653 gen_storeq_reg(s
, rs
, rd
, tmp64
);
9654 tcg_temp_free_i64(tmp64
);
9659 case 6: case 7: case 14: case 15:
9661 if (((insn
>> 24) & 3) == 3) {
9662 /* Translate into the equivalent ARM encoding. */
9663 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
9664 if (disas_neon_data_insn(env
, s
, insn
))
9666 } else if (((insn
>> 8) & 0xe) == 10) {
9667 if (disas_vfp_insn(env
, s
, insn
)) {
9671 if (insn
& (1 << 28))
9673 if (disas_coproc_insn (env
, s
, insn
))
9677 case 8: case 9: case 10: case 11:
9678 if (insn
& (1 << 15)) {
9679 /* Branches, misc control. */
9680 if (insn
& 0x5000) {
9681 /* Unconditional branch. */
9682 /* signextend(hw1[10:0]) -> offset[:12]. */
9683 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
9684 /* hw1[10:0] -> offset[11:1]. */
9685 offset
|= (insn
& 0x7ff) << 1;
9686 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9687 offset[24:22] already have the same value because of the
9688 sign extension above. */
9689 offset
^= ((~insn
) & (1 << 13)) << 10;
9690 offset
^= ((~insn
) & (1 << 11)) << 11;
9692 if (insn
& (1 << 14)) {
9693 /* Branch and link. */
9694 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
9698 if (insn
& (1 << 12)) {
9703 offset
&= ~(uint32_t)2;
9704 /* thumb2 bx, no need to check */
9705 gen_bx_im(s
, offset
);
9707 } else if (((insn
>> 23) & 7) == 7) {
9709 if (insn
& (1 << 13))
9712 if (insn
& (1 << 26)) {
9713 /* Secure monitor call (v6Z) */
9714 qemu_log_mask(LOG_UNIMP
,
9715 "arm: unimplemented secure monitor call\n");
9716 goto illegal_op
; /* not implemented. */
9718 op
= (insn
>> 20) & 7;
9720 case 0: /* msr cpsr. */
9722 tmp
= load_reg(s
, rn
);
9723 addr
= tcg_const_i32(insn
& 0xff);
9724 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9725 tcg_temp_free_i32(addr
);
9726 tcg_temp_free_i32(tmp
);
9731 case 1: /* msr spsr. */
9734 tmp
= load_reg(s
, rn
);
9736 msr_mask(env
, s
, (insn
>> 8) & 0xf, op
== 1),
9740 case 2: /* cps, nop-hint. */
9741 if (((insn
>> 8) & 7) == 0) {
9742 gen_nop_hint(s
, insn
& 0xff);
9744 /* Implemented as NOP in user mode. */
9749 if (insn
& (1 << 10)) {
9750 if (insn
& (1 << 7))
9752 if (insn
& (1 << 6))
9754 if (insn
& (1 << 5))
9756 if (insn
& (1 << 9))
9757 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
9759 if (insn
& (1 << 8)) {
9761 imm
|= (insn
& 0x1f);
9764 gen_set_psr_im(s
, offset
, 0, imm
);
9767 case 3: /* Special control operations. */
9769 op
= (insn
>> 4) & 0xf;
9777 /* These execute as NOPs. */
9784 /* Trivial implementation equivalent to bx. */
9785 tmp
= load_reg(s
, rn
);
9788 case 5: /* Exception return. */
9792 if (rn
!= 14 || rd
!= 15) {
9795 tmp
= load_reg(s
, rn
);
9796 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
9797 gen_exception_return(s
, tmp
);
9799 case 6: /* mrs cpsr. */
9800 tmp
= tcg_temp_new_i32();
9802 addr
= tcg_const_i32(insn
& 0xff);
9803 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
9804 tcg_temp_free_i32(addr
);
9806 gen_helper_cpsr_read(tmp
, cpu_env
);
9808 store_reg(s
, rd
, tmp
);
9810 case 7: /* mrs spsr. */
9811 /* Not accessible in user mode. */
9812 if (IS_USER(s
) || IS_M(env
))
9814 tmp
= load_cpu_field(spsr
);
9815 store_reg(s
, rd
, tmp
);
9820 /* Conditional branch. */
9821 op
= (insn
>> 22) & 0xf;
9822 /* Generate a conditional jump to next instruction. */
9823 s
->condlabel
= gen_new_label();
9824 arm_gen_test_cc(op
^ 1, s
->condlabel
);
9827 /* offset[11:1] = insn[10:0] */
9828 offset
= (insn
& 0x7ff) << 1;
9829 /* offset[17:12] = insn[21:16]. */
9830 offset
|= (insn
& 0x003f0000) >> 4;
9831 /* offset[31:20] = insn[26]. */
9832 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
9833 /* offset[18] = insn[13]. */
9834 offset
|= (insn
& (1 << 13)) << 5;
9835 /* offset[19] = insn[11]. */
9836 offset
|= (insn
& (1 << 11)) << 8;
9838 /* jump to the offset */
9839 gen_jmp(s
, s
->pc
+ offset
);
9842 /* Data processing immediate. */
9843 if (insn
& (1 << 25)) {
9844 if (insn
& (1 << 24)) {
9845 if (insn
& (1 << 20))
9847 /* Bitfield/Saturate. */
9848 op
= (insn
>> 21) & 7;
9850 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
9852 tmp
= tcg_temp_new_i32();
9853 tcg_gen_movi_i32(tmp
, 0);
9855 tmp
= load_reg(s
, rn
);
9858 case 2: /* Signed bitfield extract. */
9860 if (shift
+ imm
> 32)
9863 gen_sbfx(tmp
, shift
, imm
);
9865 case 6: /* Unsigned bitfield extract. */
9867 if (shift
+ imm
> 32)
9870 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
9872 case 3: /* Bitfield insert/clear. */
9875 imm
= imm
+ 1 - shift
;
9877 tmp2
= load_reg(s
, rd
);
9878 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
9879 tcg_temp_free_i32(tmp2
);
9884 default: /* Saturate. */
9887 tcg_gen_sari_i32(tmp
, tmp
, shift
);
9889 tcg_gen_shli_i32(tmp
, tmp
, shift
);
9891 tmp2
= tcg_const_i32(imm
);
9894 if ((op
& 1) && shift
== 0)
9895 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
9897 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
9900 if ((op
& 1) && shift
== 0)
9901 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
9903 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
9905 tcg_temp_free_i32(tmp2
);
9908 store_reg(s
, rd
, tmp
);
9910 imm
= ((insn
& 0x04000000) >> 15)
9911 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
9912 if (insn
& (1 << 22)) {
9913 /* 16-bit immediate. */
9914 imm
|= (insn
>> 4) & 0xf000;
9915 if (insn
& (1 << 23)) {
9917 tmp
= load_reg(s
, rd
);
9918 tcg_gen_ext16u_i32(tmp
, tmp
);
9919 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
9922 tmp
= tcg_temp_new_i32();
9923 tcg_gen_movi_i32(tmp
, imm
);
9926 /* Add/sub 12-bit immediate. */
9928 offset
= s
->pc
& ~(uint32_t)3;
9929 if (insn
& (1 << 23))
9933 tmp
= tcg_temp_new_i32();
9934 tcg_gen_movi_i32(tmp
, offset
);
9936 tmp
= load_reg(s
, rn
);
9937 if (insn
& (1 << 23))
9938 tcg_gen_subi_i32(tmp
, tmp
, imm
);
9940 tcg_gen_addi_i32(tmp
, tmp
, imm
);
9943 store_reg(s
, rd
, tmp
);
9946 int shifter_out
= 0;
9947 /* modified 12-bit immediate. */
9948 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
9949 imm
= (insn
& 0xff);
9952 /* Nothing to do. */
9954 case 1: /* 00XY00XY */
9957 case 2: /* XY00XY00 */
9961 case 3: /* XYXYXYXY */
9965 default: /* Rotated constant. */
9966 shift
= (shift
<< 1) | (imm
>> 7);
9968 imm
= imm
<< (32 - shift
);
9972 tmp2
= tcg_temp_new_i32();
9973 tcg_gen_movi_i32(tmp2
, imm
);
9974 rn
= (insn
>> 16) & 0xf;
9976 tmp
= tcg_temp_new_i32();
9977 tcg_gen_movi_i32(tmp
, 0);
9979 tmp
= load_reg(s
, rn
);
9981 op
= (insn
>> 21) & 0xf;
9982 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
9983 shifter_out
, tmp
, tmp2
))
9985 tcg_temp_free_i32(tmp2
);
9986 rd
= (insn
>> 8) & 0xf;
9988 store_reg(s
, rd
, tmp
);
9990 tcg_temp_free_i32(tmp
);
9995 case 12: /* Load/store single data item. */
10000 if ((insn
& 0x01100000) == 0x01000000) {
10001 if (disas_neon_ls_insn(env
, s
, insn
))
10005 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
10007 if (!(insn
& (1 << 20))) {
10011 /* Byte or halfword load space with dest == r15 : memory hints.
10012 * Catch them early so we don't emit pointless addressing code.
10013 * This space is a mix of:
10014 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10015 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10017 * unallocated hints, which must be treated as NOPs
10018 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10019 * which is easiest for the decoding logic
10020 * Some space which must UNDEF
10022 int op1
= (insn
>> 23) & 3;
10023 int op2
= (insn
>> 6) & 0x3f;
10028 /* UNPREDICTABLE, unallocated hint or
10029 * PLD/PLDW/PLI (literal)
10034 return 0; /* PLD/PLDW/PLI or unallocated hint */
10036 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
10037 return 0; /* PLD/PLDW/PLI or unallocated hint */
10039 /* UNDEF space, or an UNPREDICTABLE */
10043 memidx
= get_mem_index(s
);
10045 addr
= tcg_temp_new_i32();
10047 /* s->pc has already been incremented by 4. */
10048 imm
= s
->pc
& 0xfffffffc;
10049 if (insn
& (1 << 23))
10050 imm
+= insn
& 0xfff;
10052 imm
-= insn
& 0xfff;
10053 tcg_gen_movi_i32(addr
, imm
);
10055 addr
= load_reg(s
, rn
);
10056 if (insn
& (1 << 23)) {
10057 /* Positive offset. */
10058 imm
= insn
& 0xfff;
10059 tcg_gen_addi_i32(addr
, addr
, imm
);
10062 switch ((insn
>> 8) & 0xf) {
10063 case 0x0: /* Shifted Register. */
10064 shift
= (insn
>> 4) & 0xf;
10066 tcg_temp_free_i32(addr
);
10069 tmp
= load_reg(s
, rm
);
10071 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10072 tcg_gen_add_i32(addr
, addr
, tmp
);
10073 tcg_temp_free_i32(tmp
);
10075 case 0xc: /* Negative offset. */
10076 tcg_gen_addi_i32(addr
, addr
, -imm
);
10078 case 0xe: /* User privilege. */
10079 tcg_gen_addi_i32(addr
, addr
, imm
);
10080 memidx
= MMU_USER_IDX
;
10082 case 0x9: /* Post-decrement. */
10084 /* Fall through. */
10085 case 0xb: /* Post-increment. */
10089 case 0xd: /* Pre-decrement. */
10091 /* Fall through. */
10092 case 0xf: /* Pre-increment. */
10093 tcg_gen_addi_i32(addr
, addr
, imm
);
10097 tcg_temp_free_i32(addr
);
10102 if (insn
& (1 << 20)) {
10104 tmp
= tcg_temp_new_i32();
10107 gen_aa32_ld8u(tmp
, addr
, memidx
);
10110 gen_aa32_ld8s(tmp
, addr
, memidx
);
10113 gen_aa32_ld16u(tmp
, addr
, memidx
);
10116 gen_aa32_ld16s(tmp
, addr
, memidx
);
10119 gen_aa32_ld32u(tmp
, addr
, memidx
);
10122 tcg_temp_free_i32(tmp
);
10123 tcg_temp_free_i32(addr
);
10129 store_reg(s
, rs
, tmp
);
10133 tmp
= load_reg(s
, rs
);
10136 gen_aa32_st8(tmp
, addr
, memidx
);
10139 gen_aa32_st16(tmp
, addr
, memidx
);
10142 gen_aa32_st32(tmp
, addr
, memidx
);
10145 tcg_temp_free_i32(tmp
);
10146 tcg_temp_free_i32(addr
);
10149 tcg_temp_free_i32(tmp
);
10152 tcg_gen_addi_i32(addr
, addr
, imm
);
10154 store_reg(s
, rn
, addr
);
10156 tcg_temp_free_i32(addr
);
10168 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
10170 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
10177 if (s
->condexec_mask
) {
10178 cond
= s
->condexec_cond
;
10179 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
10180 s
->condlabel
= gen_new_label();
10181 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
10186 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
10189 switch (insn
>> 12) {
10193 op
= (insn
>> 11) & 3;
10196 rn
= (insn
>> 3) & 7;
10197 tmp
= load_reg(s
, rn
);
10198 if (insn
& (1 << 10)) {
10200 tmp2
= tcg_temp_new_i32();
10201 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
10204 rm
= (insn
>> 6) & 7;
10205 tmp2
= load_reg(s
, rm
);
10207 if (insn
& (1 << 9)) {
10208 if (s
->condexec_mask
)
10209 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10211 gen_sub_CC(tmp
, tmp
, tmp2
);
10213 if (s
->condexec_mask
)
10214 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10216 gen_add_CC(tmp
, tmp
, tmp2
);
10218 tcg_temp_free_i32(tmp2
);
10219 store_reg(s
, rd
, tmp
);
10221 /* shift immediate */
10222 rm
= (insn
>> 3) & 7;
10223 shift
= (insn
>> 6) & 0x1f;
10224 tmp
= load_reg(s
, rm
);
10225 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
10226 if (!s
->condexec_mask
)
10228 store_reg(s
, rd
, tmp
);
10232 /* arithmetic large immediate */
10233 op
= (insn
>> 11) & 3;
10234 rd
= (insn
>> 8) & 0x7;
10235 if (op
== 0) { /* mov */
10236 tmp
= tcg_temp_new_i32();
10237 tcg_gen_movi_i32(tmp
, insn
& 0xff);
10238 if (!s
->condexec_mask
)
10240 store_reg(s
, rd
, tmp
);
10242 tmp
= load_reg(s
, rd
);
10243 tmp2
= tcg_temp_new_i32();
10244 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
10247 gen_sub_CC(tmp
, tmp
, tmp2
);
10248 tcg_temp_free_i32(tmp
);
10249 tcg_temp_free_i32(tmp2
);
10252 if (s
->condexec_mask
)
10253 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10255 gen_add_CC(tmp
, tmp
, tmp2
);
10256 tcg_temp_free_i32(tmp2
);
10257 store_reg(s
, rd
, tmp
);
10260 if (s
->condexec_mask
)
10261 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10263 gen_sub_CC(tmp
, tmp
, tmp2
);
10264 tcg_temp_free_i32(tmp2
);
10265 store_reg(s
, rd
, tmp
);
10271 if (insn
& (1 << 11)) {
10272 rd
= (insn
>> 8) & 7;
10273 /* load pc-relative. Bit 1 of PC is ignored. */
10274 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
10275 val
&= ~(uint32_t)2;
10276 addr
= tcg_temp_new_i32();
10277 tcg_gen_movi_i32(addr
, val
);
10278 tmp
= tcg_temp_new_i32();
10279 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10280 tcg_temp_free_i32(addr
);
10281 store_reg(s
, rd
, tmp
);
10284 if (insn
& (1 << 10)) {
10285 /* data processing extended or blx */
10286 rd
= (insn
& 7) | ((insn
>> 4) & 8);
10287 rm
= (insn
>> 3) & 0xf;
10288 op
= (insn
>> 8) & 3;
10291 tmp
= load_reg(s
, rd
);
10292 tmp2
= load_reg(s
, rm
);
10293 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10294 tcg_temp_free_i32(tmp2
);
10295 store_reg(s
, rd
, tmp
);
10298 tmp
= load_reg(s
, rd
);
10299 tmp2
= load_reg(s
, rm
);
10300 gen_sub_CC(tmp
, tmp
, tmp2
);
10301 tcg_temp_free_i32(tmp2
);
10302 tcg_temp_free_i32(tmp
);
10304 case 2: /* mov/cpy */
10305 tmp
= load_reg(s
, rm
);
10306 store_reg(s
, rd
, tmp
);
10308 case 3:/* branch [and link] exchange thumb register */
10309 tmp
= load_reg(s
, rm
);
10310 if (insn
& (1 << 7)) {
10312 val
= (uint32_t)s
->pc
| 1;
10313 tmp2
= tcg_temp_new_i32();
10314 tcg_gen_movi_i32(tmp2
, val
);
10315 store_reg(s
, 14, tmp2
);
10317 /* already thumb, no need to check */
10324 /* data processing register */
10326 rm
= (insn
>> 3) & 7;
10327 op
= (insn
>> 6) & 0xf;
10328 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
10329 /* the shift/rotate ops want the operands backwards */
10338 if (op
== 9) { /* neg */
10339 tmp
= tcg_temp_new_i32();
10340 tcg_gen_movi_i32(tmp
, 0);
10341 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
10342 tmp
= load_reg(s
, rd
);
10344 TCGV_UNUSED_I32(tmp
);
10347 tmp2
= load_reg(s
, rm
);
10349 case 0x0: /* and */
10350 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
10351 if (!s
->condexec_mask
)
10354 case 0x1: /* eor */
10355 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
10356 if (!s
->condexec_mask
)
10359 case 0x2: /* lsl */
10360 if (s
->condexec_mask
) {
10361 gen_shl(tmp2
, tmp2
, tmp
);
10363 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10364 gen_logic_CC(tmp2
);
10367 case 0x3: /* lsr */
10368 if (s
->condexec_mask
) {
10369 gen_shr(tmp2
, tmp2
, tmp
);
10371 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10372 gen_logic_CC(tmp2
);
10375 case 0x4: /* asr */
10376 if (s
->condexec_mask
) {
10377 gen_sar(tmp2
, tmp2
, tmp
);
10379 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10380 gen_logic_CC(tmp2
);
10383 case 0x5: /* adc */
10384 if (s
->condexec_mask
) {
10385 gen_adc(tmp
, tmp2
);
10387 gen_adc_CC(tmp
, tmp
, tmp2
);
10390 case 0x6: /* sbc */
10391 if (s
->condexec_mask
) {
10392 gen_sub_carry(tmp
, tmp
, tmp2
);
10394 gen_sbc_CC(tmp
, tmp
, tmp2
);
10397 case 0x7: /* ror */
10398 if (s
->condexec_mask
) {
10399 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
10400 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
10402 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10403 gen_logic_CC(tmp2
);
10406 case 0x8: /* tst */
10407 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
10411 case 0x9: /* neg */
10412 if (s
->condexec_mask
)
10413 tcg_gen_neg_i32(tmp
, tmp2
);
10415 gen_sub_CC(tmp
, tmp
, tmp2
);
10417 case 0xa: /* cmp */
10418 gen_sub_CC(tmp
, tmp
, tmp2
);
10421 case 0xb: /* cmn */
10422 gen_add_CC(tmp
, tmp
, tmp2
);
10425 case 0xc: /* orr */
10426 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
10427 if (!s
->condexec_mask
)
10430 case 0xd: /* mul */
10431 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
10432 if (!s
->condexec_mask
)
10435 case 0xe: /* bic */
10436 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
10437 if (!s
->condexec_mask
)
10440 case 0xf: /* mvn */
10441 tcg_gen_not_i32(tmp2
, tmp2
);
10442 if (!s
->condexec_mask
)
10443 gen_logic_CC(tmp2
);
10450 store_reg(s
, rm
, tmp2
);
10452 tcg_temp_free_i32(tmp
);
10454 store_reg(s
, rd
, tmp
);
10455 tcg_temp_free_i32(tmp2
);
10458 tcg_temp_free_i32(tmp
);
10459 tcg_temp_free_i32(tmp2
);
10464 /* load/store register offset. */
10466 rn
= (insn
>> 3) & 7;
10467 rm
= (insn
>> 6) & 7;
10468 op
= (insn
>> 9) & 7;
10469 addr
= load_reg(s
, rn
);
10470 tmp
= load_reg(s
, rm
);
10471 tcg_gen_add_i32(addr
, addr
, tmp
);
10472 tcg_temp_free_i32(tmp
);
10474 if (op
< 3) { /* store */
10475 tmp
= load_reg(s
, rd
);
10477 tmp
= tcg_temp_new_i32();
10482 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10485 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
10488 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
10490 case 3: /* ldrsb */
10491 gen_aa32_ld8s(tmp
, addr
, get_mem_index(s
));
10494 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10497 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
10500 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
10502 case 7: /* ldrsh */
10503 gen_aa32_ld16s(tmp
, addr
, get_mem_index(s
));
10506 if (op
>= 3) { /* load */
10507 store_reg(s
, rd
, tmp
);
10509 tcg_temp_free_i32(tmp
);
10511 tcg_temp_free_i32(addr
);
10515 /* load/store word immediate offset */
10517 rn
= (insn
>> 3) & 7;
10518 addr
= load_reg(s
, rn
);
10519 val
= (insn
>> 4) & 0x7c;
10520 tcg_gen_addi_i32(addr
, addr
, val
);
10522 if (insn
& (1 << 11)) {
10524 tmp
= tcg_temp_new_i32();
10525 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10526 store_reg(s
, rd
, tmp
);
10529 tmp
= load_reg(s
, rd
);
10530 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10531 tcg_temp_free_i32(tmp
);
10533 tcg_temp_free_i32(addr
);
10537 /* load/store byte immediate offset */
10539 rn
= (insn
>> 3) & 7;
10540 addr
= load_reg(s
, rn
);
10541 val
= (insn
>> 6) & 0x1f;
10542 tcg_gen_addi_i32(addr
, addr
, val
);
10544 if (insn
& (1 << 11)) {
10546 tmp
= tcg_temp_new_i32();
10547 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
10548 store_reg(s
, rd
, tmp
);
10551 tmp
= load_reg(s
, rd
);
10552 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
10553 tcg_temp_free_i32(tmp
);
10555 tcg_temp_free_i32(addr
);
10559 /* load/store halfword immediate offset */
10561 rn
= (insn
>> 3) & 7;
10562 addr
= load_reg(s
, rn
);
10563 val
= (insn
>> 5) & 0x3e;
10564 tcg_gen_addi_i32(addr
, addr
, val
);
10566 if (insn
& (1 << 11)) {
10568 tmp
= tcg_temp_new_i32();
10569 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
10570 store_reg(s
, rd
, tmp
);
10573 tmp
= load_reg(s
, rd
);
10574 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
10575 tcg_temp_free_i32(tmp
);
10577 tcg_temp_free_i32(addr
);
10581 /* load/store from stack */
10582 rd
= (insn
>> 8) & 7;
10583 addr
= load_reg(s
, 13);
10584 val
= (insn
& 0xff) * 4;
10585 tcg_gen_addi_i32(addr
, addr
, val
);
10587 if (insn
& (1 << 11)) {
10589 tmp
= tcg_temp_new_i32();
10590 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10591 store_reg(s
, rd
, tmp
);
10594 tmp
= load_reg(s
, rd
);
10595 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10596 tcg_temp_free_i32(tmp
);
10598 tcg_temp_free_i32(addr
);
10602 /* add to high reg */
10603 rd
= (insn
>> 8) & 7;
10604 if (insn
& (1 << 11)) {
10606 tmp
= load_reg(s
, 13);
10608 /* PC. bit 1 is ignored. */
10609 tmp
= tcg_temp_new_i32();
10610 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
10612 val
= (insn
& 0xff) * 4;
10613 tcg_gen_addi_i32(tmp
, tmp
, val
);
10614 store_reg(s
, rd
, tmp
);
10619 op
= (insn
>> 8) & 0xf;
10622 /* adjust stack pointer */
10623 tmp
= load_reg(s
, 13);
10624 val
= (insn
& 0x7f) * 4;
10625 if (insn
& (1 << 7))
10626 val
= -(int32_t)val
;
10627 tcg_gen_addi_i32(tmp
, tmp
, val
);
10628 store_reg(s
, 13, tmp
);
10631 case 2: /* sign/zero extend. */
10634 rm
= (insn
>> 3) & 7;
10635 tmp
= load_reg(s
, rm
);
10636 switch ((insn
>> 6) & 3) {
10637 case 0: gen_sxth(tmp
); break;
10638 case 1: gen_sxtb(tmp
); break;
10639 case 2: gen_uxth(tmp
); break;
10640 case 3: gen_uxtb(tmp
); break;
10642 store_reg(s
, rd
, tmp
);
10644 case 4: case 5: case 0xc: case 0xd:
10646 addr
= load_reg(s
, 13);
10647 if (insn
& (1 << 8))
10651 for (i
= 0; i
< 8; i
++) {
10652 if (insn
& (1 << i
))
10655 if ((insn
& (1 << 11)) == 0) {
10656 tcg_gen_addi_i32(addr
, addr
, -offset
);
10658 for (i
= 0; i
< 8; i
++) {
10659 if (insn
& (1 << i
)) {
10660 if (insn
& (1 << 11)) {
10662 tmp
= tcg_temp_new_i32();
10663 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10664 store_reg(s
, i
, tmp
);
10667 tmp
= load_reg(s
, i
);
10668 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10669 tcg_temp_free_i32(tmp
);
10671 /* advance to the next address. */
10672 tcg_gen_addi_i32(addr
, addr
, 4);
10675 TCGV_UNUSED_I32(tmp
);
10676 if (insn
& (1 << 8)) {
10677 if (insn
& (1 << 11)) {
10679 tmp
= tcg_temp_new_i32();
10680 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10681 /* don't set the pc until the rest of the instruction
10685 tmp
= load_reg(s
, 14);
10686 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10687 tcg_temp_free_i32(tmp
);
10689 tcg_gen_addi_i32(addr
, addr
, 4);
10691 if ((insn
& (1 << 11)) == 0) {
10692 tcg_gen_addi_i32(addr
, addr
, -offset
);
10694 /* write back the new stack pointer */
10695 store_reg(s
, 13, addr
);
10696 /* set the new PC value */
10697 if ((insn
& 0x0900) == 0x0900) {
10698 store_reg_from_load(env
, s
, 15, tmp
);
10702 case 1: case 3: case 9: case 11: /* czb */
10704 tmp
= load_reg(s
, rm
);
10705 s
->condlabel
= gen_new_label();
10707 if (insn
& (1 << 11))
10708 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
10710 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
10711 tcg_temp_free_i32(tmp
);
10712 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
10713 val
= (uint32_t)s
->pc
+ 2;
10718 case 15: /* IT, nop-hint. */
10719 if ((insn
& 0xf) == 0) {
10720 gen_nop_hint(s
, (insn
>> 4) & 0xf);
10724 s
->condexec_cond
= (insn
>> 4) & 0xe;
10725 s
->condexec_mask
= insn
& 0x1f;
10726 /* No actual code generated for this insn, just setup state. */
10729 case 0xe: /* bkpt */
10731 int imm8
= extract32(insn
, 0, 8);
10733 gen_exception_insn(s
, 2, EXCP_BKPT
, syn_aa32_bkpt(imm8
, true));
10737 case 0xa: /* rev */
10739 rn
= (insn
>> 3) & 0x7;
10741 tmp
= load_reg(s
, rn
);
10742 switch ((insn
>> 6) & 3) {
10743 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
10744 case 1: gen_rev16(tmp
); break;
10745 case 3: gen_revsh(tmp
); break;
10746 default: goto illegal_op
;
10748 store_reg(s
, rd
, tmp
);
10752 switch ((insn
>> 5) & 7) {
10756 if (((insn
>> 3) & 1) != s
->bswap_code
) {
10757 /* Dynamic endianness switching not implemented. */
10758 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
10769 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
10772 addr
= tcg_const_i32(19);
10773 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10774 tcg_temp_free_i32(addr
);
10778 addr
= tcg_const_i32(16);
10779 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10780 tcg_temp_free_i32(addr
);
10782 tcg_temp_free_i32(tmp
);
10785 if (insn
& (1 << 4)) {
10786 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
10790 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
10805 /* load/store multiple */
10806 TCGv_i32 loaded_var
;
10807 TCGV_UNUSED_I32(loaded_var
);
10808 rn
= (insn
>> 8) & 0x7;
10809 addr
= load_reg(s
, rn
);
10810 for (i
= 0; i
< 8; i
++) {
10811 if (insn
& (1 << i
)) {
10812 if (insn
& (1 << 11)) {
10814 tmp
= tcg_temp_new_i32();
10815 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10819 store_reg(s
, i
, tmp
);
10823 tmp
= load_reg(s
, i
);
10824 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10825 tcg_temp_free_i32(tmp
);
10827 /* advance to the next address */
10828 tcg_gen_addi_i32(addr
, addr
, 4);
10831 if ((insn
& (1 << rn
)) == 0) {
10832 /* base reg not in list: base register writeback */
10833 store_reg(s
, rn
, addr
);
10835 /* base reg in list: if load, complete it now */
10836 if (insn
& (1 << 11)) {
10837 store_reg(s
, rn
, loaded_var
);
10839 tcg_temp_free_i32(addr
);
10844 /* conditional branch or swi */
10845 cond
= (insn
>> 8) & 0xf;
10851 gen_set_pc_im(s
, s
->pc
);
10852 s
->svc_imm
= extract32(insn
, 0, 8);
10853 s
->is_jmp
= DISAS_SWI
;
10856 /* generate a conditional jump to next instruction */
10857 s
->condlabel
= gen_new_label();
10858 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
10861 /* jump to the offset */
10862 val
= (uint32_t)s
->pc
+ 2;
10863 offset
= ((int32_t)insn
<< 24) >> 24;
10864 val
+= offset
<< 1;
10869 if (insn
& (1 << 11)) {
10870 if (disas_thumb2_insn(env
, s
, insn
))
10874 /* unconditional branch */
10875 val
= (uint32_t)s
->pc
;
10876 offset
= ((int32_t)insn
<< 21) >> 21;
10877 val
+= (offset
<< 1) + 2;
10882 if (disas_thumb2_insn(env
, s
, insn
))
10888 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized());
10892 gen_exception_insn(s
, 2, EXCP_UDEF
, syn_uncategorized());
10895 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
10896 basic block 'tb'. If search_pc is TRUE, also generate PC
10897 information for each intermediate instruction. */
10898 static inline void gen_intermediate_code_internal(ARMCPU
*cpu
,
10899 TranslationBlock
*tb
,
10902 CPUState
*cs
= CPU(cpu
);
10903 CPUARMState
*env
= &cpu
->env
;
10904 DisasContext dc1
, *dc
= &dc1
;
10906 uint16_t *gen_opc_end
;
10908 target_ulong pc_start
;
10909 target_ulong next_page_start
;
10913 /* generate intermediate code */
10915 /* The A64 decoder has its own top level loop, because it doesn't need
10916 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
10918 if (ARM_TBFLAG_AARCH64_STATE(tb
->flags
)) {
10919 gen_intermediate_code_internal_a64(cpu
, tb
, search_pc
);
10927 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
10929 dc
->is_jmp
= DISAS_NEXT
;
10931 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
10935 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
10936 dc
->bswap_code
= ARM_TBFLAG_BSWAP_CODE(tb
->flags
);
10937 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
10938 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
10939 #if !defined(CONFIG_USER_ONLY)
10940 dc
->user
= (ARM_TBFLAG_PRIV(tb
->flags
) == 0);
10942 dc
->cpacr_fpen
= ARM_TBFLAG_CPACR_FPEN(tb
->flags
);
10943 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
10944 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
10945 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
10946 dc
->c15_cpar
= ARM_TBFLAG_XSCALE_CPAR(tb
->flags
);
10947 dc
->cp_regs
= cpu
->cp_regs
;
10948 dc
->current_pl
= arm_current_pl(env
);
10949 dc
->features
= env
->features
;
10951 /* Single step state. The code-generation logic here is:
10953 * generate code with no special handling for single-stepping (except
10954 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
10955 * this happens anyway because those changes are all system register or
10957 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
10958 * emit code for one insn
10959 * emit code to clear PSTATE.SS
10960 * emit code to generate software step exception for completed step
10961 * end TB (as usual for having generated an exception)
10962 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
10963 * emit code to generate a software step exception
10966 dc
->ss_active
= ARM_TBFLAG_SS_ACTIVE(tb
->flags
);
10967 dc
->pstate_ss
= ARM_TBFLAG_PSTATE_SS(tb
->flags
);
10968 dc
->is_ldex
= false;
10969 dc
->ss_same_el
= false; /* Can't be true since EL_d must be AArch64 */
10971 cpu_F0s
= tcg_temp_new_i32();
10972 cpu_F1s
= tcg_temp_new_i32();
10973 cpu_F0d
= tcg_temp_new_i64();
10974 cpu_F1d
= tcg_temp_new_i64();
10977 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
10978 cpu_M0
= tcg_temp_new_i64();
10979 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
10982 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
10983 if (max_insns
== 0)
10984 max_insns
= CF_COUNT_MASK
;
10988 tcg_clear_temp_count();
10990 /* A note on handling of the condexec (IT) bits:
10992 * We want to avoid the overhead of having to write the updated condexec
10993 * bits back to the CPUARMState for every instruction in an IT block. So:
10994 * (1) if the condexec bits are not already zero then we write
10995 * zero back into the CPUARMState now. This avoids complications trying
10996 * to do it at the end of the block. (For example if we don't do this
10997 * it's hard to identify whether we can safely skip writing condexec
10998 * at the end of the TB, which we definitely want to do for the case
10999 * where a TB doesn't do anything with the IT state at all.)
11000 * (2) if we are going to leave the TB then we call gen_set_condexec()
11001 * which will write the correct value into CPUARMState if zero is wrong.
11002 * This is done both for leaving the TB at the end, and for leaving
11003 * it because of an exception we know will happen, which is done in
11004 * gen_exception_insn(). The latter is necessary because we need to
11005 * leave the TB with the PC/IT state just prior to execution of the
11006 * instruction which caused the exception.
11007 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11008 * then the CPUARMState will be wrong and we need to reset it.
11009 * This is handled in the same way as restoration of the
11010 * PC in these situations: we will be called again with search_pc=1
11011 * and generate a mapping of the condexec bits for each PC in
11012 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
11013 * this to restore the condexec bits.
11015 * Note that there are no instructions which can read the condexec
11016 * bits, and none which can write non-static values to them, so
11017 * we don't need to care about whether CPUARMState is correct in the
11021 /* Reset the conditional execution bits immediately. This avoids
11022 complications trying to do it at the end of the block. */
11023 if (dc
->condexec_mask
|| dc
->condexec_cond
)
11025 TCGv_i32 tmp
= tcg_temp_new_i32();
11026 tcg_gen_movi_i32(tmp
, 0);
11027 store_cpu_field(tmp
, condexec_bits
);
11030 #ifdef CONFIG_USER_ONLY
11031 /* Intercept jump to the magic kernel page. */
11032 if (dc
->pc
>= 0xffff0000) {
11033 /* We always get here via a jump, so know we are not in a
11034 conditional execution block. */
11035 gen_exception_internal(EXCP_KERNEL_TRAP
);
11036 dc
->is_jmp
= DISAS_UPDATE
;
11040 if (dc
->pc
>= 0xfffffff0 && IS_M(env
)) {
11041 /* We always get here via a jump, so know we are not in a
11042 conditional execution block. */
11043 gen_exception_internal(EXCP_EXCEPTION_EXIT
);
11044 dc
->is_jmp
= DISAS_UPDATE
;
11049 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
11050 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
11051 if (bp
->pc
== dc
->pc
) {
11052 gen_exception_internal_insn(dc
, 0, EXCP_DEBUG
);
11053 /* Advance PC so that clearing the breakpoint will
11054 invalidate this TB. */
11056 goto done_generating
;
11061 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
11065 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
11067 tcg_ctx
.gen_opc_pc
[lj
] = dc
->pc
;
11068 gen_opc_condexec_bits
[lj
] = (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1);
11069 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
11070 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
11073 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
11076 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
11077 tcg_gen_debug_insn_start(dc
->pc
);
11080 if (dc
->ss_active
&& !dc
->pstate_ss
) {
11081 /* Singlestep state is Active-pending.
11082 * If we're in this state at the start of a TB then either
11083 * a) we just took an exception to an EL which is being debugged
11084 * and this is the first insn in the exception handler
11085 * b) debug exceptions were masked and we just unmasked them
11086 * without changing EL (eg by clearing PSTATE.D)
11087 * In either case we're going to take a swstep exception in the
11088 * "did not step an insn" case, and so the syndrome ISV and EX
11089 * bits should be zero.
11091 assert(num_insns
== 0);
11092 gen_exception(EXCP_UDEF
, syn_swstep(dc
->ss_same_el
, 0, 0));
11093 goto done_generating
;
11097 disas_thumb_insn(env
, dc
);
11098 if (dc
->condexec_mask
) {
11099 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
11100 | ((dc
->condexec_mask
>> 4) & 1);
11101 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
11102 if (dc
->condexec_mask
== 0) {
11103 dc
->condexec_cond
= 0;
11107 disas_arm_insn(env
, dc
);
11110 if (dc
->condjmp
&& !dc
->is_jmp
) {
11111 gen_set_label(dc
->condlabel
);
11115 if (tcg_check_temp_count()) {
11116 fprintf(stderr
, "TCG temporary leak before "TARGET_FMT_lx
"\n",
11120 /* Translation stops when a conditional branch is encountered.
11121 * Otherwise the subsequent code could get translated several times.
11122 * Also stop translation when a page boundary is reached. This
11123 * ensures prefetch aborts occur at the right place. */
11125 } while (!dc
->is_jmp
&& tcg_ctx
.gen_opc_ptr
< gen_opc_end
&&
11126 !cs
->singlestep_enabled
&&
11129 dc
->pc
< next_page_start
&&
11130 num_insns
< max_insns
);
11132 if (tb
->cflags
& CF_LAST_IO
) {
11134 /* FIXME: This can theoretically happen with self-modifying
11136 cpu_abort(cs
, "IO on conditional branch instruction");
11141 /* At this stage dc->condjmp will only be set when the skipped
11142 instruction was a conditional branch or trap, and the PC has
11143 already been written. */
11144 if (unlikely(cs
->singlestep_enabled
|| dc
->ss_active
)) {
11145 /* Make sure the pc is updated, and raise a debug exception. */
11147 gen_set_condexec(dc
);
11148 if (dc
->is_jmp
== DISAS_SWI
) {
11149 gen_ss_advance(dc
);
11150 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
));
11151 } else if (dc
->ss_active
) {
11152 gen_step_complete_exception(dc
);
11154 gen_exception_internal(EXCP_DEBUG
);
11156 gen_set_label(dc
->condlabel
);
11158 if (dc
->condjmp
|| !dc
->is_jmp
) {
11159 gen_set_pc_im(dc
, dc
->pc
);
11162 gen_set_condexec(dc
);
11163 if (dc
->is_jmp
== DISAS_SWI
&& !dc
->condjmp
) {
11164 gen_ss_advance(dc
);
11165 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
));
11166 } else if (dc
->ss_active
) {
11167 gen_step_complete_exception(dc
);
11169 /* FIXME: Single stepping a WFI insn will not halt
11171 gen_exception_internal(EXCP_DEBUG
);
11174 /* While branches must always occur at the end of an IT block,
11175 there are a few other things that can cause us to terminate
11176 the TB in the middle of an IT block:
11177 - Exception generating instructions (bkpt, swi, undefined).
11179 - Hardware watchpoints.
11180 Hardware breakpoints have already been handled and skip this code.
11182 gen_set_condexec(dc
);
11183 switch(dc
->is_jmp
) {
11185 gen_goto_tb(dc
, 1, dc
->pc
);
11190 /* indicate that the hash table must be used to find the next TB */
11191 tcg_gen_exit_tb(0);
11193 case DISAS_TB_JUMP
:
11194 /* nothing more to generate */
11197 gen_helper_wfi(cpu_env
);
11200 gen_helper_wfe(cpu_env
);
11203 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
));
11207 gen_set_label(dc
->condlabel
);
11208 gen_set_condexec(dc
);
11209 gen_goto_tb(dc
, 1, dc
->pc
);
11215 gen_tb_end(tb
, num_insns
);
11216 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
11219 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
11220 qemu_log("----------------\n");
11221 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
11222 log_target_disas(env
, pc_start
, dc
->pc
- pc_start
,
11223 dc
->thumb
| (dc
->bswap_code
<< 1));
11228 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
11231 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
11233 tb
->size
= dc
->pc
- pc_start
;
11234 tb
->icount
= num_insns
;
11238 void gen_intermediate_code(CPUARMState
*env
, TranslationBlock
*tb
)
11240 gen_intermediate_code_internal(arm_env_get_cpu(env
), tb
, false);
11243 void gen_intermediate_code_pc(CPUARMState
*env
, TranslationBlock
*tb
)
11245 gen_intermediate_code_internal(arm_env_get_cpu(env
), tb
, true);
11248 static const char *cpu_mode_names
[16] = {
11249 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
11250 "???", "???", "hyp", "und", "???", "???", "???", "sys"
11253 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
11256 ARMCPU
*cpu
= ARM_CPU(cs
);
11257 CPUARMState
*env
= &cpu
->env
;
11262 aarch64_cpu_dump_state(cs
, f
, cpu_fprintf
, flags
);
11266 for(i
=0;i
<16;i
++) {
11267 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
11269 cpu_fprintf(f
, "\n");
11271 cpu_fprintf(f
, " ");
11273 psr
= cpsr_read(env
);
11274 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%d\n",
11276 psr
& (1 << 31) ? 'N' : '-',
11277 psr
& (1 << 30) ? 'Z' : '-',
11278 psr
& (1 << 29) ? 'C' : '-',
11279 psr
& (1 << 28) ? 'V' : '-',
11280 psr
& CPSR_T
? 'T' : 'A',
11281 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
11283 if (flags
& CPU_DUMP_FPU
) {
11284 int numvfpregs
= 0;
11285 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
11288 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
11291 for (i
= 0; i
< numvfpregs
; i
++) {
11292 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
11293 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
11294 i
* 2, (uint32_t)v
,
11295 i
* 2 + 1, (uint32_t)(v
>> 32),
11298 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
11302 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
, int pc_pos
)
11305 env
->pc
= tcg_ctx
.gen_opc_pc
[pc_pos
];
11306 env
->condexec_bits
= 0;
11308 env
->regs
[15] = tcg_ctx
.gen_opc_pc
[pc_pos
];
11309 env
->condexec_bits
= gen_opc_condexec_bits
[pc_pos
];