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
);
944 static inline void gen_hvc(DisasContext
*s
, int imm16
)
946 /* The pre HVC helper handles cases when HVC gets trapped
947 * as an undefined insn by runtime configuration (ie before
948 * the insn really executes).
950 gen_set_pc_im(s
, s
->pc
- 4);
951 gen_helper_pre_hvc(cpu_env
);
952 /* Otherwise we will treat this as a real exception which
953 * happens after execution of the insn. (The distinction matters
954 * for the PC value reported to the exception handler and also
955 * for single stepping.)
958 gen_set_pc_im(s
, s
->pc
);
959 s
->is_jmp
= DISAS_HVC
;
962 static inline void gen_smc(DisasContext
*s
)
964 /* As with HVC, we may take an exception either before or after
969 gen_set_pc_im(s
, s
->pc
- 4);
970 tmp
= tcg_const_i32(syn_aa32_smc());
971 gen_helper_pre_smc(cpu_env
, tmp
);
972 tcg_temp_free_i32(tmp
);
973 gen_set_pc_im(s
, s
->pc
);
974 s
->is_jmp
= DISAS_SMC
;
978 gen_set_condexec (DisasContext
*s
)
980 if (s
->condexec_mask
) {
981 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
982 TCGv_i32 tmp
= tcg_temp_new_i32();
983 tcg_gen_movi_i32(tmp
, val
);
984 store_cpu_field(tmp
, condexec_bits
);
988 static void gen_exception_internal_insn(DisasContext
*s
, int offset
, int excp
)
991 gen_set_pc_im(s
, s
->pc
- offset
);
992 gen_exception_internal(excp
);
993 s
->is_jmp
= DISAS_JUMP
;
996 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
, int syn
)
999 gen_set_pc_im(s
, s
->pc
- offset
);
1000 gen_exception(excp
, syn
);
1001 s
->is_jmp
= DISAS_JUMP
;
1004 /* Force a TB lookup after an instruction that changes the CPU state. */
1005 static inline void gen_lookup_tb(DisasContext
*s
)
1007 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
1008 s
->is_jmp
= DISAS_UPDATE
;
1011 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
1014 int val
, rm
, shift
, shiftop
;
1017 if (!(insn
& (1 << 25))) {
1020 if (!(insn
& (1 << 23)))
1023 tcg_gen_addi_i32(var
, var
, val
);
1025 /* shift/register */
1027 shift
= (insn
>> 7) & 0x1f;
1028 shiftop
= (insn
>> 5) & 3;
1029 offset
= load_reg(s
, rm
);
1030 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
1031 if (!(insn
& (1 << 23)))
1032 tcg_gen_sub_i32(var
, var
, offset
);
1034 tcg_gen_add_i32(var
, var
, offset
);
1035 tcg_temp_free_i32(offset
);
1039 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
1040 int extra
, TCGv_i32 var
)
1045 if (insn
& (1 << 22)) {
1047 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
1048 if (!(insn
& (1 << 23)))
1052 tcg_gen_addi_i32(var
, var
, val
);
1056 tcg_gen_addi_i32(var
, var
, extra
);
1058 offset
= load_reg(s
, rm
);
1059 if (!(insn
& (1 << 23)))
1060 tcg_gen_sub_i32(var
, var
, offset
);
1062 tcg_gen_add_i32(var
, var
, offset
);
1063 tcg_temp_free_i32(offset
);
1067 static TCGv_ptr
get_fpstatus_ptr(int neon
)
1069 TCGv_ptr statusptr
= tcg_temp_new_ptr();
1072 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
1074 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
1076 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
1080 #define VFP_OP2(name) \
1081 static inline void gen_vfp_##name(int dp) \
1083 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1085 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1087 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1089 tcg_temp_free_ptr(fpst); \
1099 static inline void gen_vfp_F1_mul(int dp
)
1101 /* Like gen_vfp_mul() but put result in F1 */
1102 TCGv_ptr fpst
= get_fpstatus_ptr(0);
1104 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
1106 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
1108 tcg_temp_free_ptr(fpst
);
1111 static inline void gen_vfp_F1_neg(int dp
)
1113 /* Like gen_vfp_neg() but put result in F1 */
1115 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
1117 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
1121 static inline void gen_vfp_abs(int dp
)
1124 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
1126 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
1129 static inline void gen_vfp_neg(int dp
)
1132 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
1134 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
1137 static inline void gen_vfp_sqrt(int dp
)
1140 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
1142 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
1145 static inline void gen_vfp_cmp(int dp
)
1148 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
1150 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
1153 static inline void gen_vfp_cmpe(int dp
)
1156 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
1158 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
1161 static inline void gen_vfp_F1_ld0(int dp
)
1164 tcg_gen_movi_i64(cpu_F1d
, 0);
1166 tcg_gen_movi_i32(cpu_F1s
, 0);
1169 #define VFP_GEN_ITOF(name) \
1170 static inline void gen_vfp_##name(int dp, int neon) \
1172 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1174 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1176 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1178 tcg_temp_free_ptr(statusptr); \
1185 #define VFP_GEN_FTOI(name) \
1186 static inline void gen_vfp_##name(int dp, int neon) \
1188 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1190 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1192 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1194 tcg_temp_free_ptr(statusptr); \
1203 #define VFP_GEN_FIX(name, round) \
1204 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1206 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1207 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1209 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1212 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1215 tcg_temp_free_i32(tmp_shift); \
1216 tcg_temp_free_ptr(statusptr); \
1218 VFP_GEN_FIX(tosh
, _round_to_zero
)
1219 VFP_GEN_FIX(tosl
, _round_to_zero
)
1220 VFP_GEN_FIX(touh
, _round_to_zero
)
1221 VFP_GEN_FIX(toul
, _round_to_zero
)
1228 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1231 gen_aa32_ld64(cpu_F0d
, addr
, get_mem_index(s
));
1233 gen_aa32_ld32u(cpu_F0s
, addr
, get_mem_index(s
));
1237 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1240 gen_aa32_st64(cpu_F0d
, addr
, get_mem_index(s
));
1242 gen_aa32_st32(cpu_F0s
, addr
, get_mem_index(s
));
1247 vfp_reg_offset (int dp
, int reg
)
1250 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1252 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1253 + offsetof(CPU_DoubleU
, l
.upper
);
1255 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1256 + offsetof(CPU_DoubleU
, l
.lower
);
1260 /* Return the offset of a 32-bit piece of a NEON register.
1261 zero is the least significant end of the register. */
1263 neon_reg_offset (int reg
, int n
)
1267 return vfp_reg_offset(0, sreg
);
1270 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1272 TCGv_i32 tmp
= tcg_temp_new_i32();
1273 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1277 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1279 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1280 tcg_temp_free_i32(var
);
1283 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1285 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1288 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1290 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1293 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1294 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1295 #define tcg_gen_st_f32 tcg_gen_st_i32
1296 #define tcg_gen_st_f64 tcg_gen_st_i64
1298 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1301 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1303 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1306 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1309 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1311 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1314 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1317 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1319 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1322 #define ARM_CP_RW_BIT (1 << 20)
1324 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1326 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1329 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1331 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1334 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1336 TCGv_i32 var
= tcg_temp_new_i32();
1337 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1341 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1343 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1344 tcg_temp_free_i32(var
);
1347 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1349 iwmmxt_store_reg(cpu_M0
, rn
);
1352 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1354 iwmmxt_load_reg(cpu_M0
, rn
);
1357 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1359 iwmmxt_load_reg(cpu_V1
, rn
);
1360 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1363 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1365 iwmmxt_load_reg(cpu_V1
, rn
);
1366 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1369 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1371 iwmmxt_load_reg(cpu_V1
, rn
);
1372 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1375 #define IWMMXT_OP(name) \
1376 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1378 iwmmxt_load_reg(cpu_V1, rn); \
1379 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1382 #define IWMMXT_OP_ENV(name) \
1383 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1385 iwmmxt_load_reg(cpu_V1, rn); \
1386 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1389 #define IWMMXT_OP_ENV_SIZE(name) \
1390 IWMMXT_OP_ENV(name##b) \
1391 IWMMXT_OP_ENV(name##w) \
1392 IWMMXT_OP_ENV(name##l)
1394 #define IWMMXT_OP_ENV1(name) \
1395 static inline void gen_op_iwmmxt_##name##_M0(void) \
1397 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1411 IWMMXT_OP_ENV_SIZE(unpackl
)
1412 IWMMXT_OP_ENV_SIZE(unpackh
)
1414 IWMMXT_OP_ENV1(unpacklub
)
1415 IWMMXT_OP_ENV1(unpackluw
)
1416 IWMMXT_OP_ENV1(unpacklul
)
1417 IWMMXT_OP_ENV1(unpackhub
)
1418 IWMMXT_OP_ENV1(unpackhuw
)
1419 IWMMXT_OP_ENV1(unpackhul
)
1420 IWMMXT_OP_ENV1(unpacklsb
)
1421 IWMMXT_OP_ENV1(unpacklsw
)
1422 IWMMXT_OP_ENV1(unpacklsl
)
1423 IWMMXT_OP_ENV1(unpackhsb
)
1424 IWMMXT_OP_ENV1(unpackhsw
)
1425 IWMMXT_OP_ENV1(unpackhsl
)
1427 IWMMXT_OP_ENV_SIZE(cmpeq
)
1428 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1429 IWMMXT_OP_ENV_SIZE(cmpgts
)
1431 IWMMXT_OP_ENV_SIZE(mins
)
1432 IWMMXT_OP_ENV_SIZE(minu
)
1433 IWMMXT_OP_ENV_SIZE(maxs
)
1434 IWMMXT_OP_ENV_SIZE(maxu
)
1436 IWMMXT_OP_ENV_SIZE(subn
)
1437 IWMMXT_OP_ENV_SIZE(addn
)
1438 IWMMXT_OP_ENV_SIZE(subu
)
1439 IWMMXT_OP_ENV_SIZE(addu
)
1440 IWMMXT_OP_ENV_SIZE(subs
)
1441 IWMMXT_OP_ENV_SIZE(adds
)
1443 IWMMXT_OP_ENV(avgb0
)
1444 IWMMXT_OP_ENV(avgb1
)
1445 IWMMXT_OP_ENV(avgw0
)
1446 IWMMXT_OP_ENV(avgw1
)
1448 IWMMXT_OP_ENV(packuw
)
1449 IWMMXT_OP_ENV(packul
)
1450 IWMMXT_OP_ENV(packuq
)
1451 IWMMXT_OP_ENV(packsw
)
1452 IWMMXT_OP_ENV(packsl
)
1453 IWMMXT_OP_ENV(packsq
)
1455 static void gen_op_iwmmxt_set_mup(void)
1458 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1459 tcg_gen_ori_i32(tmp
, tmp
, 2);
1460 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1463 static void gen_op_iwmmxt_set_cup(void)
1466 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1467 tcg_gen_ori_i32(tmp
, tmp
, 1);
1468 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1471 static void gen_op_iwmmxt_setpsr_nz(void)
1473 TCGv_i32 tmp
= tcg_temp_new_i32();
1474 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1475 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1478 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1480 iwmmxt_load_reg(cpu_V1
, rn
);
1481 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1482 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1485 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1492 rd
= (insn
>> 16) & 0xf;
1493 tmp
= load_reg(s
, rd
);
1495 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1496 if (insn
& (1 << 24)) {
1498 if (insn
& (1 << 23))
1499 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1501 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1502 tcg_gen_mov_i32(dest
, tmp
);
1503 if (insn
& (1 << 21))
1504 store_reg(s
, rd
, tmp
);
1506 tcg_temp_free_i32(tmp
);
1507 } else if (insn
& (1 << 21)) {
1509 tcg_gen_mov_i32(dest
, tmp
);
1510 if (insn
& (1 << 23))
1511 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1513 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1514 store_reg(s
, rd
, tmp
);
1515 } else if (!(insn
& (1 << 23)))
1520 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1522 int rd
= (insn
>> 0) & 0xf;
1525 if (insn
& (1 << 8)) {
1526 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1529 tmp
= iwmmxt_load_creg(rd
);
1532 tmp
= tcg_temp_new_i32();
1533 iwmmxt_load_reg(cpu_V0
, rd
);
1534 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
1536 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1537 tcg_gen_mov_i32(dest
, tmp
);
1538 tcg_temp_free_i32(tmp
);
1542 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1543 (ie. an undefined instruction). */
1544 static int disas_iwmmxt_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
1547 int rdhi
, rdlo
, rd0
, rd1
, i
;
1549 TCGv_i32 tmp
, tmp2
, tmp3
;
1551 if ((insn
& 0x0e000e00) == 0x0c000000) {
1552 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1554 rdlo
= (insn
>> 12) & 0xf;
1555 rdhi
= (insn
>> 16) & 0xf;
1556 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1557 iwmmxt_load_reg(cpu_V0
, wrd
);
1558 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1559 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1560 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1561 } else { /* TMCRR */
1562 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1563 iwmmxt_store_reg(cpu_V0
, wrd
);
1564 gen_op_iwmmxt_set_mup();
1569 wrd
= (insn
>> 12) & 0xf;
1570 addr
= tcg_temp_new_i32();
1571 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1572 tcg_temp_free_i32(addr
);
1575 if (insn
& ARM_CP_RW_BIT
) {
1576 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1577 tmp
= tcg_temp_new_i32();
1578 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
1579 iwmmxt_store_creg(wrd
, tmp
);
1582 if (insn
& (1 << 8)) {
1583 if (insn
& (1 << 22)) { /* WLDRD */
1584 gen_aa32_ld64(cpu_M0
, addr
, get_mem_index(s
));
1586 } else { /* WLDRW wRd */
1587 tmp
= tcg_temp_new_i32();
1588 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
1591 tmp
= tcg_temp_new_i32();
1592 if (insn
& (1 << 22)) { /* WLDRH */
1593 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
1594 } else { /* WLDRB */
1595 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
1599 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1600 tcg_temp_free_i32(tmp
);
1602 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1605 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1606 tmp
= iwmmxt_load_creg(wrd
);
1607 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
1609 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1610 tmp
= tcg_temp_new_i32();
1611 if (insn
& (1 << 8)) {
1612 if (insn
& (1 << 22)) { /* WSTRD */
1613 gen_aa32_st64(cpu_M0
, addr
, get_mem_index(s
));
1614 } else { /* WSTRW wRd */
1615 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1616 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
1619 if (insn
& (1 << 22)) { /* WSTRH */
1620 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1621 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
1622 } else { /* WSTRB */
1623 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1624 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
1628 tcg_temp_free_i32(tmp
);
1630 tcg_temp_free_i32(addr
);
1634 if ((insn
& 0x0f000000) != 0x0e000000)
1637 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1638 case 0x000: /* WOR */
1639 wrd
= (insn
>> 12) & 0xf;
1640 rd0
= (insn
>> 0) & 0xf;
1641 rd1
= (insn
>> 16) & 0xf;
1642 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1643 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1644 gen_op_iwmmxt_setpsr_nz();
1645 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1646 gen_op_iwmmxt_set_mup();
1647 gen_op_iwmmxt_set_cup();
1649 case 0x011: /* TMCR */
1652 rd
= (insn
>> 12) & 0xf;
1653 wrd
= (insn
>> 16) & 0xf;
1655 case ARM_IWMMXT_wCID
:
1656 case ARM_IWMMXT_wCASF
:
1658 case ARM_IWMMXT_wCon
:
1659 gen_op_iwmmxt_set_cup();
1661 case ARM_IWMMXT_wCSSF
:
1662 tmp
= iwmmxt_load_creg(wrd
);
1663 tmp2
= load_reg(s
, rd
);
1664 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1665 tcg_temp_free_i32(tmp2
);
1666 iwmmxt_store_creg(wrd
, tmp
);
1668 case ARM_IWMMXT_wCGR0
:
1669 case ARM_IWMMXT_wCGR1
:
1670 case ARM_IWMMXT_wCGR2
:
1671 case ARM_IWMMXT_wCGR3
:
1672 gen_op_iwmmxt_set_cup();
1673 tmp
= load_reg(s
, rd
);
1674 iwmmxt_store_creg(wrd
, tmp
);
1680 case 0x100: /* WXOR */
1681 wrd
= (insn
>> 12) & 0xf;
1682 rd0
= (insn
>> 0) & 0xf;
1683 rd1
= (insn
>> 16) & 0xf;
1684 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1685 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1686 gen_op_iwmmxt_setpsr_nz();
1687 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1688 gen_op_iwmmxt_set_mup();
1689 gen_op_iwmmxt_set_cup();
1691 case 0x111: /* TMRC */
1694 rd
= (insn
>> 12) & 0xf;
1695 wrd
= (insn
>> 16) & 0xf;
1696 tmp
= iwmmxt_load_creg(wrd
);
1697 store_reg(s
, rd
, tmp
);
1699 case 0x300: /* WANDN */
1700 wrd
= (insn
>> 12) & 0xf;
1701 rd0
= (insn
>> 0) & 0xf;
1702 rd1
= (insn
>> 16) & 0xf;
1703 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1704 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1705 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1706 gen_op_iwmmxt_setpsr_nz();
1707 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1708 gen_op_iwmmxt_set_mup();
1709 gen_op_iwmmxt_set_cup();
1711 case 0x200: /* WAND */
1712 wrd
= (insn
>> 12) & 0xf;
1713 rd0
= (insn
>> 0) & 0xf;
1714 rd1
= (insn
>> 16) & 0xf;
1715 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1716 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1717 gen_op_iwmmxt_setpsr_nz();
1718 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1719 gen_op_iwmmxt_set_mup();
1720 gen_op_iwmmxt_set_cup();
1722 case 0x810: case 0xa10: /* WMADD */
1723 wrd
= (insn
>> 12) & 0xf;
1724 rd0
= (insn
>> 0) & 0xf;
1725 rd1
= (insn
>> 16) & 0xf;
1726 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1727 if (insn
& (1 << 21))
1728 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1730 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1731 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1732 gen_op_iwmmxt_set_mup();
1734 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1735 wrd
= (insn
>> 12) & 0xf;
1736 rd0
= (insn
>> 16) & 0xf;
1737 rd1
= (insn
>> 0) & 0xf;
1738 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1739 switch ((insn
>> 22) & 3) {
1741 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1744 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1747 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1752 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1753 gen_op_iwmmxt_set_mup();
1754 gen_op_iwmmxt_set_cup();
1756 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1757 wrd
= (insn
>> 12) & 0xf;
1758 rd0
= (insn
>> 16) & 0xf;
1759 rd1
= (insn
>> 0) & 0xf;
1760 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1761 switch ((insn
>> 22) & 3) {
1763 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1766 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1769 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1774 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1775 gen_op_iwmmxt_set_mup();
1776 gen_op_iwmmxt_set_cup();
1778 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
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 << 22))
1784 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1786 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1787 if (!(insn
& (1 << 20)))
1788 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1789 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1790 gen_op_iwmmxt_set_mup();
1792 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1793 wrd
= (insn
>> 12) & 0xf;
1794 rd0
= (insn
>> 16) & 0xf;
1795 rd1
= (insn
>> 0) & 0xf;
1796 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1797 if (insn
& (1 << 21)) {
1798 if (insn
& (1 << 20))
1799 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1801 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1803 if (insn
& (1 << 20))
1804 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1806 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1808 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1809 gen_op_iwmmxt_set_mup();
1811 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1812 wrd
= (insn
>> 12) & 0xf;
1813 rd0
= (insn
>> 16) & 0xf;
1814 rd1
= (insn
>> 0) & 0xf;
1815 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1816 if (insn
& (1 << 21))
1817 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1819 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1820 if (!(insn
& (1 << 20))) {
1821 iwmmxt_load_reg(cpu_V1
, wrd
);
1822 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1824 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1825 gen_op_iwmmxt_set_mup();
1827 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1828 wrd
= (insn
>> 12) & 0xf;
1829 rd0
= (insn
>> 16) & 0xf;
1830 rd1
= (insn
>> 0) & 0xf;
1831 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1832 switch ((insn
>> 22) & 3) {
1834 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
1837 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1840 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
1845 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1846 gen_op_iwmmxt_set_mup();
1847 gen_op_iwmmxt_set_cup();
1849 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1850 wrd
= (insn
>> 12) & 0xf;
1851 rd0
= (insn
>> 16) & 0xf;
1852 rd1
= (insn
>> 0) & 0xf;
1853 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1854 if (insn
& (1 << 22)) {
1855 if (insn
& (1 << 20))
1856 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1858 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1860 if (insn
& (1 << 20))
1861 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1863 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
1865 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1866 gen_op_iwmmxt_set_mup();
1867 gen_op_iwmmxt_set_cup();
1869 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1870 wrd
= (insn
>> 12) & 0xf;
1871 rd0
= (insn
>> 16) & 0xf;
1872 rd1
= (insn
>> 0) & 0xf;
1873 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1874 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
1875 tcg_gen_andi_i32(tmp
, tmp
, 7);
1876 iwmmxt_load_reg(cpu_V1
, rd1
);
1877 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
1878 tcg_temp_free_i32(tmp
);
1879 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1880 gen_op_iwmmxt_set_mup();
1882 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1883 if (((insn
>> 6) & 3) == 3)
1885 rd
= (insn
>> 12) & 0xf;
1886 wrd
= (insn
>> 16) & 0xf;
1887 tmp
= load_reg(s
, rd
);
1888 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1889 switch ((insn
>> 6) & 3) {
1891 tmp2
= tcg_const_i32(0xff);
1892 tmp3
= tcg_const_i32((insn
& 7) << 3);
1895 tmp2
= tcg_const_i32(0xffff);
1896 tmp3
= tcg_const_i32((insn
& 3) << 4);
1899 tmp2
= tcg_const_i32(0xffffffff);
1900 tmp3
= tcg_const_i32((insn
& 1) << 5);
1903 TCGV_UNUSED_I32(tmp2
);
1904 TCGV_UNUSED_I32(tmp3
);
1906 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
1907 tcg_temp_free_i32(tmp3
);
1908 tcg_temp_free_i32(tmp2
);
1909 tcg_temp_free_i32(tmp
);
1910 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1911 gen_op_iwmmxt_set_mup();
1913 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1914 rd
= (insn
>> 12) & 0xf;
1915 wrd
= (insn
>> 16) & 0xf;
1916 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
1918 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1919 tmp
= tcg_temp_new_i32();
1920 switch ((insn
>> 22) & 3) {
1922 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
1923 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1925 tcg_gen_ext8s_i32(tmp
, tmp
);
1927 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
1931 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
1932 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1934 tcg_gen_ext16s_i32(tmp
, tmp
);
1936 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
1940 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
1941 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1944 store_reg(s
, rd
, tmp
);
1946 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1947 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1949 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1950 switch ((insn
>> 22) & 3) {
1952 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
1955 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
1958 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
1961 tcg_gen_shli_i32(tmp
, tmp
, 28);
1963 tcg_temp_free_i32(tmp
);
1965 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1966 if (((insn
>> 6) & 3) == 3)
1968 rd
= (insn
>> 12) & 0xf;
1969 wrd
= (insn
>> 16) & 0xf;
1970 tmp
= load_reg(s
, rd
);
1971 switch ((insn
>> 6) & 3) {
1973 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
1976 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
1979 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
1982 tcg_temp_free_i32(tmp
);
1983 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1984 gen_op_iwmmxt_set_mup();
1986 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1987 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1989 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1990 tmp2
= tcg_temp_new_i32();
1991 tcg_gen_mov_i32(tmp2
, tmp
);
1992 switch ((insn
>> 22) & 3) {
1994 for (i
= 0; i
< 7; i
++) {
1995 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1996 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2000 for (i
= 0; i
< 3; i
++) {
2001 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2002 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2006 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2007 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2011 tcg_temp_free_i32(tmp2
);
2012 tcg_temp_free_i32(tmp
);
2014 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2015 wrd
= (insn
>> 12) & 0xf;
2016 rd0
= (insn
>> 16) & 0xf;
2017 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2018 switch ((insn
>> 22) & 3) {
2020 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
2023 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
2026 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
2031 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2032 gen_op_iwmmxt_set_mup();
2034 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2035 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2037 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2038 tmp2
= tcg_temp_new_i32();
2039 tcg_gen_mov_i32(tmp2
, tmp
);
2040 switch ((insn
>> 22) & 3) {
2042 for (i
= 0; i
< 7; i
++) {
2043 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2044 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2048 for (i
= 0; i
< 3; i
++) {
2049 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2050 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2054 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2055 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2059 tcg_temp_free_i32(tmp2
);
2060 tcg_temp_free_i32(tmp
);
2062 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2063 rd
= (insn
>> 12) & 0xf;
2064 rd0
= (insn
>> 16) & 0xf;
2065 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
2067 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2068 tmp
= tcg_temp_new_i32();
2069 switch ((insn
>> 22) & 3) {
2071 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
2074 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
2077 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
2080 store_reg(s
, rd
, tmp
);
2082 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2083 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2084 wrd
= (insn
>> 12) & 0xf;
2085 rd0
= (insn
>> 16) & 0xf;
2086 rd1
= (insn
>> 0) & 0xf;
2087 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2088 switch ((insn
>> 22) & 3) {
2090 if (insn
& (1 << 21))
2091 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
2093 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
2096 if (insn
& (1 << 21))
2097 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2099 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2102 if (insn
& (1 << 21))
2103 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2105 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2110 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2111 gen_op_iwmmxt_set_mup();
2112 gen_op_iwmmxt_set_cup();
2114 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2115 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2116 wrd
= (insn
>> 12) & 0xf;
2117 rd0
= (insn
>> 16) & 0xf;
2118 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2119 switch ((insn
>> 22) & 3) {
2121 if (insn
& (1 << 21))
2122 gen_op_iwmmxt_unpacklsb_M0();
2124 gen_op_iwmmxt_unpacklub_M0();
2127 if (insn
& (1 << 21))
2128 gen_op_iwmmxt_unpacklsw_M0();
2130 gen_op_iwmmxt_unpackluw_M0();
2133 if (insn
& (1 << 21))
2134 gen_op_iwmmxt_unpacklsl_M0();
2136 gen_op_iwmmxt_unpacklul_M0();
2141 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2142 gen_op_iwmmxt_set_mup();
2143 gen_op_iwmmxt_set_cup();
2145 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2146 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2147 wrd
= (insn
>> 12) & 0xf;
2148 rd0
= (insn
>> 16) & 0xf;
2149 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2150 switch ((insn
>> 22) & 3) {
2152 if (insn
& (1 << 21))
2153 gen_op_iwmmxt_unpackhsb_M0();
2155 gen_op_iwmmxt_unpackhub_M0();
2158 if (insn
& (1 << 21))
2159 gen_op_iwmmxt_unpackhsw_M0();
2161 gen_op_iwmmxt_unpackhuw_M0();
2164 if (insn
& (1 << 21))
2165 gen_op_iwmmxt_unpackhsl_M0();
2167 gen_op_iwmmxt_unpackhul_M0();
2172 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2173 gen_op_iwmmxt_set_mup();
2174 gen_op_iwmmxt_set_cup();
2176 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2177 case 0x214: case 0x614: case 0xa14: case 0xe14:
2178 if (((insn
>> 22) & 3) == 0)
2180 wrd
= (insn
>> 12) & 0xf;
2181 rd0
= (insn
>> 16) & 0xf;
2182 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2183 tmp
= tcg_temp_new_i32();
2184 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2185 tcg_temp_free_i32(tmp
);
2188 switch ((insn
>> 22) & 3) {
2190 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2193 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2196 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2199 tcg_temp_free_i32(tmp
);
2200 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2201 gen_op_iwmmxt_set_mup();
2202 gen_op_iwmmxt_set_cup();
2204 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2205 case 0x014: case 0x414: case 0x814: case 0xc14:
2206 if (((insn
>> 22) & 3) == 0)
2208 wrd
= (insn
>> 12) & 0xf;
2209 rd0
= (insn
>> 16) & 0xf;
2210 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2211 tmp
= tcg_temp_new_i32();
2212 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2213 tcg_temp_free_i32(tmp
);
2216 switch ((insn
>> 22) & 3) {
2218 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2221 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2224 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2227 tcg_temp_free_i32(tmp
);
2228 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2229 gen_op_iwmmxt_set_mup();
2230 gen_op_iwmmxt_set_cup();
2232 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2233 case 0x114: case 0x514: case 0x914: case 0xd14:
2234 if (((insn
>> 22) & 3) == 0)
2236 wrd
= (insn
>> 12) & 0xf;
2237 rd0
= (insn
>> 16) & 0xf;
2238 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2239 tmp
= tcg_temp_new_i32();
2240 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2241 tcg_temp_free_i32(tmp
);
2244 switch ((insn
>> 22) & 3) {
2246 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2249 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2252 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2255 tcg_temp_free_i32(tmp
);
2256 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2257 gen_op_iwmmxt_set_mup();
2258 gen_op_iwmmxt_set_cup();
2260 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2261 case 0x314: case 0x714: case 0xb14: case 0xf14:
2262 if (((insn
>> 22) & 3) == 0)
2264 wrd
= (insn
>> 12) & 0xf;
2265 rd0
= (insn
>> 16) & 0xf;
2266 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2267 tmp
= tcg_temp_new_i32();
2268 switch ((insn
>> 22) & 3) {
2270 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2271 tcg_temp_free_i32(tmp
);
2274 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2277 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2278 tcg_temp_free_i32(tmp
);
2281 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2284 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2285 tcg_temp_free_i32(tmp
);
2288 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2291 tcg_temp_free_i32(tmp
);
2292 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2293 gen_op_iwmmxt_set_mup();
2294 gen_op_iwmmxt_set_cup();
2296 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2297 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2298 wrd
= (insn
>> 12) & 0xf;
2299 rd0
= (insn
>> 16) & 0xf;
2300 rd1
= (insn
>> 0) & 0xf;
2301 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2302 switch ((insn
>> 22) & 3) {
2304 if (insn
& (1 << 21))
2305 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2307 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2310 if (insn
& (1 << 21))
2311 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2313 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2316 if (insn
& (1 << 21))
2317 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2319 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2324 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2325 gen_op_iwmmxt_set_mup();
2327 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2328 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2329 wrd
= (insn
>> 12) & 0xf;
2330 rd0
= (insn
>> 16) & 0xf;
2331 rd1
= (insn
>> 0) & 0xf;
2332 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2333 switch ((insn
>> 22) & 3) {
2335 if (insn
& (1 << 21))
2336 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2338 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2341 if (insn
& (1 << 21))
2342 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2344 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2347 if (insn
& (1 << 21))
2348 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2350 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2355 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2356 gen_op_iwmmxt_set_mup();
2358 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2359 case 0x402: case 0x502: case 0x602: case 0x702:
2360 wrd
= (insn
>> 12) & 0xf;
2361 rd0
= (insn
>> 16) & 0xf;
2362 rd1
= (insn
>> 0) & 0xf;
2363 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2364 tmp
= tcg_const_i32((insn
>> 20) & 3);
2365 iwmmxt_load_reg(cpu_V1
, rd1
);
2366 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2367 tcg_temp_free_i32(tmp
);
2368 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2369 gen_op_iwmmxt_set_mup();
2371 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2372 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2373 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2374 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2375 wrd
= (insn
>> 12) & 0xf;
2376 rd0
= (insn
>> 16) & 0xf;
2377 rd1
= (insn
>> 0) & 0xf;
2378 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2379 switch ((insn
>> 20) & 0xf) {
2381 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2384 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2387 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2390 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2393 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2396 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2399 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2402 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2405 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2410 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2411 gen_op_iwmmxt_set_mup();
2412 gen_op_iwmmxt_set_cup();
2414 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2415 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2416 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2417 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2418 wrd
= (insn
>> 12) & 0xf;
2419 rd0
= (insn
>> 16) & 0xf;
2420 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2421 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2422 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2423 tcg_temp_free_i32(tmp
);
2424 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2425 gen_op_iwmmxt_set_mup();
2426 gen_op_iwmmxt_set_cup();
2428 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2429 case 0x418: case 0x518: case 0x618: case 0x718:
2430 case 0x818: case 0x918: case 0xa18: case 0xb18:
2431 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2432 wrd
= (insn
>> 12) & 0xf;
2433 rd0
= (insn
>> 16) & 0xf;
2434 rd1
= (insn
>> 0) & 0xf;
2435 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2436 switch ((insn
>> 20) & 0xf) {
2438 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2441 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2444 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2447 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2450 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2453 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2456 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2459 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2462 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2467 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2468 gen_op_iwmmxt_set_mup();
2469 gen_op_iwmmxt_set_cup();
2471 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2472 case 0x408: case 0x508: case 0x608: case 0x708:
2473 case 0x808: case 0x908: case 0xa08: case 0xb08:
2474 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2475 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2477 wrd
= (insn
>> 12) & 0xf;
2478 rd0
= (insn
>> 16) & 0xf;
2479 rd1
= (insn
>> 0) & 0xf;
2480 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2481 switch ((insn
>> 22) & 3) {
2483 if (insn
& (1 << 21))
2484 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2486 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2489 if (insn
& (1 << 21))
2490 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2492 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2495 if (insn
& (1 << 21))
2496 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2498 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2501 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2502 gen_op_iwmmxt_set_mup();
2503 gen_op_iwmmxt_set_cup();
2505 case 0x201: case 0x203: case 0x205: case 0x207:
2506 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2507 case 0x211: case 0x213: case 0x215: case 0x217:
2508 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2509 wrd
= (insn
>> 5) & 0xf;
2510 rd0
= (insn
>> 12) & 0xf;
2511 rd1
= (insn
>> 0) & 0xf;
2512 if (rd0
== 0xf || rd1
== 0xf)
2514 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2515 tmp
= load_reg(s
, rd0
);
2516 tmp2
= load_reg(s
, rd1
);
2517 switch ((insn
>> 16) & 0xf) {
2518 case 0x0: /* TMIA */
2519 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2521 case 0x8: /* TMIAPH */
2522 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2524 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2525 if (insn
& (1 << 16))
2526 tcg_gen_shri_i32(tmp
, tmp
, 16);
2527 if (insn
& (1 << 17))
2528 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2529 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2532 tcg_temp_free_i32(tmp2
);
2533 tcg_temp_free_i32(tmp
);
2536 tcg_temp_free_i32(tmp2
);
2537 tcg_temp_free_i32(tmp
);
2538 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2539 gen_op_iwmmxt_set_mup();
2548 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2549 (ie. an undefined instruction). */
2550 static int disas_dsp_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
2552 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2555 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2556 /* Multiply with Internal Accumulate Format */
2557 rd0
= (insn
>> 12) & 0xf;
2559 acc
= (insn
>> 5) & 7;
2564 tmp
= load_reg(s
, rd0
);
2565 tmp2
= load_reg(s
, rd1
);
2566 switch ((insn
>> 16) & 0xf) {
2568 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2570 case 0x8: /* MIAPH */
2571 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2573 case 0xc: /* MIABB */
2574 case 0xd: /* MIABT */
2575 case 0xe: /* MIATB */
2576 case 0xf: /* MIATT */
2577 if (insn
& (1 << 16))
2578 tcg_gen_shri_i32(tmp
, tmp
, 16);
2579 if (insn
& (1 << 17))
2580 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2581 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2586 tcg_temp_free_i32(tmp2
);
2587 tcg_temp_free_i32(tmp
);
2589 gen_op_iwmmxt_movq_wRn_M0(acc
);
2593 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2594 /* Internal Accumulator Access Format */
2595 rdhi
= (insn
>> 16) & 0xf;
2596 rdlo
= (insn
>> 12) & 0xf;
2602 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2603 iwmmxt_load_reg(cpu_V0
, acc
);
2604 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2605 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2606 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2607 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2609 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2610 iwmmxt_store_reg(cpu_V0
, acc
);
2618 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2619 #define VFP_SREG(insn, bigbit, smallbit) \
2620 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2621 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2622 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2623 reg = (((insn) >> (bigbit)) & 0x0f) \
2624 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2626 if (insn & (1 << (smallbit))) \
2628 reg = ((insn) >> (bigbit)) & 0x0f; \
2631 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2632 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2633 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2634 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2635 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2636 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2638 /* Move between integer and VFP cores. */
2639 static TCGv_i32
gen_vfp_mrs(void)
2641 TCGv_i32 tmp
= tcg_temp_new_i32();
2642 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2646 static void gen_vfp_msr(TCGv_i32 tmp
)
2648 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2649 tcg_temp_free_i32(tmp
);
2652 static void gen_neon_dup_u8(TCGv_i32 var
, int shift
)
2654 TCGv_i32 tmp
= tcg_temp_new_i32();
2656 tcg_gen_shri_i32(var
, var
, shift
);
2657 tcg_gen_ext8u_i32(var
, var
);
2658 tcg_gen_shli_i32(tmp
, var
, 8);
2659 tcg_gen_or_i32(var
, var
, tmp
);
2660 tcg_gen_shli_i32(tmp
, var
, 16);
2661 tcg_gen_or_i32(var
, var
, tmp
);
2662 tcg_temp_free_i32(tmp
);
2665 static void gen_neon_dup_low16(TCGv_i32 var
)
2667 TCGv_i32 tmp
= tcg_temp_new_i32();
2668 tcg_gen_ext16u_i32(var
, var
);
2669 tcg_gen_shli_i32(tmp
, var
, 16);
2670 tcg_gen_or_i32(var
, var
, tmp
);
2671 tcg_temp_free_i32(tmp
);
2674 static void gen_neon_dup_high16(TCGv_i32 var
)
2676 TCGv_i32 tmp
= tcg_temp_new_i32();
2677 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2678 tcg_gen_shri_i32(tmp
, var
, 16);
2679 tcg_gen_or_i32(var
, var
, tmp
);
2680 tcg_temp_free_i32(tmp
);
2683 static TCGv_i32
gen_load_and_replicate(DisasContext
*s
, TCGv_i32 addr
, int size
)
2685 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2686 TCGv_i32 tmp
= tcg_temp_new_i32();
2689 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
2690 gen_neon_dup_u8(tmp
, 0);
2693 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
2694 gen_neon_dup_low16(tmp
);
2697 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
2699 default: /* Avoid compiler warnings. */
2705 static int handle_vsel(uint32_t insn
, uint32_t rd
, uint32_t rn
, uint32_t rm
,
2708 uint32_t cc
= extract32(insn
, 20, 2);
2711 TCGv_i64 frn
, frm
, dest
;
2712 TCGv_i64 tmp
, zero
, zf
, nf
, vf
;
2714 zero
= tcg_const_i64(0);
2716 frn
= tcg_temp_new_i64();
2717 frm
= tcg_temp_new_i64();
2718 dest
= tcg_temp_new_i64();
2720 zf
= tcg_temp_new_i64();
2721 nf
= tcg_temp_new_i64();
2722 vf
= tcg_temp_new_i64();
2724 tcg_gen_extu_i32_i64(zf
, cpu_ZF
);
2725 tcg_gen_ext_i32_i64(nf
, cpu_NF
);
2726 tcg_gen_ext_i32_i64(vf
, cpu_VF
);
2728 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2729 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2732 tcg_gen_movcond_i64(TCG_COND_EQ
, dest
, zf
, zero
,
2736 tcg_gen_movcond_i64(TCG_COND_LT
, dest
, vf
, zero
,
2739 case 2: /* ge: N == V -> N ^ V == 0 */
2740 tmp
= tcg_temp_new_i64();
2741 tcg_gen_xor_i64(tmp
, vf
, nf
);
2742 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2744 tcg_temp_free_i64(tmp
);
2746 case 3: /* gt: !Z && N == V */
2747 tcg_gen_movcond_i64(TCG_COND_NE
, dest
, zf
, zero
,
2749 tmp
= tcg_temp_new_i64();
2750 tcg_gen_xor_i64(tmp
, vf
, nf
);
2751 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2753 tcg_temp_free_i64(tmp
);
2756 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2757 tcg_temp_free_i64(frn
);
2758 tcg_temp_free_i64(frm
);
2759 tcg_temp_free_i64(dest
);
2761 tcg_temp_free_i64(zf
);
2762 tcg_temp_free_i64(nf
);
2763 tcg_temp_free_i64(vf
);
2765 tcg_temp_free_i64(zero
);
2767 TCGv_i32 frn
, frm
, dest
;
2770 zero
= tcg_const_i32(0);
2772 frn
= tcg_temp_new_i32();
2773 frm
= tcg_temp_new_i32();
2774 dest
= tcg_temp_new_i32();
2775 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2776 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2779 tcg_gen_movcond_i32(TCG_COND_EQ
, dest
, cpu_ZF
, zero
,
2783 tcg_gen_movcond_i32(TCG_COND_LT
, dest
, cpu_VF
, zero
,
2786 case 2: /* ge: N == V -> N ^ V == 0 */
2787 tmp
= tcg_temp_new_i32();
2788 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2789 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2791 tcg_temp_free_i32(tmp
);
2793 case 3: /* gt: !Z && N == V */
2794 tcg_gen_movcond_i32(TCG_COND_NE
, dest
, cpu_ZF
, zero
,
2796 tmp
= tcg_temp_new_i32();
2797 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2798 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2800 tcg_temp_free_i32(tmp
);
2803 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2804 tcg_temp_free_i32(frn
);
2805 tcg_temp_free_i32(frm
);
2806 tcg_temp_free_i32(dest
);
2808 tcg_temp_free_i32(zero
);
2814 static int handle_vminmaxnm(uint32_t insn
, uint32_t rd
, uint32_t rn
,
2815 uint32_t rm
, uint32_t dp
)
2817 uint32_t vmin
= extract32(insn
, 6, 1);
2818 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2821 TCGv_i64 frn
, frm
, dest
;
2823 frn
= tcg_temp_new_i64();
2824 frm
= tcg_temp_new_i64();
2825 dest
= tcg_temp_new_i64();
2827 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2828 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2830 gen_helper_vfp_minnumd(dest
, frn
, frm
, fpst
);
2832 gen_helper_vfp_maxnumd(dest
, frn
, frm
, fpst
);
2834 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2835 tcg_temp_free_i64(frn
);
2836 tcg_temp_free_i64(frm
);
2837 tcg_temp_free_i64(dest
);
2839 TCGv_i32 frn
, frm
, dest
;
2841 frn
= tcg_temp_new_i32();
2842 frm
= tcg_temp_new_i32();
2843 dest
= tcg_temp_new_i32();
2845 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2846 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2848 gen_helper_vfp_minnums(dest
, frn
, frm
, fpst
);
2850 gen_helper_vfp_maxnums(dest
, frn
, frm
, fpst
);
2852 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2853 tcg_temp_free_i32(frn
);
2854 tcg_temp_free_i32(frm
);
2855 tcg_temp_free_i32(dest
);
2858 tcg_temp_free_ptr(fpst
);
2862 static int handle_vrint(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
2865 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2868 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
2869 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2874 tcg_op
= tcg_temp_new_i64();
2875 tcg_res
= tcg_temp_new_i64();
2876 tcg_gen_ld_f64(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
2877 gen_helper_rintd(tcg_res
, tcg_op
, fpst
);
2878 tcg_gen_st_f64(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
2879 tcg_temp_free_i64(tcg_op
);
2880 tcg_temp_free_i64(tcg_res
);
2884 tcg_op
= tcg_temp_new_i32();
2885 tcg_res
= tcg_temp_new_i32();
2886 tcg_gen_ld_f32(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
2887 gen_helper_rints(tcg_res
, tcg_op
, fpst
);
2888 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
2889 tcg_temp_free_i32(tcg_op
);
2890 tcg_temp_free_i32(tcg_res
);
2893 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2894 tcg_temp_free_i32(tcg_rmode
);
2896 tcg_temp_free_ptr(fpst
);
2900 static int handle_vcvt(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
2903 bool is_signed
= extract32(insn
, 7, 1);
2904 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2905 TCGv_i32 tcg_rmode
, tcg_shift
;
2907 tcg_shift
= tcg_const_i32(0);
2909 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
2910 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2913 TCGv_i64 tcg_double
, tcg_res
;
2915 /* Rd is encoded as a single precision register even when the source
2916 * is double precision.
2918 rd
= ((rd
<< 1) & 0x1e) | ((rd
>> 4) & 0x1);
2919 tcg_double
= tcg_temp_new_i64();
2920 tcg_res
= tcg_temp_new_i64();
2921 tcg_tmp
= tcg_temp_new_i32();
2922 tcg_gen_ld_f64(tcg_double
, cpu_env
, vfp_reg_offset(1, rm
));
2924 gen_helper_vfp_tosld(tcg_res
, tcg_double
, tcg_shift
, fpst
);
2926 gen_helper_vfp_tould(tcg_res
, tcg_double
, tcg_shift
, fpst
);
2928 tcg_gen_trunc_i64_i32(tcg_tmp
, tcg_res
);
2929 tcg_gen_st_f32(tcg_tmp
, cpu_env
, vfp_reg_offset(0, rd
));
2930 tcg_temp_free_i32(tcg_tmp
);
2931 tcg_temp_free_i64(tcg_res
);
2932 tcg_temp_free_i64(tcg_double
);
2934 TCGv_i32 tcg_single
, tcg_res
;
2935 tcg_single
= tcg_temp_new_i32();
2936 tcg_res
= tcg_temp_new_i32();
2937 tcg_gen_ld_f32(tcg_single
, cpu_env
, vfp_reg_offset(0, rm
));
2939 gen_helper_vfp_tosls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
2941 gen_helper_vfp_touls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
2943 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(0, rd
));
2944 tcg_temp_free_i32(tcg_res
);
2945 tcg_temp_free_i32(tcg_single
);
2948 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2949 tcg_temp_free_i32(tcg_rmode
);
2951 tcg_temp_free_i32(tcg_shift
);
2953 tcg_temp_free_ptr(fpst
);
2958 /* Table for converting the most common AArch32 encoding of
2959 * rounding mode to arm_fprounding order (which matches the
2960 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
2962 static const uint8_t fp_decode_rm
[] = {
2969 static int disas_vfp_v8_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
2971 uint32_t rd
, rn
, rm
, dp
= extract32(insn
, 8, 1);
2973 if (!arm_feature(env
, ARM_FEATURE_V8
)) {
2978 VFP_DREG_D(rd
, insn
);
2979 VFP_DREG_N(rn
, insn
);
2980 VFP_DREG_M(rm
, insn
);
2982 rd
= VFP_SREG_D(insn
);
2983 rn
= VFP_SREG_N(insn
);
2984 rm
= VFP_SREG_M(insn
);
2987 if ((insn
& 0x0f800e50) == 0x0e000a00) {
2988 return handle_vsel(insn
, rd
, rn
, rm
, dp
);
2989 } else if ((insn
& 0x0fb00e10) == 0x0e800a00) {
2990 return handle_vminmaxnm(insn
, rd
, rn
, rm
, dp
);
2991 } else if ((insn
& 0x0fbc0ed0) == 0x0eb80a40) {
2992 /* VRINTA, VRINTN, VRINTP, VRINTM */
2993 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
2994 return handle_vrint(insn
, rd
, rm
, dp
, rounding
);
2995 } else if ((insn
& 0x0fbc0e50) == 0x0ebc0a40) {
2996 /* VCVTA, VCVTN, VCVTP, VCVTM */
2997 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
2998 return handle_vcvt(insn
, rd
, rm
, dp
, rounding
);
3003 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3004 (ie. an undefined instruction). */
3005 static int disas_vfp_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
3007 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
3013 if (!arm_feature(env
, ARM_FEATURE_VFP
))
3016 /* FIXME: this access check should not take precedence over UNDEF
3017 * for invalid encodings; we will generate incorrect syndrome information
3018 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3020 if (!s
->cpacr_fpen
) {
3021 gen_exception_insn(s
, 4, EXCP_UDEF
,
3022 syn_fp_access_trap(1, 0xe, s
->thumb
));
3026 if (!s
->vfp_enabled
) {
3027 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3028 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
3030 rn
= (insn
>> 16) & 0xf;
3031 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
&& rn
!= ARM_VFP_MVFR2
3032 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
) {
3037 if (extract32(insn
, 28, 4) == 0xf) {
3038 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3039 * only used in v8 and above.
3041 return disas_vfp_v8_insn(env
, s
, insn
);
3044 dp
= ((insn
& 0xf00) == 0xb00);
3045 switch ((insn
>> 24) & 0xf) {
3047 if (insn
& (1 << 4)) {
3048 /* single register transfer */
3049 rd
= (insn
>> 12) & 0xf;
3054 VFP_DREG_N(rn
, insn
);
3057 if (insn
& 0x00c00060
3058 && !arm_feature(env
, ARM_FEATURE_NEON
))
3061 pass
= (insn
>> 21) & 1;
3062 if (insn
& (1 << 22)) {
3064 offset
= ((insn
>> 5) & 3) * 8;
3065 } else if (insn
& (1 << 5)) {
3067 offset
= (insn
& (1 << 6)) ? 16 : 0;
3072 if (insn
& ARM_CP_RW_BIT
) {
3074 tmp
= neon_load_reg(rn
, pass
);
3078 tcg_gen_shri_i32(tmp
, tmp
, offset
);
3079 if (insn
& (1 << 23))
3085 if (insn
& (1 << 23)) {
3087 tcg_gen_shri_i32(tmp
, tmp
, 16);
3093 tcg_gen_sari_i32(tmp
, tmp
, 16);
3102 store_reg(s
, rd
, tmp
);
3105 tmp
= load_reg(s
, rd
);
3106 if (insn
& (1 << 23)) {
3109 gen_neon_dup_u8(tmp
, 0);
3110 } else if (size
== 1) {
3111 gen_neon_dup_low16(tmp
);
3113 for (n
= 0; n
<= pass
* 2; n
++) {
3114 tmp2
= tcg_temp_new_i32();
3115 tcg_gen_mov_i32(tmp2
, tmp
);
3116 neon_store_reg(rn
, n
, tmp2
);
3118 neon_store_reg(rn
, n
, tmp
);
3123 tmp2
= neon_load_reg(rn
, pass
);
3124 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 8);
3125 tcg_temp_free_i32(tmp2
);
3128 tmp2
= neon_load_reg(rn
, pass
);
3129 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 16);
3130 tcg_temp_free_i32(tmp2
);
3135 neon_store_reg(rn
, pass
, tmp
);
3139 if ((insn
& 0x6f) != 0x00)
3141 rn
= VFP_SREG_N(insn
);
3142 if (insn
& ARM_CP_RW_BIT
) {
3144 if (insn
& (1 << 21)) {
3145 /* system register */
3150 /* VFP2 allows access to FSID from userspace.
3151 VFP3 restricts all id registers to privileged
3154 && arm_feature(env
, ARM_FEATURE_VFP3
))
3156 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3161 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3163 case ARM_VFP_FPINST
:
3164 case ARM_VFP_FPINST2
:
3165 /* Not present in VFP3. */
3167 || arm_feature(env
, ARM_FEATURE_VFP3
))
3169 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3173 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
3174 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
3176 tmp
= tcg_temp_new_i32();
3177 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
3181 if (!arm_feature(env
, ARM_FEATURE_V8
)) {
3188 || !arm_feature(env
, ARM_FEATURE_MVFR
))
3190 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3196 gen_mov_F0_vreg(0, rn
);
3197 tmp
= gen_vfp_mrs();
3200 /* Set the 4 flag bits in the CPSR. */
3202 tcg_temp_free_i32(tmp
);
3204 store_reg(s
, rd
, tmp
);
3208 if (insn
& (1 << 21)) {
3210 /* system register */
3215 /* Writes are ignored. */
3218 tmp
= load_reg(s
, rd
);
3219 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
3220 tcg_temp_free_i32(tmp
);
3226 /* TODO: VFP subarchitecture support.
3227 * For now, keep the EN bit only */
3228 tmp
= load_reg(s
, rd
);
3229 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
3230 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3233 case ARM_VFP_FPINST
:
3234 case ARM_VFP_FPINST2
:
3238 tmp
= load_reg(s
, rd
);
3239 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3245 tmp
= load_reg(s
, rd
);
3247 gen_mov_vreg_F0(0, rn
);
3252 /* data processing */
3253 /* The opcode is in bits 23, 21, 20 and 6. */
3254 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
3258 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
3260 /* rn is register number */
3261 VFP_DREG_N(rn
, insn
);
3264 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18) ||
3265 ((rn
& 0x1e) == 0x6))) {
3266 /* Integer or single/half precision destination. */
3267 rd
= VFP_SREG_D(insn
);
3269 VFP_DREG_D(rd
, insn
);
3272 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14) ||
3273 ((rn
& 0x1e) == 0x4))) {
3274 /* VCVT from int or half precision is always from S reg
3275 * regardless of dp bit. VCVT with immediate frac_bits
3276 * has same format as SREG_M.
3278 rm
= VFP_SREG_M(insn
);
3280 VFP_DREG_M(rm
, insn
);
3283 rn
= VFP_SREG_N(insn
);
3284 if (op
== 15 && rn
== 15) {
3285 /* Double precision destination. */
3286 VFP_DREG_D(rd
, insn
);
3288 rd
= VFP_SREG_D(insn
);
3290 /* NB that we implicitly rely on the encoding for the frac_bits
3291 * in VCVT of fixed to float being the same as that of an SREG_M
3293 rm
= VFP_SREG_M(insn
);
3296 veclen
= s
->vec_len
;
3297 if (op
== 15 && rn
> 3)
3300 /* Shut up compiler warnings. */
3311 /* Figure out what type of vector operation this is. */
3312 if ((rd
& bank_mask
) == 0) {
3317 delta_d
= (s
->vec_stride
>> 1) + 1;
3319 delta_d
= s
->vec_stride
+ 1;
3321 if ((rm
& bank_mask
) == 0) {
3322 /* mixed scalar/vector */
3331 /* Load the initial operands. */
3336 /* Integer source */
3337 gen_mov_F0_vreg(0, rm
);
3342 gen_mov_F0_vreg(dp
, rd
);
3343 gen_mov_F1_vreg(dp
, rm
);
3347 /* Compare with zero */
3348 gen_mov_F0_vreg(dp
, rd
);
3359 /* Source and destination the same. */
3360 gen_mov_F0_vreg(dp
, rd
);
3366 /* VCVTB, VCVTT: only present with the halfprec extension
3367 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3368 * (we choose to UNDEF)
3370 if ((dp
&& !arm_feature(env
, ARM_FEATURE_V8
)) ||
3371 !arm_feature(env
, ARM_FEATURE_VFP_FP16
)) {
3374 if (!extract32(rn
, 1, 1)) {
3375 /* Half precision source. */
3376 gen_mov_F0_vreg(0, rm
);
3379 /* Otherwise fall through */
3381 /* One source operand. */
3382 gen_mov_F0_vreg(dp
, rm
);
3386 /* Two source operands. */
3387 gen_mov_F0_vreg(dp
, rn
);
3388 gen_mov_F1_vreg(dp
, rm
);
3392 /* Perform the calculation. */
3394 case 0: /* VMLA: fd + (fn * fm) */
3395 /* Note that order of inputs to the add matters for NaNs */
3397 gen_mov_F0_vreg(dp
, rd
);
3400 case 1: /* VMLS: fd + -(fn * fm) */
3403 gen_mov_F0_vreg(dp
, rd
);
3406 case 2: /* VNMLS: -fd + (fn * fm) */
3407 /* Note that it isn't valid to replace (-A + B) with (B - A)
3408 * or similar plausible looking simplifications
3409 * because this will give wrong results for NaNs.
3412 gen_mov_F0_vreg(dp
, rd
);
3416 case 3: /* VNMLA: -fd + -(fn * fm) */
3419 gen_mov_F0_vreg(dp
, rd
);
3423 case 4: /* mul: fn * fm */
3426 case 5: /* nmul: -(fn * fm) */
3430 case 6: /* add: fn + fm */
3433 case 7: /* sub: fn - fm */
3436 case 8: /* div: fn / fm */
3439 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3440 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3441 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3442 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3443 /* These are fused multiply-add, and must be done as one
3444 * floating point operation with no rounding between the
3445 * multiplication and addition steps.
3446 * NB that doing the negations here as separate steps is
3447 * correct : an input NaN should come out with its sign bit
3448 * flipped if it is a negated-input.
3450 if (!arm_feature(env
, ARM_FEATURE_VFP4
)) {
3458 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3460 frd
= tcg_temp_new_i64();
3461 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3464 gen_helper_vfp_negd(frd
, frd
);
3466 fpst
= get_fpstatus_ptr(0);
3467 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3468 cpu_F1d
, frd
, fpst
);
3469 tcg_temp_free_ptr(fpst
);
3470 tcg_temp_free_i64(frd
);
3476 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3478 frd
= tcg_temp_new_i32();
3479 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3481 gen_helper_vfp_negs(frd
, frd
);
3483 fpst
= get_fpstatus_ptr(0);
3484 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3485 cpu_F1s
, frd
, fpst
);
3486 tcg_temp_free_ptr(fpst
);
3487 tcg_temp_free_i32(frd
);
3490 case 14: /* fconst */
3491 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3494 n
= (insn
<< 12) & 0x80000000;
3495 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3502 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3509 tcg_gen_movi_i32(cpu_F0s
, n
);
3512 case 15: /* extension space */
3526 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3527 tmp
= gen_vfp_mrs();
3528 tcg_gen_ext16u_i32(tmp
, tmp
);
3530 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3533 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3536 tcg_temp_free_i32(tmp
);
3538 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3539 tmp
= gen_vfp_mrs();
3540 tcg_gen_shri_i32(tmp
, tmp
, 16);
3542 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3545 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3548 tcg_temp_free_i32(tmp
);
3550 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3551 tmp
= tcg_temp_new_i32();
3553 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3556 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3559 gen_mov_F0_vreg(0, rd
);
3560 tmp2
= gen_vfp_mrs();
3561 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3562 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3563 tcg_temp_free_i32(tmp2
);
3566 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3567 tmp
= tcg_temp_new_i32();
3569 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3572 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3575 tcg_gen_shli_i32(tmp
, tmp
, 16);
3576 gen_mov_F0_vreg(0, rd
);
3577 tmp2
= gen_vfp_mrs();
3578 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3579 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3580 tcg_temp_free_i32(tmp2
);
3592 case 11: /* cmpez */
3596 case 12: /* vrintr */
3598 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3600 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3602 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3604 tcg_temp_free_ptr(fpst
);
3607 case 13: /* vrintz */
3609 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3611 tcg_rmode
= tcg_const_i32(float_round_to_zero
);
3612 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3614 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3616 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3618 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3619 tcg_temp_free_i32(tcg_rmode
);
3620 tcg_temp_free_ptr(fpst
);
3623 case 14: /* vrintx */
3625 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3627 gen_helper_rintd_exact(cpu_F0d
, cpu_F0d
, fpst
);
3629 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpst
);
3631 tcg_temp_free_ptr(fpst
);
3634 case 15: /* single<->double conversion */
3636 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3638 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3640 case 16: /* fuito */
3641 gen_vfp_uito(dp
, 0);
3643 case 17: /* fsito */
3644 gen_vfp_sito(dp
, 0);
3646 case 20: /* fshto */
3647 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3649 gen_vfp_shto(dp
, 16 - rm
, 0);
3651 case 21: /* fslto */
3652 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3654 gen_vfp_slto(dp
, 32 - rm
, 0);
3656 case 22: /* fuhto */
3657 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3659 gen_vfp_uhto(dp
, 16 - rm
, 0);
3661 case 23: /* fulto */
3662 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3664 gen_vfp_ulto(dp
, 32 - rm
, 0);
3666 case 24: /* ftoui */
3667 gen_vfp_toui(dp
, 0);
3669 case 25: /* ftouiz */
3670 gen_vfp_touiz(dp
, 0);
3672 case 26: /* ftosi */
3673 gen_vfp_tosi(dp
, 0);
3675 case 27: /* ftosiz */
3676 gen_vfp_tosiz(dp
, 0);
3678 case 28: /* ftosh */
3679 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3681 gen_vfp_tosh(dp
, 16 - rm
, 0);
3683 case 29: /* ftosl */
3684 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3686 gen_vfp_tosl(dp
, 32 - rm
, 0);
3688 case 30: /* ftouh */
3689 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3691 gen_vfp_touh(dp
, 16 - rm
, 0);
3693 case 31: /* ftoul */
3694 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3696 gen_vfp_toul(dp
, 32 - rm
, 0);
3698 default: /* undefined */
3702 default: /* undefined */
3706 /* Write back the result. */
3707 if (op
== 15 && (rn
>= 8 && rn
<= 11)) {
3708 /* Comparison, do nothing. */
3709 } else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18 ||
3710 (rn
& 0x1e) == 0x6)) {
3711 /* VCVT double to int: always integer result.
3712 * VCVT double to half precision is always a single
3715 gen_mov_vreg_F0(0, rd
);
3716 } else if (op
== 15 && rn
== 15) {
3718 gen_mov_vreg_F0(!dp
, rd
);
3720 gen_mov_vreg_F0(dp
, rd
);
3723 /* break out of the loop if we have finished */
3727 if (op
== 15 && delta_m
== 0) {
3728 /* single source one-many */
3730 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3732 gen_mov_vreg_F0(dp
, rd
);
3736 /* Setup the next operands. */
3738 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3742 /* One source operand. */
3743 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3745 gen_mov_F0_vreg(dp
, rm
);
3747 /* Two source operands. */
3748 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3750 gen_mov_F0_vreg(dp
, rn
);
3752 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3754 gen_mov_F1_vreg(dp
, rm
);
3762 if ((insn
& 0x03e00000) == 0x00400000) {
3763 /* two-register transfer */
3764 rn
= (insn
>> 16) & 0xf;
3765 rd
= (insn
>> 12) & 0xf;
3767 VFP_DREG_M(rm
, insn
);
3769 rm
= VFP_SREG_M(insn
);
3772 if (insn
& ARM_CP_RW_BIT
) {
3775 gen_mov_F0_vreg(0, rm
* 2);
3776 tmp
= gen_vfp_mrs();
3777 store_reg(s
, rd
, tmp
);
3778 gen_mov_F0_vreg(0, rm
* 2 + 1);
3779 tmp
= gen_vfp_mrs();
3780 store_reg(s
, rn
, tmp
);
3782 gen_mov_F0_vreg(0, rm
);
3783 tmp
= gen_vfp_mrs();
3784 store_reg(s
, rd
, tmp
);
3785 gen_mov_F0_vreg(0, rm
+ 1);
3786 tmp
= gen_vfp_mrs();
3787 store_reg(s
, rn
, tmp
);
3792 tmp
= load_reg(s
, rd
);
3794 gen_mov_vreg_F0(0, rm
* 2);
3795 tmp
= load_reg(s
, rn
);
3797 gen_mov_vreg_F0(0, rm
* 2 + 1);
3799 tmp
= load_reg(s
, rd
);
3801 gen_mov_vreg_F0(0, rm
);
3802 tmp
= load_reg(s
, rn
);
3804 gen_mov_vreg_F0(0, rm
+ 1);
3809 rn
= (insn
>> 16) & 0xf;
3811 VFP_DREG_D(rd
, insn
);
3813 rd
= VFP_SREG_D(insn
);
3814 if ((insn
& 0x01200000) == 0x01000000) {
3815 /* Single load/store */
3816 offset
= (insn
& 0xff) << 2;
3817 if ((insn
& (1 << 23)) == 0)
3819 if (s
->thumb
&& rn
== 15) {
3820 /* This is actually UNPREDICTABLE */
3821 addr
= tcg_temp_new_i32();
3822 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3824 addr
= load_reg(s
, rn
);
3826 tcg_gen_addi_i32(addr
, addr
, offset
);
3827 if (insn
& (1 << 20)) {
3828 gen_vfp_ld(s
, dp
, addr
);
3829 gen_mov_vreg_F0(dp
, rd
);
3831 gen_mov_F0_vreg(dp
, rd
);
3832 gen_vfp_st(s
, dp
, addr
);
3834 tcg_temp_free_i32(addr
);
3836 /* load/store multiple */
3837 int w
= insn
& (1 << 21);
3839 n
= (insn
>> 1) & 0x7f;
3843 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
3844 /* P == U , W == 1 => UNDEF */
3847 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
3848 /* UNPREDICTABLE cases for bad immediates: we choose to
3849 * UNDEF to avoid generating huge numbers of TCG ops
3853 if (rn
== 15 && w
) {
3854 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3858 if (s
->thumb
&& rn
== 15) {
3859 /* This is actually UNPREDICTABLE */
3860 addr
= tcg_temp_new_i32();
3861 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3863 addr
= load_reg(s
, rn
);
3865 if (insn
& (1 << 24)) /* pre-decrement */
3866 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
3872 for (i
= 0; i
< n
; i
++) {
3873 if (insn
& ARM_CP_RW_BIT
) {
3875 gen_vfp_ld(s
, dp
, addr
);
3876 gen_mov_vreg_F0(dp
, rd
+ i
);
3879 gen_mov_F0_vreg(dp
, rd
+ i
);
3880 gen_vfp_st(s
, dp
, addr
);
3882 tcg_gen_addi_i32(addr
, addr
, offset
);
3886 if (insn
& (1 << 24))
3887 offset
= -offset
* n
;
3888 else if (dp
&& (insn
& 1))
3894 tcg_gen_addi_i32(addr
, addr
, offset
);
3895 store_reg(s
, rn
, addr
);
3897 tcg_temp_free_i32(addr
);
3903 /* Should never happen. */
3909 static inline void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
3911 TranslationBlock
*tb
;
3914 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
3916 gen_set_pc_im(s
, dest
);
3917 tcg_gen_exit_tb((uintptr_t)tb
+ n
);
3919 gen_set_pc_im(s
, dest
);
3924 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
3926 if (unlikely(s
->singlestep_enabled
|| s
->ss_active
)) {
3927 /* An indirect jump so that we still trigger the debug exception. */
3932 gen_goto_tb(s
, 0, dest
);
3933 s
->is_jmp
= DISAS_TB_JUMP
;
3937 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
3940 tcg_gen_sari_i32(t0
, t0
, 16);
3944 tcg_gen_sari_i32(t1
, t1
, 16);
3947 tcg_gen_mul_i32(t0
, t0
, t1
);
3950 /* Return the mask of PSR bits set by a MSR instruction. */
3951 static uint32_t msr_mask(CPUARMState
*env
, DisasContext
*s
, int flags
, int spsr
) {
3955 if (flags
& (1 << 0))
3957 if (flags
& (1 << 1))
3959 if (flags
& (1 << 2))
3961 if (flags
& (1 << 3))
3964 /* Mask out undefined bits. */
3965 mask
&= ~CPSR_RESERVED
;
3966 if (!arm_feature(env
, ARM_FEATURE_V4T
))
3968 if (!arm_feature(env
, ARM_FEATURE_V5
))
3969 mask
&= ~CPSR_Q
; /* V5TE in reality*/
3970 if (!arm_feature(env
, ARM_FEATURE_V6
))
3971 mask
&= ~(CPSR_E
| CPSR_GE
);
3972 if (!arm_feature(env
, ARM_FEATURE_THUMB2
))
3974 /* Mask out execution state and reserved bits. */
3976 mask
&= ~(CPSR_EXEC
| CPSR_RESERVED
);
3978 /* Mask out privileged bits. */
3984 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3985 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
3989 /* ??? This is also undefined in system mode. */
3993 tmp
= load_cpu_field(spsr
);
3994 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
3995 tcg_gen_andi_i32(t0
, t0
, mask
);
3996 tcg_gen_or_i32(tmp
, tmp
, t0
);
3997 store_cpu_field(tmp
, spsr
);
3999 gen_set_cpsr(t0
, mask
);
4001 tcg_temp_free_i32(t0
);
4006 /* Returns nonzero if access to the PSR is not permitted. */
4007 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
4010 tmp
= tcg_temp_new_i32();
4011 tcg_gen_movi_i32(tmp
, val
);
4012 return gen_set_psr(s
, mask
, spsr
, tmp
);
4015 /* Generate an old-style exception return. Marks pc as dead. */
4016 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
4019 store_reg(s
, 15, pc
);
4020 tmp
= load_cpu_field(spsr
);
4021 gen_set_cpsr(tmp
, CPSR_ERET_MASK
);
4022 tcg_temp_free_i32(tmp
);
4023 s
->is_jmp
= DISAS_UPDATE
;
4026 /* Generate a v6 exception return. Marks both values as dead. */
4027 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
4029 gen_set_cpsr(cpsr
, CPSR_ERET_MASK
);
4030 tcg_temp_free_i32(cpsr
);
4031 store_reg(s
, 15, pc
);
4032 s
->is_jmp
= DISAS_UPDATE
;
4035 static void gen_nop_hint(DisasContext
*s
, int val
)
4039 gen_set_pc_im(s
, s
->pc
);
4040 s
->is_jmp
= DISAS_WFI
;
4043 gen_set_pc_im(s
, s
->pc
);
4044 s
->is_jmp
= DISAS_WFE
;
4048 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4054 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4056 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4059 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
4060 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
4061 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
4066 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4069 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
4070 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
4071 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
4076 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4077 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4078 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4079 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4080 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4082 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4083 switch ((size << 1) | u) { \
4085 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4088 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4091 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4094 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4097 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4100 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4102 default: return 1; \
4105 #define GEN_NEON_INTEGER_OP(name) do { \
4106 switch ((size << 1) | u) { \
4108 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4111 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4114 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4117 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4120 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4123 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4125 default: return 1; \
4128 static TCGv_i32
neon_load_scratch(int scratch
)
4130 TCGv_i32 tmp
= tcg_temp_new_i32();
4131 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4135 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
4137 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4138 tcg_temp_free_i32(var
);
4141 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
4145 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
4147 gen_neon_dup_high16(tmp
);
4149 gen_neon_dup_low16(tmp
);
4152 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
4157 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
4160 if (!q
&& size
== 2) {
4163 tmp
= tcg_const_i32(rd
);
4164 tmp2
= tcg_const_i32(rm
);
4168 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
4171 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
4174 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
4182 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
4185 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
4191 tcg_temp_free_i32(tmp
);
4192 tcg_temp_free_i32(tmp2
);
4196 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
4199 if (!q
&& size
== 2) {
4202 tmp
= tcg_const_i32(rd
);
4203 tmp2
= tcg_const_i32(rm
);
4207 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
4210 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
4213 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
4221 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
4224 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
4230 tcg_temp_free_i32(tmp
);
4231 tcg_temp_free_i32(tmp2
);
4235 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
4239 rd
= tcg_temp_new_i32();
4240 tmp
= tcg_temp_new_i32();
4242 tcg_gen_shli_i32(rd
, t0
, 8);
4243 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
4244 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
4245 tcg_gen_or_i32(rd
, rd
, tmp
);
4247 tcg_gen_shri_i32(t1
, t1
, 8);
4248 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
4249 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
4250 tcg_gen_or_i32(t1
, t1
, tmp
);
4251 tcg_gen_mov_i32(t0
, rd
);
4253 tcg_temp_free_i32(tmp
);
4254 tcg_temp_free_i32(rd
);
4257 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
4261 rd
= tcg_temp_new_i32();
4262 tmp
= tcg_temp_new_i32();
4264 tcg_gen_shli_i32(rd
, t0
, 16);
4265 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
4266 tcg_gen_or_i32(rd
, rd
, tmp
);
4267 tcg_gen_shri_i32(t1
, t1
, 16);
4268 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
4269 tcg_gen_or_i32(t1
, t1
, tmp
);
4270 tcg_gen_mov_i32(t0
, rd
);
4272 tcg_temp_free_i32(tmp
);
4273 tcg_temp_free_i32(rd
);
4281 } neon_ls_element_type
[11] = {
4295 /* Translate a NEON load/store element instruction. Return nonzero if the
4296 instruction is invalid. */
4297 static int disas_neon_ls_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
4316 /* FIXME: this access check should not take precedence over UNDEF
4317 * for invalid encodings; we will generate incorrect syndrome information
4318 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4320 if (!s
->cpacr_fpen
) {
4321 gen_exception_insn(s
, 4, EXCP_UDEF
,
4322 syn_fp_access_trap(1, 0xe, s
->thumb
));
4326 if (!s
->vfp_enabled
)
4328 VFP_DREG_D(rd
, insn
);
4329 rn
= (insn
>> 16) & 0xf;
4331 load
= (insn
& (1 << 21)) != 0;
4332 if ((insn
& (1 << 23)) == 0) {
4333 /* Load store all elements. */
4334 op
= (insn
>> 8) & 0xf;
4335 size
= (insn
>> 6) & 3;
4338 /* Catch UNDEF cases for bad values of align field */
4341 if (((insn
>> 5) & 1) == 1) {
4346 if (((insn
>> 4) & 3) == 3) {
4353 nregs
= neon_ls_element_type
[op
].nregs
;
4354 interleave
= neon_ls_element_type
[op
].interleave
;
4355 spacing
= neon_ls_element_type
[op
].spacing
;
4356 if (size
== 3 && (interleave
| spacing
) != 1)
4358 addr
= tcg_temp_new_i32();
4359 load_reg_var(s
, addr
, rn
);
4360 stride
= (1 << size
) * interleave
;
4361 for (reg
= 0; reg
< nregs
; reg
++) {
4362 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
4363 load_reg_var(s
, addr
, rn
);
4364 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
4365 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
4366 load_reg_var(s
, addr
, rn
);
4367 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4370 tmp64
= tcg_temp_new_i64();
4372 gen_aa32_ld64(tmp64
, addr
, get_mem_index(s
));
4373 neon_store_reg64(tmp64
, rd
);
4375 neon_load_reg64(tmp64
, rd
);
4376 gen_aa32_st64(tmp64
, addr
, get_mem_index(s
));
4378 tcg_temp_free_i64(tmp64
);
4379 tcg_gen_addi_i32(addr
, addr
, stride
);
4381 for (pass
= 0; pass
< 2; pass
++) {
4384 tmp
= tcg_temp_new_i32();
4385 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
4386 neon_store_reg(rd
, pass
, tmp
);
4388 tmp
= neon_load_reg(rd
, pass
);
4389 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
4390 tcg_temp_free_i32(tmp
);
4392 tcg_gen_addi_i32(addr
, addr
, stride
);
4393 } else if (size
== 1) {
4395 tmp
= tcg_temp_new_i32();
4396 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
4397 tcg_gen_addi_i32(addr
, addr
, stride
);
4398 tmp2
= tcg_temp_new_i32();
4399 gen_aa32_ld16u(tmp2
, addr
, get_mem_index(s
));
4400 tcg_gen_addi_i32(addr
, addr
, stride
);
4401 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
4402 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4403 tcg_temp_free_i32(tmp2
);
4404 neon_store_reg(rd
, pass
, tmp
);
4406 tmp
= neon_load_reg(rd
, pass
);
4407 tmp2
= tcg_temp_new_i32();
4408 tcg_gen_shri_i32(tmp2
, tmp
, 16);
4409 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
4410 tcg_temp_free_i32(tmp
);
4411 tcg_gen_addi_i32(addr
, addr
, stride
);
4412 gen_aa32_st16(tmp2
, addr
, get_mem_index(s
));
4413 tcg_temp_free_i32(tmp2
);
4414 tcg_gen_addi_i32(addr
, addr
, stride
);
4416 } else /* size == 0 */ {
4418 TCGV_UNUSED_I32(tmp2
);
4419 for (n
= 0; n
< 4; n
++) {
4420 tmp
= tcg_temp_new_i32();
4421 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
4422 tcg_gen_addi_i32(addr
, addr
, stride
);
4426 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
4427 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
4428 tcg_temp_free_i32(tmp
);
4431 neon_store_reg(rd
, pass
, tmp2
);
4433 tmp2
= neon_load_reg(rd
, pass
);
4434 for (n
= 0; n
< 4; n
++) {
4435 tmp
= tcg_temp_new_i32();
4437 tcg_gen_mov_i32(tmp
, tmp2
);
4439 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
4441 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
4442 tcg_temp_free_i32(tmp
);
4443 tcg_gen_addi_i32(addr
, addr
, stride
);
4445 tcg_temp_free_i32(tmp2
);
4452 tcg_temp_free_i32(addr
);
4455 size
= (insn
>> 10) & 3;
4457 /* Load single element to all lanes. */
4458 int a
= (insn
>> 4) & 1;
4462 size
= (insn
>> 6) & 3;
4463 nregs
= ((insn
>> 8) & 3) + 1;
4466 if (nregs
!= 4 || a
== 0) {
4469 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4472 if (nregs
== 1 && a
== 1 && size
== 0) {
4475 if (nregs
== 3 && a
== 1) {
4478 addr
= tcg_temp_new_i32();
4479 load_reg_var(s
, addr
, rn
);
4481 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4482 tmp
= gen_load_and_replicate(s
, addr
, size
);
4483 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4484 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4485 if (insn
& (1 << 5)) {
4486 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
4487 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
4489 tcg_temp_free_i32(tmp
);
4491 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4492 stride
= (insn
& (1 << 5)) ? 2 : 1;
4493 for (reg
= 0; reg
< nregs
; reg
++) {
4494 tmp
= gen_load_and_replicate(s
, addr
, size
);
4495 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4496 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4497 tcg_temp_free_i32(tmp
);
4498 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4502 tcg_temp_free_i32(addr
);
4503 stride
= (1 << size
) * nregs
;
4505 /* Single element. */
4506 int idx
= (insn
>> 4) & 0xf;
4507 pass
= (insn
>> 7) & 1;
4510 shift
= ((insn
>> 5) & 3) * 8;
4514 shift
= ((insn
>> 6) & 1) * 16;
4515 stride
= (insn
& (1 << 5)) ? 2 : 1;
4519 stride
= (insn
& (1 << 6)) ? 2 : 1;
4524 nregs
= ((insn
>> 8) & 3) + 1;
4525 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4528 if (((idx
& (1 << size
)) != 0) ||
4529 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
4534 if ((idx
& 1) != 0) {
4539 if (size
== 2 && (idx
& 2) != 0) {
4544 if ((size
== 2) && ((idx
& 3) == 3)) {
4551 if ((rd
+ stride
* (nregs
- 1)) > 31) {
4552 /* Attempts to write off the end of the register file
4553 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4554 * the neon_load_reg() would write off the end of the array.
4558 addr
= tcg_temp_new_i32();
4559 load_reg_var(s
, addr
, rn
);
4560 for (reg
= 0; reg
< nregs
; reg
++) {
4562 tmp
= tcg_temp_new_i32();
4565 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
4568 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
4571 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
4573 default: /* Avoid compiler warnings. */
4577 tmp2
= neon_load_reg(rd
, pass
);
4578 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
4579 shift
, size
? 16 : 8);
4580 tcg_temp_free_i32(tmp2
);
4582 neon_store_reg(rd
, pass
, tmp
);
4583 } else { /* Store */
4584 tmp
= neon_load_reg(rd
, pass
);
4586 tcg_gen_shri_i32(tmp
, tmp
, shift
);
4589 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
4592 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
4595 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
4598 tcg_temp_free_i32(tmp
);
4601 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4603 tcg_temp_free_i32(addr
);
4604 stride
= nregs
* (1 << size
);
4610 base
= load_reg(s
, rn
);
4612 tcg_gen_addi_i32(base
, base
, stride
);
4615 index
= load_reg(s
, rm
);
4616 tcg_gen_add_i32(base
, base
, index
);
4617 tcg_temp_free_i32(index
);
4619 store_reg(s
, rn
, base
);
4624 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4625 static void gen_neon_bsl(TCGv_i32 dest
, TCGv_i32 t
, TCGv_i32 f
, TCGv_i32 c
)
4627 tcg_gen_and_i32(t
, t
, c
);
4628 tcg_gen_andc_i32(f
, f
, c
);
4629 tcg_gen_or_i32(dest
, t
, f
);
4632 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4635 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4636 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4637 case 2: tcg_gen_trunc_i64_i32(dest
, src
); break;
4642 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4645 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4646 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4647 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
4652 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4655 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
4656 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
4657 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
4662 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4665 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
4666 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
4667 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
4672 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
4678 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
4679 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
4684 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
4685 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
4692 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
4693 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
4698 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
4699 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
4706 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
4710 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
4711 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
4712 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
4717 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
4718 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
4719 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
4723 tcg_temp_free_i32(src
);
4726 static inline void gen_neon_addl(int size
)
4729 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
4730 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
4731 case 2: tcg_gen_add_i64(CPU_V001
); break;
4736 static inline void gen_neon_subl(int size
)
4739 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
4740 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
4741 case 2: tcg_gen_sub_i64(CPU_V001
); break;
4746 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
4749 case 0: gen_helper_neon_negl_u16(var
, var
); break;
4750 case 1: gen_helper_neon_negl_u32(var
, var
); break;
4752 tcg_gen_neg_i64(var
, var
);
4758 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
4761 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
4762 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
4767 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
4772 switch ((size
<< 1) | u
) {
4773 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
4774 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
4775 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
4776 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
4778 tmp
= gen_muls_i64_i32(a
, b
);
4779 tcg_gen_mov_i64(dest
, tmp
);
4780 tcg_temp_free_i64(tmp
);
4783 tmp
= gen_mulu_i64_i32(a
, b
);
4784 tcg_gen_mov_i64(dest
, tmp
);
4785 tcg_temp_free_i64(tmp
);
4790 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4791 Don't forget to clean them now. */
4793 tcg_temp_free_i32(a
);
4794 tcg_temp_free_i32(b
);
4798 static void gen_neon_narrow_op(int op
, int u
, int size
,
4799 TCGv_i32 dest
, TCGv_i64 src
)
4803 gen_neon_unarrow_sats(size
, dest
, src
);
4805 gen_neon_narrow(size
, dest
, src
);
4809 gen_neon_narrow_satu(size
, dest
, src
);
4811 gen_neon_narrow_sats(size
, dest
, src
);
4816 /* Symbolic constants for op fields for Neon 3-register same-length.
4817 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4820 #define NEON_3R_VHADD 0
4821 #define NEON_3R_VQADD 1
4822 #define NEON_3R_VRHADD 2
4823 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4824 #define NEON_3R_VHSUB 4
4825 #define NEON_3R_VQSUB 5
4826 #define NEON_3R_VCGT 6
4827 #define NEON_3R_VCGE 7
4828 #define NEON_3R_VSHL 8
4829 #define NEON_3R_VQSHL 9
4830 #define NEON_3R_VRSHL 10
4831 #define NEON_3R_VQRSHL 11
4832 #define NEON_3R_VMAX 12
4833 #define NEON_3R_VMIN 13
4834 #define NEON_3R_VABD 14
4835 #define NEON_3R_VABA 15
4836 #define NEON_3R_VADD_VSUB 16
4837 #define NEON_3R_VTST_VCEQ 17
4838 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4839 #define NEON_3R_VMUL 19
4840 #define NEON_3R_VPMAX 20
4841 #define NEON_3R_VPMIN 21
4842 #define NEON_3R_VQDMULH_VQRDMULH 22
4843 #define NEON_3R_VPADD 23
4844 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
4845 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4846 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4847 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4848 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4849 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4850 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4851 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4853 static const uint8_t neon_3r_sizes
[] = {
4854 [NEON_3R_VHADD
] = 0x7,
4855 [NEON_3R_VQADD
] = 0xf,
4856 [NEON_3R_VRHADD
] = 0x7,
4857 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
4858 [NEON_3R_VHSUB
] = 0x7,
4859 [NEON_3R_VQSUB
] = 0xf,
4860 [NEON_3R_VCGT
] = 0x7,
4861 [NEON_3R_VCGE
] = 0x7,
4862 [NEON_3R_VSHL
] = 0xf,
4863 [NEON_3R_VQSHL
] = 0xf,
4864 [NEON_3R_VRSHL
] = 0xf,
4865 [NEON_3R_VQRSHL
] = 0xf,
4866 [NEON_3R_VMAX
] = 0x7,
4867 [NEON_3R_VMIN
] = 0x7,
4868 [NEON_3R_VABD
] = 0x7,
4869 [NEON_3R_VABA
] = 0x7,
4870 [NEON_3R_VADD_VSUB
] = 0xf,
4871 [NEON_3R_VTST_VCEQ
] = 0x7,
4872 [NEON_3R_VML
] = 0x7,
4873 [NEON_3R_VMUL
] = 0x7,
4874 [NEON_3R_VPMAX
] = 0x7,
4875 [NEON_3R_VPMIN
] = 0x7,
4876 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
4877 [NEON_3R_VPADD
] = 0x7,
4878 [NEON_3R_SHA
] = 0xf, /* size field encodes op type */
4879 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
4880 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
4881 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
4882 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
4883 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
4884 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
4885 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
4888 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4889 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4892 #define NEON_2RM_VREV64 0
4893 #define NEON_2RM_VREV32 1
4894 #define NEON_2RM_VREV16 2
4895 #define NEON_2RM_VPADDL 4
4896 #define NEON_2RM_VPADDL_U 5
4897 #define NEON_2RM_AESE 6 /* Includes AESD */
4898 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4899 #define NEON_2RM_VCLS 8
4900 #define NEON_2RM_VCLZ 9
4901 #define NEON_2RM_VCNT 10
4902 #define NEON_2RM_VMVN 11
4903 #define NEON_2RM_VPADAL 12
4904 #define NEON_2RM_VPADAL_U 13
4905 #define NEON_2RM_VQABS 14
4906 #define NEON_2RM_VQNEG 15
4907 #define NEON_2RM_VCGT0 16
4908 #define NEON_2RM_VCGE0 17
4909 #define NEON_2RM_VCEQ0 18
4910 #define NEON_2RM_VCLE0 19
4911 #define NEON_2RM_VCLT0 20
4912 #define NEON_2RM_SHA1H 21
4913 #define NEON_2RM_VABS 22
4914 #define NEON_2RM_VNEG 23
4915 #define NEON_2RM_VCGT0_F 24
4916 #define NEON_2RM_VCGE0_F 25
4917 #define NEON_2RM_VCEQ0_F 26
4918 #define NEON_2RM_VCLE0_F 27
4919 #define NEON_2RM_VCLT0_F 28
4920 #define NEON_2RM_VABS_F 30
4921 #define NEON_2RM_VNEG_F 31
4922 #define NEON_2RM_VSWP 32
4923 #define NEON_2RM_VTRN 33
4924 #define NEON_2RM_VUZP 34
4925 #define NEON_2RM_VZIP 35
4926 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4927 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4928 #define NEON_2RM_VSHLL 38
4929 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
4930 #define NEON_2RM_VRINTN 40
4931 #define NEON_2RM_VRINTX 41
4932 #define NEON_2RM_VRINTA 42
4933 #define NEON_2RM_VRINTZ 43
4934 #define NEON_2RM_VCVT_F16_F32 44
4935 #define NEON_2RM_VRINTM 45
4936 #define NEON_2RM_VCVT_F32_F16 46
4937 #define NEON_2RM_VRINTP 47
4938 #define NEON_2RM_VCVTAU 48
4939 #define NEON_2RM_VCVTAS 49
4940 #define NEON_2RM_VCVTNU 50
4941 #define NEON_2RM_VCVTNS 51
4942 #define NEON_2RM_VCVTPU 52
4943 #define NEON_2RM_VCVTPS 53
4944 #define NEON_2RM_VCVTMU 54
4945 #define NEON_2RM_VCVTMS 55
4946 #define NEON_2RM_VRECPE 56
4947 #define NEON_2RM_VRSQRTE 57
4948 #define NEON_2RM_VRECPE_F 58
4949 #define NEON_2RM_VRSQRTE_F 59
4950 #define NEON_2RM_VCVT_FS 60
4951 #define NEON_2RM_VCVT_FU 61
4952 #define NEON_2RM_VCVT_SF 62
4953 #define NEON_2RM_VCVT_UF 63
4955 static int neon_2rm_is_float_op(int op
)
4957 /* Return true if this neon 2reg-misc op is float-to-float */
4958 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
4959 (op
>= NEON_2RM_VRINTN
&& op
<= NEON_2RM_VRINTZ
) ||
4960 op
== NEON_2RM_VRINTM
||
4961 (op
>= NEON_2RM_VRINTP
&& op
<= NEON_2RM_VCVTMS
) ||
4962 op
>= NEON_2RM_VRECPE_F
);
4965 /* Each entry in this array has bit n set if the insn allows
4966 * size value n (otherwise it will UNDEF). Since unallocated
4967 * op values will have no bits set they always UNDEF.
4969 static const uint8_t neon_2rm_sizes
[] = {
4970 [NEON_2RM_VREV64
] = 0x7,
4971 [NEON_2RM_VREV32
] = 0x3,
4972 [NEON_2RM_VREV16
] = 0x1,
4973 [NEON_2RM_VPADDL
] = 0x7,
4974 [NEON_2RM_VPADDL_U
] = 0x7,
4975 [NEON_2RM_AESE
] = 0x1,
4976 [NEON_2RM_AESMC
] = 0x1,
4977 [NEON_2RM_VCLS
] = 0x7,
4978 [NEON_2RM_VCLZ
] = 0x7,
4979 [NEON_2RM_VCNT
] = 0x1,
4980 [NEON_2RM_VMVN
] = 0x1,
4981 [NEON_2RM_VPADAL
] = 0x7,
4982 [NEON_2RM_VPADAL_U
] = 0x7,
4983 [NEON_2RM_VQABS
] = 0x7,
4984 [NEON_2RM_VQNEG
] = 0x7,
4985 [NEON_2RM_VCGT0
] = 0x7,
4986 [NEON_2RM_VCGE0
] = 0x7,
4987 [NEON_2RM_VCEQ0
] = 0x7,
4988 [NEON_2RM_VCLE0
] = 0x7,
4989 [NEON_2RM_VCLT0
] = 0x7,
4990 [NEON_2RM_SHA1H
] = 0x4,
4991 [NEON_2RM_VABS
] = 0x7,
4992 [NEON_2RM_VNEG
] = 0x7,
4993 [NEON_2RM_VCGT0_F
] = 0x4,
4994 [NEON_2RM_VCGE0_F
] = 0x4,
4995 [NEON_2RM_VCEQ0_F
] = 0x4,
4996 [NEON_2RM_VCLE0_F
] = 0x4,
4997 [NEON_2RM_VCLT0_F
] = 0x4,
4998 [NEON_2RM_VABS_F
] = 0x4,
4999 [NEON_2RM_VNEG_F
] = 0x4,
5000 [NEON_2RM_VSWP
] = 0x1,
5001 [NEON_2RM_VTRN
] = 0x7,
5002 [NEON_2RM_VUZP
] = 0x7,
5003 [NEON_2RM_VZIP
] = 0x7,
5004 [NEON_2RM_VMOVN
] = 0x7,
5005 [NEON_2RM_VQMOVN
] = 0x7,
5006 [NEON_2RM_VSHLL
] = 0x7,
5007 [NEON_2RM_SHA1SU1
] = 0x4,
5008 [NEON_2RM_VRINTN
] = 0x4,
5009 [NEON_2RM_VRINTX
] = 0x4,
5010 [NEON_2RM_VRINTA
] = 0x4,
5011 [NEON_2RM_VRINTZ
] = 0x4,
5012 [NEON_2RM_VCVT_F16_F32
] = 0x2,
5013 [NEON_2RM_VRINTM
] = 0x4,
5014 [NEON_2RM_VCVT_F32_F16
] = 0x2,
5015 [NEON_2RM_VRINTP
] = 0x4,
5016 [NEON_2RM_VCVTAU
] = 0x4,
5017 [NEON_2RM_VCVTAS
] = 0x4,
5018 [NEON_2RM_VCVTNU
] = 0x4,
5019 [NEON_2RM_VCVTNS
] = 0x4,
5020 [NEON_2RM_VCVTPU
] = 0x4,
5021 [NEON_2RM_VCVTPS
] = 0x4,
5022 [NEON_2RM_VCVTMU
] = 0x4,
5023 [NEON_2RM_VCVTMS
] = 0x4,
5024 [NEON_2RM_VRECPE
] = 0x4,
5025 [NEON_2RM_VRSQRTE
] = 0x4,
5026 [NEON_2RM_VRECPE_F
] = 0x4,
5027 [NEON_2RM_VRSQRTE_F
] = 0x4,
5028 [NEON_2RM_VCVT_FS
] = 0x4,
5029 [NEON_2RM_VCVT_FU
] = 0x4,
5030 [NEON_2RM_VCVT_SF
] = 0x4,
5031 [NEON_2RM_VCVT_UF
] = 0x4,
5034 /* Translate a NEON data processing instruction. Return nonzero if the
5035 instruction is invalid.
5036 We process data in a mixture of 32-bit and 64-bit chunks.
5037 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5039 static int disas_neon_data_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
5051 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
5054 /* FIXME: this access check should not take precedence over UNDEF
5055 * for invalid encodings; we will generate incorrect syndrome information
5056 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5058 if (!s
->cpacr_fpen
) {
5059 gen_exception_insn(s
, 4, EXCP_UDEF
,
5060 syn_fp_access_trap(1, 0xe, s
->thumb
));
5064 if (!s
->vfp_enabled
)
5066 q
= (insn
& (1 << 6)) != 0;
5067 u
= (insn
>> 24) & 1;
5068 VFP_DREG_D(rd
, insn
);
5069 VFP_DREG_N(rn
, insn
);
5070 VFP_DREG_M(rm
, insn
);
5071 size
= (insn
>> 20) & 3;
5072 if ((insn
& (1 << 23)) == 0) {
5073 /* Three register same length. */
5074 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
5075 /* Catch invalid op and bad size combinations: UNDEF */
5076 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
5079 /* All insns of this form UNDEF for either this condition or the
5080 * superset of cases "Q==1"; we catch the latter later.
5082 if (q
&& ((rd
| rn
| rm
) & 1)) {
5086 * The SHA-1/SHA-256 3-register instructions require special treatment
5087 * here, as their size field is overloaded as an op type selector, and
5088 * they all consume their input in a single pass.
5090 if (op
== NEON_3R_SHA
) {
5094 if (!u
) { /* SHA-1 */
5095 if (!arm_feature(env
, ARM_FEATURE_V8_SHA1
)) {
5098 tmp
= tcg_const_i32(rd
);
5099 tmp2
= tcg_const_i32(rn
);
5100 tmp3
= tcg_const_i32(rm
);
5101 tmp4
= tcg_const_i32(size
);
5102 gen_helper_crypto_sha1_3reg(cpu_env
, tmp
, tmp2
, tmp3
, tmp4
);
5103 tcg_temp_free_i32(tmp4
);
5104 } else { /* SHA-256 */
5105 if (!arm_feature(env
, ARM_FEATURE_V8_SHA256
) || size
== 3) {
5108 tmp
= tcg_const_i32(rd
);
5109 tmp2
= tcg_const_i32(rn
);
5110 tmp3
= tcg_const_i32(rm
);
5113 gen_helper_crypto_sha256h(cpu_env
, tmp
, tmp2
, tmp3
);
5116 gen_helper_crypto_sha256h2(cpu_env
, tmp
, tmp2
, tmp3
);
5119 gen_helper_crypto_sha256su1(cpu_env
, tmp
, tmp2
, tmp3
);
5123 tcg_temp_free_i32(tmp
);
5124 tcg_temp_free_i32(tmp2
);
5125 tcg_temp_free_i32(tmp3
);
5128 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
5129 /* 64-bit element instructions. */
5130 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5131 neon_load_reg64(cpu_V0
, rn
+ pass
);
5132 neon_load_reg64(cpu_V1
, rm
+ pass
);
5136 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
5139 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
5145 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
5148 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
5154 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5156 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5161 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5164 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5170 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5172 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5175 case NEON_3R_VQRSHL
:
5177 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
5180 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
5184 case NEON_3R_VADD_VSUB
:
5186 tcg_gen_sub_i64(CPU_V001
);
5188 tcg_gen_add_i64(CPU_V001
);
5194 neon_store_reg64(cpu_V0
, rd
+ pass
);
5203 case NEON_3R_VQRSHL
:
5206 /* Shift instruction operands are reversed. */
5221 case NEON_3R_FLOAT_ARITH
:
5222 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
5224 case NEON_3R_FLOAT_MINMAX
:
5225 pairwise
= u
; /* if VPMIN/VPMAX (float) */
5227 case NEON_3R_FLOAT_CMP
:
5229 /* no encoding for U=0 C=1x */
5233 case NEON_3R_FLOAT_ACMP
:
5238 case NEON_3R_FLOAT_MISC
:
5239 /* VMAXNM/VMINNM in ARMv8 */
5240 if (u
&& !arm_feature(env
, ARM_FEATURE_V8
)) {
5245 if (u
&& (size
!= 0)) {
5246 /* UNDEF on invalid size for polynomial subcase */
5251 if (!arm_feature(env
, ARM_FEATURE_VFP4
) || u
) {
5259 if (pairwise
&& q
) {
5260 /* All the pairwise insns UNDEF if Q is set */
5264 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5269 tmp
= neon_load_reg(rn
, 0);
5270 tmp2
= neon_load_reg(rn
, 1);
5272 tmp
= neon_load_reg(rm
, 0);
5273 tmp2
= neon_load_reg(rm
, 1);
5277 tmp
= neon_load_reg(rn
, pass
);
5278 tmp2
= neon_load_reg(rm
, pass
);
5282 GEN_NEON_INTEGER_OP(hadd
);
5285 GEN_NEON_INTEGER_OP_ENV(qadd
);
5287 case NEON_3R_VRHADD
:
5288 GEN_NEON_INTEGER_OP(rhadd
);
5290 case NEON_3R_LOGIC
: /* Logic ops. */
5291 switch ((u
<< 2) | size
) {
5293 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
5296 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
5299 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5302 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
5305 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
5308 tmp3
= neon_load_reg(rd
, pass
);
5309 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
5310 tcg_temp_free_i32(tmp3
);
5313 tmp3
= neon_load_reg(rd
, pass
);
5314 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
5315 tcg_temp_free_i32(tmp3
);
5318 tmp3
= neon_load_reg(rd
, pass
);
5319 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
5320 tcg_temp_free_i32(tmp3
);
5325 GEN_NEON_INTEGER_OP(hsub
);
5328 GEN_NEON_INTEGER_OP_ENV(qsub
);
5331 GEN_NEON_INTEGER_OP(cgt
);
5334 GEN_NEON_INTEGER_OP(cge
);
5337 GEN_NEON_INTEGER_OP(shl
);
5340 GEN_NEON_INTEGER_OP_ENV(qshl
);
5343 GEN_NEON_INTEGER_OP(rshl
);
5345 case NEON_3R_VQRSHL
:
5346 GEN_NEON_INTEGER_OP_ENV(qrshl
);
5349 GEN_NEON_INTEGER_OP(max
);
5352 GEN_NEON_INTEGER_OP(min
);
5355 GEN_NEON_INTEGER_OP(abd
);
5358 GEN_NEON_INTEGER_OP(abd
);
5359 tcg_temp_free_i32(tmp2
);
5360 tmp2
= neon_load_reg(rd
, pass
);
5361 gen_neon_add(size
, tmp
, tmp2
);
5363 case NEON_3R_VADD_VSUB
:
5364 if (!u
) { /* VADD */
5365 gen_neon_add(size
, tmp
, tmp2
);
5368 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
5369 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
5370 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
5375 case NEON_3R_VTST_VCEQ
:
5376 if (!u
) { /* VTST */
5378 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
5379 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
5380 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
5385 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
5386 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
5387 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
5392 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
5394 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5395 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5396 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5399 tcg_temp_free_i32(tmp2
);
5400 tmp2
= neon_load_reg(rd
, pass
);
5402 gen_neon_rsb(size
, tmp
, tmp2
);
5404 gen_neon_add(size
, tmp
, tmp2
);
5408 if (u
) { /* polynomial */
5409 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
5410 } else { /* Integer */
5412 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5413 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5414 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5420 GEN_NEON_INTEGER_OP(pmax
);
5423 GEN_NEON_INTEGER_OP(pmin
);
5425 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
5426 if (!u
) { /* VQDMULH */
5429 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5432 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5436 } else { /* VQRDMULH */
5439 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5442 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5450 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
5451 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
5452 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
5456 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
5458 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5459 switch ((u
<< 2) | size
) {
5462 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5465 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
5468 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
5473 tcg_temp_free_ptr(fpstatus
);
5476 case NEON_3R_FLOAT_MULTIPLY
:
5478 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5479 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5481 tcg_temp_free_i32(tmp2
);
5482 tmp2
= neon_load_reg(rd
, pass
);
5484 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5486 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5489 tcg_temp_free_ptr(fpstatus
);
5492 case NEON_3R_FLOAT_CMP
:
5494 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5496 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
5499 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5501 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5504 tcg_temp_free_ptr(fpstatus
);
5507 case NEON_3R_FLOAT_ACMP
:
5509 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5511 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5513 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5515 tcg_temp_free_ptr(fpstatus
);
5518 case NEON_3R_FLOAT_MINMAX
:
5520 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5522 gen_helper_vfp_maxs(tmp
, tmp
, tmp2
, fpstatus
);
5524 gen_helper_vfp_mins(tmp
, tmp
, tmp2
, fpstatus
);
5526 tcg_temp_free_ptr(fpstatus
);
5529 case NEON_3R_FLOAT_MISC
:
5532 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5534 gen_helper_vfp_maxnums(tmp
, tmp
, tmp2
, fpstatus
);
5536 gen_helper_vfp_minnums(tmp
, tmp
, tmp2
, fpstatus
);
5538 tcg_temp_free_ptr(fpstatus
);
5541 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
5543 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
5549 /* VFMA, VFMS: fused multiply-add */
5550 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5551 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
5554 gen_helper_vfp_negs(tmp
, tmp
);
5556 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
5557 tcg_temp_free_i32(tmp3
);
5558 tcg_temp_free_ptr(fpstatus
);
5564 tcg_temp_free_i32(tmp2
);
5566 /* Save the result. For elementwise operations we can put it
5567 straight into the destination register. For pairwise operations
5568 we have to be careful to avoid clobbering the source operands. */
5569 if (pairwise
&& rd
== rm
) {
5570 neon_store_scratch(pass
, tmp
);
5572 neon_store_reg(rd
, pass
, tmp
);
5576 if (pairwise
&& rd
== rm
) {
5577 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5578 tmp
= neon_load_scratch(pass
);
5579 neon_store_reg(rd
, pass
, tmp
);
5582 /* End of 3 register same size operations. */
5583 } else if (insn
& (1 << 4)) {
5584 if ((insn
& 0x00380080) != 0) {
5585 /* Two registers and shift. */
5586 op
= (insn
>> 8) & 0xf;
5587 if (insn
& (1 << 7)) {
5595 while ((insn
& (1 << (size
+ 19))) == 0)
5598 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
5599 /* To avoid excessive duplication of ops we implement shift
5600 by immediate using the variable shift operations. */
5602 /* Shift by immediate:
5603 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5604 if (q
&& ((rd
| rm
) & 1)) {
5607 if (!u
&& (op
== 4 || op
== 6)) {
5610 /* Right shifts are encoded as N - shift, where N is the
5611 element size in bits. */
5613 shift
= shift
- (1 << (size
+ 3));
5621 imm
= (uint8_t) shift
;
5626 imm
= (uint16_t) shift
;
5637 for (pass
= 0; pass
< count
; pass
++) {
5639 neon_load_reg64(cpu_V0
, rm
+ pass
);
5640 tcg_gen_movi_i64(cpu_V1
, imm
);
5645 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5647 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5652 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5654 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5657 case 5: /* VSHL, VSLI */
5658 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5660 case 6: /* VQSHLU */
5661 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
5666 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5669 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5674 if (op
== 1 || op
== 3) {
5676 neon_load_reg64(cpu_V1
, rd
+ pass
);
5677 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5678 } else if (op
== 4 || (op
== 5 && u
)) {
5680 neon_load_reg64(cpu_V1
, rd
+ pass
);
5682 if (shift
< -63 || shift
> 63) {
5686 mask
= 0xffffffffffffffffull
>> -shift
;
5688 mask
= 0xffffffffffffffffull
<< shift
;
5691 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
5692 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5694 neon_store_reg64(cpu_V0
, rd
+ pass
);
5695 } else { /* size < 3 */
5696 /* Operands in T0 and T1. */
5697 tmp
= neon_load_reg(rm
, pass
);
5698 tmp2
= tcg_temp_new_i32();
5699 tcg_gen_movi_i32(tmp2
, imm
);
5703 GEN_NEON_INTEGER_OP(shl
);
5707 GEN_NEON_INTEGER_OP(rshl
);
5710 case 5: /* VSHL, VSLI */
5712 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
5713 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
5714 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
5718 case 6: /* VQSHLU */
5721 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
5725 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
5729 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
5737 GEN_NEON_INTEGER_OP_ENV(qshl
);
5740 tcg_temp_free_i32(tmp2
);
5742 if (op
== 1 || op
== 3) {
5744 tmp2
= neon_load_reg(rd
, pass
);
5745 gen_neon_add(size
, tmp
, tmp2
);
5746 tcg_temp_free_i32(tmp2
);
5747 } else if (op
== 4 || (op
== 5 && u
)) {
5752 mask
= 0xff >> -shift
;
5754 mask
= (uint8_t)(0xff << shift
);
5760 mask
= 0xffff >> -shift
;
5762 mask
= (uint16_t)(0xffff << shift
);
5766 if (shift
< -31 || shift
> 31) {
5770 mask
= 0xffffffffu
>> -shift
;
5772 mask
= 0xffffffffu
<< shift
;
5778 tmp2
= neon_load_reg(rd
, pass
);
5779 tcg_gen_andi_i32(tmp
, tmp
, mask
);
5780 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
5781 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5782 tcg_temp_free_i32(tmp2
);
5784 neon_store_reg(rd
, pass
, tmp
);
5787 } else if (op
< 10) {
5788 /* Shift by immediate and narrow:
5789 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5790 int input_unsigned
= (op
== 8) ? !u
: u
;
5794 shift
= shift
- (1 << (size
+ 3));
5797 tmp64
= tcg_const_i64(shift
);
5798 neon_load_reg64(cpu_V0
, rm
);
5799 neon_load_reg64(cpu_V1
, rm
+ 1);
5800 for (pass
= 0; pass
< 2; pass
++) {
5808 if (input_unsigned
) {
5809 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
5811 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
5814 if (input_unsigned
) {
5815 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
5817 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
5820 tmp
= tcg_temp_new_i32();
5821 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5822 neon_store_reg(rd
, pass
, tmp
);
5824 tcg_temp_free_i64(tmp64
);
5827 imm
= (uint16_t)shift
;
5831 imm
= (uint32_t)shift
;
5833 tmp2
= tcg_const_i32(imm
);
5834 tmp4
= neon_load_reg(rm
+ 1, 0);
5835 tmp5
= neon_load_reg(rm
+ 1, 1);
5836 for (pass
= 0; pass
< 2; pass
++) {
5838 tmp
= neon_load_reg(rm
, 0);
5842 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
5845 tmp3
= neon_load_reg(rm
, 1);
5849 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
5851 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
5852 tcg_temp_free_i32(tmp
);
5853 tcg_temp_free_i32(tmp3
);
5854 tmp
= tcg_temp_new_i32();
5855 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5856 neon_store_reg(rd
, pass
, tmp
);
5858 tcg_temp_free_i32(tmp2
);
5860 } else if (op
== 10) {
5862 if (q
|| (rd
& 1)) {
5865 tmp
= neon_load_reg(rm
, 0);
5866 tmp2
= neon_load_reg(rm
, 1);
5867 for (pass
= 0; pass
< 2; pass
++) {
5871 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5874 /* The shift is less than the width of the source
5875 type, so we can just shift the whole register. */
5876 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
5877 /* Widen the result of shift: we need to clear
5878 * the potential overflow bits resulting from
5879 * left bits of the narrow input appearing as
5880 * right bits of left the neighbour narrow
5882 if (size
< 2 || !u
) {
5885 imm
= (0xffu
>> (8 - shift
));
5887 } else if (size
== 1) {
5888 imm
= 0xffff >> (16 - shift
);
5891 imm
= 0xffffffff >> (32 - shift
);
5894 imm64
= imm
| (((uint64_t)imm
) << 32);
5898 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
5901 neon_store_reg64(cpu_V0
, rd
+ pass
);
5903 } else if (op
>= 14) {
5904 /* VCVT fixed-point. */
5905 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
5908 /* We have already masked out the must-be-1 top bit of imm6,
5909 * hence this 32-shift where the ARM ARM has 64-imm6.
5912 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5913 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
5916 gen_vfp_ulto(0, shift
, 1);
5918 gen_vfp_slto(0, shift
, 1);
5921 gen_vfp_toul(0, shift
, 1);
5923 gen_vfp_tosl(0, shift
, 1);
5925 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
5930 } else { /* (insn & 0x00380080) == 0 */
5932 if (q
&& (rd
& 1)) {
5936 op
= (insn
>> 8) & 0xf;
5937 /* One register and immediate. */
5938 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
5939 invert
= (insn
& (1 << 5)) != 0;
5940 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5941 * We choose to not special-case this and will behave as if a
5942 * valid constant encoding of 0 had been given.
5961 imm
= (imm
<< 8) | (imm
<< 24);
5964 imm
= (imm
<< 8) | 0xff;
5967 imm
= (imm
<< 16) | 0xffff;
5970 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
5978 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
5979 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
5985 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5986 if (op
& 1 && op
< 12) {
5987 tmp
= neon_load_reg(rd
, pass
);
5989 /* The immediate value has already been inverted, so
5991 tcg_gen_andi_i32(tmp
, tmp
, imm
);
5993 tcg_gen_ori_i32(tmp
, tmp
, imm
);
5997 tmp
= tcg_temp_new_i32();
5998 if (op
== 14 && invert
) {
6002 for (n
= 0; n
< 4; n
++) {
6003 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
6004 val
|= 0xff << (n
* 8);
6006 tcg_gen_movi_i32(tmp
, val
);
6008 tcg_gen_movi_i32(tmp
, imm
);
6011 neon_store_reg(rd
, pass
, tmp
);
6014 } else { /* (insn & 0x00800010 == 0x00800000) */
6016 op
= (insn
>> 8) & 0xf;
6017 if ((insn
& (1 << 6)) == 0) {
6018 /* Three registers of different lengths. */
6022 /* undefreq: bit 0 : UNDEF if size == 0
6023 * bit 1 : UNDEF if size == 1
6024 * bit 2 : UNDEF if size == 2
6025 * bit 3 : UNDEF if U == 1
6026 * Note that [2:0] set implies 'always UNDEF'
6029 /* prewiden, src1_wide, src2_wide, undefreq */
6030 static const int neon_3reg_wide
[16][4] = {
6031 {1, 0, 0, 0}, /* VADDL */
6032 {1, 1, 0, 0}, /* VADDW */
6033 {1, 0, 0, 0}, /* VSUBL */
6034 {1, 1, 0, 0}, /* VSUBW */
6035 {0, 1, 1, 0}, /* VADDHN */
6036 {0, 0, 0, 0}, /* VABAL */
6037 {0, 1, 1, 0}, /* VSUBHN */
6038 {0, 0, 0, 0}, /* VABDL */
6039 {0, 0, 0, 0}, /* VMLAL */
6040 {0, 0, 0, 9}, /* VQDMLAL */
6041 {0, 0, 0, 0}, /* VMLSL */
6042 {0, 0, 0, 9}, /* VQDMLSL */
6043 {0, 0, 0, 0}, /* Integer VMULL */
6044 {0, 0, 0, 1}, /* VQDMULL */
6045 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6046 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6049 prewiden
= neon_3reg_wide
[op
][0];
6050 src1_wide
= neon_3reg_wide
[op
][1];
6051 src2_wide
= neon_3reg_wide
[op
][2];
6052 undefreq
= neon_3reg_wide
[op
][3];
6054 if ((undefreq
& (1 << size
)) ||
6055 ((undefreq
& 8) && u
)) {
6058 if ((src1_wide
&& (rn
& 1)) ||
6059 (src2_wide
&& (rm
& 1)) ||
6060 (!src2_wide
&& (rd
& 1))) {
6064 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6065 * outside the loop below as it only performs a single pass.
6067 if (op
== 14 && size
== 2) {
6068 TCGv_i64 tcg_rn
, tcg_rm
, tcg_rd
;
6070 if (!arm_feature(env
, ARM_FEATURE_V8_PMULL
)) {
6073 tcg_rn
= tcg_temp_new_i64();
6074 tcg_rm
= tcg_temp_new_i64();
6075 tcg_rd
= tcg_temp_new_i64();
6076 neon_load_reg64(tcg_rn
, rn
);
6077 neon_load_reg64(tcg_rm
, rm
);
6078 gen_helper_neon_pmull_64_lo(tcg_rd
, tcg_rn
, tcg_rm
);
6079 neon_store_reg64(tcg_rd
, rd
);
6080 gen_helper_neon_pmull_64_hi(tcg_rd
, tcg_rn
, tcg_rm
);
6081 neon_store_reg64(tcg_rd
, rd
+ 1);
6082 tcg_temp_free_i64(tcg_rn
);
6083 tcg_temp_free_i64(tcg_rm
);
6084 tcg_temp_free_i64(tcg_rd
);
6088 /* Avoid overlapping operands. Wide source operands are
6089 always aligned so will never overlap with wide
6090 destinations in problematic ways. */
6091 if (rd
== rm
&& !src2_wide
) {
6092 tmp
= neon_load_reg(rm
, 1);
6093 neon_store_scratch(2, tmp
);
6094 } else if (rd
== rn
&& !src1_wide
) {
6095 tmp
= neon_load_reg(rn
, 1);
6096 neon_store_scratch(2, tmp
);
6098 TCGV_UNUSED_I32(tmp3
);
6099 for (pass
= 0; pass
< 2; pass
++) {
6101 neon_load_reg64(cpu_V0
, rn
+ pass
);
6102 TCGV_UNUSED_I32(tmp
);
6104 if (pass
== 1 && rd
== rn
) {
6105 tmp
= neon_load_scratch(2);
6107 tmp
= neon_load_reg(rn
, pass
);
6110 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6114 neon_load_reg64(cpu_V1
, rm
+ pass
);
6115 TCGV_UNUSED_I32(tmp2
);
6117 if (pass
== 1 && rd
== rm
) {
6118 tmp2
= neon_load_scratch(2);
6120 tmp2
= neon_load_reg(rm
, pass
);
6123 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
6127 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6128 gen_neon_addl(size
);
6130 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6131 gen_neon_subl(size
);
6133 case 5: case 7: /* VABAL, VABDL */
6134 switch ((size
<< 1) | u
) {
6136 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
6139 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
6142 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
6145 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
6148 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
6151 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
6155 tcg_temp_free_i32(tmp2
);
6156 tcg_temp_free_i32(tmp
);
6158 case 8: case 9: case 10: case 11: case 12: case 13:
6159 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6160 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6162 case 14: /* Polynomial VMULL */
6163 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
6164 tcg_temp_free_i32(tmp2
);
6165 tcg_temp_free_i32(tmp
);
6167 default: /* 15 is RESERVED: caught earlier */
6172 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6173 neon_store_reg64(cpu_V0
, rd
+ pass
);
6174 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
6176 neon_load_reg64(cpu_V1
, rd
+ pass
);
6178 case 10: /* VMLSL */
6179 gen_neon_negl(cpu_V0
, size
);
6181 case 5: case 8: /* VABAL, VMLAL */
6182 gen_neon_addl(size
);
6184 case 9: case 11: /* VQDMLAL, VQDMLSL */
6185 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6187 gen_neon_negl(cpu_V0
, size
);
6189 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6194 neon_store_reg64(cpu_V0
, rd
+ pass
);
6195 } else if (op
== 4 || op
== 6) {
6196 /* Narrowing operation. */
6197 tmp
= tcg_temp_new_i32();
6201 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
6204 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
6207 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6208 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
6215 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
6218 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
6221 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
6222 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6223 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
6231 neon_store_reg(rd
, 0, tmp3
);
6232 neon_store_reg(rd
, 1, tmp
);
6235 /* Write back the result. */
6236 neon_store_reg64(cpu_V0
, rd
+ pass
);
6240 /* Two registers and a scalar. NB that for ops of this form
6241 * the ARM ARM labels bit 24 as Q, but it is in our variable
6248 case 1: /* Float VMLA scalar */
6249 case 5: /* Floating point VMLS scalar */
6250 case 9: /* Floating point VMUL scalar */
6255 case 0: /* Integer VMLA scalar */
6256 case 4: /* Integer VMLS scalar */
6257 case 8: /* Integer VMUL scalar */
6258 case 12: /* VQDMULH scalar */
6259 case 13: /* VQRDMULH scalar */
6260 if (u
&& ((rd
| rn
) & 1)) {
6263 tmp
= neon_get_scalar(size
, rm
);
6264 neon_store_scratch(0, tmp
);
6265 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6266 tmp
= neon_load_scratch(0);
6267 tmp2
= neon_load_reg(rn
, pass
);
6270 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6272 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6274 } else if (op
== 13) {
6276 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6278 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6280 } else if (op
& 1) {
6281 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6282 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6283 tcg_temp_free_ptr(fpstatus
);
6286 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6287 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6288 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6292 tcg_temp_free_i32(tmp2
);
6295 tmp2
= neon_load_reg(rd
, pass
);
6298 gen_neon_add(size
, tmp
, tmp2
);
6302 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6303 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6304 tcg_temp_free_ptr(fpstatus
);
6308 gen_neon_rsb(size
, tmp
, tmp2
);
6312 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6313 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6314 tcg_temp_free_ptr(fpstatus
);
6320 tcg_temp_free_i32(tmp2
);
6322 neon_store_reg(rd
, pass
, tmp
);
6325 case 3: /* VQDMLAL scalar */
6326 case 7: /* VQDMLSL scalar */
6327 case 11: /* VQDMULL scalar */
6332 case 2: /* VMLAL sclar */
6333 case 6: /* VMLSL scalar */
6334 case 10: /* VMULL scalar */
6338 tmp2
= neon_get_scalar(size
, rm
);
6339 /* We need a copy of tmp2 because gen_neon_mull
6340 * deletes it during pass 0. */
6341 tmp4
= tcg_temp_new_i32();
6342 tcg_gen_mov_i32(tmp4
, tmp2
);
6343 tmp3
= neon_load_reg(rn
, 1);
6345 for (pass
= 0; pass
< 2; pass
++) {
6347 tmp
= neon_load_reg(rn
, 0);
6352 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6354 neon_load_reg64(cpu_V1
, rd
+ pass
);
6358 gen_neon_negl(cpu_V0
, size
);
6361 gen_neon_addl(size
);
6364 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6366 gen_neon_negl(cpu_V0
, size
);
6368 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6374 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6379 neon_store_reg64(cpu_V0
, rd
+ pass
);
6384 default: /* 14 and 15 are RESERVED */
6388 } else { /* size == 3 */
6391 imm
= (insn
>> 8) & 0xf;
6396 if (q
&& ((rd
| rn
| rm
) & 1)) {
6401 neon_load_reg64(cpu_V0
, rn
);
6403 neon_load_reg64(cpu_V1
, rn
+ 1);
6405 } else if (imm
== 8) {
6406 neon_load_reg64(cpu_V0
, rn
+ 1);
6408 neon_load_reg64(cpu_V1
, rm
);
6411 tmp64
= tcg_temp_new_i64();
6413 neon_load_reg64(cpu_V0
, rn
);
6414 neon_load_reg64(tmp64
, rn
+ 1);
6416 neon_load_reg64(cpu_V0
, rn
+ 1);
6417 neon_load_reg64(tmp64
, rm
);
6419 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
6420 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
6421 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6423 neon_load_reg64(cpu_V1
, rm
);
6425 neon_load_reg64(cpu_V1
, rm
+ 1);
6428 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6429 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
6430 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
6431 tcg_temp_free_i64(tmp64
);
6434 neon_load_reg64(cpu_V0
, rn
);
6435 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
6436 neon_load_reg64(cpu_V1
, rm
);
6437 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6438 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6440 neon_store_reg64(cpu_V0
, rd
);
6442 neon_store_reg64(cpu_V1
, rd
+ 1);
6444 } else if ((insn
& (1 << 11)) == 0) {
6445 /* Two register misc. */
6446 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
6447 size
= (insn
>> 18) & 3;
6448 /* UNDEF for unknown op values and bad op-size combinations */
6449 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
6452 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
6453 q
&& ((rm
| rd
) & 1)) {
6457 case NEON_2RM_VREV64
:
6458 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
6459 tmp
= neon_load_reg(rm
, pass
* 2);
6460 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
6462 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6463 case 1: gen_swap_half(tmp
); break;
6464 case 2: /* no-op */ break;
6467 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
6469 neon_store_reg(rd
, pass
* 2, tmp2
);
6472 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
6473 case 1: gen_swap_half(tmp2
); break;
6476 neon_store_reg(rd
, pass
* 2, tmp2
);
6480 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
6481 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
6482 for (pass
= 0; pass
< q
+ 1; pass
++) {
6483 tmp
= neon_load_reg(rm
, pass
* 2);
6484 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
6485 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
6486 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
6488 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
6489 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
6490 case 2: tcg_gen_add_i64(CPU_V001
); break;
6493 if (op
>= NEON_2RM_VPADAL
) {
6495 neon_load_reg64(cpu_V1
, rd
+ pass
);
6496 gen_neon_addl(size
);
6498 neon_store_reg64(cpu_V0
, rd
+ pass
);
6504 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
6505 tmp
= neon_load_reg(rm
, n
);
6506 tmp2
= neon_load_reg(rd
, n
+ 1);
6507 neon_store_reg(rm
, n
, tmp2
);
6508 neon_store_reg(rd
, n
+ 1, tmp
);
6515 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
6520 if (gen_neon_zip(rd
, rm
, size
, q
)) {
6524 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
6525 /* also VQMOVUN; op field and mnemonics don't line up */
6529 TCGV_UNUSED_I32(tmp2
);
6530 for (pass
= 0; pass
< 2; pass
++) {
6531 neon_load_reg64(cpu_V0
, rm
+ pass
);
6532 tmp
= tcg_temp_new_i32();
6533 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
6538 neon_store_reg(rd
, 0, tmp2
);
6539 neon_store_reg(rd
, 1, tmp
);
6543 case NEON_2RM_VSHLL
:
6544 if (q
|| (rd
& 1)) {
6547 tmp
= neon_load_reg(rm
, 0);
6548 tmp2
= neon_load_reg(rm
, 1);
6549 for (pass
= 0; pass
< 2; pass
++) {
6552 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
6553 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
6554 neon_store_reg64(cpu_V0
, rd
+ pass
);
6557 case NEON_2RM_VCVT_F16_F32
:
6558 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
6562 tmp
= tcg_temp_new_i32();
6563 tmp2
= tcg_temp_new_i32();
6564 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
6565 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6566 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
6567 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6568 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6569 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6570 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
6571 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6572 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
6573 neon_store_reg(rd
, 0, tmp2
);
6574 tmp2
= tcg_temp_new_i32();
6575 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6576 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6577 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6578 neon_store_reg(rd
, 1, tmp2
);
6579 tcg_temp_free_i32(tmp
);
6581 case NEON_2RM_VCVT_F32_F16
:
6582 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
6586 tmp3
= tcg_temp_new_i32();
6587 tmp
= neon_load_reg(rm
, 0);
6588 tmp2
= neon_load_reg(rm
, 1);
6589 tcg_gen_ext16u_i32(tmp3
, tmp
);
6590 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6591 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
6592 tcg_gen_shri_i32(tmp3
, tmp
, 16);
6593 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6594 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
6595 tcg_temp_free_i32(tmp
);
6596 tcg_gen_ext16u_i32(tmp3
, tmp2
);
6597 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6598 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
6599 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
6600 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6601 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
6602 tcg_temp_free_i32(tmp2
);
6603 tcg_temp_free_i32(tmp3
);
6605 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
6606 if (!arm_feature(env
, ARM_FEATURE_V8_AES
)
6607 || ((rm
| rd
) & 1)) {
6610 tmp
= tcg_const_i32(rd
);
6611 tmp2
= tcg_const_i32(rm
);
6613 /* Bit 6 is the lowest opcode bit; it distinguishes between
6614 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6616 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
6618 if (op
== NEON_2RM_AESE
) {
6619 gen_helper_crypto_aese(cpu_env
, tmp
, tmp2
, tmp3
);
6621 gen_helper_crypto_aesmc(cpu_env
, tmp
, tmp2
, tmp3
);
6623 tcg_temp_free_i32(tmp
);
6624 tcg_temp_free_i32(tmp2
);
6625 tcg_temp_free_i32(tmp3
);
6627 case NEON_2RM_SHA1H
:
6628 if (!arm_feature(env
, ARM_FEATURE_V8_SHA1
)
6629 || ((rm
| rd
) & 1)) {
6632 tmp
= tcg_const_i32(rd
);
6633 tmp2
= tcg_const_i32(rm
);
6635 gen_helper_crypto_sha1h(cpu_env
, tmp
, tmp2
);
6637 tcg_temp_free_i32(tmp
);
6638 tcg_temp_free_i32(tmp2
);
6640 case NEON_2RM_SHA1SU1
:
6641 if ((rm
| rd
) & 1) {
6644 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6646 if (!arm_feature(env
, ARM_FEATURE_V8_SHA256
)) {
6649 } else if (!arm_feature(env
, ARM_FEATURE_V8_SHA1
)) {
6652 tmp
= tcg_const_i32(rd
);
6653 tmp2
= tcg_const_i32(rm
);
6655 gen_helper_crypto_sha256su0(cpu_env
, tmp
, tmp2
);
6657 gen_helper_crypto_sha1su1(cpu_env
, tmp
, tmp2
);
6659 tcg_temp_free_i32(tmp
);
6660 tcg_temp_free_i32(tmp2
);
6664 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6665 if (neon_2rm_is_float_op(op
)) {
6666 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
6667 neon_reg_offset(rm
, pass
));
6668 TCGV_UNUSED_I32(tmp
);
6670 tmp
= neon_load_reg(rm
, pass
);
6673 case NEON_2RM_VREV32
:
6675 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6676 case 1: gen_swap_half(tmp
); break;
6680 case NEON_2RM_VREV16
:
6685 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
6686 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
6687 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
6693 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
6694 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
6695 case 2: gen_helper_clz(tmp
, tmp
); break;
6700 gen_helper_neon_cnt_u8(tmp
, tmp
);
6703 tcg_gen_not_i32(tmp
, tmp
);
6705 case NEON_2RM_VQABS
:
6708 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
6711 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
6714 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
6719 case NEON_2RM_VQNEG
:
6722 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
6725 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
6728 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
6733 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
6734 tmp2
= tcg_const_i32(0);
6736 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
6737 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
6738 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
6741 tcg_temp_free_i32(tmp2
);
6742 if (op
== NEON_2RM_VCLE0
) {
6743 tcg_gen_not_i32(tmp
, tmp
);
6746 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
6747 tmp2
= tcg_const_i32(0);
6749 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
6750 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
6751 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
6754 tcg_temp_free_i32(tmp2
);
6755 if (op
== NEON_2RM_VCLT0
) {
6756 tcg_gen_not_i32(tmp
, tmp
);
6759 case NEON_2RM_VCEQ0
:
6760 tmp2
= tcg_const_i32(0);
6762 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
6763 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
6764 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
6767 tcg_temp_free_i32(tmp2
);
6771 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
6772 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
6773 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
6778 tmp2
= tcg_const_i32(0);
6779 gen_neon_rsb(size
, tmp
, tmp2
);
6780 tcg_temp_free_i32(tmp2
);
6782 case NEON_2RM_VCGT0_F
:
6784 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6785 tmp2
= tcg_const_i32(0);
6786 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6787 tcg_temp_free_i32(tmp2
);
6788 tcg_temp_free_ptr(fpstatus
);
6791 case NEON_2RM_VCGE0_F
:
6793 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6794 tmp2
= tcg_const_i32(0);
6795 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6796 tcg_temp_free_i32(tmp2
);
6797 tcg_temp_free_ptr(fpstatus
);
6800 case NEON_2RM_VCEQ0_F
:
6802 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6803 tmp2
= tcg_const_i32(0);
6804 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6805 tcg_temp_free_i32(tmp2
);
6806 tcg_temp_free_ptr(fpstatus
);
6809 case NEON_2RM_VCLE0_F
:
6811 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6812 tmp2
= tcg_const_i32(0);
6813 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
6814 tcg_temp_free_i32(tmp2
);
6815 tcg_temp_free_ptr(fpstatus
);
6818 case NEON_2RM_VCLT0_F
:
6820 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6821 tmp2
= tcg_const_i32(0);
6822 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
6823 tcg_temp_free_i32(tmp2
);
6824 tcg_temp_free_ptr(fpstatus
);
6827 case NEON_2RM_VABS_F
:
6830 case NEON_2RM_VNEG_F
:
6834 tmp2
= neon_load_reg(rd
, pass
);
6835 neon_store_reg(rm
, pass
, tmp2
);
6838 tmp2
= neon_load_reg(rd
, pass
);
6840 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
6841 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
6844 neon_store_reg(rm
, pass
, tmp2
);
6846 case NEON_2RM_VRINTN
:
6847 case NEON_2RM_VRINTA
:
6848 case NEON_2RM_VRINTM
:
6849 case NEON_2RM_VRINTP
:
6850 case NEON_2RM_VRINTZ
:
6853 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6856 if (op
== NEON_2RM_VRINTZ
) {
6857 rmode
= FPROUNDING_ZERO
;
6859 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
6862 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
6863 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6865 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpstatus
);
6866 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6868 tcg_temp_free_ptr(fpstatus
);
6869 tcg_temp_free_i32(tcg_rmode
);
6872 case NEON_2RM_VRINTX
:
6874 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6875 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpstatus
);
6876 tcg_temp_free_ptr(fpstatus
);
6879 case NEON_2RM_VCVTAU
:
6880 case NEON_2RM_VCVTAS
:
6881 case NEON_2RM_VCVTNU
:
6882 case NEON_2RM_VCVTNS
:
6883 case NEON_2RM_VCVTPU
:
6884 case NEON_2RM_VCVTPS
:
6885 case NEON_2RM_VCVTMU
:
6886 case NEON_2RM_VCVTMS
:
6888 bool is_signed
= !extract32(insn
, 7, 1);
6889 TCGv_ptr fpst
= get_fpstatus_ptr(1);
6890 TCGv_i32 tcg_rmode
, tcg_shift
;
6891 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
6893 tcg_shift
= tcg_const_i32(0);
6894 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
6895 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6899 gen_helper_vfp_tosls(cpu_F0s
, cpu_F0s
,
6902 gen_helper_vfp_touls(cpu_F0s
, cpu_F0s
,
6906 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6908 tcg_temp_free_i32(tcg_rmode
);
6909 tcg_temp_free_i32(tcg_shift
);
6910 tcg_temp_free_ptr(fpst
);
6913 case NEON_2RM_VRECPE
:
6915 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6916 gen_helper_recpe_u32(tmp
, tmp
, fpstatus
);
6917 tcg_temp_free_ptr(fpstatus
);
6920 case NEON_2RM_VRSQRTE
:
6922 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6923 gen_helper_rsqrte_u32(tmp
, tmp
, fpstatus
);
6924 tcg_temp_free_ptr(fpstatus
);
6927 case NEON_2RM_VRECPE_F
:
6929 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6930 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
6931 tcg_temp_free_ptr(fpstatus
);
6934 case NEON_2RM_VRSQRTE_F
:
6936 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6937 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
6938 tcg_temp_free_ptr(fpstatus
);
6941 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
6944 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
6947 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
6948 gen_vfp_tosiz(0, 1);
6950 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
6951 gen_vfp_touiz(0, 1);
6954 /* Reserved op values were caught by the
6955 * neon_2rm_sizes[] check earlier.
6959 if (neon_2rm_is_float_op(op
)) {
6960 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
6961 neon_reg_offset(rd
, pass
));
6963 neon_store_reg(rd
, pass
, tmp
);
6968 } else if ((insn
& (1 << 10)) == 0) {
6970 int n
= ((insn
>> 8) & 3) + 1;
6971 if ((rn
+ n
) > 32) {
6972 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6973 * helper function running off the end of the register file.
6978 if (insn
& (1 << 6)) {
6979 tmp
= neon_load_reg(rd
, 0);
6981 tmp
= tcg_temp_new_i32();
6982 tcg_gen_movi_i32(tmp
, 0);
6984 tmp2
= neon_load_reg(rm
, 0);
6985 tmp4
= tcg_const_i32(rn
);
6986 tmp5
= tcg_const_i32(n
);
6987 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
6988 tcg_temp_free_i32(tmp
);
6989 if (insn
& (1 << 6)) {
6990 tmp
= neon_load_reg(rd
, 1);
6992 tmp
= tcg_temp_new_i32();
6993 tcg_gen_movi_i32(tmp
, 0);
6995 tmp3
= neon_load_reg(rm
, 1);
6996 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
6997 tcg_temp_free_i32(tmp5
);
6998 tcg_temp_free_i32(tmp4
);
6999 neon_store_reg(rd
, 0, tmp2
);
7000 neon_store_reg(rd
, 1, tmp3
);
7001 tcg_temp_free_i32(tmp
);
7002 } else if ((insn
& 0x380) == 0) {
7004 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
7007 if (insn
& (1 << 19)) {
7008 tmp
= neon_load_reg(rm
, 1);
7010 tmp
= neon_load_reg(rm
, 0);
7012 if (insn
& (1 << 16)) {
7013 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
7014 } else if (insn
& (1 << 17)) {
7015 if ((insn
>> 18) & 1)
7016 gen_neon_dup_high16(tmp
);
7018 gen_neon_dup_low16(tmp
);
7020 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7021 tmp2
= tcg_temp_new_i32();
7022 tcg_gen_mov_i32(tmp2
, tmp
);
7023 neon_store_reg(rd
, pass
, tmp2
);
7025 tcg_temp_free_i32(tmp
);
7034 static int disas_coproc_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
7036 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
7037 const ARMCPRegInfo
*ri
;
7039 cpnum
= (insn
>> 8) & 0xf;
7041 /* First check for coprocessor space used for XScale/iwMMXt insns */
7042 if (arm_feature(env
, ARM_FEATURE_XSCALE
) && (cpnum
< 2)) {
7043 if (extract32(s
->c15_cpar
, cpnum
, 1) == 0) {
7046 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
7047 return disas_iwmmxt_insn(env
, s
, insn
);
7048 } else if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
7049 return disas_dsp_insn(env
, s
, insn
);
7054 /* Otherwise treat as a generic register access */
7055 is64
= (insn
& (1 << 25)) == 0;
7056 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
7064 opc1
= (insn
>> 4) & 0xf;
7066 rt2
= (insn
>> 16) & 0xf;
7068 crn
= (insn
>> 16) & 0xf;
7069 opc1
= (insn
>> 21) & 7;
7070 opc2
= (insn
>> 5) & 7;
7073 isread
= (insn
>> 20) & 1;
7074 rt
= (insn
>> 12) & 0xf;
7076 ri
= get_arm_cp_reginfo(s
->cp_regs
,
7077 ENCODE_CP_REG(cpnum
, is64
, crn
, crm
, opc1
, opc2
));
7079 /* Check access permissions */
7080 if (!cp_access_ok(s
->current_el
, ri
, isread
)) {
7085 (arm_feature(env
, ARM_FEATURE_XSCALE
) && cpnum
< 14)) {
7086 /* Emit code to perform further access permissions checks at
7087 * runtime; this may result in an exception.
7088 * Note that on XScale all cp0..c13 registers do an access check
7089 * call in order to handle c15_cpar.
7095 /* Note that since we are an implementation which takes an
7096 * exception on a trapped conditional instruction only if the
7097 * instruction passes its condition code check, we can take
7098 * advantage of the clause in the ARM ARM that allows us to set
7099 * the COND field in the instruction to 0xE in all cases.
7100 * We could fish the actual condition out of the insn (ARM)
7101 * or the condexec bits (Thumb) but it isn't necessary.
7106 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7109 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7110 rt
, isread
, s
->thumb
);
7115 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7118 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7119 rt
, isread
, s
->thumb
);
7123 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7124 * so this can only happen if this is an ARMv7 or earlier CPU,
7125 * in which case the syndrome information won't actually be
7128 assert(!arm_feature(env
, ARM_FEATURE_V8
));
7129 syndrome
= syn_uncategorized();
7133 gen_set_pc_im(s
, s
->pc
);
7134 tmpptr
= tcg_const_ptr(ri
);
7135 tcg_syn
= tcg_const_i32(syndrome
);
7136 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
);
7137 tcg_temp_free_ptr(tmpptr
);
7138 tcg_temp_free_i32(tcg_syn
);
7141 /* Handle special cases first */
7142 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
7149 gen_set_pc_im(s
, s
->pc
);
7150 s
->is_jmp
= DISAS_WFI
;
7156 if (use_icount
&& (ri
->type
& ARM_CP_IO
)) {
7165 if (ri
->type
& ARM_CP_CONST
) {
7166 tmp64
= tcg_const_i64(ri
->resetvalue
);
7167 } else if (ri
->readfn
) {
7169 tmp64
= tcg_temp_new_i64();
7170 tmpptr
= tcg_const_ptr(ri
);
7171 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
7172 tcg_temp_free_ptr(tmpptr
);
7174 tmp64
= tcg_temp_new_i64();
7175 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7177 tmp
= tcg_temp_new_i32();
7178 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7179 store_reg(s
, rt
, tmp
);
7180 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7181 tmp
= tcg_temp_new_i32();
7182 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7183 tcg_temp_free_i64(tmp64
);
7184 store_reg(s
, rt2
, tmp
);
7187 if (ri
->type
& ARM_CP_CONST
) {
7188 tmp
= tcg_const_i32(ri
->resetvalue
);
7189 } else if (ri
->readfn
) {
7191 tmp
= tcg_temp_new_i32();
7192 tmpptr
= tcg_const_ptr(ri
);
7193 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
7194 tcg_temp_free_ptr(tmpptr
);
7196 tmp
= load_cpu_offset(ri
->fieldoffset
);
7199 /* Destination register of r15 for 32 bit loads sets
7200 * the condition codes from the high 4 bits of the value
7203 tcg_temp_free_i32(tmp
);
7205 store_reg(s
, rt
, tmp
);
7210 if (ri
->type
& ARM_CP_CONST
) {
7211 /* If not forbidden by access permissions, treat as WI */
7216 TCGv_i32 tmplo
, tmphi
;
7217 TCGv_i64 tmp64
= tcg_temp_new_i64();
7218 tmplo
= load_reg(s
, rt
);
7219 tmphi
= load_reg(s
, rt2
);
7220 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
7221 tcg_temp_free_i32(tmplo
);
7222 tcg_temp_free_i32(tmphi
);
7224 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
7225 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
7226 tcg_temp_free_ptr(tmpptr
);
7228 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7230 tcg_temp_free_i64(tmp64
);
7235 tmp
= load_reg(s
, rt
);
7236 tmpptr
= tcg_const_ptr(ri
);
7237 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
7238 tcg_temp_free_ptr(tmpptr
);
7239 tcg_temp_free_i32(tmp
);
7241 TCGv_i32 tmp
= load_reg(s
, rt
);
7242 store_cpu_offset(tmp
, ri
->fieldoffset
);
7247 if (use_icount
&& (ri
->type
& ARM_CP_IO
)) {
7248 /* I/O operations must end the TB here (whether read or write) */
7251 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
7252 /* We default to ending the TB on a coprocessor register write,
7253 * but allow this to be suppressed by the register definition
7254 * (usually only necessary to work around guest bugs).
7262 /* Unknown register; this might be a guest error or a QEMU
7263 * unimplemented feature.
7266 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7267 "64 bit system register cp:%d opc1: %d crm:%d\n",
7268 isread
? "read" : "write", cpnum
, opc1
, crm
);
7270 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7271 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d\n",
7272 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
);
7279 /* Store a 64-bit value to a register pair. Clobbers val. */
7280 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
7283 tmp
= tcg_temp_new_i32();
7284 tcg_gen_trunc_i64_i32(tmp
, val
);
7285 store_reg(s
, rlow
, tmp
);
7286 tmp
= tcg_temp_new_i32();
7287 tcg_gen_shri_i64(val
, val
, 32);
7288 tcg_gen_trunc_i64_i32(tmp
, val
);
7289 store_reg(s
, rhigh
, tmp
);
7292 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7293 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
7298 /* Load value and extend to 64 bits. */
7299 tmp
= tcg_temp_new_i64();
7300 tmp2
= load_reg(s
, rlow
);
7301 tcg_gen_extu_i32_i64(tmp
, tmp2
);
7302 tcg_temp_free_i32(tmp2
);
7303 tcg_gen_add_i64(val
, val
, tmp
);
7304 tcg_temp_free_i64(tmp
);
7307 /* load and add a 64-bit value from a register pair. */
7308 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
7314 /* Load 64-bit value rd:rn. */
7315 tmpl
= load_reg(s
, rlow
);
7316 tmph
= load_reg(s
, rhigh
);
7317 tmp
= tcg_temp_new_i64();
7318 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
7319 tcg_temp_free_i32(tmpl
);
7320 tcg_temp_free_i32(tmph
);
7321 tcg_gen_add_i64(val
, val
, tmp
);
7322 tcg_temp_free_i64(tmp
);
7325 /* Set N and Z flags from hi|lo. */
7326 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
7328 tcg_gen_mov_i32(cpu_NF
, hi
);
7329 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
7332 /* Load/Store exclusive instructions are implemented by remembering
7333 the value/address loaded, and seeing if these are the same
7334 when the store is performed. This should be sufficient to implement
7335 the architecturally mandated semantics, and avoids having to monitor
7338 In system emulation mode only one CPU will be running at once, so
7339 this sequence is effectively atomic. In user emulation mode we
7340 throw an exception and handle the atomic operation elsewhere. */
7341 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
7342 TCGv_i32 addr
, int size
)
7344 TCGv_i32 tmp
= tcg_temp_new_i32();
7350 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
7353 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
7357 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
7364 TCGv_i32 tmp2
= tcg_temp_new_i32();
7365 TCGv_i32 tmp3
= tcg_temp_new_i32();
7367 tcg_gen_addi_i32(tmp2
, addr
, 4);
7368 gen_aa32_ld32u(tmp3
, tmp2
, get_mem_index(s
));
7369 tcg_temp_free_i32(tmp2
);
7370 tcg_gen_concat_i32_i64(cpu_exclusive_val
, tmp
, tmp3
);
7371 store_reg(s
, rt2
, tmp3
);
7373 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
7376 store_reg(s
, rt
, tmp
);
7377 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
7380 static void gen_clrex(DisasContext
*s
)
7382 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7385 #ifdef CONFIG_USER_ONLY
7386 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7387 TCGv_i32 addr
, int size
)
7389 tcg_gen_extu_i32_i64(cpu_exclusive_test
, addr
);
7390 tcg_gen_movi_i32(cpu_exclusive_info
,
7391 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
7392 gen_exception_internal_insn(s
, 4, EXCP_STREX
);
7395 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7396 TCGv_i32 addr
, int size
)
7399 TCGv_i64 val64
, extaddr
;
7403 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7409 fail_label
= gen_new_label();
7410 done_label
= gen_new_label();
7411 extaddr
= tcg_temp_new_i64();
7412 tcg_gen_extu_i32_i64(extaddr
, addr
);
7413 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
7414 tcg_temp_free_i64(extaddr
);
7416 tmp
= tcg_temp_new_i32();
7419 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
7422 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
7426 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
7432 val64
= tcg_temp_new_i64();
7434 TCGv_i32 tmp2
= tcg_temp_new_i32();
7435 TCGv_i32 tmp3
= tcg_temp_new_i32();
7436 tcg_gen_addi_i32(tmp2
, addr
, 4);
7437 gen_aa32_ld32u(tmp3
, tmp2
, get_mem_index(s
));
7438 tcg_temp_free_i32(tmp2
);
7439 tcg_gen_concat_i32_i64(val64
, tmp
, tmp3
);
7440 tcg_temp_free_i32(tmp3
);
7442 tcg_gen_extu_i32_i64(val64
, tmp
);
7444 tcg_temp_free_i32(tmp
);
7446 tcg_gen_brcond_i64(TCG_COND_NE
, val64
, cpu_exclusive_val
, fail_label
);
7447 tcg_temp_free_i64(val64
);
7449 tmp
= load_reg(s
, rt
);
7452 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
7455 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
7459 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7464 tcg_temp_free_i32(tmp
);
7466 tcg_gen_addi_i32(addr
, addr
, 4);
7467 tmp
= load_reg(s
, rt2
);
7468 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7469 tcg_temp_free_i32(tmp
);
7471 tcg_gen_movi_i32(cpu_R
[rd
], 0);
7472 tcg_gen_br(done_label
);
7473 gen_set_label(fail_label
);
7474 tcg_gen_movi_i32(cpu_R
[rd
], 1);
7475 gen_set_label(done_label
);
7476 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7483 * @mode: mode field from insn (which stack to store to)
7484 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7485 * @writeback: true if writeback bit set
7487 * Generate code for the SRS (Store Return State) insn.
7489 static void gen_srs(DisasContext
*s
,
7490 uint32_t mode
, uint32_t amode
, bool writeback
)
7493 TCGv_i32 addr
= tcg_temp_new_i32();
7494 TCGv_i32 tmp
= tcg_const_i32(mode
);
7495 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
7496 tcg_temp_free_i32(tmp
);
7513 tcg_gen_addi_i32(addr
, addr
, offset
);
7514 tmp
= load_reg(s
, 14);
7515 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7516 tcg_temp_free_i32(tmp
);
7517 tmp
= load_cpu_field(spsr
);
7518 tcg_gen_addi_i32(addr
, addr
, 4);
7519 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7520 tcg_temp_free_i32(tmp
);
7538 tcg_gen_addi_i32(addr
, addr
, offset
);
7539 tmp
= tcg_const_i32(mode
);
7540 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
7541 tcg_temp_free_i32(tmp
);
7543 tcg_temp_free_i32(addr
);
7546 static void disas_arm_insn(CPUARMState
* env
, DisasContext
*s
)
7548 unsigned int cond
, insn
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
7555 insn
= arm_ldl_code(env
, s
->pc
, s
->bswap_code
);
7558 /* M variants do not implement ARM mode. */
7563 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7564 * choose to UNDEF. In ARMv5 and above the space is used
7565 * for miscellaneous unconditional instructions.
7569 /* Unconditional instructions. */
7570 if (((insn
>> 25) & 7) == 1) {
7571 /* NEON Data processing. */
7572 if (!arm_feature(env
, ARM_FEATURE_NEON
))
7575 if (disas_neon_data_insn(env
, s
, insn
))
7579 if ((insn
& 0x0f100000) == 0x04000000) {
7580 /* NEON load/store. */
7581 if (!arm_feature(env
, ARM_FEATURE_NEON
))
7584 if (disas_neon_ls_insn(env
, s
, insn
))
7588 if ((insn
& 0x0f000e10) == 0x0e000a00) {
7590 if (disas_vfp_insn(env
, s
, insn
)) {
7595 if (((insn
& 0x0f30f000) == 0x0510f000) ||
7596 ((insn
& 0x0f30f010) == 0x0710f000)) {
7597 if ((insn
& (1 << 22)) == 0) {
7599 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
7603 /* Otherwise PLD; v5TE+ */
7607 if (((insn
& 0x0f70f000) == 0x0450f000) ||
7608 ((insn
& 0x0f70f010) == 0x0650f000)) {
7610 return; /* PLI; V7 */
7612 if (((insn
& 0x0f700000) == 0x04100000) ||
7613 ((insn
& 0x0f700010) == 0x06100000)) {
7614 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
7617 return; /* v7MP: Unallocated memory hint: must NOP */
7620 if ((insn
& 0x0ffffdff) == 0x01010000) {
7623 if (((insn
>> 9) & 1) != s
->bswap_code
) {
7624 /* Dynamic endianness switching not implemented. */
7625 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
7629 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
7630 switch ((insn
>> 4) & 0xf) {
7639 /* We don't emulate caches so these are a no-op. */
7644 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
7650 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
7652 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
7658 rn
= (insn
>> 16) & 0xf;
7659 addr
= load_reg(s
, rn
);
7660 i
= (insn
>> 23) & 3;
7662 case 0: offset
= -4; break; /* DA */
7663 case 1: offset
= 0; break; /* IA */
7664 case 2: offset
= -8; break; /* DB */
7665 case 3: offset
= 4; break; /* IB */
7669 tcg_gen_addi_i32(addr
, addr
, offset
);
7670 /* Load PC into tmp and CPSR into tmp2. */
7671 tmp
= tcg_temp_new_i32();
7672 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
7673 tcg_gen_addi_i32(addr
, addr
, 4);
7674 tmp2
= tcg_temp_new_i32();
7675 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
7676 if (insn
& (1 << 21)) {
7677 /* Base writeback. */
7679 case 0: offset
= -8; break;
7680 case 1: offset
= 4; break;
7681 case 2: offset
= -4; break;
7682 case 3: offset
= 0; break;
7686 tcg_gen_addi_i32(addr
, addr
, offset
);
7687 store_reg(s
, rn
, addr
);
7689 tcg_temp_free_i32(addr
);
7691 gen_rfe(s
, tmp
, tmp2
);
7693 } else if ((insn
& 0x0e000000) == 0x0a000000) {
7694 /* branch link and change to thumb (blx <offset>) */
7697 val
= (uint32_t)s
->pc
;
7698 tmp
= tcg_temp_new_i32();
7699 tcg_gen_movi_i32(tmp
, val
);
7700 store_reg(s
, 14, tmp
);
7701 /* Sign-extend the 24-bit offset */
7702 offset
= (((int32_t)insn
) << 8) >> 8;
7703 /* offset * 4 + bit24 * 2 + (thumb bit) */
7704 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
7705 /* pipeline offset */
7707 /* protected by ARCH(5); above, near the start of uncond block */
7710 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
7711 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
7712 /* iWMMXt register transfer. */
7713 if (extract32(s
->c15_cpar
, 1, 1)) {
7714 if (!disas_iwmmxt_insn(env
, s
, insn
)) {
7719 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
7720 /* Coprocessor double register transfer. */
7722 } else if ((insn
& 0x0f000010) == 0x0e000010) {
7723 /* Additional coprocessor register transfer. */
7724 } else if ((insn
& 0x0ff10020) == 0x01000000) {
7727 /* cps (privileged) */
7731 if (insn
& (1 << 19)) {
7732 if (insn
& (1 << 8))
7734 if (insn
& (1 << 7))
7736 if (insn
& (1 << 6))
7738 if (insn
& (1 << 18))
7741 if (insn
& (1 << 17)) {
7743 val
|= (insn
& 0x1f);
7746 gen_set_psr_im(s
, mask
, 0, val
);
7753 /* if not always execute, we generate a conditional jump to
7755 s
->condlabel
= gen_new_label();
7756 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
7759 if ((insn
& 0x0f900000) == 0x03000000) {
7760 if ((insn
& (1 << 21)) == 0) {
7762 rd
= (insn
>> 12) & 0xf;
7763 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
7764 if ((insn
& (1 << 22)) == 0) {
7766 tmp
= tcg_temp_new_i32();
7767 tcg_gen_movi_i32(tmp
, val
);
7770 tmp
= load_reg(s
, rd
);
7771 tcg_gen_ext16u_i32(tmp
, tmp
);
7772 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
7774 store_reg(s
, rd
, tmp
);
7776 if (((insn
>> 12) & 0xf) != 0xf)
7778 if (((insn
>> 16) & 0xf) == 0) {
7779 gen_nop_hint(s
, insn
& 0xff);
7781 /* CPSR = immediate */
7783 shift
= ((insn
>> 8) & 0xf) * 2;
7785 val
= (val
>> shift
) | (val
<< (32 - shift
));
7786 i
= ((insn
& (1 << 22)) != 0);
7787 if (gen_set_psr_im(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, val
))
7791 } else if ((insn
& 0x0f900000) == 0x01000000
7792 && (insn
& 0x00000090) != 0x00000090) {
7793 /* miscellaneous instructions */
7794 op1
= (insn
>> 21) & 3;
7795 sh
= (insn
>> 4) & 0xf;
7798 case 0x0: /* move program status register */
7801 tmp
= load_reg(s
, rm
);
7802 i
= ((op1
& 2) != 0);
7803 if (gen_set_psr(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
7807 rd
= (insn
>> 12) & 0xf;
7811 tmp
= load_cpu_field(spsr
);
7813 tmp
= tcg_temp_new_i32();
7814 gen_helper_cpsr_read(tmp
, cpu_env
);
7816 store_reg(s
, rd
, tmp
);
7821 /* branch/exchange thumb (bx). */
7823 tmp
= load_reg(s
, rm
);
7825 } else if (op1
== 3) {
7828 rd
= (insn
>> 12) & 0xf;
7829 tmp
= load_reg(s
, rm
);
7830 gen_helper_clz(tmp
, tmp
);
7831 store_reg(s
, rd
, tmp
);
7839 /* Trivial implementation equivalent to bx. */
7840 tmp
= load_reg(s
, rm
);
7851 /* branch link/exchange thumb (blx) */
7852 tmp
= load_reg(s
, rm
);
7853 tmp2
= tcg_temp_new_i32();
7854 tcg_gen_movi_i32(tmp2
, s
->pc
);
7855 store_reg(s
, 14, tmp2
);
7861 uint32_t c
= extract32(insn
, 8, 4);
7863 /* Check this CPU supports ARMv8 CRC instructions.
7864 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
7865 * Bits 8, 10 and 11 should be zero.
7867 if (!arm_feature(env
, ARM_FEATURE_CRC
) || op1
== 0x3 ||
7872 rn
= extract32(insn
, 16, 4);
7873 rd
= extract32(insn
, 12, 4);
7875 tmp
= load_reg(s
, rn
);
7876 tmp2
= load_reg(s
, rm
);
7878 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
7879 } else if (op1
== 1) {
7880 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
7882 tmp3
= tcg_const_i32(1 << op1
);
7884 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
7886 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
7888 tcg_temp_free_i32(tmp2
);
7889 tcg_temp_free_i32(tmp3
);
7890 store_reg(s
, rd
, tmp
);
7893 case 0x5: /* saturating add/subtract */
7895 rd
= (insn
>> 12) & 0xf;
7896 rn
= (insn
>> 16) & 0xf;
7897 tmp
= load_reg(s
, rm
);
7898 tmp2
= load_reg(s
, rn
);
7900 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
7902 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
7904 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
7905 tcg_temp_free_i32(tmp2
);
7906 store_reg(s
, rd
, tmp
);
7910 int imm16
= extract32(insn
, 0, 4) | (extract32(insn
, 8, 12) << 4);
7915 gen_exception_insn(s
, 4, EXCP_BKPT
,
7916 syn_aa32_bkpt(imm16
, false));
7919 /* Hypervisor call (v7) */
7927 /* Secure monitor call (v6+) */
7939 case 0x8: /* signed multiply */
7944 rs
= (insn
>> 8) & 0xf;
7945 rn
= (insn
>> 12) & 0xf;
7946 rd
= (insn
>> 16) & 0xf;
7948 /* (32 * 16) >> 16 */
7949 tmp
= load_reg(s
, rm
);
7950 tmp2
= load_reg(s
, rs
);
7952 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
7955 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7956 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
7957 tmp
= tcg_temp_new_i32();
7958 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7959 tcg_temp_free_i64(tmp64
);
7960 if ((sh
& 2) == 0) {
7961 tmp2
= load_reg(s
, rn
);
7962 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7963 tcg_temp_free_i32(tmp2
);
7965 store_reg(s
, rd
, tmp
);
7968 tmp
= load_reg(s
, rm
);
7969 tmp2
= load_reg(s
, rs
);
7970 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
7971 tcg_temp_free_i32(tmp2
);
7973 tmp64
= tcg_temp_new_i64();
7974 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7975 tcg_temp_free_i32(tmp
);
7976 gen_addq(s
, tmp64
, rn
, rd
);
7977 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7978 tcg_temp_free_i64(tmp64
);
7981 tmp2
= load_reg(s
, rn
);
7982 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7983 tcg_temp_free_i32(tmp2
);
7985 store_reg(s
, rd
, tmp
);
7992 } else if (((insn
& 0x0e000000) == 0 &&
7993 (insn
& 0x00000090) != 0x90) ||
7994 ((insn
& 0x0e000000) == (1 << 25))) {
7995 int set_cc
, logic_cc
, shiftop
;
7997 op1
= (insn
>> 21) & 0xf;
7998 set_cc
= (insn
>> 20) & 1;
7999 logic_cc
= table_logic_cc
[op1
] & set_cc
;
8001 /* data processing instruction */
8002 if (insn
& (1 << 25)) {
8003 /* immediate operand */
8005 shift
= ((insn
>> 8) & 0xf) * 2;
8007 val
= (val
>> shift
) | (val
<< (32 - shift
));
8009 tmp2
= tcg_temp_new_i32();
8010 tcg_gen_movi_i32(tmp2
, val
);
8011 if (logic_cc
&& shift
) {
8012 gen_set_CF_bit31(tmp2
);
8017 tmp2
= load_reg(s
, rm
);
8018 shiftop
= (insn
>> 5) & 3;
8019 if (!(insn
& (1 << 4))) {
8020 shift
= (insn
>> 7) & 0x1f;
8021 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8023 rs
= (insn
>> 8) & 0xf;
8024 tmp
= load_reg(s
, rs
);
8025 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
8028 if (op1
!= 0x0f && op1
!= 0x0d) {
8029 rn
= (insn
>> 16) & 0xf;
8030 tmp
= load_reg(s
, rn
);
8032 TCGV_UNUSED_I32(tmp
);
8034 rd
= (insn
>> 12) & 0xf;
8037 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8041 store_reg_bx(env
, s
, rd
, tmp
);
8044 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8048 store_reg_bx(env
, s
, rd
, tmp
);
8051 if (set_cc
&& rd
== 15) {
8052 /* SUBS r15, ... is used for exception return. */
8056 gen_sub_CC(tmp
, tmp
, tmp2
);
8057 gen_exception_return(s
, tmp
);
8060 gen_sub_CC(tmp
, tmp
, tmp2
);
8062 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8064 store_reg_bx(env
, s
, rd
, tmp
);
8069 gen_sub_CC(tmp
, tmp2
, tmp
);
8071 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8073 store_reg_bx(env
, s
, rd
, tmp
);
8077 gen_add_CC(tmp
, tmp
, tmp2
);
8079 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8081 store_reg_bx(env
, s
, rd
, tmp
);
8085 gen_adc_CC(tmp
, tmp
, tmp2
);
8087 gen_add_carry(tmp
, tmp
, tmp2
);
8089 store_reg_bx(env
, s
, rd
, tmp
);
8093 gen_sbc_CC(tmp
, tmp
, tmp2
);
8095 gen_sub_carry(tmp
, tmp
, tmp2
);
8097 store_reg_bx(env
, s
, rd
, tmp
);
8101 gen_sbc_CC(tmp
, tmp2
, tmp
);
8103 gen_sub_carry(tmp
, tmp2
, tmp
);
8105 store_reg_bx(env
, s
, rd
, tmp
);
8109 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8112 tcg_temp_free_i32(tmp
);
8116 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8119 tcg_temp_free_i32(tmp
);
8123 gen_sub_CC(tmp
, tmp
, tmp2
);
8125 tcg_temp_free_i32(tmp
);
8129 gen_add_CC(tmp
, tmp
, tmp2
);
8131 tcg_temp_free_i32(tmp
);
8134 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8138 store_reg_bx(env
, s
, rd
, tmp
);
8141 if (logic_cc
&& rd
== 15) {
8142 /* MOVS r15, ... is used for exception return. */
8146 gen_exception_return(s
, tmp2
);
8151 store_reg_bx(env
, s
, rd
, tmp2
);
8155 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
8159 store_reg_bx(env
, s
, rd
, tmp
);
8163 tcg_gen_not_i32(tmp2
, tmp2
);
8167 store_reg_bx(env
, s
, rd
, tmp2
);
8170 if (op1
!= 0x0f && op1
!= 0x0d) {
8171 tcg_temp_free_i32(tmp2
);
8174 /* other instructions */
8175 op1
= (insn
>> 24) & 0xf;
8179 /* multiplies, extra load/stores */
8180 sh
= (insn
>> 5) & 3;
8183 rd
= (insn
>> 16) & 0xf;
8184 rn
= (insn
>> 12) & 0xf;
8185 rs
= (insn
>> 8) & 0xf;
8187 op1
= (insn
>> 20) & 0xf;
8189 case 0: case 1: case 2: case 3: case 6:
8191 tmp
= load_reg(s
, rs
);
8192 tmp2
= load_reg(s
, rm
);
8193 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8194 tcg_temp_free_i32(tmp2
);
8195 if (insn
& (1 << 22)) {
8196 /* Subtract (mls) */
8198 tmp2
= load_reg(s
, rn
);
8199 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8200 tcg_temp_free_i32(tmp2
);
8201 } else if (insn
& (1 << 21)) {
8203 tmp2
= load_reg(s
, rn
);
8204 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8205 tcg_temp_free_i32(tmp2
);
8207 if (insn
& (1 << 20))
8209 store_reg(s
, rd
, tmp
);
8212 /* 64 bit mul double accumulate (UMAAL) */
8214 tmp
= load_reg(s
, rs
);
8215 tmp2
= load_reg(s
, rm
);
8216 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8217 gen_addq_lo(s
, tmp64
, rn
);
8218 gen_addq_lo(s
, tmp64
, rd
);
8219 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8220 tcg_temp_free_i64(tmp64
);
8222 case 8: case 9: case 10: case 11:
8223 case 12: case 13: case 14: case 15:
8224 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8225 tmp
= load_reg(s
, rs
);
8226 tmp2
= load_reg(s
, rm
);
8227 if (insn
& (1 << 22)) {
8228 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
8230 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
8232 if (insn
& (1 << 21)) { /* mult accumulate */
8233 TCGv_i32 al
= load_reg(s
, rn
);
8234 TCGv_i32 ah
= load_reg(s
, rd
);
8235 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
8236 tcg_temp_free_i32(al
);
8237 tcg_temp_free_i32(ah
);
8239 if (insn
& (1 << 20)) {
8240 gen_logicq_cc(tmp
, tmp2
);
8242 store_reg(s
, rn
, tmp
);
8243 store_reg(s
, rd
, tmp2
);
8249 rn
= (insn
>> 16) & 0xf;
8250 rd
= (insn
>> 12) & 0xf;
8251 if (insn
& (1 << 23)) {
8252 /* load/store exclusive */
8253 int op2
= (insn
>> 8) & 3;
8254 op1
= (insn
>> 21) & 0x3;
8257 case 0: /* lda/stl */
8263 case 1: /* reserved */
8265 case 2: /* ldaex/stlex */
8268 case 3: /* ldrex/strex */
8277 addr
= tcg_temp_local_new_i32();
8278 load_reg_var(s
, addr
, rn
);
8280 /* Since the emulation does not have barriers,
8281 the acquire/release semantics need no special
8284 if (insn
& (1 << 20)) {
8285 tmp
= tcg_temp_new_i32();
8288 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8291 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
8294 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
8299 store_reg(s
, rd
, tmp
);
8302 tmp
= load_reg(s
, rm
);
8305 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8308 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
8311 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
8316 tcg_temp_free_i32(tmp
);
8318 } else if (insn
& (1 << 20)) {
8321 gen_load_exclusive(s
, rd
, 15, addr
, 2);
8323 case 1: /* ldrexd */
8324 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
8326 case 2: /* ldrexb */
8327 gen_load_exclusive(s
, rd
, 15, addr
, 0);
8329 case 3: /* ldrexh */
8330 gen_load_exclusive(s
, rd
, 15, addr
, 1);
8339 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
8341 case 1: /* strexd */
8342 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
8344 case 2: /* strexb */
8345 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
8347 case 3: /* strexh */
8348 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
8354 tcg_temp_free_i32(addr
);
8356 /* SWP instruction */
8359 /* ??? This is not really atomic. However we know
8360 we never have multiple CPUs running in parallel,
8361 so it is good enough. */
8362 addr
= load_reg(s
, rn
);
8363 tmp
= load_reg(s
, rm
);
8364 tmp2
= tcg_temp_new_i32();
8365 if (insn
& (1 << 22)) {
8366 gen_aa32_ld8u(tmp2
, addr
, get_mem_index(s
));
8367 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
8369 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
8370 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8372 tcg_temp_free_i32(tmp
);
8373 tcg_temp_free_i32(addr
);
8374 store_reg(s
, rd
, tmp2
);
8380 /* Misc load/store */
8381 rn
= (insn
>> 16) & 0xf;
8382 rd
= (insn
>> 12) & 0xf;
8383 addr
= load_reg(s
, rn
);
8384 if (insn
& (1 << 24))
8385 gen_add_datah_offset(s
, insn
, 0, addr
);
8387 if (insn
& (1 << 20)) {
8389 tmp
= tcg_temp_new_i32();
8392 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
8395 gen_aa32_ld8s(tmp
, addr
, get_mem_index(s
));
8399 gen_aa32_ld16s(tmp
, addr
, get_mem_index(s
));
8403 } else if (sh
& 2) {
8408 tmp
= load_reg(s
, rd
);
8409 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8410 tcg_temp_free_i32(tmp
);
8411 tcg_gen_addi_i32(addr
, addr
, 4);
8412 tmp
= load_reg(s
, rd
+ 1);
8413 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8414 tcg_temp_free_i32(tmp
);
8418 tmp
= tcg_temp_new_i32();
8419 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8420 store_reg(s
, rd
, tmp
);
8421 tcg_gen_addi_i32(addr
, addr
, 4);
8422 tmp
= tcg_temp_new_i32();
8423 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8427 address_offset
= -4;
8430 tmp
= load_reg(s
, rd
);
8431 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
8432 tcg_temp_free_i32(tmp
);
8435 /* Perform base writeback before the loaded value to
8436 ensure correct behavior with overlapping index registers.
8437 ldrd with base writeback is is undefined if the
8438 destination and index registers overlap. */
8439 if (!(insn
& (1 << 24))) {
8440 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
8441 store_reg(s
, rn
, addr
);
8442 } else if (insn
& (1 << 21)) {
8444 tcg_gen_addi_i32(addr
, addr
, address_offset
);
8445 store_reg(s
, rn
, addr
);
8447 tcg_temp_free_i32(addr
);
8450 /* Complete the load. */
8451 store_reg(s
, rd
, tmp
);
8460 if (insn
& (1 << 4)) {
8462 /* Armv6 Media instructions. */
8464 rn
= (insn
>> 16) & 0xf;
8465 rd
= (insn
>> 12) & 0xf;
8466 rs
= (insn
>> 8) & 0xf;
8467 switch ((insn
>> 23) & 3) {
8468 case 0: /* Parallel add/subtract. */
8469 op1
= (insn
>> 20) & 7;
8470 tmp
= load_reg(s
, rn
);
8471 tmp2
= load_reg(s
, rm
);
8472 sh
= (insn
>> 5) & 7;
8473 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
8475 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
8476 tcg_temp_free_i32(tmp2
);
8477 store_reg(s
, rd
, tmp
);
8480 if ((insn
& 0x00700020) == 0) {
8481 /* Halfword pack. */
8482 tmp
= load_reg(s
, rn
);
8483 tmp2
= load_reg(s
, rm
);
8484 shift
= (insn
>> 7) & 0x1f;
8485 if (insn
& (1 << 6)) {
8489 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8490 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8491 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8495 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8496 tcg_gen_ext16u_i32(tmp
, tmp
);
8497 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8499 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8500 tcg_temp_free_i32(tmp2
);
8501 store_reg(s
, rd
, tmp
);
8502 } else if ((insn
& 0x00200020) == 0x00200000) {
8504 tmp
= load_reg(s
, rm
);
8505 shift
= (insn
>> 7) & 0x1f;
8506 if (insn
& (1 << 6)) {
8509 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8511 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8513 sh
= (insn
>> 16) & 0x1f;
8514 tmp2
= tcg_const_i32(sh
);
8515 if (insn
& (1 << 22))
8516 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
8518 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
8519 tcg_temp_free_i32(tmp2
);
8520 store_reg(s
, rd
, tmp
);
8521 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
8523 tmp
= load_reg(s
, rm
);
8524 sh
= (insn
>> 16) & 0x1f;
8525 tmp2
= tcg_const_i32(sh
);
8526 if (insn
& (1 << 22))
8527 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
8529 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
8530 tcg_temp_free_i32(tmp2
);
8531 store_reg(s
, rd
, tmp
);
8532 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
8534 tmp
= load_reg(s
, rn
);
8535 tmp2
= load_reg(s
, rm
);
8536 tmp3
= tcg_temp_new_i32();
8537 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
8538 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
8539 tcg_temp_free_i32(tmp3
);
8540 tcg_temp_free_i32(tmp2
);
8541 store_reg(s
, rd
, tmp
);
8542 } else if ((insn
& 0x000003e0) == 0x00000060) {
8543 tmp
= load_reg(s
, rm
);
8544 shift
= (insn
>> 10) & 3;
8545 /* ??? In many cases it's not necessary to do a
8546 rotate, a shift is sufficient. */
8548 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
8549 op1
= (insn
>> 20) & 7;
8551 case 0: gen_sxtb16(tmp
); break;
8552 case 2: gen_sxtb(tmp
); break;
8553 case 3: gen_sxth(tmp
); break;
8554 case 4: gen_uxtb16(tmp
); break;
8555 case 6: gen_uxtb(tmp
); break;
8556 case 7: gen_uxth(tmp
); break;
8557 default: goto illegal_op
;
8560 tmp2
= load_reg(s
, rn
);
8561 if ((op1
& 3) == 0) {
8562 gen_add16(tmp
, tmp2
);
8564 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8565 tcg_temp_free_i32(tmp2
);
8568 store_reg(s
, rd
, tmp
);
8569 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
8571 tmp
= load_reg(s
, rm
);
8572 if (insn
& (1 << 22)) {
8573 if (insn
& (1 << 7)) {
8577 gen_helper_rbit(tmp
, tmp
);
8580 if (insn
& (1 << 7))
8583 tcg_gen_bswap32_i32(tmp
, tmp
);
8585 store_reg(s
, rd
, tmp
);
8590 case 2: /* Multiplies (Type 3). */
8591 switch ((insn
>> 20) & 0x7) {
8593 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
8594 /* op2 not 00x or 11x : UNDEF */
8597 /* Signed multiply most significant [accumulate].
8598 (SMMUL, SMMLA, SMMLS) */
8599 tmp
= load_reg(s
, rm
);
8600 tmp2
= load_reg(s
, rs
);
8601 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8604 tmp
= load_reg(s
, rd
);
8605 if (insn
& (1 << 6)) {
8606 tmp64
= gen_subq_msw(tmp64
, tmp
);
8608 tmp64
= gen_addq_msw(tmp64
, tmp
);
8611 if (insn
& (1 << 5)) {
8612 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
8614 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
8615 tmp
= tcg_temp_new_i32();
8616 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8617 tcg_temp_free_i64(tmp64
);
8618 store_reg(s
, rn
, tmp
);
8622 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8623 if (insn
& (1 << 7)) {
8626 tmp
= load_reg(s
, rm
);
8627 tmp2
= load_reg(s
, rs
);
8628 if (insn
& (1 << 5))
8629 gen_swap_half(tmp2
);
8630 gen_smul_dual(tmp
, tmp2
);
8631 if (insn
& (1 << 22)) {
8632 /* smlald, smlsld */
8635 tmp64
= tcg_temp_new_i64();
8636 tmp64_2
= tcg_temp_new_i64();
8637 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8638 tcg_gen_ext_i32_i64(tmp64_2
, tmp2
);
8639 tcg_temp_free_i32(tmp
);
8640 tcg_temp_free_i32(tmp2
);
8641 if (insn
& (1 << 6)) {
8642 tcg_gen_sub_i64(tmp64
, tmp64
, tmp64_2
);
8644 tcg_gen_add_i64(tmp64
, tmp64
, tmp64_2
);
8646 tcg_temp_free_i64(tmp64_2
);
8647 gen_addq(s
, tmp64
, rd
, rn
);
8648 gen_storeq_reg(s
, rd
, rn
, tmp64
);
8649 tcg_temp_free_i64(tmp64
);
8651 /* smuad, smusd, smlad, smlsd */
8652 if (insn
& (1 << 6)) {
8653 /* This subtraction cannot overflow. */
8654 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8656 /* This addition cannot overflow 32 bits;
8657 * however it may overflow considered as a
8658 * signed operation, in which case we must set
8661 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8663 tcg_temp_free_i32(tmp2
);
8666 tmp2
= load_reg(s
, rd
);
8667 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8668 tcg_temp_free_i32(tmp2
);
8670 store_reg(s
, rn
, tmp
);
8676 if (!arm_feature(env
, ARM_FEATURE_ARM_DIV
)) {
8679 if (((insn
>> 5) & 7) || (rd
!= 15)) {
8682 tmp
= load_reg(s
, rm
);
8683 tmp2
= load_reg(s
, rs
);
8684 if (insn
& (1 << 21)) {
8685 gen_helper_udiv(tmp
, tmp
, tmp2
);
8687 gen_helper_sdiv(tmp
, tmp
, tmp2
);
8689 tcg_temp_free_i32(tmp2
);
8690 store_reg(s
, rn
, tmp
);
8697 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
8699 case 0: /* Unsigned sum of absolute differences. */
8701 tmp
= load_reg(s
, rm
);
8702 tmp2
= load_reg(s
, rs
);
8703 gen_helper_usad8(tmp
, tmp
, tmp2
);
8704 tcg_temp_free_i32(tmp2
);
8706 tmp2
= load_reg(s
, rd
);
8707 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8708 tcg_temp_free_i32(tmp2
);
8710 store_reg(s
, rn
, tmp
);
8712 case 0x20: case 0x24: case 0x28: case 0x2c:
8713 /* Bitfield insert/clear. */
8715 shift
= (insn
>> 7) & 0x1f;
8716 i
= (insn
>> 16) & 0x1f;
8719 tmp
= tcg_temp_new_i32();
8720 tcg_gen_movi_i32(tmp
, 0);
8722 tmp
= load_reg(s
, rm
);
8725 tmp2
= load_reg(s
, rd
);
8726 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
8727 tcg_temp_free_i32(tmp2
);
8729 store_reg(s
, rd
, tmp
);
8731 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8732 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8734 tmp
= load_reg(s
, rm
);
8735 shift
= (insn
>> 7) & 0x1f;
8736 i
= ((insn
>> 16) & 0x1f) + 1;
8741 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
8743 gen_sbfx(tmp
, shift
, i
);
8746 store_reg(s
, rd
, tmp
);
8756 /* Check for undefined extension instructions
8757 * per the ARM Bible IE:
8758 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8760 sh
= (0xf << 20) | (0xf << 4);
8761 if (op1
== 0x7 && ((insn
& sh
) == sh
))
8765 /* load/store byte/word */
8766 rn
= (insn
>> 16) & 0xf;
8767 rd
= (insn
>> 12) & 0xf;
8768 tmp2
= load_reg(s
, rn
);
8769 if ((insn
& 0x01200000) == 0x00200000) {
8773 i
= get_mem_index(s
);
8775 if (insn
& (1 << 24))
8776 gen_add_data_offset(s
, insn
, tmp2
);
8777 if (insn
& (1 << 20)) {
8779 tmp
= tcg_temp_new_i32();
8780 if (insn
& (1 << 22)) {
8781 gen_aa32_ld8u(tmp
, tmp2
, i
);
8783 gen_aa32_ld32u(tmp
, tmp2
, i
);
8787 tmp
= load_reg(s
, rd
);
8788 if (insn
& (1 << 22)) {
8789 gen_aa32_st8(tmp
, tmp2
, i
);
8791 gen_aa32_st32(tmp
, tmp2
, i
);
8793 tcg_temp_free_i32(tmp
);
8795 if (!(insn
& (1 << 24))) {
8796 gen_add_data_offset(s
, insn
, tmp2
);
8797 store_reg(s
, rn
, tmp2
);
8798 } else if (insn
& (1 << 21)) {
8799 store_reg(s
, rn
, tmp2
);
8801 tcg_temp_free_i32(tmp2
);
8803 if (insn
& (1 << 20)) {
8804 /* Complete the load. */
8805 store_reg_from_load(env
, s
, rd
, tmp
);
8811 int j
, n
, user
, loaded_base
;
8812 TCGv_i32 loaded_var
;
8813 /* load/store multiple words */
8814 /* XXX: store correct base if write back */
8816 if (insn
& (1 << 22)) {
8818 goto illegal_op
; /* only usable in supervisor mode */
8820 if ((insn
& (1 << 15)) == 0)
8823 rn
= (insn
>> 16) & 0xf;
8824 addr
= load_reg(s
, rn
);
8826 /* compute total size */
8828 TCGV_UNUSED_I32(loaded_var
);
8831 if (insn
& (1 << i
))
8834 /* XXX: test invalid n == 0 case ? */
8835 if (insn
& (1 << 23)) {
8836 if (insn
& (1 << 24)) {
8838 tcg_gen_addi_i32(addr
, addr
, 4);
8840 /* post increment */
8843 if (insn
& (1 << 24)) {
8845 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
8847 /* post decrement */
8849 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
8854 if (insn
& (1 << i
)) {
8855 if (insn
& (1 << 20)) {
8857 tmp
= tcg_temp_new_i32();
8858 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8860 tmp2
= tcg_const_i32(i
);
8861 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
8862 tcg_temp_free_i32(tmp2
);
8863 tcg_temp_free_i32(tmp
);
8864 } else if (i
== rn
) {
8868 store_reg_from_load(env
, s
, i
, tmp
);
8873 /* special case: r15 = PC + 8 */
8874 val
= (long)s
->pc
+ 4;
8875 tmp
= tcg_temp_new_i32();
8876 tcg_gen_movi_i32(tmp
, val
);
8878 tmp
= tcg_temp_new_i32();
8879 tmp2
= tcg_const_i32(i
);
8880 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
8881 tcg_temp_free_i32(tmp2
);
8883 tmp
= load_reg(s
, i
);
8885 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8886 tcg_temp_free_i32(tmp
);
8889 /* no need to add after the last transfer */
8891 tcg_gen_addi_i32(addr
, addr
, 4);
8894 if (insn
& (1 << 21)) {
8896 if (insn
& (1 << 23)) {
8897 if (insn
& (1 << 24)) {
8900 /* post increment */
8901 tcg_gen_addi_i32(addr
, addr
, 4);
8904 if (insn
& (1 << 24)) {
8907 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
8909 /* post decrement */
8910 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
8913 store_reg(s
, rn
, addr
);
8915 tcg_temp_free_i32(addr
);
8918 store_reg(s
, rn
, loaded_var
);
8920 if ((insn
& (1 << 22)) && !user
) {
8921 /* Restore CPSR from SPSR. */
8922 tmp
= load_cpu_field(spsr
);
8923 gen_set_cpsr(tmp
, CPSR_ERET_MASK
);
8924 tcg_temp_free_i32(tmp
);
8925 s
->is_jmp
= DISAS_UPDATE
;
8934 /* branch (and link) */
8935 val
= (int32_t)s
->pc
;
8936 if (insn
& (1 << 24)) {
8937 tmp
= tcg_temp_new_i32();
8938 tcg_gen_movi_i32(tmp
, val
);
8939 store_reg(s
, 14, tmp
);
8941 offset
= sextract32(insn
<< 2, 0, 26);
8949 if (((insn
>> 8) & 0xe) == 10) {
8951 if (disas_vfp_insn(env
, s
, insn
)) {
8954 } else if (disas_coproc_insn(env
, s
, insn
)) {
8961 gen_set_pc_im(s
, s
->pc
);
8962 s
->svc_imm
= extract32(insn
, 0, 24);
8963 s
->is_jmp
= DISAS_SWI
;
8967 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized());
8973 /* Return true if this is a Thumb-2 logical op. */
8975 thumb2_logic_op(int op
)
8980 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
8981 then set condition code flags based on the result of the operation.
8982 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8983 to the high bit of T1.
8984 Returns zero if the opcode is valid. */
8987 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
8988 TCGv_i32 t0
, TCGv_i32 t1
)
8995 tcg_gen_and_i32(t0
, t0
, t1
);
8999 tcg_gen_andc_i32(t0
, t0
, t1
);
9003 tcg_gen_or_i32(t0
, t0
, t1
);
9007 tcg_gen_orc_i32(t0
, t0
, t1
);
9011 tcg_gen_xor_i32(t0
, t0
, t1
);
9016 gen_add_CC(t0
, t0
, t1
);
9018 tcg_gen_add_i32(t0
, t0
, t1
);
9022 gen_adc_CC(t0
, t0
, t1
);
9028 gen_sbc_CC(t0
, t0
, t1
);
9030 gen_sub_carry(t0
, t0
, t1
);
9035 gen_sub_CC(t0
, t0
, t1
);
9037 tcg_gen_sub_i32(t0
, t0
, t1
);
9041 gen_sub_CC(t0
, t1
, t0
);
9043 tcg_gen_sub_i32(t0
, t1
, t0
);
9045 default: /* 5, 6, 7, 9, 12, 15. */
9051 gen_set_CF_bit31(t1
);
9056 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
9058 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
9060 uint32_t insn
, imm
, shift
, offset
;
9061 uint32_t rd
, rn
, rm
, rs
;
9072 if (!(arm_feature(env
, ARM_FEATURE_THUMB2
)
9073 || arm_feature (env
, ARM_FEATURE_M
))) {
9074 /* Thumb-1 cores may need to treat bl and blx as a pair of
9075 16-bit instructions to get correct prefetch abort behavior. */
9077 if ((insn
& (1 << 12)) == 0) {
9079 /* Second half of blx. */
9080 offset
= ((insn
& 0x7ff) << 1);
9081 tmp
= load_reg(s
, 14);
9082 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9083 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
9085 tmp2
= tcg_temp_new_i32();
9086 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9087 store_reg(s
, 14, tmp2
);
9091 if (insn
& (1 << 11)) {
9092 /* Second half of bl. */
9093 offset
= ((insn
& 0x7ff) << 1) | 1;
9094 tmp
= load_reg(s
, 14);
9095 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9097 tmp2
= tcg_temp_new_i32();
9098 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9099 store_reg(s
, 14, tmp2
);
9103 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
9104 /* Instruction spans a page boundary. Implement it as two
9105 16-bit instructions in case the second half causes an
9107 offset
= ((int32_t)insn
<< 21) >> 9;
9108 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
9111 /* Fall through to 32-bit decode. */
9114 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
9116 insn
|= (uint32_t)insn_hw1
<< 16;
9118 if ((insn
& 0xf800e800) != 0xf000e800) {
9122 rn
= (insn
>> 16) & 0xf;
9123 rs
= (insn
>> 12) & 0xf;
9124 rd
= (insn
>> 8) & 0xf;
9126 switch ((insn
>> 25) & 0xf) {
9127 case 0: case 1: case 2: case 3:
9128 /* 16-bit instructions. Should never happen. */
9131 if (insn
& (1 << 22)) {
9132 /* Other load/store, table branch. */
9133 if (insn
& 0x01200000) {
9134 /* Load/store doubleword. */
9136 addr
= tcg_temp_new_i32();
9137 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
9139 addr
= load_reg(s
, rn
);
9141 offset
= (insn
& 0xff) * 4;
9142 if ((insn
& (1 << 23)) == 0)
9144 if (insn
& (1 << 24)) {
9145 tcg_gen_addi_i32(addr
, addr
, offset
);
9148 if (insn
& (1 << 20)) {
9150 tmp
= tcg_temp_new_i32();
9151 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9152 store_reg(s
, rs
, tmp
);
9153 tcg_gen_addi_i32(addr
, addr
, 4);
9154 tmp
= tcg_temp_new_i32();
9155 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9156 store_reg(s
, rd
, tmp
);
9159 tmp
= load_reg(s
, rs
);
9160 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9161 tcg_temp_free_i32(tmp
);
9162 tcg_gen_addi_i32(addr
, addr
, 4);
9163 tmp
= load_reg(s
, rd
);
9164 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9165 tcg_temp_free_i32(tmp
);
9167 if (insn
& (1 << 21)) {
9168 /* Base writeback. */
9171 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
9172 store_reg(s
, rn
, addr
);
9174 tcg_temp_free_i32(addr
);
9176 } else if ((insn
& (1 << 23)) == 0) {
9177 /* Load/store exclusive word. */
9178 addr
= tcg_temp_local_new_i32();
9179 load_reg_var(s
, addr
, rn
);
9180 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
9181 if (insn
& (1 << 20)) {
9182 gen_load_exclusive(s
, rs
, 15, addr
, 2);
9184 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
9186 tcg_temp_free_i32(addr
);
9187 } else if ((insn
& (7 << 5)) == 0) {
9190 addr
= tcg_temp_new_i32();
9191 tcg_gen_movi_i32(addr
, s
->pc
);
9193 addr
= load_reg(s
, rn
);
9195 tmp
= load_reg(s
, rm
);
9196 tcg_gen_add_i32(addr
, addr
, tmp
);
9197 if (insn
& (1 << 4)) {
9199 tcg_gen_add_i32(addr
, addr
, tmp
);
9200 tcg_temp_free_i32(tmp
);
9201 tmp
= tcg_temp_new_i32();
9202 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
9204 tcg_temp_free_i32(tmp
);
9205 tmp
= tcg_temp_new_i32();
9206 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
9208 tcg_temp_free_i32(addr
);
9209 tcg_gen_shli_i32(tmp
, tmp
, 1);
9210 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
9211 store_reg(s
, 15, tmp
);
9213 int op2
= (insn
>> 6) & 0x3;
9214 op
= (insn
>> 4) & 0x3;
9219 /* Load/store exclusive byte/halfword/doubleword */
9226 /* Load-acquire/store-release */
9232 /* Load-acquire/store-release exclusive */
9236 addr
= tcg_temp_local_new_i32();
9237 load_reg_var(s
, addr
, rn
);
9239 if (insn
& (1 << 20)) {
9240 tmp
= tcg_temp_new_i32();
9243 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
9246 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
9249 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9254 store_reg(s
, rs
, tmp
);
9256 tmp
= load_reg(s
, rs
);
9259 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
9262 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
9265 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9270 tcg_temp_free_i32(tmp
);
9272 } else if (insn
& (1 << 20)) {
9273 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
9275 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
9277 tcg_temp_free_i32(addr
);
9280 /* Load/store multiple, RFE, SRS. */
9281 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
9282 /* RFE, SRS: not available in user mode or on M profile */
9283 if (IS_USER(s
) || IS_M(env
)) {
9286 if (insn
& (1 << 20)) {
9288 addr
= load_reg(s
, rn
);
9289 if ((insn
& (1 << 24)) == 0)
9290 tcg_gen_addi_i32(addr
, addr
, -8);
9291 /* Load PC into tmp and CPSR into tmp2. */
9292 tmp
= tcg_temp_new_i32();
9293 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9294 tcg_gen_addi_i32(addr
, addr
, 4);
9295 tmp2
= tcg_temp_new_i32();
9296 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
9297 if (insn
& (1 << 21)) {
9298 /* Base writeback. */
9299 if (insn
& (1 << 24)) {
9300 tcg_gen_addi_i32(addr
, addr
, 4);
9302 tcg_gen_addi_i32(addr
, addr
, -4);
9304 store_reg(s
, rn
, addr
);
9306 tcg_temp_free_i32(addr
);
9308 gen_rfe(s
, tmp
, tmp2
);
9311 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
9315 int i
, loaded_base
= 0;
9316 TCGv_i32 loaded_var
;
9317 /* Load/store multiple. */
9318 addr
= load_reg(s
, rn
);
9320 for (i
= 0; i
< 16; i
++) {
9321 if (insn
& (1 << i
))
9324 if (insn
& (1 << 24)) {
9325 tcg_gen_addi_i32(addr
, addr
, -offset
);
9328 TCGV_UNUSED_I32(loaded_var
);
9329 for (i
= 0; i
< 16; i
++) {
9330 if ((insn
& (1 << i
)) == 0)
9332 if (insn
& (1 << 20)) {
9334 tmp
= tcg_temp_new_i32();
9335 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9338 } else if (i
== rn
) {
9342 store_reg(s
, i
, tmp
);
9346 tmp
= load_reg(s
, i
);
9347 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9348 tcg_temp_free_i32(tmp
);
9350 tcg_gen_addi_i32(addr
, addr
, 4);
9353 store_reg(s
, rn
, loaded_var
);
9355 if (insn
& (1 << 21)) {
9356 /* Base register writeback. */
9357 if (insn
& (1 << 24)) {
9358 tcg_gen_addi_i32(addr
, addr
, -offset
);
9360 /* Fault if writeback register is in register list. */
9361 if (insn
& (1 << rn
))
9363 store_reg(s
, rn
, addr
);
9365 tcg_temp_free_i32(addr
);
9372 op
= (insn
>> 21) & 0xf;
9374 /* Halfword pack. */
9375 tmp
= load_reg(s
, rn
);
9376 tmp2
= load_reg(s
, rm
);
9377 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
9378 if (insn
& (1 << 5)) {
9382 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9383 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9384 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9388 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9389 tcg_gen_ext16u_i32(tmp
, tmp
);
9390 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9392 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9393 tcg_temp_free_i32(tmp2
);
9394 store_reg(s
, rd
, tmp
);
9396 /* Data processing register constant shift. */
9398 tmp
= tcg_temp_new_i32();
9399 tcg_gen_movi_i32(tmp
, 0);
9401 tmp
= load_reg(s
, rn
);
9403 tmp2
= load_reg(s
, rm
);
9405 shiftop
= (insn
>> 4) & 3;
9406 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
9407 conds
= (insn
& (1 << 20)) != 0;
9408 logic_cc
= (conds
&& thumb2_logic_op(op
));
9409 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
9410 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
9412 tcg_temp_free_i32(tmp2
);
9414 store_reg(s
, rd
, tmp
);
9416 tcg_temp_free_i32(tmp
);
9420 case 13: /* Misc data processing. */
9421 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
9422 if (op
< 4 && (insn
& 0xf000) != 0xf000)
9425 case 0: /* Register controlled shift. */
9426 tmp
= load_reg(s
, rn
);
9427 tmp2
= load_reg(s
, rm
);
9428 if ((insn
& 0x70) != 0)
9430 op
= (insn
>> 21) & 3;
9431 logic_cc
= (insn
& (1 << 20)) != 0;
9432 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
9435 store_reg_bx(env
, s
, rd
, tmp
);
9437 case 1: /* Sign/zero extend. */
9438 tmp
= load_reg(s
, rm
);
9439 shift
= (insn
>> 4) & 3;
9440 /* ??? In many cases it's not necessary to do a
9441 rotate, a shift is sufficient. */
9443 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9444 op
= (insn
>> 20) & 7;
9446 case 0: gen_sxth(tmp
); break;
9447 case 1: gen_uxth(tmp
); break;
9448 case 2: gen_sxtb16(tmp
); break;
9449 case 3: gen_uxtb16(tmp
); break;
9450 case 4: gen_sxtb(tmp
); break;
9451 case 5: gen_uxtb(tmp
); break;
9452 default: goto illegal_op
;
9455 tmp2
= load_reg(s
, rn
);
9456 if ((op
>> 1) == 1) {
9457 gen_add16(tmp
, tmp2
);
9459 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9460 tcg_temp_free_i32(tmp2
);
9463 store_reg(s
, rd
, tmp
);
9465 case 2: /* SIMD add/subtract. */
9466 op
= (insn
>> 20) & 7;
9467 shift
= (insn
>> 4) & 7;
9468 if ((op
& 3) == 3 || (shift
& 3) == 3)
9470 tmp
= load_reg(s
, rn
);
9471 tmp2
= load_reg(s
, rm
);
9472 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
9473 tcg_temp_free_i32(tmp2
);
9474 store_reg(s
, rd
, tmp
);
9476 case 3: /* Other data processing. */
9477 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
9479 /* Saturating add/subtract. */
9480 tmp
= load_reg(s
, rn
);
9481 tmp2
= load_reg(s
, rm
);
9483 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
9485 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
9487 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
9488 tcg_temp_free_i32(tmp2
);
9490 tmp
= load_reg(s
, rn
);
9492 case 0x0a: /* rbit */
9493 gen_helper_rbit(tmp
, tmp
);
9495 case 0x08: /* rev */
9496 tcg_gen_bswap32_i32(tmp
, tmp
);
9498 case 0x09: /* rev16 */
9501 case 0x0b: /* revsh */
9504 case 0x10: /* sel */
9505 tmp2
= load_reg(s
, rm
);
9506 tmp3
= tcg_temp_new_i32();
9507 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
9508 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
9509 tcg_temp_free_i32(tmp3
);
9510 tcg_temp_free_i32(tmp2
);
9512 case 0x18: /* clz */
9513 gen_helper_clz(tmp
, tmp
);
9523 uint32_t sz
= op
& 0x3;
9524 uint32_t c
= op
& 0x8;
9526 if (!arm_feature(env
, ARM_FEATURE_CRC
)) {
9530 tmp2
= load_reg(s
, rm
);
9532 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
9533 } else if (sz
== 1) {
9534 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
9536 tmp3
= tcg_const_i32(1 << sz
);
9538 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
9540 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
9542 tcg_temp_free_i32(tmp2
);
9543 tcg_temp_free_i32(tmp3
);
9550 store_reg(s
, rd
, tmp
);
9552 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
9553 op
= (insn
>> 4) & 0xf;
9554 tmp
= load_reg(s
, rn
);
9555 tmp2
= load_reg(s
, rm
);
9556 switch ((insn
>> 20) & 7) {
9557 case 0: /* 32 x 32 -> 32 */
9558 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
9559 tcg_temp_free_i32(tmp2
);
9561 tmp2
= load_reg(s
, rs
);
9563 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
9565 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9566 tcg_temp_free_i32(tmp2
);
9569 case 1: /* 16 x 16 -> 32 */
9570 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
9571 tcg_temp_free_i32(tmp2
);
9573 tmp2
= load_reg(s
, rs
);
9574 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9575 tcg_temp_free_i32(tmp2
);
9578 case 2: /* Dual multiply add. */
9579 case 4: /* Dual multiply subtract. */
9581 gen_swap_half(tmp2
);
9582 gen_smul_dual(tmp
, tmp2
);
9583 if (insn
& (1 << 22)) {
9584 /* This subtraction cannot overflow. */
9585 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9587 /* This addition cannot overflow 32 bits;
9588 * however it may overflow considered as a signed
9589 * operation, in which case we must set the Q flag.
9591 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9593 tcg_temp_free_i32(tmp2
);
9596 tmp2
= load_reg(s
, rs
);
9597 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9598 tcg_temp_free_i32(tmp2
);
9601 case 3: /* 32 * 16 -> 32msb */
9603 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
9606 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9607 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
9608 tmp
= tcg_temp_new_i32();
9609 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
9610 tcg_temp_free_i64(tmp64
);
9613 tmp2
= load_reg(s
, rs
);
9614 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9615 tcg_temp_free_i32(tmp2
);
9618 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9619 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9621 tmp
= load_reg(s
, rs
);
9622 if (insn
& (1 << 20)) {
9623 tmp64
= gen_addq_msw(tmp64
, tmp
);
9625 tmp64
= gen_subq_msw(tmp64
, tmp
);
9628 if (insn
& (1 << 4)) {
9629 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
9631 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
9632 tmp
= tcg_temp_new_i32();
9633 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
9634 tcg_temp_free_i64(tmp64
);
9636 case 7: /* Unsigned sum of absolute differences. */
9637 gen_helper_usad8(tmp
, tmp
, tmp2
);
9638 tcg_temp_free_i32(tmp2
);
9640 tmp2
= load_reg(s
, rs
);
9641 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9642 tcg_temp_free_i32(tmp2
);
9646 store_reg(s
, rd
, tmp
);
9648 case 6: case 7: /* 64-bit multiply, Divide. */
9649 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
9650 tmp
= load_reg(s
, rn
);
9651 tmp2
= load_reg(s
, rm
);
9652 if ((op
& 0x50) == 0x10) {
9654 if (!arm_feature(env
, ARM_FEATURE_THUMB_DIV
)) {
9658 gen_helper_udiv(tmp
, tmp
, tmp2
);
9660 gen_helper_sdiv(tmp
, tmp
, tmp2
);
9661 tcg_temp_free_i32(tmp2
);
9662 store_reg(s
, rd
, tmp
);
9663 } else if ((op
& 0xe) == 0xc) {
9664 /* Dual multiply accumulate long. */
9666 gen_swap_half(tmp2
);
9667 gen_smul_dual(tmp
, tmp2
);
9669 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9671 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9673 tcg_temp_free_i32(tmp2
);
9675 tmp64
= tcg_temp_new_i64();
9676 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9677 tcg_temp_free_i32(tmp
);
9678 gen_addq(s
, tmp64
, rs
, rd
);
9679 gen_storeq_reg(s
, rs
, rd
, tmp64
);
9680 tcg_temp_free_i64(tmp64
);
9683 /* Unsigned 64-bit multiply */
9684 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
9688 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
9689 tcg_temp_free_i32(tmp2
);
9690 tmp64
= tcg_temp_new_i64();
9691 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9692 tcg_temp_free_i32(tmp
);
9694 /* Signed 64-bit multiply */
9695 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9700 gen_addq_lo(s
, tmp64
, rs
);
9701 gen_addq_lo(s
, tmp64
, rd
);
9702 } else if (op
& 0x40) {
9703 /* 64-bit accumulate. */
9704 gen_addq(s
, tmp64
, rs
, rd
);
9706 gen_storeq_reg(s
, rs
, rd
, tmp64
);
9707 tcg_temp_free_i64(tmp64
);
9712 case 6: case 7: case 14: case 15:
9714 if (((insn
>> 24) & 3) == 3) {
9715 /* Translate into the equivalent ARM encoding. */
9716 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
9717 if (disas_neon_data_insn(env
, s
, insn
))
9719 } else if (((insn
>> 8) & 0xe) == 10) {
9720 if (disas_vfp_insn(env
, s
, insn
)) {
9724 if (insn
& (1 << 28))
9726 if (disas_coproc_insn (env
, s
, insn
))
9730 case 8: case 9: case 10: case 11:
9731 if (insn
& (1 << 15)) {
9732 /* Branches, misc control. */
9733 if (insn
& 0x5000) {
9734 /* Unconditional branch. */
9735 /* signextend(hw1[10:0]) -> offset[:12]. */
9736 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
9737 /* hw1[10:0] -> offset[11:1]. */
9738 offset
|= (insn
& 0x7ff) << 1;
9739 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9740 offset[24:22] already have the same value because of the
9741 sign extension above. */
9742 offset
^= ((~insn
) & (1 << 13)) << 10;
9743 offset
^= ((~insn
) & (1 << 11)) << 11;
9745 if (insn
& (1 << 14)) {
9746 /* Branch and link. */
9747 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
9751 if (insn
& (1 << 12)) {
9756 offset
&= ~(uint32_t)2;
9757 /* thumb2 bx, no need to check */
9758 gen_bx_im(s
, offset
);
9760 } else if (((insn
>> 23) & 7) == 7) {
9762 if (insn
& (1 << 13))
9765 if (insn
& (1 << 26)) {
9766 if (!(insn
& (1 << 20))) {
9767 /* Hypervisor call (v7) */
9768 int imm16
= extract32(insn
, 16, 4) << 12
9769 | extract32(insn
, 0, 12);
9776 /* Secure monitor call (v6+) */
9784 op
= (insn
>> 20) & 7;
9786 case 0: /* msr cpsr. */
9788 tmp
= load_reg(s
, rn
);
9789 addr
= tcg_const_i32(insn
& 0xff);
9790 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9791 tcg_temp_free_i32(addr
);
9792 tcg_temp_free_i32(tmp
);
9797 case 1: /* msr spsr. */
9800 tmp
= load_reg(s
, rn
);
9802 msr_mask(env
, s
, (insn
>> 8) & 0xf, op
== 1),
9806 case 2: /* cps, nop-hint. */
9807 if (((insn
>> 8) & 7) == 0) {
9808 gen_nop_hint(s
, insn
& 0xff);
9810 /* Implemented as NOP in user mode. */
9815 if (insn
& (1 << 10)) {
9816 if (insn
& (1 << 7))
9818 if (insn
& (1 << 6))
9820 if (insn
& (1 << 5))
9822 if (insn
& (1 << 9))
9823 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
9825 if (insn
& (1 << 8)) {
9827 imm
|= (insn
& 0x1f);
9830 gen_set_psr_im(s
, offset
, 0, imm
);
9833 case 3: /* Special control operations. */
9835 op
= (insn
>> 4) & 0xf;
9843 /* These execute as NOPs. */
9850 /* Trivial implementation equivalent to bx. */
9851 tmp
= load_reg(s
, rn
);
9854 case 5: /* Exception return. */
9858 if (rn
!= 14 || rd
!= 15) {
9861 tmp
= load_reg(s
, rn
);
9862 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
9863 gen_exception_return(s
, tmp
);
9865 case 6: /* mrs cpsr. */
9866 tmp
= tcg_temp_new_i32();
9868 addr
= tcg_const_i32(insn
& 0xff);
9869 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
9870 tcg_temp_free_i32(addr
);
9872 gen_helper_cpsr_read(tmp
, cpu_env
);
9874 store_reg(s
, rd
, tmp
);
9876 case 7: /* mrs spsr. */
9877 /* Not accessible in user mode. */
9878 if (IS_USER(s
) || IS_M(env
))
9880 tmp
= load_cpu_field(spsr
);
9881 store_reg(s
, rd
, tmp
);
9886 /* Conditional branch. */
9887 op
= (insn
>> 22) & 0xf;
9888 /* Generate a conditional jump to next instruction. */
9889 s
->condlabel
= gen_new_label();
9890 arm_gen_test_cc(op
^ 1, s
->condlabel
);
9893 /* offset[11:1] = insn[10:0] */
9894 offset
= (insn
& 0x7ff) << 1;
9895 /* offset[17:12] = insn[21:16]. */
9896 offset
|= (insn
& 0x003f0000) >> 4;
9897 /* offset[31:20] = insn[26]. */
9898 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
9899 /* offset[18] = insn[13]. */
9900 offset
|= (insn
& (1 << 13)) << 5;
9901 /* offset[19] = insn[11]. */
9902 offset
|= (insn
& (1 << 11)) << 8;
9904 /* jump to the offset */
9905 gen_jmp(s
, s
->pc
+ offset
);
9908 /* Data processing immediate. */
9909 if (insn
& (1 << 25)) {
9910 if (insn
& (1 << 24)) {
9911 if (insn
& (1 << 20))
9913 /* Bitfield/Saturate. */
9914 op
= (insn
>> 21) & 7;
9916 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
9918 tmp
= tcg_temp_new_i32();
9919 tcg_gen_movi_i32(tmp
, 0);
9921 tmp
= load_reg(s
, rn
);
9924 case 2: /* Signed bitfield extract. */
9926 if (shift
+ imm
> 32)
9929 gen_sbfx(tmp
, shift
, imm
);
9931 case 6: /* Unsigned bitfield extract. */
9933 if (shift
+ imm
> 32)
9936 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
9938 case 3: /* Bitfield insert/clear. */
9941 imm
= imm
+ 1 - shift
;
9943 tmp2
= load_reg(s
, rd
);
9944 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
9945 tcg_temp_free_i32(tmp2
);
9950 default: /* Saturate. */
9953 tcg_gen_sari_i32(tmp
, tmp
, shift
);
9955 tcg_gen_shli_i32(tmp
, tmp
, shift
);
9957 tmp2
= tcg_const_i32(imm
);
9960 if ((op
& 1) && shift
== 0)
9961 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
9963 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
9966 if ((op
& 1) && shift
== 0)
9967 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
9969 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
9971 tcg_temp_free_i32(tmp2
);
9974 store_reg(s
, rd
, tmp
);
9976 imm
= ((insn
& 0x04000000) >> 15)
9977 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
9978 if (insn
& (1 << 22)) {
9979 /* 16-bit immediate. */
9980 imm
|= (insn
>> 4) & 0xf000;
9981 if (insn
& (1 << 23)) {
9983 tmp
= load_reg(s
, rd
);
9984 tcg_gen_ext16u_i32(tmp
, tmp
);
9985 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
9988 tmp
= tcg_temp_new_i32();
9989 tcg_gen_movi_i32(tmp
, imm
);
9992 /* Add/sub 12-bit immediate. */
9994 offset
= s
->pc
& ~(uint32_t)3;
9995 if (insn
& (1 << 23))
9999 tmp
= tcg_temp_new_i32();
10000 tcg_gen_movi_i32(tmp
, offset
);
10002 tmp
= load_reg(s
, rn
);
10003 if (insn
& (1 << 23))
10004 tcg_gen_subi_i32(tmp
, tmp
, imm
);
10006 tcg_gen_addi_i32(tmp
, tmp
, imm
);
10009 store_reg(s
, rd
, tmp
);
10012 int shifter_out
= 0;
10013 /* modified 12-bit immediate. */
10014 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
10015 imm
= (insn
& 0xff);
10018 /* Nothing to do. */
10020 case 1: /* 00XY00XY */
10023 case 2: /* XY00XY00 */
10027 case 3: /* XYXYXYXY */
10031 default: /* Rotated constant. */
10032 shift
= (shift
<< 1) | (imm
>> 7);
10034 imm
= imm
<< (32 - shift
);
10038 tmp2
= tcg_temp_new_i32();
10039 tcg_gen_movi_i32(tmp2
, imm
);
10040 rn
= (insn
>> 16) & 0xf;
10042 tmp
= tcg_temp_new_i32();
10043 tcg_gen_movi_i32(tmp
, 0);
10045 tmp
= load_reg(s
, rn
);
10047 op
= (insn
>> 21) & 0xf;
10048 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
10049 shifter_out
, tmp
, tmp2
))
10051 tcg_temp_free_i32(tmp2
);
10052 rd
= (insn
>> 8) & 0xf;
10054 store_reg(s
, rd
, tmp
);
10056 tcg_temp_free_i32(tmp
);
10061 case 12: /* Load/store single data item. */
10066 if ((insn
& 0x01100000) == 0x01000000) {
10067 if (disas_neon_ls_insn(env
, s
, insn
))
10071 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
10073 if (!(insn
& (1 << 20))) {
10077 /* Byte or halfword load space with dest == r15 : memory hints.
10078 * Catch them early so we don't emit pointless addressing code.
10079 * This space is a mix of:
10080 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10081 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10083 * unallocated hints, which must be treated as NOPs
10084 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10085 * which is easiest for the decoding logic
10086 * Some space which must UNDEF
10088 int op1
= (insn
>> 23) & 3;
10089 int op2
= (insn
>> 6) & 0x3f;
10094 /* UNPREDICTABLE, unallocated hint or
10095 * PLD/PLDW/PLI (literal)
10100 return 0; /* PLD/PLDW/PLI or unallocated hint */
10102 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
10103 return 0; /* PLD/PLDW/PLI or unallocated hint */
10105 /* UNDEF space, or an UNPREDICTABLE */
10109 memidx
= get_mem_index(s
);
10111 addr
= tcg_temp_new_i32();
10113 /* s->pc has already been incremented by 4. */
10114 imm
= s
->pc
& 0xfffffffc;
10115 if (insn
& (1 << 23))
10116 imm
+= insn
& 0xfff;
10118 imm
-= insn
& 0xfff;
10119 tcg_gen_movi_i32(addr
, imm
);
10121 addr
= load_reg(s
, rn
);
10122 if (insn
& (1 << 23)) {
10123 /* Positive offset. */
10124 imm
= insn
& 0xfff;
10125 tcg_gen_addi_i32(addr
, addr
, imm
);
10128 switch ((insn
>> 8) & 0xf) {
10129 case 0x0: /* Shifted Register. */
10130 shift
= (insn
>> 4) & 0xf;
10132 tcg_temp_free_i32(addr
);
10135 tmp
= load_reg(s
, rm
);
10137 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10138 tcg_gen_add_i32(addr
, addr
, tmp
);
10139 tcg_temp_free_i32(tmp
);
10141 case 0xc: /* Negative offset. */
10142 tcg_gen_addi_i32(addr
, addr
, -imm
);
10144 case 0xe: /* User privilege. */
10145 tcg_gen_addi_i32(addr
, addr
, imm
);
10146 memidx
= MMU_USER_IDX
;
10148 case 0x9: /* Post-decrement. */
10150 /* Fall through. */
10151 case 0xb: /* Post-increment. */
10155 case 0xd: /* Pre-decrement. */
10157 /* Fall through. */
10158 case 0xf: /* Pre-increment. */
10159 tcg_gen_addi_i32(addr
, addr
, imm
);
10163 tcg_temp_free_i32(addr
);
10168 if (insn
& (1 << 20)) {
10170 tmp
= tcg_temp_new_i32();
10173 gen_aa32_ld8u(tmp
, addr
, memidx
);
10176 gen_aa32_ld8s(tmp
, addr
, memidx
);
10179 gen_aa32_ld16u(tmp
, addr
, memidx
);
10182 gen_aa32_ld16s(tmp
, addr
, memidx
);
10185 gen_aa32_ld32u(tmp
, addr
, memidx
);
10188 tcg_temp_free_i32(tmp
);
10189 tcg_temp_free_i32(addr
);
10195 store_reg(s
, rs
, tmp
);
10199 tmp
= load_reg(s
, rs
);
10202 gen_aa32_st8(tmp
, addr
, memidx
);
10205 gen_aa32_st16(tmp
, addr
, memidx
);
10208 gen_aa32_st32(tmp
, addr
, memidx
);
10211 tcg_temp_free_i32(tmp
);
10212 tcg_temp_free_i32(addr
);
10215 tcg_temp_free_i32(tmp
);
10218 tcg_gen_addi_i32(addr
, addr
, imm
);
10220 store_reg(s
, rn
, addr
);
10222 tcg_temp_free_i32(addr
);
10234 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
10236 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
10243 if (s
->condexec_mask
) {
10244 cond
= s
->condexec_cond
;
10245 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
10246 s
->condlabel
= gen_new_label();
10247 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
10252 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
10255 switch (insn
>> 12) {
10259 op
= (insn
>> 11) & 3;
10262 rn
= (insn
>> 3) & 7;
10263 tmp
= load_reg(s
, rn
);
10264 if (insn
& (1 << 10)) {
10266 tmp2
= tcg_temp_new_i32();
10267 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
10270 rm
= (insn
>> 6) & 7;
10271 tmp2
= load_reg(s
, rm
);
10273 if (insn
& (1 << 9)) {
10274 if (s
->condexec_mask
)
10275 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10277 gen_sub_CC(tmp
, tmp
, tmp2
);
10279 if (s
->condexec_mask
)
10280 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10282 gen_add_CC(tmp
, tmp
, tmp2
);
10284 tcg_temp_free_i32(tmp2
);
10285 store_reg(s
, rd
, tmp
);
10287 /* shift immediate */
10288 rm
= (insn
>> 3) & 7;
10289 shift
= (insn
>> 6) & 0x1f;
10290 tmp
= load_reg(s
, rm
);
10291 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
10292 if (!s
->condexec_mask
)
10294 store_reg(s
, rd
, tmp
);
10298 /* arithmetic large immediate */
10299 op
= (insn
>> 11) & 3;
10300 rd
= (insn
>> 8) & 0x7;
10301 if (op
== 0) { /* mov */
10302 tmp
= tcg_temp_new_i32();
10303 tcg_gen_movi_i32(tmp
, insn
& 0xff);
10304 if (!s
->condexec_mask
)
10306 store_reg(s
, rd
, tmp
);
10308 tmp
= load_reg(s
, rd
);
10309 tmp2
= tcg_temp_new_i32();
10310 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
10313 gen_sub_CC(tmp
, tmp
, tmp2
);
10314 tcg_temp_free_i32(tmp
);
10315 tcg_temp_free_i32(tmp2
);
10318 if (s
->condexec_mask
)
10319 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10321 gen_add_CC(tmp
, tmp
, tmp2
);
10322 tcg_temp_free_i32(tmp2
);
10323 store_reg(s
, rd
, tmp
);
10326 if (s
->condexec_mask
)
10327 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10329 gen_sub_CC(tmp
, tmp
, tmp2
);
10330 tcg_temp_free_i32(tmp2
);
10331 store_reg(s
, rd
, tmp
);
10337 if (insn
& (1 << 11)) {
10338 rd
= (insn
>> 8) & 7;
10339 /* load pc-relative. Bit 1 of PC is ignored. */
10340 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
10341 val
&= ~(uint32_t)2;
10342 addr
= tcg_temp_new_i32();
10343 tcg_gen_movi_i32(addr
, val
);
10344 tmp
= tcg_temp_new_i32();
10345 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10346 tcg_temp_free_i32(addr
);
10347 store_reg(s
, rd
, tmp
);
10350 if (insn
& (1 << 10)) {
10351 /* data processing extended or blx */
10352 rd
= (insn
& 7) | ((insn
>> 4) & 8);
10353 rm
= (insn
>> 3) & 0xf;
10354 op
= (insn
>> 8) & 3;
10357 tmp
= load_reg(s
, rd
);
10358 tmp2
= load_reg(s
, rm
);
10359 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10360 tcg_temp_free_i32(tmp2
);
10361 store_reg(s
, rd
, tmp
);
10364 tmp
= load_reg(s
, rd
);
10365 tmp2
= load_reg(s
, rm
);
10366 gen_sub_CC(tmp
, tmp
, tmp2
);
10367 tcg_temp_free_i32(tmp2
);
10368 tcg_temp_free_i32(tmp
);
10370 case 2: /* mov/cpy */
10371 tmp
= load_reg(s
, rm
);
10372 store_reg(s
, rd
, tmp
);
10374 case 3:/* branch [and link] exchange thumb register */
10375 tmp
= load_reg(s
, rm
);
10376 if (insn
& (1 << 7)) {
10378 val
= (uint32_t)s
->pc
| 1;
10379 tmp2
= tcg_temp_new_i32();
10380 tcg_gen_movi_i32(tmp2
, val
);
10381 store_reg(s
, 14, tmp2
);
10383 /* already thumb, no need to check */
10390 /* data processing register */
10392 rm
= (insn
>> 3) & 7;
10393 op
= (insn
>> 6) & 0xf;
10394 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
10395 /* the shift/rotate ops want the operands backwards */
10404 if (op
== 9) { /* neg */
10405 tmp
= tcg_temp_new_i32();
10406 tcg_gen_movi_i32(tmp
, 0);
10407 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
10408 tmp
= load_reg(s
, rd
);
10410 TCGV_UNUSED_I32(tmp
);
10413 tmp2
= load_reg(s
, rm
);
10415 case 0x0: /* and */
10416 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
10417 if (!s
->condexec_mask
)
10420 case 0x1: /* eor */
10421 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
10422 if (!s
->condexec_mask
)
10425 case 0x2: /* lsl */
10426 if (s
->condexec_mask
) {
10427 gen_shl(tmp2
, tmp2
, tmp
);
10429 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10430 gen_logic_CC(tmp2
);
10433 case 0x3: /* lsr */
10434 if (s
->condexec_mask
) {
10435 gen_shr(tmp2
, tmp2
, tmp
);
10437 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10438 gen_logic_CC(tmp2
);
10441 case 0x4: /* asr */
10442 if (s
->condexec_mask
) {
10443 gen_sar(tmp2
, tmp2
, tmp
);
10445 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10446 gen_logic_CC(tmp2
);
10449 case 0x5: /* adc */
10450 if (s
->condexec_mask
) {
10451 gen_adc(tmp
, tmp2
);
10453 gen_adc_CC(tmp
, tmp
, tmp2
);
10456 case 0x6: /* sbc */
10457 if (s
->condexec_mask
) {
10458 gen_sub_carry(tmp
, tmp
, tmp2
);
10460 gen_sbc_CC(tmp
, tmp
, tmp2
);
10463 case 0x7: /* ror */
10464 if (s
->condexec_mask
) {
10465 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
10466 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
10468 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10469 gen_logic_CC(tmp2
);
10472 case 0x8: /* tst */
10473 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
10477 case 0x9: /* neg */
10478 if (s
->condexec_mask
)
10479 tcg_gen_neg_i32(tmp
, tmp2
);
10481 gen_sub_CC(tmp
, tmp
, tmp2
);
10483 case 0xa: /* cmp */
10484 gen_sub_CC(tmp
, tmp
, tmp2
);
10487 case 0xb: /* cmn */
10488 gen_add_CC(tmp
, tmp
, tmp2
);
10491 case 0xc: /* orr */
10492 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
10493 if (!s
->condexec_mask
)
10496 case 0xd: /* mul */
10497 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
10498 if (!s
->condexec_mask
)
10501 case 0xe: /* bic */
10502 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
10503 if (!s
->condexec_mask
)
10506 case 0xf: /* mvn */
10507 tcg_gen_not_i32(tmp2
, tmp2
);
10508 if (!s
->condexec_mask
)
10509 gen_logic_CC(tmp2
);
10516 store_reg(s
, rm
, tmp2
);
10518 tcg_temp_free_i32(tmp
);
10520 store_reg(s
, rd
, tmp
);
10521 tcg_temp_free_i32(tmp2
);
10524 tcg_temp_free_i32(tmp
);
10525 tcg_temp_free_i32(tmp2
);
10530 /* load/store register offset. */
10532 rn
= (insn
>> 3) & 7;
10533 rm
= (insn
>> 6) & 7;
10534 op
= (insn
>> 9) & 7;
10535 addr
= load_reg(s
, rn
);
10536 tmp
= load_reg(s
, rm
);
10537 tcg_gen_add_i32(addr
, addr
, tmp
);
10538 tcg_temp_free_i32(tmp
);
10540 if (op
< 3) { /* store */
10541 tmp
= load_reg(s
, rd
);
10543 tmp
= tcg_temp_new_i32();
10548 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10551 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
10554 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
10556 case 3: /* ldrsb */
10557 gen_aa32_ld8s(tmp
, addr
, get_mem_index(s
));
10560 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10563 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
10566 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
10568 case 7: /* ldrsh */
10569 gen_aa32_ld16s(tmp
, addr
, get_mem_index(s
));
10572 if (op
>= 3) { /* load */
10573 store_reg(s
, rd
, tmp
);
10575 tcg_temp_free_i32(tmp
);
10577 tcg_temp_free_i32(addr
);
10581 /* load/store word immediate offset */
10583 rn
= (insn
>> 3) & 7;
10584 addr
= load_reg(s
, rn
);
10585 val
= (insn
>> 4) & 0x7c;
10586 tcg_gen_addi_i32(addr
, addr
, val
);
10588 if (insn
& (1 << 11)) {
10590 tmp
= tcg_temp_new_i32();
10591 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10592 store_reg(s
, rd
, tmp
);
10595 tmp
= load_reg(s
, rd
);
10596 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10597 tcg_temp_free_i32(tmp
);
10599 tcg_temp_free_i32(addr
);
10603 /* load/store byte immediate offset */
10605 rn
= (insn
>> 3) & 7;
10606 addr
= load_reg(s
, rn
);
10607 val
= (insn
>> 6) & 0x1f;
10608 tcg_gen_addi_i32(addr
, addr
, val
);
10610 if (insn
& (1 << 11)) {
10612 tmp
= tcg_temp_new_i32();
10613 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
10614 store_reg(s
, rd
, tmp
);
10617 tmp
= load_reg(s
, rd
);
10618 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
10619 tcg_temp_free_i32(tmp
);
10621 tcg_temp_free_i32(addr
);
10625 /* load/store halfword immediate offset */
10627 rn
= (insn
>> 3) & 7;
10628 addr
= load_reg(s
, rn
);
10629 val
= (insn
>> 5) & 0x3e;
10630 tcg_gen_addi_i32(addr
, addr
, val
);
10632 if (insn
& (1 << 11)) {
10634 tmp
= tcg_temp_new_i32();
10635 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
10636 store_reg(s
, rd
, tmp
);
10639 tmp
= load_reg(s
, rd
);
10640 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
10641 tcg_temp_free_i32(tmp
);
10643 tcg_temp_free_i32(addr
);
10647 /* load/store from stack */
10648 rd
= (insn
>> 8) & 7;
10649 addr
= load_reg(s
, 13);
10650 val
= (insn
& 0xff) * 4;
10651 tcg_gen_addi_i32(addr
, addr
, val
);
10653 if (insn
& (1 << 11)) {
10655 tmp
= tcg_temp_new_i32();
10656 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10657 store_reg(s
, rd
, tmp
);
10660 tmp
= load_reg(s
, rd
);
10661 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10662 tcg_temp_free_i32(tmp
);
10664 tcg_temp_free_i32(addr
);
10668 /* add to high reg */
10669 rd
= (insn
>> 8) & 7;
10670 if (insn
& (1 << 11)) {
10672 tmp
= load_reg(s
, 13);
10674 /* PC. bit 1 is ignored. */
10675 tmp
= tcg_temp_new_i32();
10676 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
10678 val
= (insn
& 0xff) * 4;
10679 tcg_gen_addi_i32(tmp
, tmp
, val
);
10680 store_reg(s
, rd
, tmp
);
10685 op
= (insn
>> 8) & 0xf;
10688 /* adjust stack pointer */
10689 tmp
= load_reg(s
, 13);
10690 val
= (insn
& 0x7f) * 4;
10691 if (insn
& (1 << 7))
10692 val
= -(int32_t)val
;
10693 tcg_gen_addi_i32(tmp
, tmp
, val
);
10694 store_reg(s
, 13, tmp
);
10697 case 2: /* sign/zero extend. */
10700 rm
= (insn
>> 3) & 7;
10701 tmp
= load_reg(s
, rm
);
10702 switch ((insn
>> 6) & 3) {
10703 case 0: gen_sxth(tmp
); break;
10704 case 1: gen_sxtb(tmp
); break;
10705 case 2: gen_uxth(tmp
); break;
10706 case 3: gen_uxtb(tmp
); break;
10708 store_reg(s
, rd
, tmp
);
10710 case 4: case 5: case 0xc: case 0xd:
10712 addr
= load_reg(s
, 13);
10713 if (insn
& (1 << 8))
10717 for (i
= 0; i
< 8; i
++) {
10718 if (insn
& (1 << i
))
10721 if ((insn
& (1 << 11)) == 0) {
10722 tcg_gen_addi_i32(addr
, addr
, -offset
);
10724 for (i
= 0; i
< 8; i
++) {
10725 if (insn
& (1 << i
)) {
10726 if (insn
& (1 << 11)) {
10728 tmp
= tcg_temp_new_i32();
10729 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10730 store_reg(s
, i
, tmp
);
10733 tmp
= load_reg(s
, i
);
10734 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10735 tcg_temp_free_i32(tmp
);
10737 /* advance to the next address. */
10738 tcg_gen_addi_i32(addr
, addr
, 4);
10741 TCGV_UNUSED_I32(tmp
);
10742 if (insn
& (1 << 8)) {
10743 if (insn
& (1 << 11)) {
10745 tmp
= tcg_temp_new_i32();
10746 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10747 /* don't set the pc until the rest of the instruction
10751 tmp
= load_reg(s
, 14);
10752 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10753 tcg_temp_free_i32(tmp
);
10755 tcg_gen_addi_i32(addr
, addr
, 4);
10757 if ((insn
& (1 << 11)) == 0) {
10758 tcg_gen_addi_i32(addr
, addr
, -offset
);
10760 /* write back the new stack pointer */
10761 store_reg(s
, 13, addr
);
10762 /* set the new PC value */
10763 if ((insn
& 0x0900) == 0x0900) {
10764 store_reg_from_load(env
, s
, 15, tmp
);
10768 case 1: case 3: case 9: case 11: /* czb */
10770 tmp
= load_reg(s
, rm
);
10771 s
->condlabel
= gen_new_label();
10773 if (insn
& (1 << 11))
10774 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
10776 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
10777 tcg_temp_free_i32(tmp
);
10778 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
10779 val
= (uint32_t)s
->pc
+ 2;
10784 case 15: /* IT, nop-hint. */
10785 if ((insn
& 0xf) == 0) {
10786 gen_nop_hint(s
, (insn
>> 4) & 0xf);
10790 s
->condexec_cond
= (insn
>> 4) & 0xe;
10791 s
->condexec_mask
= insn
& 0x1f;
10792 /* No actual code generated for this insn, just setup state. */
10795 case 0xe: /* bkpt */
10797 int imm8
= extract32(insn
, 0, 8);
10799 gen_exception_insn(s
, 2, EXCP_BKPT
, syn_aa32_bkpt(imm8
, true));
10803 case 0xa: /* rev */
10805 rn
= (insn
>> 3) & 0x7;
10807 tmp
= load_reg(s
, rn
);
10808 switch ((insn
>> 6) & 3) {
10809 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
10810 case 1: gen_rev16(tmp
); break;
10811 case 3: gen_revsh(tmp
); break;
10812 default: goto illegal_op
;
10814 store_reg(s
, rd
, tmp
);
10818 switch ((insn
>> 5) & 7) {
10822 if (((insn
>> 3) & 1) != s
->bswap_code
) {
10823 /* Dynamic endianness switching not implemented. */
10824 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
10835 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
10838 addr
= tcg_const_i32(19);
10839 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10840 tcg_temp_free_i32(addr
);
10844 addr
= tcg_const_i32(16);
10845 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10846 tcg_temp_free_i32(addr
);
10848 tcg_temp_free_i32(tmp
);
10851 if (insn
& (1 << 4)) {
10852 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
10856 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
10871 /* load/store multiple */
10872 TCGv_i32 loaded_var
;
10873 TCGV_UNUSED_I32(loaded_var
);
10874 rn
= (insn
>> 8) & 0x7;
10875 addr
= load_reg(s
, rn
);
10876 for (i
= 0; i
< 8; i
++) {
10877 if (insn
& (1 << i
)) {
10878 if (insn
& (1 << 11)) {
10880 tmp
= tcg_temp_new_i32();
10881 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10885 store_reg(s
, i
, tmp
);
10889 tmp
= load_reg(s
, i
);
10890 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10891 tcg_temp_free_i32(tmp
);
10893 /* advance to the next address */
10894 tcg_gen_addi_i32(addr
, addr
, 4);
10897 if ((insn
& (1 << rn
)) == 0) {
10898 /* base reg not in list: base register writeback */
10899 store_reg(s
, rn
, addr
);
10901 /* base reg in list: if load, complete it now */
10902 if (insn
& (1 << 11)) {
10903 store_reg(s
, rn
, loaded_var
);
10905 tcg_temp_free_i32(addr
);
10910 /* conditional branch or swi */
10911 cond
= (insn
>> 8) & 0xf;
10917 gen_set_pc_im(s
, s
->pc
);
10918 s
->svc_imm
= extract32(insn
, 0, 8);
10919 s
->is_jmp
= DISAS_SWI
;
10922 /* generate a conditional jump to next instruction */
10923 s
->condlabel
= gen_new_label();
10924 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
10927 /* jump to the offset */
10928 val
= (uint32_t)s
->pc
+ 2;
10929 offset
= ((int32_t)insn
<< 24) >> 24;
10930 val
+= offset
<< 1;
10935 if (insn
& (1 << 11)) {
10936 if (disas_thumb2_insn(env
, s
, insn
))
10940 /* unconditional branch */
10941 val
= (uint32_t)s
->pc
;
10942 offset
= ((int32_t)insn
<< 21) >> 21;
10943 val
+= (offset
<< 1) + 2;
10948 if (disas_thumb2_insn(env
, s
, insn
))
10954 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized());
10958 gen_exception_insn(s
, 2, EXCP_UDEF
, syn_uncategorized());
10961 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
10962 basic block 'tb'. If search_pc is TRUE, also generate PC
10963 information for each intermediate instruction. */
10964 static inline void gen_intermediate_code_internal(ARMCPU
*cpu
,
10965 TranslationBlock
*tb
,
10968 CPUState
*cs
= CPU(cpu
);
10969 CPUARMState
*env
= &cpu
->env
;
10970 DisasContext dc1
, *dc
= &dc1
;
10972 uint16_t *gen_opc_end
;
10974 target_ulong pc_start
;
10975 target_ulong next_page_start
;
10979 /* generate intermediate code */
10981 /* The A64 decoder has its own top level loop, because it doesn't need
10982 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
10984 if (ARM_TBFLAG_AARCH64_STATE(tb
->flags
)) {
10985 gen_intermediate_code_internal_a64(cpu
, tb
, search_pc
);
10993 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
10995 dc
->is_jmp
= DISAS_NEXT
;
10997 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
11001 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
11002 dc
->bswap_code
= ARM_TBFLAG_BSWAP_CODE(tb
->flags
);
11003 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
11004 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
11005 #if !defined(CONFIG_USER_ONLY)
11006 dc
->user
= (ARM_TBFLAG_PRIV(tb
->flags
) == 0);
11008 dc
->cpacr_fpen
= ARM_TBFLAG_CPACR_FPEN(tb
->flags
);
11009 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
11010 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
11011 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
11012 dc
->c15_cpar
= ARM_TBFLAG_XSCALE_CPAR(tb
->flags
);
11013 dc
->cp_regs
= cpu
->cp_regs
;
11014 dc
->current_el
= arm_current_el(env
);
11015 dc
->features
= env
->features
;
11017 /* Single step state. The code-generation logic here is:
11019 * generate code with no special handling for single-stepping (except
11020 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11021 * this happens anyway because those changes are all system register or
11023 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11024 * emit code for one insn
11025 * emit code to clear PSTATE.SS
11026 * emit code to generate software step exception for completed step
11027 * end TB (as usual for having generated an exception)
11028 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11029 * emit code to generate a software step exception
11032 dc
->ss_active
= ARM_TBFLAG_SS_ACTIVE(tb
->flags
);
11033 dc
->pstate_ss
= ARM_TBFLAG_PSTATE_SS(tb
->flags
);
11034 dc
->is_ldex
= false;
11035 dc
->ss_same_el
= false; /* Can't be true since EL_d must be AArch64 */
11037 cpu_F0s
= tcg_temp_new_i32();
11038 cpu_F1s
= tcg_temp_new_i32();
11039 cpu_F0d
= tcg_temp_new_i64();
11040 cpu_F1d
= tcg_temp_new_i64();
11043 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11044 cpu_M0
= tcg_temp_new_i64();
11045 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
11048 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
11049 if (max_insns
== 0)
11050 max_insns
= CF_COUNT_MASK
;
11054 tcg_clear_temp_count();
11056 /* A note on handling of the condexec (IT) bits:
11058 * We want to avoid the overhead of having to write the updated condexec
11059 * bits back to the CPUARMState for every instruction in an IT block. So:
11060 * (1) if the condexec bits are not already zero then we write
11061 * zero back into the CPUARMState now. This avoids complications trying
11062 * to do it at the end of the block. (For example if we don't do this
11063 * it's hard to identify whether we can safely skip writing condexec
11064 * at the end of the TB, which we definitely want to do for the case
11065 * where a TB doesn't do anything with the IT state at all.)
11066 * (2) if we are going to leave the TB then we call gen_set_condexec()
11067 * which will write the correct value into CPUARMState if zero is wrong.
11068 * This is done both for leaving the TB at the end, and for leaving
11069 * it because of an exception we know will happen, which is done in
11070 * gen_exception_insn(). The latter is necessary because we need to
11071 * leave the TB with the PC/IT state just prior to execution of the
11072 * instruction which caused the exception.
11073 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11074 * then the CPUARMState will be wrong and we need to reset it.
11075 * This is handled in the same way as restoration of the
11076 * PC in these situations: we will be called again with search_pc=1
11077 * and generate a mapping of the condexec bits for each PC in
11078 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
11079 * this to restore the condexec bits.
11081 * Note that there are no instructions which can read the condexec
11082 * bits, and none which can write non-static values to them, so
11083 * we don't need to care about whether CPUARMState is correct in the
11087 /* Reset the conditional execution bits immediately. This avoids
11088 complications trying to do it at the end of the block. */
11089 if (dc
->condexec_mask
|| dc
->condexec_cond
)
11091 TCGv_i32 tmp
= tcg_temp_new_i32();
11092 tcg_gen_movi_i32(tmp
, 0);
11093 store_cpu_field(tmp
, condexec_bits
);
11096 #ifdef CONFIG_USER_ONLY
11097 /* Intercept jump to the magic kernel page. */
11098 if (dc
->pc
>= 0xffff0000) {
11099 /* We always get here via a jump, so know we are not in a
11100 conditional execution block. */
11101 gen_exception_internal(EXCP_KERNEL_TRAP
);
11102 dc
->is_jmp
= DISAS_UPDATE
;
11106 if (dc
->pc
>= 0xfffffff0 && IS_M(env
)) {
11107 /* We always get here via a jump, so know we are not in a
11108 conditional execution block. */
11109 gen_exception_internal(EXCP_EXCEPTION_EXIT
);
11110 dc
->is_jmp
= DISAS_UPDATE
;
11115 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
11116 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
11117 if (bp
->pc
== dc
->pc
) {
11118 gen_exception_internal_insn(dc
, 0, EXCP_DEBUG
);
11119 /* Advance PC so that clearing the breakpoint will
11120 invalidate this TB. */
11122 goto done_generating
;
11127 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
11131 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
11133 tcg_ctx
.gen_opc_pc
[lj
] = dc
->pc
;
11134 gen_opc_condexec_bits
[lj
] = (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1);
11135 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
11136 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
11139 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
11142 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
11143 tcg_gen_debug_insn_start(dc
->pc
);
11146 if (dc
->ss_active
&& !dc
->pstate_ss
) {
11147 /* Singlestep state is Active-pending.
11148 * If we're in this state at the start of a TB then either
11149 * a) we just took an exception to an EL which is being debugged
11150 * and this is the first insn in the exception handler
11151 * b) debug exceptions were masked and we just unmasked them
11152 * without changing EL (eg by clearing PSTATE.D)
11153 * In either case we're going to take a swstep exception in the
11154 * "did not step an insn" case, and so the syndrome ISV and EX
11155 * bits should be zero.
11157 assert(num_insns
== 0);
11158 gen_exception(EXCP_UDEF
, syn_swstep(dc
->ss_same_el
, 0, 0));
11159 goto done_generating
;
11163 disas_thumb_insn(env
, dc
);
11164 if (dc
->condexec_mask
) {
11165 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
11166 | ((dc
->condexec_mask
>> 4) & 1);
11167 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
11168 if (dc
->condexec_mask
== 0) {
11169 dc
->condexec_cond
= 0;
11173 disas_arm_insn(env
, dc
);
11176 if (dc
->condjmp
&& !dc
->is_jmp
) {
11177 gen_set_label(dc
->condlabel
);
11181 if (tcg_check_temp_count()) {
11182 fprintf(stderr
, "TCG temporary leak before "TARGET_FMT_lx
"\n",
11186 /* Translation stops when a conditional branch is encountered.
11187 * Otherwise the subsequent code could get translated several times.
11188 * Also stop translation when a page boundary is reached. This
11189 * ensures prefetch aborts occur at the right place. */
11191 } while (!dc
->is_jmp
&& tcg_ctx
.gen_opc_ptr
< gen_opc_end
&&
11192 !cs
->singlestep_enabled
&&
11195 dc
->pc
< next_page_start
&&
11196 num_insns
< max_insns
);
11198 if (tb
->cflags
& CF_LAST_IO
) {
11200 /* FIXME: This can theoretically happen with self-modifying
11202 cpu_abort(cs
, "IO on conditional branch instruction");
11207 /* At this stage dc->condjmp will only be set when the skipped
11208 instruction was a conditional branch or trap, and the PC has
11209 already been written. */
11210 if (unlikely(cs
->singlestep_enabled
|| dc
->ss_active
)) {
11211 /* Make sure the pc is updated, and raise a debug exception. */
11213 gen_set_condexec(dc
);
11214 if (dc
->is_jmp
== DISAS_SWI
) {
11215 gen_ss_advance(dc
);
11216 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
));
11217 } else if (dc
->is_jmp
== DISAS_HVC
) {
11218 gen_ss_advance(dc
);
11219 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
));
11220 } else if (dc
->is_jmp
== DISAS_SMC
) {
11221 gen_ss_advance(dc
);
11222 gen_exception(EXCP_SMC
, syn_aa32_smc());
11223 } else if (dc
->ss_active
) {
11224 gen_step_complete_exception(dc
);
11226 gen_exception_internal(EXCP_DEBUG
);
11228 gen_set_label(dc
->condlabel
);
11230 if (dc
->condjmp
|| !dc
->is_jmp
) {
11231 gen_set_pc_im(dc
, dc
->pc
);
11234 gen_set_condexec(dc
);
11235 if (dc
->is_jmp
== DISAS_SWI
&& !dc
->condjmp
) {
11236 gen_ss_advance(dc
);
11237 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
));
11238 } else if (dc
->is_jmp
== DISAS_HVC
&& !dc
->condjmp
) {
11239 gen_ss_advance(dc
);
11240 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
));
11241 } else if (dc
->is_jmp
== DISAS_SMC
&& !dc
->condjmp
) {
11242 gen_ss_advance(dc
);
11243 gen_exception(EXCP_SMC
, syn_aa32_smc());
11244 } else if (dc
->ss_active
) {
11245 gen_step_complete_exception(dc
);
11247 /* FIXME: Single stepping a WFI insn will not halt
11249 gen_exception_internal(EXCP_DEBUG
);
11252 /* While branches must always occur at the end of an IT block,
11253 there are a few other things that can cause us to terminate
11254 the TB in the middle of an IT block:
11255 - Exception generating instructions (bkpt, swi, undefined).
11257 - Hardware watchpoints.
11258 Hardware breakpoints have already been handled and skip this code.
11260 gen_set_condexec(dc
);
11261 switch(dc
->is_jmp
) {
11263 gen_goto_tb(dc
, 1, dc
->pc
);
11268 /* indicate that the hash table must be used to find the next TB */
11269 tcg_gen_exit_tb(0);
11271 case DISAS_TB_JUMP
:
11272 /* nothing more to generate */
11275 gen_helper_wfi(cpu_env
);
11278 gen_helper_wfe(cpu_env
);
11281 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
));
11284 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
));
11287 gen_exception(EXCP_SMC
, syn_aa32_smc());
11291 gen_set_label(dc
->condlabel
);
11292 gen_set_condexec(dc
);
11293 gen_goto_tb(dc
, 1, dc
->pc
);
11299 gen_tb_end(tb
, num_insns
);
11300 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
11303 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
11304 qemu_log("----------------\n");
11305 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
11306 log_target_disas(env
, pc_start
, dc
->pc
- pc_start
,
11307 dc
->thumb
| (dc
->bswap_code
<< 1));
11312 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
11315 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
11317 tb
->size
= dc
->pc
- pc_start
;
11318 tb
->icount
= num_insns
;
11322 void gen_intermediate_code(CPUARMState
*env
, TranslationBlock
*tb
)
11324 gen_intermediate_code_internal(arm_env_get_cpu(env
), tb
, false);
11327 void gen_intermediate_code_pc(CPUARMState
*env
, TranslationBlock
*tb
)
11329 gen_intermediate_code_internal(arm_env_get_cpu(env
), tb
, true);
11332 static const char *cpu_mode_names
[16] = {
11333 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
11334 "???", "???", "hyp", "und", "???", "???", "???", "sys"
11337 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
11340 ARMCPU
*cpu
= ARM_CPU(cs
);
11341 CPUARMState
*env
= &cpu
->env
;
11346 aarch64_cpu_dump_state(cs
, f
, cpu_fprintf
, flags
);
11350 for(i
=0;i
<16;i
++) {
11351 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
11353 cpu_fprintf(f
, "\n");
11355 cpu_fprintf(f
, " ");
11357 psr
= cpsr_read(env
);
11358 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%d\n",
11360 psr
& (1 << 31) ? 'N' : '-',
11361 psr
& (1 << 30) ? 'Z' : '-',
11362 psr
& (1 << 29) ? 'C' : '-',
11363 psr
& (1 << 28) ? 'V' : '-',
11364 psr
& CPSR_T
? 'T' : 'A',
11365 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
11367 if (flags
& CPU_DUMP_FPU
) {
11368 int numvfpregs
= 0;
11369 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
11372 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
11375 for (i
= 0; i
< numvfpregs
; i
++) {
11376 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
11377 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
11378 i
* 2, (uint32_t)v
,
11379 i
* 2 + 1, (uint32_t)(v
>> 32),
11382 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
11386 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
, int pc_pos
)
11389 env
->pc
= tcg_ctx
.gen_opc_pc
[pc_pos
];
11390 env
->condexec_bits
= 0;
11392 env
->regs
[15] = tcg_ctx
.gen_opc_pc
[pc_pos
];
11393 env
->condexec_bits
= gen_opc_condexec_bits
[pc_pos
];