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
:
3235 tmp
= load_reg(s
, rd
);
3236 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3242 tmp
= load_reg(s
, rd
);
3244 gen_mov_vreg_F0(0, rn
);
3249 /* data processing */
3250 /* The opcode is in bits 23, 21, 20 and 6. */
3251 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
3255 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
3257 /* rn is register number */
3258 VFP_DREG_N(rn
, insn
);
3261 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18) ||
3262 ((rn
& 0x1e) == 0x6))) {
3263 /* Integer or single/half precision destination. */
3264 rd
= VFP_SREG_D(insn
);
3266 VFP_DREG_D(rd
, insn
);
3269 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14) ||
3270 ((rn
& 0x1e) == 0x4))) {
3271 /* VCVT from int or half precision is always from S reg
3272 * regardless of dp bit. VCVT with immediate frac_bits
3273 * has same format as SREG_M.
3275 rm
= VFP_SREG_M(insn
);
3277 VFP_DREG_M(rm
, insn
);
3280 rn
= VFP_SREG_N(insn
);
3281 if (op
== 15 && rn
== 15) {
3282 /* Double precision destination. */
3283 VFP_DREG_D(rd
, insn
);
3285 rd
= VFP_SREG_D(insn
);
3287 /* NB that we implicitly rely on the encoding for the frac_bits
3288 * in VCVT of fixed to float being the same as that of an SREG_M
3290 rm
= VFP_SREG_M(insn
);
3293 veclen
= s
->vec_len
;
3294 if (op
== 15 && rn
> 3)
3297 /* Shut up compiler warnings. */
3308 /* Figure out what type of vector operation this is. */
3309 if ((rd
& bank_mask
) == 0) {
3314 delta_d
= (s
->vec_stride
>> 1) + 1;
3316 delta_d
= s
->vec_stride
+ 1;
3318 if ((rm
& bank_mask
) == 0) {
3319 /* mixed scalar/vector */
3328 /* Load the initial operands. */
3333 /* Integer source */
3334 gen_mov_F0_vreg(0, rm
);
3339 gen_mov_F0_vreg(dp
, rd
);
3340 gen_mov_F1_vreg(dp
, rm
);
3344 /* Compare with zero */
3345 gen_mov_F0_vreg(dp
, rd
);
3356 /* Source and destination the same. */
3357 gen_mov_F0_vreg(dp
, rd
);
3363 /* VCVTB, VCVTT: only present with the halfprec extension
3364 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3365 * (we choose to UNDEF)
3367 if ((dp
&& !arm_feature(env
, ARM_FEATURE_V8
)) ||
3368 !arm_feature(env
, ARM_FEATURE_VFP_FP16
)) {
3371 if (!extract32(rn
, 1, 1)) {
3372 /* Half precision source. */
3373 gen_mov_F0_vreg(0, rm
);
3376 /* Otherwise fall through */
3378 /* One source operand. */
3379 gen_mov_F0_vreg(dp
, rm
);
3383 /* Two source operands. */
3384 gen_mov_F0_vreg(dp
, rn
);
3385 gen_mov_F1_vreg(dp
, rm
);
3389 /* Perform the calculation. */
3391 case 0: /* VMLA: fd + (fn * fm) */
3392 /* Note that order of inputs to the add matters for NaNs */
3394 gen_mov_F0_vreg(dp
, rd
);
3397 case 1: /* VMLS: fd + -(fn * fm) */
3400 gen_mov_F0_vreg(dp
, rd
);
3403 case 2: /* VNMLS: -fd + (fn * fm) */
3404 /* Note that it isn't valid to replace (-A + B) with (B - A)
3405 * or similar plausible looking simplifications
3406 * because this will give wrong results for NaNs.
3409 gen_mov_F0_vreg(dp
, rd
);
3413 case 3: /* VNMLA: -fd + -(fn * fm) */
3416 gen_mov_F0_vreg(dp
, rd
);
3420 case 4: /* mul: fn * fm */
3423 case 5: /* nmul: -(fn * fm) */
3427 case 6: /* add: fn + fm */
3430 case 7: /* sub: fn - fm */
3433 case 8: /* div: fn / fm */
3436 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3437 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3438 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3439 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3440 /* These are fused multiply-add, and must be done as one
3441 * floating point operation with no rounding between the
3442 * multiplication and addition steps.
3443 * NB that doing the negations here as separate steps is
3444 * correct : an input NaN should come out with its sign bit
3445 * flipped if it is a negated-input.
3447 if (!arm_feature(env
, ARM_FEATURE_VFP4
)) {
3455 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3457 frd
= tcg_temp_new_i64();
3458 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3461 gen_helper_vfp_negd(frd
, frd
);
3463 fpst
= get_fpstatus_ptr(0);
3464 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3465 cpu_F1d
, frd
, fpst
);
3466 tcg_temp_free_ptr(fpst
);
3467 tcg_temp_free_i64(frd
);
3473 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3475 frd
= tcg_temp_new_i32();
3476 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3478 gen_helper_vfp_negs(frd
, frd
);
3480 fpst
= get_fpstatus_ptr(0);
3481 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3482 cpu_F1s
, frd
, fpst
);
3483 tcg_temp_free_ptr(fpst
);
3484 tcg_temp_free_i32(frd
);
3487 case 14: /* fconst */
3488 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3491 n
= (insn
<< 12) & 0x80000000;
3492 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3499 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3506 tcg_gen_movi_i32(cpu_F0s
, n
);
3509 case 15: /* extension space */
3523 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3524 tmp
= gen_vfp_mrs();
3525 tcg_gen_ext16u_i32(tmp
, tmp
);
3527 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3530 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3533 tcg_temp_free_i32(tmp
);
3535 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3536 tmp
= gen_vfp_mrs();
3537 tcg_gen_shri_i32(tmp
, tmp
, 16);
3539 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3542 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3545 tcg_temp_free_i32(tmp
);
3547 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3548 tmp
= tcg_temp_new_i32();
3550 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3553 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3556 gen_mov_F0_vreg(0, rd
);
3557 tmp2
= gen_vfp_mrs();
3558 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3559 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3560 tcg_temp_free_i32(tmp2
);
3563 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3564 tmp
= tcg_temp_new_i32();
3566 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3569 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3572 tcg_gen_shli_i32(tmp
, tmp
, 16);
3573 gen_mov_F0_vreg(0, rd
);
3574 tmp2
= gen_vfp_mrs();
3575 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3576 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3577 tcg_temp_free_i32(tmp2
);
3589 case 11: /* cmpez */
3593 case 12: /* vrintr */
3595 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3597 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3599 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3601 tcg_temp_free_ptr(fpst
);
3604 case 13: /* vrintz */
3606 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3608 tcg_rmode
= tcg_const_i32(float_round_to_zero
);
3609 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3611 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3613 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3615 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3616 tcg_temp_free_i32(tcg_rmode
);
3617 tcg_temp_free_ptr(fpst
);
3620 case 14: /* vrintx */
3622 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3624 gen_helper_rintd_exact(cpu_F0d
, cpu_F0d
, fpst
);
3626 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpst
);
3628 tcg_temp_free_ptr(fpst
);
3631 case 15: /* single<->double conversion */
3633 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3635 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3637 case 16: /* fuito */
3638 gen_vfp_uito(dp
, 0);
3640 case 17: /* fsito */
3641 gen_vfp_sito(dp
, 0);
3643 case 20: /* fshto */
3644 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3646 gen_vfp_shto(dp
, 16 - rm
, 0);
3648 case 21: /* fslto */
3649 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3651 gen_vfp_slto(dp
, 32 - rm
, 0);
3653 case 22: /* fuhto */
3654 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3656 gen_vfp_uhto(dp
, 16 - rm
, 0);
3658 case 23: /* fulto */
3659 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3661 gen_vfp_ulto(dp
, 32 - rm
, 0);
3663 case 24: /* ftoui */
3664 gen_vfp_toui(dp
, 0);
3666 case 25: /* ftouiz */
3667 gen_vfp_touiz(dp
, 0);
3669 case 26: /* ftosi */
3670 gen_vfp_tosi(dp
, 0);
3672 case 27: /* ftosiz */
3673 gen_vfp_tosiz(dp
, 0);
3675 case 28: /* ftosh */
3676 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3678 gen_vfp_tosh(dp
, 16 - rm
, 0);
3680 case 29: /* ftosl */
3681 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3683 gen_vfp_tosl(dp
, 32 - rm
, 0);
3685 case 30: /* ftouh */
3686 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3688 gen_vfp_touh(dp
, 16 - rm
, 0);
3690 case 31: /* ftoul */
3691 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3693 gen_vfp_toul(dp
, 32 - rm
, 0);
3695 default: /* undefined */
3699 default: /* undefined */
3703 /* Write back the result. */
3704 if (op
== 15 && (rn
>= 8 && rn
<= 11)) {
3705 /* Comparison, do nothing. */
3706 } else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18 ||
3707 (rn
& 0x1e) == 0x6)) {
3708 /* VCVT double to int: always integer result.
3709 * VCVT double to half precision is always a single
3712 gen_mov_vreg_F0(0, rd
);
3713 } else if (op
== 15 && rn
== 15) {
3715 gen_mov_vreg_F0(!dp
, rd
);
3717 gen_mov_vreg_F0(dp
, rd
);
3720 /* break out of the loop if we have finished */
3724 if (op
== 15 && delta_m
== 0) {
3725 /* single source one-many */
3727 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3729 gen_mov_vreg_F0(dp
, rd
);
3733 /* Setup the next operands. */
3735 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3739 /* One source operand. */
3740 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3742 gen_mov_F0_vreg(dp
, rm
);
3744 /* Two source operands. */
3745 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3747 gen_mov_F0_vreg(dp
, rn
);
3749 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3751 gen_mov_F1_vreg(dp
, rm
);
3759 if ((insn
& 0x03e00000) == 0x00400000) {
3760 /* two-register transfer */
3761 rn
= (insn
>> 16) & 0xf;
3762 rd
= (insn
>> 12) & 0xf;
3764 VFP_DREG_M(rm
, insn
);
3766 rm
= VFP_SREG_M(insn
);
3769 if (insn
& ARM_CP_RW_BIT
) {
3772 gen_mov_F0_vreg(0, rm
* 2);
3773 tmp
= gen_vfp_mrs();
3774 store_reg(s
, rd
, tmp
);
3775 gen_mov_F0_vreg(0, rm
* 2 + 1);
3776 tmp
= gen_vfp_mrs();
3777 store_reg(s
, rn
, tmp
);
3779 gen_mov_F0_vreg(0, rm
);
3780 tmp
= gen_vfp_mrs();
3781 store_reg(s
, rd
, tmp
);
3782 gen_mov_F0_vreg(0, rm
+ 1);
3783 tmp
= gen_vfp_mrs();
3784 store_reg(s
, rn
, tmp
);
3789 tmp
= load_reg(s
, rd
);
3791 gen_mov_vreg_F0(0, rm
* 2);
3792 tmp
= load_reg(s
, rn
);
3794 gen_mov_vreg_F0(0, rm
* 2 + 1);
3796 tmp
= load_reg(s
, rd
);
3798 gen_mov_vreg_F0(0, rm
);
3799 tmp
= load_reg(s
, rn
);
3801 gen_mov_vreg_F0(0, rm
+ 1);
3806 rn
= (insn
>> 16) & 0xf;
3808 VFP_DREG_D(rd
, insn
);
3810 rd
= VFP_SREG_D(insn
);
3811 if ((insn
& 0x01200000) == 0x01000000) {
3812 /* Single load/store */
3813 offset
= (insn
& 0xff) << 2;
3814 if ((insn
& (1 << 23)) == 0)
3816 if (s
->thumb
&& rn
== 15) {
3817 /* This is actually UNPREDICTABLE */
3818 addr
= tcg_temp_new_i32();
3819 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3821 addr
= load_reg(s
, rn
);
3823 tcg_gen_addi_i32(addr
, addr
, offset
);
3824 if (insn
& (1 << 20)) {
3825 gen_vfp_ld(s
, dp
, addr
);
3826 gen_mov_vreg_F0(dp
, rd
);
3828 gen_mov_F0_vreg(dp
, rd
);
3829 gen_vfp_st(s
, dp
, addr
);
3831 tcg_temp_free_i32(addr
);
3833 /* load/store multiple */
3834 int w
= insn
& (1 << 21);
3836 n
= (insn
>> 1) & 0x7f;
3840 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
3841 /* P == U , W == 1 => UNDEF */
3844 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
3845 /* UNPREDICTABLE cases for bad immediates: we choose to
3846 * UNDEF to avoid generating huge numbers of TCG ops
3850 if (rn
== 15 && w
) {
3851 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3855 if (s
->thumb
&& rn
== 15) {
3856 /* This is actually UNPREDICTABLE */
3857 addr
= tcg_temp_new_i32();
3858 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3860 addr
= load_reg(s
, rn
);
3862 if (insn
& (1 << 24)) /* pre-decrement */
3863 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
3869 for (i
= 0; i
< n
; i
++) {
3870 if (insn
& ARM_CP_RW_BIT
) {
3872 gen_vfp_ld(s
, dp
, addr
);
3873 gen_mov_vreg_F0(dp
, rd
+ i
);
3876 gen_mov_F0_vreg(dp
, rd
+ i
);
3877 gen_vfp_st(s
, dp
, addr
);
3879 tcg_gen_addi_i32(addr
, addr
, offset
);
3883 if (insn
& (1 << 24))
3884 offset
= -offset
* n
;
3885 else if (dp
&& (insn
& 1))
3891 tcg_gen_addi_i32(addr
, addr
, offset
);
3892 store_reg(s
, rn
, addr
);
3894 tcg_temp_free_i32(addr
);
3900 /* Should never happen. */
3906 static inline void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
3908 TranslationBlock
*tb
;
3911 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
3913 gen_set_pc_im(s
, dest
);
3914 tcg_gen_exit_tb((uintptr_t)tb
+ n
);
3916 gen_set_pc_im(s
, dest
);
3921 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
3923 if (unlikely(s
->singlestep_enabled
|| s
->ss_active
)) {
3924 /* An indirect jump so that we still trigger the debug exception. */
3929 gen_goto_tb(s
, 0, dest
);
3930 s
->is_jmp
= DISAS_TB_JUMP
;
3934 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
3937 tcg_gen_sari_i32(t0
, t0
, 16);
3941 tcg_gen_sari_i32(t1
, t1
, 16);
3944 tcg_gen_mul_i32(t0
, t0
, t1
);
3947 /* Return the mask of PSR bits set by a MSR instruction. */
3948 static uint32_t msr_mask(CPUARMState
*env
, DisasContext
*s
, int flags
, int spsr
) {
3952 if (flags
& (1 << 0))
3954 if (flags
& (1 << 1))
3956 if (flags
& (1 << 2))
3958 if (flags
& (1 << 3))
3961 /* Mask out undefined bits. */
3962 mask
&= ~CPSR_RESERVED
;
3963 if (!arm_feature(env
, ARM_FEATURE_V4T
))
3965 if (!arm_feature(env
, ARM_FEATURE_V5
))
3966 mask
&= ~CPSR_Q
; /* V5TE in reality*/
3967 if (!arm_feature(env
, ARM_FEATURE_V6
))
3968 mask
&= ~(CPSR_E
| CPSR_GE
);
3969 if (!arm_feature(env
, ARM_FEATURE_THUMB2
))
3971 /* Mask out execution state and reserved bits. */
3973 mask
&= ~(CPSR_EXEC
| CPSR_RESERVED
);
3975 /* Mask out privileged bits. */
3981 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3982 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
3986 /* ??? This is also undefined in system mode. */
3990 tmp
= load_cpu_field(spsr
);
3991 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
3992 tcg_gen_andi_i32(t0
, t0
, mask
);
3993 tcg_gen_or_i32(tmp
, tmp
, t0
);
3994 store_cpu_field(tmp
, spsr
);
3996 gen_set_cpsr(t0
, mask
);
3998 tcg_temp_free_i32(t0
);
4003 /* Returns nonzero if access to the PSR is not permitted. */
4004 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
4007 tmp
= tcg_temp_new_i32();
4008 tcg_gen_movi_i32(tmp
, val
);
4009 return gen_set_psr(s
, mask
, spsr
, tmp
);
4012 /* Generate an old-style exception return. Marks pc as dead. */
4013 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
4016 store_reg(s
, 15, pc
);
4017 tmp
= load_cpu_field(spsr
);
4018 gen_set_cpsr(tmp
, CPSR_ERET_MASK
);
4019 tcg_temp_free_i32(tmp
);
4020 s
->is_jmp
= DISAS_UPDATE
;
4023 /* Generate a v6 exception return. Marks both values as dead. */
4024 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
4026 gen_set_cpsr(cpsr
, CPSR_ERET_MASK
);
4027 tcg_temp_free_i32(cpsr
);
4028 store_reg(s
, 15, pc
);
4029 s
->is_jmp
= DISAS_UPDATE
;
4032 static void gen_nop_hint(DisasContext
*s
, int val
)
4036 gen_set_pc_im(s
, s
->pc
);
4037 s
->is_jmp
= DISAS_WFI
;
4040 gen_set_pc_im(s
, s
->pc
);
4041 s
->is_jmp
= DISAS_WFE
;
4045 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4051 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4053 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4056 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
4057 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
4058 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
4063 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4066 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
4067 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
4068 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
4073 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4074 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4075 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4076 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4077 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4079 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4080 switch ((size << 1) | u) { \
4082 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4085 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4088 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4091 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4094 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4097 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4099 default: return 1; \
4102 #define GEN_NEON_INTEGER_OP(name) do { \
4103 switch ((size << 1) | u) { \
4105 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4108 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4111 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4114 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4117 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4120 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4122 default: return 1; \
4125 static TCGv_i32
neon_load_scratch(int scratch
)
4127 TCGv_i32 tmp
= tcg_temp_new_i32();
4128 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4132 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
4134 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4135 tcg_temp_free_i32(var
);
4138 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
4142 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
4144 gen_neon_dup_high16(tmp
);
4146 gen_neon_dup_low16(tmp
);
4149 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
4154 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
4157 if (!q
&& size
== 2) {
4160 tmp
= tcg_const_i32(rd
);
4161 tmp2
= tcg_const_i32(rm
);
4165 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
4168 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
4171 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
4179 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
4182 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
4188 tcg_temp_free_i32(tmp
);
4189 tcg_temp_free_i32(tmp2
);
4193 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
4196 if (!q
&& size
== 2) {
4199 tmp
= tcg_const_i32(rd
);
4200 tmp2
= tcg_const_i32(rm
);
4204 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
4207 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
4210 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
4218 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
4221 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
4227 tcg_temp_free_i32(tmp
);
4228 tcg_temp_free_i32(tmp2
);
4232 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
4236 rd
= tcg_temp_new_i32();
4237 tmp
= tcg_temp_new_i32();
4239 tcg_gen_shli_i32(rd
, t0
, 8);
4240 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
4241 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
4242 tcg_gen_or_i32(rd
, rd
, tmp
);
4244 tcg_gen_shri_i32(t1
, t1
, 8);
4245 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
4246 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
4247 tcg_gen_or_i32(t1
, t1
, tmp
);
4248 tcg_gen_mov_i32(t0
, rd
);
4250 tcg_temp_free_i32(tmp
);
4251 tcg_temp_free_i32(rd
);
4254 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
4258 rd
= tcg_temp_new_i32();
4259 tmp
= tcg_temp_new_i32();
4261 tcg_gen_shli_i32(rd
, t0
, 16);
4262 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
4263 tcg_gen_or_i32(rd
, rd
, tmp
);
4264 tcg_gen_shri_i32(t1
, t1
, 16);
4265 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
4266 tcg_gen_or_i32(t1
, t1
, tmp
);
4267 tcg_gen_mov_i32(t0
, rd
);
4269 tcg_temp_free_i32(tmp
);
4270 tcg_temp_free_i32(rd
);
4278 } neon_ls_element_type
[11] = {
4292 /* Translate a NEON load/store element instruction. Return nonzero if the
4293 instruction is invalid. */
4294 static int disas_neon_ls_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
4313 /* FIXME: this access check should not take precedence over UNDEF
4314 * for invalid encodings; we will generate incorrect syndrome information
4315 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4317 if (!s
->cpacr_fpen
) {
4318 gen_exception_insn(s
, 4, EXCP_UDEF
,
4319 syn_fp_access_trap(1, 0xe, s
->thumb
));
4323 if (!s
->vfp_enabled
)
4325 VFP_DREG_D(rd
, insn
);
4326 rn
= (insn
>> 16) & 0xf;
4328 load
= (insn
& (1 << 21)) != 0;
4329 if ((insn
& (1 << 23)) == 0) {
4330 /* Load store all elements. */
4331 op
= (insn
>> 8) & 0xf;
4332 size
= (insn
>> 6) & 3;
4335 /* Catch UNDEF cases for bad values of align field */
4338 if (((insn
>> 5) & 1) == 1) {
4343 if (((insn
>> 4) & 3) == 3) {
4350 nregs
= neon_ls_element_type
[op
].nregs
;
4351 interleave
= neon_ls_element_type
[op
].interleave
;
4352 spacing
= neon_ls_element_type
[op
].spacing
;
4353 if (size
== 3 && (interleave
| spacing
) != 1)
4355 addr
= tcg_temp_new_i32();
4356 load_reg_var(s
, addr
, rn
);
4357 stride
= (1 << size
) * interleave
;
4358 for (reg
= 0; reg
< nregs
; reg
++) {
4359 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
4360 load_reg_var(s
, addr
, rn
);
4361 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
4362 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
4363 load_reg_var(s
, addr
, rn
);
4364 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4367 tmp64
= tcg_temp_new_i64();
4369 gen_aa32_ld64(tmp64
, addr
, get_mem_index(s
));
4370 neon_store_reg64(tmp64
, rd
);
4372 neon_load_reg64(tmp64
, rd
);
4373 gen_aa32_st64(tmp64
, addr
, get_mem_index(s
));
4375 tcg_temp_free_i64(tmp64
);
4376 tcg_gen_addi_i32(addr
, addr
, stride
);
4378 for (pass
= 0; pass
< 2; pass
++) {
4381 tmp
= tcg_temp_new_i32();
4382 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
4383 neon_store_reg(rd
, pass
, tmp
);
4385 tmp
= neon_load_reg(rd
, pass
);
4386 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
4387 tcg_temp_free_i32(tmp
);
4389 tcg_gen_addi_i32(addr
, addr
, stride
);
4390 } else if (size
== 1) {
4392 tmp
= tcg_temp_new_i32();
4393 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
4394 tcg_gen_addi_i32(addr
, addr
, stride
);
4395 tmp2
= tcg_temp_new_i32();
4396 gen_aa32_ld16u(tmp2
, addr
, get_mem_index(s
));
4397 tcg_gen_addi_i32(addr
, addr
, stride
);
4398 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
4399 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4400 tcg_temp_free_i32(tmp2
);
4401 neon_store_reg(rd
, pass
, tmp
);
4403 tmp
= neon_load_reg(rd
, pass
);
4404 tmp2
= tcg_temp_new_i32();
4405 tcg_gen_shri_i32(tmp2
, tmp
, 16);
4406 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
4407 tcg_temp_free_i32(tmp
);
4408 tcg_gen_addi_i32(addr
, addr
, stride
);
4409 gen_aa32_st16(tmp2
, addr
, get_mem_index(s
));
4410 tcg_temp_free_i32(tmp2
);
4411 tcg_gen_addi_i32(addr
, addr
, stride
);
4413 } else /* size == 0 */ {
4415 TCGV_UNUSED_I32(tmp2
);
4416 for (n
= 0; n
< 4; n
++) {
4417 tmp
= tcg_temp_new_i32();
4418 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
4419 tcg_gen_addi_i32(addr
, addr
, stride
);
4423 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
4424 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
4425 tcg_temp_free_i32(tmp
);
4428 neon_store_reg(rd
, pass
, tmp2
);
4430 tmp2
= neon_load_reg(rd
, pass
);
4431 for (n
= 0; n
< 4; n
++) {
4432 tmp
= tcg_temp_new_i32();
4434 tcg_gen_mov_i32(tmp
, tmp2
);
4436 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
4438 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
4439 tcg_temp_free_i32(tmp
);
4440 tcg_gen_addi_i32(addr
, addr
, stride
);
4442 tcg_temp_free_i32(tmp2
);
4449 tcg_temp_free_i32(addr
);
4452 size
= (insn
>> 10) & 3;
4454 /* Load single element to all lanes. */
4455 int a
= (insn
>> 4) & 1;
4459 size
= (insn
>> 6) & 3;
4460 nregs
= ((insn
>> 8) & 3) + 1;
4463 if (nregs
!= 4 || a
== 0) {
4466 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4469 if (nregs
== 1 && a
== 1 && size
== 0) {
4472 if (nregs
== 3 && a
== 1) {
4475 addr
= tcg_temp_new_i32();
4476 load_reg_var(s
, addr
, rn
);
4478 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4479 tmp
= gen_load_and_replicate(s
, addr
, size
);
4480 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4481 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4482 if (insn
& (1 << 5)) {
4483 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
4484 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
4486 tcg_temp_free_i32(tmp
);
4488 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4489 stride
= (insn
& (1 << 5)) ? 2 : 1;
4490 for (reg
= 0; reg
< nregs
; reg
++) {
4491 tmp
= gen_load_and_replicate(s
, addr
, size
);
4492 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4493 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4494 tcg_temp_free_i32(tmp
);
4495 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4499 tcg_temp_free_i32(addr
);
4500 stride
= (1 << size
) * nregs
;
4502 /* Single element. */
4503 int idx
= (insn
>> 4) & 0xf;
4504 pass
= (insn
>> 7) & 1;
4507 shift
= ((insn
>> 5) & 3) * 8;
4511 shift
= ((insn
>> 6) & 1) * 16;
4512 stride
= (insn
& (1 << 5)) ? 2 : 1;
4516 stride
= (insn
& (1 << 6)) ? 2 : 1;
4521 nregs
= ((insn
>> 8) & 3) + 1;
4522 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4525 if (((idx
& (1 << size
)) != 0) ||
4526 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
4531 if ((idx
& 1) != 0) {
4536 if (size
== 2 && (idx
& 2) != 0) {
4541 if ((size
== 2) && ((idx
& 3) == 3)) {
4548 if ((rd
+ stride
* (nregs
- 1)) > 31) {
4549 /* Attempts to write off the end of the register file
4550 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4551 * the neon_load_reg() would write off the end of the array.
4555 addr
= tcg_temp_new_i32();
4556 load_reg_var(s
, addr
, rn
);
4557 for (reg
= 0; reg
< nregs
; reg
++) {
4559 tmp
= tcg_temp_new_i32();
4562 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
4565 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
4568 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
4570 default: /* Avoid compiler warnings. */
4574 tmp2
= neon_load_reg(rd
, pass
);
4575 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
4576 shift
, size
? 16 : 8);
4577 tcg_temp_free_i32(tmp2
);
4579 neon_store_reg(rd
, pass
, tmp
);
4580 } else { /* Store */
4581 tmp
= neon_load_reg(rd
, pass
);
4583 tcg_gen_shri_i32(tmp
, tmp
, shift
);
4586 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
4589 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
4592 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
4595 tcg_temp_free_i32(tmp
);
4598 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4600 tcg_temp_free_i32(addr
);
4601 stride
= nregs
* (1 << size
);
4607 base
= load_reg(s
, rn
);
4609 tcg_gen_addi_i32(base
, base
, stride
);
4612 index
= load_reg(s
, rm
);
4613 tcg_gen_add_i32(base
, base
, index
);
4614 tcg_temp_free_i32(index
);
4616 store_reg(s
, rn
, base
);
4621 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4622 static void gen_neon_bsl(TCGv_i32 dest
, TCGv_i32 t
, TCGv_i32 f
, TCGv_i32 c
)
4624 tcg_gen_and_i32(t
, t
, c
);
4625 tcg_gen_andc_i32(f
, f
, c
);
4626 tcg_gen_or_i32(dest
, t
, f
);
4629 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4632 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4633 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4634 case 2: tcg_gen_trunc_i64_i32(dest
, src
); break;
4639 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4642 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4643 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4644 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
4649 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4652 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
4653 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
4654 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
4659 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4662 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
4663 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
4664 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
4669 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
4675 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
4676 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
4681 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
4682 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
4689 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
4690 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
4695 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
4696 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
4703 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
4707 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
4708 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
4709 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
4714 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
4715 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
4716 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
4720 tcg_temp_free_i32(src
);
4723 static inline void gen_neon_addl(int size
)
4726 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
4727 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
4728 case 2: tcg_gen_add_i64(CPU_V001
); break;
4733 static inline void gen_neon_subl(int size
)
4736 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
4737 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
4738 case 2: tcg_gen_sub_i64(CPU_V001
); break;
4743 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
4746 case 0: gen_helper_neon_negl_u16(var
, var
); break;
4747 case 1: gen_helper_neon_negl_u32(var
, var
); break;
4749 tcg_gen_neg_i64(var
, var
);
4755 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
4758 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
4759 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
4764 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
4769 switch ((size
<< 1) | u
) {
4770 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
4771 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
4772 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
4773 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
4775 tmp
= gen_muls_i64_i32(a
, b
);
4776 tcg_gen_mov_i64(dest
, tmp
);
4777 tcg_temp_free_i64(tmp
);
4780 tmp
= gen_mulu_i64_i32(a
, b
);
4781 tcg_gen_mov_i64(dest
, tmp
);
4782 tcg_temp_free_i64(tmp
);
4787 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4788 Don't forget to clean them now. */
4790 tcg_temp_free_i32(a
);
4791 tcg_temp_free_i32(b
);
4795 static void gen_neon_narrow_op(int op
, int u
, int size
,
4796 TCGv_i32 dest
, TCGv_i64 src
)
4800 gen_neon_unarrow_sats(size
, dest
, src
);
4802 gen_neon_narrow(size
, dest
, src
);
4806 gen_neon_narrow_satu(size
, dest
, src
);
4808 gen_neon_narrow_sats(size
, dest
, src
);
4813 /* Symbolic constants for op fields for Neon 3-register same-length.
4814 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4817 #define NEON_3R_VHADD 0
4818 #define NEON_3R_VQADD 1
4819 #define NEON_3R_VRHADD 2
4820 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4821 #define NEON_3R_VHSUB 4
4822 #define NEON_3R_VQSUB 5
4823 #define NEON_3R_VCGT 6
4824 #define NEON_3R_VCGE 7
4825 #define NEON_3R_VSHL 8
4826 #define NEON_3R_VQSHL 9
4827 #define NEON_3R_VRSHL 10
4828 #define NEON_3R_VQRSHL 11
4829 #define NEON_3R_VMAX 12
4830 #define NEON_3R_VMIN 13
4831 #define NEON_3R_VABD 14
4832 #define NEON_3R_VABA 15
4833 #define NEON_3R_VADD_VSUB 16
4834 #define NEON_3R_VTST_VCEQ 17
4835 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4836 #define NEON_3R_VMUL 19
4837 #define NEON_3R_VPMAX 20
4838 #define NEON_3R_VPMIN 21
4839 #define NEON_3R_VQDMULH_VQRDMULH 22
4840 #define NEON_3R_VPADD 23
4841 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
4842 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4843 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4844 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4845 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4846 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4847 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4848 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4850 static const uint8_t neon_3r_sizes
[] = {
4851 [NEON_3R_VHADD
] = 0x7,
4852 [NEON_3R_VQADD
] = 0xf,
4853 [NEON_3R_VRHADD
] = 0x7,
4854 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
4855 [NEON_3R_VHSUB
] = 0x7,
4856 [NEON_3R_VQSUB
] = 0xf,
4857 [NEON_3R_VCGT
] = 0x7,
4858 [NEON_3R_VCGE
] = 0x7,
4859 [NEON_3R_VSHL
] = 0xf,
4860 [NEON_3R_VQSHL
] = 0xf,
4861 [NEON_3R_VRSHL
] = 0xf,
4862 [NEON_3R_VQRSHL
] = 0xf,
4863 [NEON_3R_VMAX
] = 0x7,
4864 [NEON_3R_VMIN
] = 0x7,
4865 [NEON_3R_VABD
] = 0x7,
4866 [NEON_3R_VABA
] = 0x7,
4867 [NEON_3R_VADD_VSUB
] = 0xf,
4868 [NEON_3R_VTST_VCEQ
] = 0x7,
4869 [NEON_3R_VML
] = 0x7,
4870 [NEON_3R_VMUL
] = 0x7,
4871 [NEON_3R_VPMAX
] = 0x7,
4872 [NEON_3R_VPMIN
] = 0x7,
4873 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
4874 [NEON_3R_VPADD
] = 0x7,
4875 [NEON_3R_SHA
] = 0xf, /* size field encodes op type */
4876 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
4877 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
4878 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
4879 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
4880 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
4881 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
4882 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
4885 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4886 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4889 #define NEON_2RM_VREV64 0
4890 #define NEON_2RM_VREV32 1
4891 #define NEON_2RM_VREV16 2
4892 #define NEON_2RM_VPADDL 4
4893 #define NEON_2RM_VPADDL_U 5
4894 #define NEON_2RM_AESE 6 /* Includes AESD */
4895 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4896 #define NEON_2RM_VCLS 8
4897 #define NEON_2RM_VCLZ 9
4898 #define NEON_2RM_VCNT 10
4899 #define NEON_2RM_VMVN 11
4900 #define NEON_2RM_VPADAL 12
4901 #define NEON_2RM_VPADAL_U 13
4902 #define NEON_2RM_VQABS 14
4903 #define NEON_2RM_VQNEG 15
4904 #define NEON_2RM_VCGT0 16
4905 #define NEON_2RM_VCGE0 17
4906 #define NEON_2RM_VCEQ0 18
4907 #define NEON_2RM_VCLE0 19
4908 #define NEON_2RM_VCLT0 20
4909 #define NEON_2RM_SHA1H 21
4910 #define NEON_2RM_VABS 22
4911 #define NEON_2RM_VNEG 23
4912 #define NEON_2RM_VCGT0_F 24
4913 #define NEON_2RM_VCGE0_F 25
4914 #define NEON_2RM_VCEQ0_F 26
4915 #define NEON_2RM_VCLE0_F 27
4916 #define NEON_2RM_VCLT0_F 28
4917 #define NEON_2RM_VABS_F 30
4918 #define NEON_2RM_VNEG_F 31
4919 #define NEON_2RM_VSWP 32
4920 #define NEON_2RM_VTRN 33
4921 #define NEON_2RM_VUZP 34
4922 #define NEON_2RM_VZIP 35
4923 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4924 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4925 #define NEON_2RM_VSHLL 38
4926 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
4927 #define NEON_2RM_VRINTN 40
4928 #define NEON_2RM_VRINTX 41
4929 #define NEON_2RM_VRINTA 42
4930 #define NEON_2RM_VRINTZ 43
4931 #define NEON_2RM_VCVT_F16_F32 44
4932 #define NEON_2RM_VRINTM 45
4933 #define NEON_2RM_VCVT_F32_F16 46
4934 #define NEON_2RM_VRINTP 47
4935 #define NEON_2RM_VCVTAU 48
4936 #define NEON_2RM_VCVTAS 49
4937 #define NEON_2RM_VCVTNU 50
4938 #define NEON_2RM_VCVTNS 51
4939 #define NEON_2RM_VCVTPU 52
4940 #define NEON_2RM_VCVTPS 53
4941 #define NEON_2RM_VCVTMU 54
4942 #define NEON_2RM_VCVTMS 55
4943 #define NEON_2RM_VRECPE 56
4944 #define NEON_2RM_VRSQRTE 57
4945 #define NEON_2RM_VRECPE_F 58
4946 #define NEON_2RM_VRSQRTE_F 59
4947 #define NEON_2RM_VCVT_FS 60
4948 #define NEON_2RM_VCVT_FU 61
4949 #define NEON_2RM_VCVT_SF 62
4950 #define NEON_2RM_VCVT_UF 63
4952 static int neon_2rm_is_float_op(int op
)
4954 /* Return true if this neon 2reg-misc op is float-to-float */
4955 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
4956 (op
>= NEON_2RM_VRINTN
&& op
<= NEON_2RM_VRINTZ
) ||
4957 op
== NEON_2RM_VRINTM
||
4958 (op
>= NEON_2RM_VRINTP
&& op
<= NEON_2RM_VCVTMS
) ||
4959 op
>= NEON_2RM_VRECPE_F
);
4962 /* Each entry in this array has bit n set if the insn allows
4963 * size value n (otherwise it will UNDEF). Since unallocated
4964 * op values will have no bits set they always UNDEF.
4966 static const uint8_t neon_2rm_sizes
[] = {
4967 [NEON_2RM_VREV64
] = 0x7,
4968 [NEON_2RM_VREV32
] = 0x3,
4969 [NEON_2RM_VREV16
] = 0x1,
4970 [NEON_2RM_VPADDL
] = 0x7,
4971 [NEON_2RM_VPADDL_U
] = 0x7,
4972 [NEON_2RM_AESE
] = 0x1,
4973 [NEON_2RM_AESMC
] = 0x1,
4974 [NEON_2RM_VCLS
] = 0x7,
4975 [NEON_2RM_VCLZ
] = 0x7,
4976 [NEON_2RM_VCNT
] = 0x1,
4977 [NEON_2RM_VMVN
] = 0x1,
4978 [NEON_2RM_VPADAL
] = 0x7,
4979 [NEON_2RM_VPADAL_U
] = 0x7,
4980 [NEON_2RM_VQABS
] = 0x7,
4981 [NEON_2RM_VQNEG
] = 0x7,
4982 [NEON_2RM_VCGT0
] = 0x7,
4983 [NEON_2RM_VCGE0
] = 0x7,
4984 [NEON_2RM_VCEQ0
] = 0x7,
4985 [NEON_2RM_VCLE0
] = 0x7,
4986 [NEON_2RM_VCLT0
] = 0x7,
4987 [NEON_2RM_SHA1H
] = 0x4,
4988 [NEON_2RM_VABS
] = 0x7,
4989 [NEON_2RM_VNEG
] = 0x7,
4990 [NEON_2RM_VCGT0_F
] = 0x4,
4991 [NEON_2RM_VCGE0_F
] = 0x4,
4992 [NEON_2RM_VCEQ0_F
] = 0x4,
4993 [NEON_2RM_VCLE0_F
] = 0x4,
4994 [NEON_2RM_VCLT0_F
] = 0x4,
4995 [NEON_2RM_VABS_F
] = 0x4,
4996 [NEON_2RM_VNEG_F
] = 0x4,
4997 [NEON_2RM_VSWP
] = 0x1,
4998 [NEON_2RM_VTRN
] = 0x7,
4999 [NEON_2RM_VUZP
] = 0x7,
5000 [NEON_2RM_VZIP
] = 0x7,
5001 [NEON_2RM_VMOVN
] = 0x7,
5002 [NEON_2RM_VQMOVN
] = 0x7,
5003 [NEON_2RM_VSHLL
] = 0x7,
5004 [NEON_2RM_SHA1SU1
] = 0x4,
5005 [NEON_2RM_VRINTN
] = 0x4,
5006 [NEON_2RM_VRINTX
] = 0x4,
5007 [NEON_2RM_VRINTA
] = 0x4,
5008 [NEON_2RM_VRINTZ
] = 0x4,
5009 [NEON_2RM_VCVT_F16_F32
] = 0x2,
5010 [NEON_2RM_VRINTM
] = 0x4,
5011 [NEON_2RM_VCVT_F32_F16
] = 0x2,
5012 [NEON_2RM_VRINTP
] = 0x4,
5013 [NEON_2RM_VCVTAU
] = 0x4,
5014 [NEON_2RM_VCVTAS
] = 0x4,
5015 [NEON_2RM_VCVTNU
] = 0x4,
5016 [NEON_2RM_VCVTNS
] = 0x4,
5017 [NEON_2RM_VCVTPU
] = 0x4,
5018 [NEON_2RM_VCVTPS
] = 0x4,
5019 [NEON_2RM_VCVTMU
] = 0x4,
5020 [NEON_2RM_VCVTMS
] = 0x4,
5021 [NEON_2RM_VRECPE
] = 0x4,
5022 [NEON_2RM_VRSQRTE
] = 0x4,
5023 [NEON_2RM_VRECPE_F
] = 0x4,
5024 [NEON_2RM_VRSQRTE_F
] = 0x4,
5025 [NEON_2RM_VCVT_FS
] = 0x4,
5026 [NEON_2RM_VCVT_FU
] = 0x4,
5027 [NEON_2RM_VCVT_SF
] = 0x4,
5028 [NEON_2RM_VCVT_UF
] = 0x4,
5031 /* Translate a NEON data processing instruction. Return nonzero if the
5032 instruction is invalid.
5033 We process data in a mixture of 32-bit and 64-bit chunks.
5034 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5036 static int disas_neon_data_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
5048 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
5051 /* FIXME: this access check should not take precedence over UNDEF
5052 * for invalid encodings; we will generate incorrect syndrome information
5053 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5055 if (!s
->cpacr_fpen
) {
5056 gen_exception_insn(s
, 4, EXCP_UDEF
,
5057 syn_fp_access_trap(1, 0xe, s
->thumb
));
5061 if (!s
->vfp_enabled
)
5063 q
= (insn
& (1 << 6)) != 0;
5064 u
= (insn
>> 24) & 1;
5065 VFP_DREG_D(rd
, insn
);
5066 VFP_DREG_N(rn
, insn
);
5067 VFP_DREG_M(rm
, insn
);
5068 size
= (insn
>> 20) & 3;
5069 if ((insn
& (1 << 23)) == 0) {
5070 /* Three register same length. */
5071 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
5072 /* Catch invalid op and bad size combinations: UNDEF */
5073 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
5076 /* All insns of this form UNDEF for either this condition or the
5077 * superset of cases "Q==1"; we catch the latter later.
5079 if (q
&& ((rd
| rn
| rm
) & 1)) {
5083 * The SHA-1/SHA-256 3-register instructions require special treatment
5084 * here, as their size field is overloaded as an op type selector, and
5085 * they all consume their input in a single pass.
5087 if (op
== NEON_3R_SHA
) {
5091 if (!u
) { /* SHA-1 */
5092 if (!arm_feature(env
, ARM_FEATURE_V8_SHA1
)) {
5095 tmp
= tcg_const_i32(rd
);
5096 tmp2
= tcg_const_i32(rn
);
5097 tmp3
= tcg_const_i32(rm
);
5098 tmp4
= tcg_const_i32(size
);
5099 gen_helper_crypto_sha1_3reg(cpu_env
, tmp
, tmp2
, tmp3
, tmp4
);
5100 tcg_temp_free_i32(tmp4
);
5101 } else { /* SHA-256 */
5102 if (!arm_feature(env
, ARM_FEATURE_V8_SHA256
) || size
== 3) {
5105 tmp
= tcg_const_i32(rd
);
5106 tmp2
= tcg_const_i32(rn
);
5107 tmp3
= tcg_const_i32(rm
);
5110 gen_helper_crypto_sha256h(cpu_env
, tmp
, tmp2
, tmp3
);
5113 gen_helper_crypto_sha256h2(cpu_env
, tmp
, tmp2
, tmp3
);
5116 gen_helper_crypto_sha256su1(cpu_env
, tmp
, tmp2
, tmp3
);
5120 tcg_temp_free_i32(tmp
);
5121 tcg_temp_free_i32(tmp2
);
5122 tcg_temp_free_i32(tmp3
);
5125 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
5126 /* 64-bit element instructions. */
5127 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5128 neon_load_reg64(cpu_V0
, rn
+ pass
);
5129 neon_load_reg64(cpu_V1
, rm
+ pass
);
5133 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
5136 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
5142 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
5145 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
5151 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5153 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5158 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5161 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5167 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5169 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5172 case NEON_3R_VQRSHL
:
5174 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
5177 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
5181 case NEON_3R_VADD_VSUB
:
5183 tcg_gen_sub_i64(CPU_V001
);
5185 tcg_gen_add_i64(CPU_V001
);
5191 neon_store_reg64(cpu_V0
, rd
+ pass
);
5200 case NEON_3R_VQRSHL
:
5203 /* Shift instruction operands are reversed. */
5218 case NEON_3R_FLOAT_ARITH
:
5219 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
5221 case NEON_3R_FLOAT_MINMAX
:
5222 pairwise
= u
; /* if VPMIN/VPMAX (float) */
5224 case NEON_3R_FLOAT_CMP
:
5226 /* no encoding for U=0 C=1x */
5230 case NEON_3R_FLOAT_ACMP
:
5235 case NEON_3R_FLOAT_MISC
:
5236 /* VMAXNM/VMINNM in ARMv8 */
5237 if (u
&& !arm_feature(env
, ARM_FEATURE_V8
)) {
5242 if (u
&& (size
!= 0)) {
5243 /* UNDEF on invalid size for polynomial subcase */
5248 if (!arm_feature(env
, ARM_FEATURE_VFP4
) || u
) {
5256 if (pairwise
&& q
) {
5257 /* All the pairwise insns UNDEF if Q is set */
5261 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5266 tmp
= neon_load_reg(rn
, 0);
5267 tmp2
= neon_load_reg(rn
, 1);
5269 tmp
= neon_load_reg(rm
, 0);
5270 tmp2
= neon_load_reg(rm
, 1);
5274 tmp
= neon_load_reg(rn
, pass
);
5275 tmp2
= neon_load_reg(rm
, pass
);
5279 GEN_NEON_INTEGER_OP(hadd
);
5282 GEN_NEON_INTEGER_OP_ENV(qadd
);
5284 case NEON_3R_VRHADD
:
5285 GEN_NEON_INTEGER_OP(rhadd
);
5287 case NEON_3R_LOGIC
: /* Logic ops. */
5288 switch ((u
<< 2) | size
) {
5290 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
5293 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
5296 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5299 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
5302 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
5305 tmp3
= neon_load_reg(rd
, pass
);
5306 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
5307 tcg_temp_free_i32(tmp3
);
5310 tmp3
= neon_load_reg(rd
, pass
);
5311 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
5312 tcg_temp_free_i32(tmp3
);
5315 tmp3
= neon_load_reg(rd
, pass
);
5316 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
5317 tcg_temp_free_i32(tmp3
);
5322 GEN_NEON_INTEGER_OP(hsub
);
5325 GEN_NEON_INTEGER_OP_ENV(qsub
);
5328 GEN_NEON_INTEGER_OP(cgt
);
5331 GEN_NEON_INTEGER_OP(cge
);
5334 GEN_NEON_INTEGER_OP(shl
);
5337 GEN_NEON_INTEGER_OP_ENV(qshl
);
5340 GEN_NEON_INTEGER_OP(rshl
);
5342 case NEON_3R_VQRSHL
:
5343 GEN_NEON_INTEGER_OP_ENV(qrshl
);
5346 GEN_NEON_INTEGER_OP(max
);
5349 GEN_NEON_INTEGER_OP(min
);
5352 GEN_NEON_INTEGER_OP(abd
);
5355 GEN_NEON_INTEGER_OP(abd
);
5356 tcg_temp_free_i32(tmp2
);
5357 tmp2
= neon_load_reg(rd
, pass
);
5358 gen_neon_add(size
, tmp
, tmp2
);
5360 case NEON_3R_VADD_VSUB
:
5361 if (!u
) { /* VADD */
5362 gen_neon_add(size
, tmp
, tmp2
);
5365 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
5366 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
5367 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
5372 case NEON_3R_VTST_VCEQ
:
5373 if (!u
) { /* VTST */
5375 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
5376 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
5377 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
5382 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
5383 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
5384 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
5389 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
5391 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5392 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5393 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5396 tcg_temp_free_i32(tmp2
);
5397 tmp2
= neon_load_reg(rd
, pass
);
5399 gen_neon_rsb(size
, tmp
, tmp2
);
5401 gen_neon_add(size
, tmp
, tmp2
);
5405 if (u
) { /* polynomial */
5406 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
5407 } else { /* Integer */
5409 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5410 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5411 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5417 GEN_NEON_INTEGER_OP(pmax
);
5420 GEN_NEON_INTEGER_OP(pmin
);
5422 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
5423 if (!u
) { /* VQDMULH */
5426 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5429 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5433 } else { /* VQRDMULH */
5436 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5439 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5447 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
5448 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
5449 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
5453 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
5455 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5456 switch ((u
<< 2) | size
) {
5459 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5462 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
5465 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
5470 tcg_temp_free_ptr(fpstatus
);
5473 case NEON_3R_FLOAT_MULTIPLY
:
5475 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5476 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5478 tcg_temp_free_i32(tmp2
);
5479 tmp2
= neon_load_reg(rd
, pass
);
5481 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5483 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5486 tcg_temp_free_ptr(fpstatus
);
5489 case NEON_3R_FLOAT_CMP
:
5491 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5493 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
5496 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5498 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5501 tcg_temp_free_ptr(fpstatus
);
5504 case NEON_3R_FLOAT_ACMP
:
5506 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5508 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5510 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5512 tcg_temp_free_ptr(fpstatus
);
5515 case NEON_3R_FLOAT_MINMAX
:
5517 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5519 gen_helper_vfp_maxs(tmp
, tmp
, tmp2
, fpstatus
);
5521 gen_helper_vfp_mins(tmp
, tmp
, tmp2
, fpstatus
);
5523 tcg_temp_free_ptr(fpstatus
);
5526 case NEON_3R_FLOAT_MISC
:
5529 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5531 gen_helper_vfp_maxnums(tmp
, tmp
, tmp2
, fpstatus
);
5533 gen_helper_vfp_minnums(tmp
, tmp
, tmp2
, fpstatus
);
5535 tcg_temp_free_ptr(fpstatus
);
5538 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
5540 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
5546 /* VFMA, VFMS: fused multiply-add */
5547 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5548 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
5551 gen_helper_vfp_negs(tmp
, tmp
);
5553 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
5554 tcg_temp_free_i32(tmp3
);
5555 tcg_temp_free_ptr(fpstatus
);
5561 tcg_temp_free_i32(tmp2
);
5563 /* Save the result. For elementwise operations we can put it
5564 straight into the destination register. For pairwise operations
5565 we have to be careful to avoid clobbering the source operands. */
5566 if (pairwise
&& rd
== rm
) {
5567 neon_store_scratch(pass
, tmp
);
5569 neon_store_reg(rd
, pass
, tmp
);
5573 if (pairwise
&& rd
== rm
) {
5574 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5575 tmp
= neon_load_scratch(pass
);
5576 neon_store_reg(rd
, pass
, tmp
);
5579 /* End of 3 register same size operations. */
5580 } else if (insn
& (1 << 4)) {
5581 if ((insn
& 0x00380080) != 0) {
5582 /* Two registers and shift. */
5583 op
= (insn
>> 8) & 0xf;
5584 if (insn
& (1 << 7)) {
5592 while ((insn
& (1 << (size
+ 19))) == 0)
5595 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
5596 /* To avoid excessive duplication of ops we implement shift
5597 by immediate using the variable shift operations. */
5599 /* Shift by immediate:
5600 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5601 if (q
&& ((rd
| rm
) & 1)) {
5604 if (!u
&& (op
== 4 || op
== 6)) {
5607 /* Right shifts are encoded as N - shift, where N is the
5608 element size in bits. */
5610 shift
= shift
- (1 << (size
+ 3));
5618 imm
= (uint8_t) shift
;
5623 imm
= (uint16_t) shift
;
5634 for (pass
= 0; pass
< count
; pass
++) {
5636 neon_load_reg64(cpu_V0
, rm
+ pass
);
5637 tcg_gen_movi_i64(cpu_V1
, imm
);
5642 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5644 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5649 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5651 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5654 case 5: /* VSHL, VSLI */
5655 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5657 case 6: /* VQSHLU */
5658 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
5663 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5666 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5671 if (op
== 1 || op
== 3) {
5673 neon_load_reg64(cpu_V1
, rd
+ pass
);
5674 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5675 } else if (op
== 4 || (op
== 5 && u
)) {
5677 neon_load_reg64(cpu_V1
, rd
+ pass
);
5679 if (shift
< -63 || shift
> 63) {
5683 mask
= 0xffffffffffffffffull
>> -shift
;
5685 mask
= 0xffffffffffffffffull
<< shift
;
5688 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
5689 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5691 neon_store_reg64(cpu_V0
, rd
+ pass
);
5692 } else { /* size < 3 */
5693 /* Operands in T0 and T1. */
5694 tmp
= neon_load_reg(rm
, pass
);
5695 tmp2
= tcg_temp_new_i32();
5696 tcg_gen_movi_i32(tmp2
, imm
);
5700 GEN_NEON_INTEGER_OP(shl
);
5704 GEN_NEON_INTEGER_OP(rshl
);
5707 case 5: /* VSHL, VSLI */
5709 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
5710 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
5711 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
5715 case 6: /* VQSHLU */
5718 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
5722 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
5726 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
5734 GEN_NEON_INTEGER_OP_ENV(qshl
);
5737 tcg_temp_free_i32(tmp2
);
5739 if (op
== 1 || op
== 3) {
5741 tmp2
= neon_load_reg(rd
, pass
);
5742 gen_neon_add(size
, tmp
, tmp2
);
5743 tcg_temp_free_i32(tmp2
);
5744 } else if (op
== 4 || (op
== 5 && u
)) {
5749 mask
= 0xff >> -shift
;
5751 mask
= (uint8_t)(0xff << shift
);
5757 mask
= 0xffff >> -shift
;
5759 mask
= (uint16_t)(0xffff << shift
);
5763 if (shift
< -31 || shift
> 31) {
5767 mask
= 0xffffffffu
>> -shift
;
5769 mask
= 0xffffffffu
<< shift
;
5775 tmp2
= neon_load_reg(rd
, pass
);
5776 tcg_gen_andi_i32(tmp
, tmp
, mask
);
5777 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
5778 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5779 tcg_temp_free_i32(tmp2
);
5781 neon_store_reg(rd
, pass
, tmp
);
5784 } else if (op
< 10) {
5785 /* Shift by immediate and narrow:
5786 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5787 int input_unsigned
= (op
== 8) ? !u
: u
;
5791 shift
= shift
- (1 << (size
+ 3));
5794 tmp64
= tcg_const_i64(shift
);
5795 neon_load_reg64(cpu_V0
, rm
);
5796 neon_load_reg64(cpu_V1
, rm
+ 1);
5797 for (pass
= 0; pass
< 2; pass
++) {
5805 if (input_unsigned
) {
5806 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
5808 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
5811 if (input_unsigned
) {
5812 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
5814 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
5817 tmp
= tcg_temp_new_i32();
5818 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5819 neon_store_reg(rd
, pass
, tmp
);
5821 tcg_temp_free_i64(tmp64
);
5824 imm
= (uint16_t)shift
;
5828 imm
= (uint32_t)shift
;
5830 tmp2
= tcg_const_i32(imm
);
5831 tmp4
= neon_load_reg(rm
+ 1, 0);
5832 tmp5
= neon_load_reg(rm
+ 1, 1);
5833 for (pass
= 0; pass
< 2; pass
++) {
5835 tmp
= neon_load_reg(rm
, 0);
5839 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
5842 tmp3
= neon_load_reg(rm
, 1);
5846 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
5848 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
5849 tcg_temp_free_i32(tmp
);
5850 tcg_temp_free_i32(tmp3
);
5851 tmp
= tcg_temp_new_i32();
5852 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5853 neon_store_reg(rd
, pass
, tmp
);
5855 tcg_temp_free_i32(tmp2
);
5857 } else if (op
== 10) {
5859 if (q
|| (rd
& 1)) {
5862 tmp
= neon_load_reg(rm
, 0);
5863 tmp2
= neon_load_reg(rm
, 1);
5864 for (pass
= 0; pass
< 2; pass
++) {
5868 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5871 /* The shift is less than the width of the source
5872 type, so we can just shift the whole register. */
5873 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
5874 /* Widen the result of shift: we need to clear
5875 * the potential overflow bits resulting from
5876 * left bits of the narrow input appearing as
5877 * right bits of left the neighbour narrow
5879 if (size
< 2 || !u
) {
5882 imm
= (0xffu
>> (8 - shift
));
5884 } else if (size
== 1) {
5885 imm
= 0xffff >> (16 - shift
);
5888 imm
= 0xffffffff >> (32 - shift
);
5891 imm64
= imm
| (((uint64_t)imm
) << 32);
5895 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
5898 neon_store_reg64(cpu_V0
, rd
+ pass
);
5900 } else if (op
>= 14) {
5901 /* VCVT fixed-point. */
5902 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
5905 /* We have already masked out the must-be-1 top bit of imm6,
5906 * hence this 32-shift where the ARM ARM has 64-imm6.
5909 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5910 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
5913 gen_vfp_ulto(0, shift
, 1);
5915 gen_vfp_slto(0, shift
, 1);
5918 gen_vfp_toul(0, shift
, 1);
5920 gen_vfp_tosl(0, shift
, 1);
5922 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
5927 } else { /* (insn & 0x00380080) == 0 */
5929 if (q
&& (rd
& 1)) {
5933 op
= (insn
>> 8) & 0xf;
5934 /* One register and immediate. */
5935 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
5936 invert
= (insn
& (1 << 5)) != 0;
5937 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5938 * We choose to not special-case this and will behave as if a
5939 * valid constant encoding of 0 had been given.
5958 imm
= (imm
<< 8) | (imm
<< 24);
5961 imm
= (imm
<< 8) | 0xff;
5964 imm
= (imm
<< 16) | 0xffff;
5967 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
5975 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
5976 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
5982 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5983 if (op
& 1 && op
< 12) {
5984 tmp
= neon_load_reg(rd
, pass
);
5986 /* The immediate value has already been inverted, so
5988 tcg_gen_andi_i32(tmp
, tmp
, imm
);
5990 tcg_gen_ori_i32(tmp
, tmp
, imm
);
5994 tmp
= tcg_temp_new_i32();
5995 if (op
== 14 && invert
) {
5999 for (n
= 0; n
< 4; n
++) {
6000 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
6001 val
|= 0xff << (n
* 8);
6003 tcg_gen_movi_i32(tmp
, val
);
6005 tcg_gen_movi_i32(tmp
, imm
);
6008 neon_store_reg(rd
, pass
, tmp
);
6011 } else { /* (insn & 0x00800010 == 0x00800000) */
6013 op
= (insn
>> 8) & 0xf;
6014 if ((insn
& (1 << 6)) == 0) {
6015 /* Three registers of different lengths. */
6019 /* undefreq: bit 0 : UNDEF if size == 0
6020 * bit 1 : UNDEF if size == 1
6021 * bit 2 : UNDEF if size == 2
6022 * bit 3 : UNDEF if U == 1
6023 * Note that [2:0] set implies 'always UNDEF'
6026 /* prewiden, src1_wide, src2_wide, undefreq */
6027 static const int neon_3reg_wide
[16][4] = {
6028 {1, 0, 0, 0}, /* VADDL */
6029 {1, 1, 0, 0}, /* VADDW */
6030 {1, 0, 0, 0}, /* VSUBL */
6031 {1, 1, 0, 0}, /* VSUBW */
6032 {0, 1, 1, 0}, /* VADDHN */
6033 {0, 0, 0, 0}, /* VABAL */
6034 {0, 1, 1, 0}, /* VSUBHN */
6035 {0, 0, 0, 0}, /* VABDL */
6036 {0, 0, 0, 0}, /* VMLAL */
6037 {0, 0, 0, 9}, /* VQDMLAL */
6038 {0, 0, 0, 0}, /* VMLSL */
6039 {0, 0, 0, 9}, /* VQDMLSL */
6040 {0, 0, 0, 0}, /* Integer VMULL */
6041 {0, 0, 0, 1}, /* VQDMULL */
6042 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6043 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6046 prewiden
= neon_3reg_wide
[op
][0];
6047 src1_wide
= neon_3reg_wide
[op
][1];
6048 src2_wide
= neon_3reg_wide
[op
][2];
6049 undefreq
= neon_3reg_wide
[op
][3];
6051 if ((undefreq
& (1 << size
)) ||
6052 ((undefreq
& 8) && u
)) {
6055 if ((src1_wide
&& (rn
& 1)) ||
6056 (src2_wide
&& (rm
& 1)) ||
6057 (!src2_wide
&& (rd
& 1))) {
6061 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6062 * outside the loop below as it only performs a single pass.
6064 if (op
== 14 && size
== 2) {
6065 TCGv_i64 tcg_rn
, tcg_rm
, tcg_rd
;
6067 if (!arm_feature(env
, ARM_FEATURE_V8_PMULL
)) {
6070 tcg_rn
= tcg_temp_new_i64();
6071 tcg_rm
= tcg_temp_new_i64();
6072 tcg_rd
= tcg_temp_new_i64();
6073 neon_load_reg64(tcg_rn
, rn
);
6074 neon_load_reg64(tcg_rm
, rm
);
6075 gen_helper_neon_pmull_64_lo(tcg_rd
, tcg_rn
, tcg_rm
);
6076 neon_store_reg64(tcg_rd
, rd
);
6077 gen_helper_neon_pmull_64_hi(tcg_rd
, tcg_rn
, tcg_rm
);
6078 neon_store_reg64(tcg_rd
, rd
+ 1);
6079 tcg_temp_free_i64(tcg_rn
);
6080 tcg_temp_free_i64(tcg_rm
);
6081 tcg_temp_free_i64(tcg_rd
);
6085 /* Avoid overlapping operands. Wide source operands are
6086 always aligned so will never overlap with wide
6087 destinations in problematic ways. */
6088 if (rd
== rm
&& !src2_wide
) {
6089 tmp
= neon_load_reg(rm
, 1);
6090 neon_store_scratch(2, tmp
);
6091 } else if (rd
== rn
&& !src1_wide
) {
6092 tmp
= neon_load_reg(rn
, 1);
6093 neon_store_scratch(2, tmp
);
6095 TCGV_UNUSED_I32(tmp3
);
6096 for (pass
= 0; pass
< 2; pass
++) {
6098 neon_load_reg64(cpu_V0
, rn
+ pass
);
6099 TCGV_UNUSED_I32(tmp
);
6101 if (pass
== 1 && rd
== rn
) {
6102 tmp
= neon_load_scratch(2);
6104 tmp
= neon_load_reg(rn
, pass
);
6107 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6111 neon_load_reg64(cpu_V1
, rm
+ pass
);
6112 TCGV_UNUSED_I32(tmp2
);
6114 if (pass
== 1 && rd
== rm
) {
6115 tmp2
= neon_load_scratch(2);
6117 tmp2
= neon_load_reg(rm
, pass
);
6120 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
6124 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6125 gen_neon_addl(size
);
6127 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6128 gen_neon_subl(size
);
6130 case 5: case 7: /* VABAL, VABDL */
6131 switch ((size
<< 1) | u
) {
6133 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
6136 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
6139 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
6142 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
6145 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
6148 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
6152 tcg_temp_free_i32(tmp2
);
6153 tcg_temp_free_i32(tmp
);
6155 case 8: case 9: case 10: case 11: case 12: case 13:
6156 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6157 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6159 case 14: /* Polynomial VMULL */
6160 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
6161 tcg_temp_free_i32(tmp2
);
6162 tcg_temp_free_i32(tmp
);
6164 default: /* 15 is RESERVED: caught earlier */
6169 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6170 neon_store_reg64(cpu_V0
, rd
+ pass
);
6171 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
6173 neon_load_reg64(cpu_V1
, rd
+ pass
);
6175 case 10: /* VMLSL */
6176 gen_neon_negl(cpu_V0
, size
);
6178 case 5: case 8: /* VABAL, VMLAL */
6179 gen_neon_addl(size
);
6181 case 9: case 11: /* VQDMLAL, VQDMLSL */
6182 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6184 gen_neon_negl(cpu_V0
, size
);
6186 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6191 neon_store_reg64(cpu_V0
, rd
+ pass
);
6192 } else if (op
== 4 || op
== 6) {
6193 /* Narrowing operation. */
6194 tmp
= tcg_temp_new_i32();
6198 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
6201 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
6204 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6205 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
6212 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
6215 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
6218 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
6219 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6220 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
6228 neon_store_reg(rd
, 0, tmp3
);
6229 neon_store_reg(rd
, 1, tmp
);
6232 /* Write back the result. */
6233 neon_store_reg64(cpu_V0
, rd
+ pass
);
6237 /* Two registers and a scalar. NB that for ops of this form
6238 * the ARM ARM labels bit 24 as Q, but it is in our variable
6245 case 1: /* Float VMLA scalar */
6246 case 5: /* Floating point VMLS scalar */
6247 case 9: /* Floating point VMUL scalar */
6252 case 0: /* Integer VMLA scalar */
6253 case 4: /* Integer VMLS scalar */
6254 case 8: /* Integer VMUL scalar */
6255 case 12: /* VQDMULH scalar */
6256 case 13: /* VQRDMULH scalar */
6257 if (u
&& ((rd
| rn
) & 1)) {
6260 tmp
= neon_get_scalar(size
, rm
);
6261 neon_store_scratch(0, tmp
);
6262 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6263 tmp
= neon_load_scratch(0);
6264 tmp2
= neon_load_reg(rn
, pass
);
6267 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6269 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6271 } else if (op
== 13) {
6273 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6275 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6277 } else if (op
& 1) {
6278 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6279 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6280 tcg_temp_free_ptr(fpstatus
);
6283 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6284 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6285 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6289 tcg_temp_free_i32(tmp2
);
6292 tmp2
= neon_load_reg(rd
, pass
);
6295 gen_neon_add(size
, tmp
, tmp2
);
6299 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6300 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6301 tcg_temp_free_ptr(fpstatus
);
6305 gen_neon_rsb(size
, tmp
, tmp2
);
6309 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6310 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6311 tcg_temp_free_ptr(fpstatus
);
6317 tcg_temp_free_i32(tmp2
);
6319 neon_store_reg(rd
, pass
, tmp
);
6322 case 3: /* VQDMLAL scalar */
6323 case 7: /* VQDMLSL scalar */
6324 case 11: /* VQDMULL scalar */
6329 case 2: /* VMLAL sclar */
6330 case 6: /* VMLSL scalar */
6331 case 10: /* VMULL scalar */
6335 tmp2
= neon_get_scalar(size
, rm
);
6336 /* We need a copy of tmp2 because gen_neon_mull
6337 * deletes it during pass 0. */
6338 tmp4
= tcg_temp_new_i32();
6339 tcg_gen_mov_i32(tmp4
, tmp2
);
6340 tmp3
= neon_load_reg(rn
, 1);
6342 for (pass
= 0; pass
< 2; pass
++) {
6344 tmp
= neon_load_reg(rn
, 0);
6349 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6351 neon_load_reg64(cpu_V1
, rd
+ pass
);
6355 gen_neon_negl(cpu_V0
, size
);
6358 gen_neon_addl(size
);
6361 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6363 gen_neon_negl(cpu_V0
, size
);
6365 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6371 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6376 neon_store_reg64(cpu_V0
, rd
+ pass
);
6381 default: /* 14 and 15 are RESERVED */
6385 } else { /* size == 3 */
6388 imm
= (insn
>> 8) & 0xf;
6393 if (q
&& ((rd
| rn
| rm
) & 1)) {
6398 neon_load_reg64(cpu_V0
, rn
);
6400 neon_load_reg64(cpu_V1
, rn
+ 1);
6402 } else if (imm
== 8) {
6403 neon_load_reg64(cpu_V0
, rn
+ 1);
6405 neon_load_reg64(cpu_V1
, rm
);
6408 tmp64
= tcg_temp_new_i64();
6410 neon_load_reg64(cpu_V0
, rn
);
6411 neon_load_reg64(tmp64
, rn
+ 1);
6413 neon_load_reg64(cpu_V0
, rn
+ 1);
6414 neon_load_reg64(tmp64
, rm
);
6416 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
6417 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
6418 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6420 neon_load_reg64(cpu_V1
, rm
);
6422 neon_load_reg64(cpu_V1
, rm
+ 1);
6425 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6426 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
6427 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
6428 tcg_temp_free_i64(tmp64
);
6431 neon_load_reg64(cpu_V0
, rn
);
6432 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
6433 neon_load_reg64(cpu_V1
, rm
);
6434 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6435 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6437 neon_store_reg64(cpu_V0
, rd
);
6439 neon_store_reg64(cpu_V1
, rd
+ 1);
6441 } else if ((insn
& (1 << 11)) == 0) {
6442 /* Two register misc. */
6443 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
6444 size
= (insn
>> 18) & 3;
6445 /* UNDEF for unknown op values and bad op-size combinations */
6446 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
6449 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
6450 q
&& ((rm
| rd
) & 1)) {
6454 case NEON_2RM_VREV64
:
6455 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
6456 tmp
= neon_load_reg(rm
, pass
* 2);
6457 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
6459 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6460 case 1: gen_swap_half(tmp
); break;
6461 case 2: /* no-op */ break;
6464 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
6466 neon_store_reg(rd
, pass
* 2, tmp2
);
6469 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
6470 case 1: gen_swap_half(tmp2
); break;
6473 neon_store_reg(rd
, pass
* 2, tmp2
);
6477 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
6478 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
6479 for (pass
= 0; pass
< q
+ 1; pass
++) {
6480 tmp
= neon_load_reg(rm
, pass
* 2);
6481 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
6482 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
6483 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
6485 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
6486 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
6487 case 2: tcg_gen_add_i64(CPU_V001
); break;
6490 if (op
>= NEON_2RM_VPADAL
) {
6492 neon_load_reg64(cpu_V1
, rd
+ pass
);
6493 gen_neon_addl(size
);
6495 neon_store_reg64(cpu_V0
, rd
+ pass
);
6501 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
6502 tmp
= neon_load_reg(rm
, n
);
6503 tmp2
= neon_load_reg(rd
, n
+ 1);
6504 neon_store_reg(rm
, n
, tmp2
);
6505 neon_store_reg(rd
, n
+ 1, tmp
);
6512 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
6517 if (gen_neon_zip(rd
, rm
, size
, q
)) {
6521 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
6522 /* also VQMOVUN; op field and mnemonics don't line up */
6526 TCGV_UNUSED_I32(tmp2
);
6527 for (pass
= 0; pass
< 2; pass
++) {
6528 neon_load_reg64(cpu_V0
, rm
+ pass
);
6529 tmp
= tcg_temp_new_i32();
6530 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
6535 neon_store_reg(rd
, 0, tmp2
);
6536 neon_store_reg(rd
, 1, tmp
);
6540 case NEON_2RM_VSHLL
:
6541 if (q
|| (rd
& 1)) {
6544 tmp
= neon_load_reg(rm
, 0);
6545 tmp2
= neon_load_reg(rm
, 1);
6546 for (pass
= 0; pass
< 2; pass
++) {
6549 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
6550 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
6551 neon_store_reg64(cpu_V0
, rd
+ pass
);
6554 case NEON_2RM_VCVT_F16_F32
:
6555 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
6559 tmp
= tcg_temp_new_i32();
6560 tmp2
= tcg_temp_new_i32();
6561 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
6562 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6563 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
6564 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6565 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6566 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6567 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
6568 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6569 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
6570 neon_store_reg(rd
, 0, tmp2
);
6571 tmp2
= tcg_temp_new_i32();
6572 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6573 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6574 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6575 neon_store_reg(rd
, 1, tmp2
);
6576 tcg_temp_free_i32(tmp
);
6578 case NEON_2RM_VCVT_F32_F16
:
6579 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
6583 tmp3
= tcg_temp_new_i32();
6584 tmp
= neon_load_reg(rm
, 0);
6585 tmp2
= neon_load_reg(rm
, 1);
6586 tcg_gen_ext16u_i32(tmp3
, tmp
);
6587 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6588 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
6589 tcg_gen_shri_i32(tmp3
, tmp
, 16);
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
, 1));
6592 tcg_temp_free_i32(tmp
);
6593 tcg_gen_ext16u_i32(tmp3
, tmp2
);
6594 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6595 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
6596 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
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
, 3));
6599 tcg_temp_free_i32(tmp2
);
6600 tcg_temp_free_i32(tmp3
);
6602 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
6603 if (!arm_feature(env
, ARM_FEATURE_V8_AES
)
6604 || ((rm
| rd
) & 1)) {
6607 tmp
= tcg_const_i32(rd
);
6608 tmp2
= tcg_const_i32(rm
);
6610 /* Bit 6 is the lowest opcode bit; it distinguishes between
6611 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6613 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
6615 if (op
== NEON_2RM_AESE
) {
6616 gen_helper_crypto_aese(cpu_env
, tmp
, tmp2
, tmp3
);
6618 gen_helper_crypto_aesmc(cpu_env
, tmp
, tmp2
, tmp3
);
6620 tcg_temp_free_i32(tmp
);
6621 tcg_temp_free_i32(tmp2
);
6622 tcg_temp_free_i32(tmp3
);
6624 case NEON_2RM_SHA1H
:
6625 if (!arm_feature(env
, ARM_FEATURE_V8_SHA1
)
6626 || ((rm
| rd
) & 1)) {
6629 tmp
= tcg_const_i32(rd
);
6630 tmp2
= tcg_const_i32(rm
);
6632 gen_helper_crypto_sha1h(cpu_env
, tmp
, tmp2
);
6634 tcg_temp_free_i32(tmp
);
6635 tcg_temp_free_i32(tmp2
);
6637 case NEON_2RM_SHA1SU1
:
6638 if ((rm
| rd
) & 1) {
6641 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6643 if (!arm_feature(env
, ARM_FEATURE_V8_SHA256
)) {
6646 } else if (!arm_feature(env
, ARM_FEATURE_V8_SHA1
)) {
6649 tmp
= tcg_const_i32(rd
);
6650 tmp2
= tcg_const_i32(rm
);
6652 gen_helper_crypto_sha256su0(cpu_env
, tmp
, tmp2
);
6654 gen_helper_crypto_sha1su1(cpu_env
, tmp
, tmp2
);
6656 tcg_temp_free_i32(tmp
);
6657 tcg_temp_free_i32(tmp2
);
6661 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6662 if (neon_2rm_is_float_op(op
)) {
6663 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
6664 neon_reg_offset(rm
, pass
));
6665 TCGV_UNUSED_I32(tmp
);
6667 tmp
= neon_load_reg(rm
, pass
);
6670 case NEON_2RM_VREV32
:
6672 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6673 case 1: gen_swap_half(tmp
); break;
6677 case NEON_2RM_VREV16
:
6682 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
6683 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
6684 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
6690 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
6691 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
6692 case 2: gen_helper_clz(tmp
, tmp
); break;
6697 gen_helper_neon_cnt_u8(tmp
, tmp
);
6700 tcg_gen_not_i32(tmp
, tmp
);
6702 case NEON_2RM_VQABS
:
6705 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
6708 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
6711 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
6716 case NEON_2RM_VQNEG
:
6719 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
6722 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
6725 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
6730 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
6731 tmp2
= tcg_const_i32(0);
6733 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
6734 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
6735 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
6738 tcg_temp_free_i32(tmp2
);
6739 if (op
== NEON_2RM_VCLE0
) {
6740 tcg_gen_not_i32(tmp
, tmp
);
6743 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
6744 tmp2
= tcg_const_i32(0);
6746 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
6747 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
6748 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
6751 tcg_temp_free_i32(tmp2
);
6752 if (op
== NEON_2RM_VCLT0
) {
6753 tcg_gen_not_i32(tmp
, tmp
);
6756 case NEON_2RM_VCEQ0
:
6757 tmp2
= tcg_const_i32(0);
6759 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
6760 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
6761 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
6764 tcg_temp_free_i32(tmp2
);
6768 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
6769 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
6770 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
6775 tmp2
= tcg_const_i32(0);
6776 gen_neon_rsb(size
, tmp
, tmp2
);
6777 tcg_temp_free_i32(tmp2
);
6779 case NEON_2RM_VCGT0_F
:
6781 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6782 tmp2
= tcg_const_i32(0);
6783 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6784 tcg_temp_free_i32(tmp2
);
6785 tcg_temp_free_ptr(fpstatus
);
6788 case NEON_2RM_VCGE0_F
:
6790 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6791 tmp2
= tcg_const_i32(0);
6792 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6793 tcg_temp_free_i32(tmp2
);
6794 tcg_temp_free_ptr(fpstatus
);
6797 case NEON_2RM_VCEQ0_F
:
6799 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6800 tmp2
= tcg_const_i32(0);
6801 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6802 tcg_temp_free_i32(tmp2
);
6803 tcg_temp_free_ptr(fpstatus
);
6806 case NEON_2RM_VCLE0_F
:
6808 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6809 tmp2
= tcg_const_i32(0);
6810 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
6811 tcg_temp_free_i32(tmp2
);
6812 tcg_temp_free_ptr(fpstatus
);
6815 case NEON_2RM_VCLT0_F
:
6817 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6818 tmp2
= tcg_const_i32(0);
6819 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
6820 tcg_temp_free_i32(tmp2
);
6821 tcg_temp_free_ptr(fpstatus
);
6824 case NEON_2RM_VABS_F
:
6827 case NEON_2RM_VNEG_F
:
6831 tmp2
= neon_load_reg(rd
, pass
);
6832 neon_store_reg(rm
, pass
, tmp2
);
6835 tmp2
= neon_load_reg(rd
, pass
);
6837 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
6838 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
6841 neon_store_reg(rm
, pass
, tmp2
);
6843 case NEON_2RM_VRINTN
:
6844 case NEON_2RM_VRINTA
:
6845 case NEON_2RM_VRINTM
:
6846 case NEON_2RM_VRINTP
:
6847 case NEON_2RM_VRINTZ
:
6850 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6853 if (op
== NEON_2RM_VRINTZ
) {
6854 rmode
= FPROUNDING_ZERO
;
6856 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
6859 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
6860 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6862 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpstatus
);
6863 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6865 tcg_temp_free_ptr(fpstatus
);
6866 tcg_temp_free_i32(tcg_rmode
);
6869 case NEON_2RM_VRINTX
:
6871 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6872 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpstatus
);
6873 tcg_temp_free_ptr(fpstatus
);
6876 case NEON_2RM_VCVTAU
:
6877 case NEON_2RM_VCVTAS
:
6878 case NEON_2RM_VCVTNU
:
6879 case NEON_2RM_VCVTNS
:
6880 case NEON_2RM_VCVTPU
:
6881 case NEON_2RM_VCVTPS
:
6882 case NEON_2RM_VCVTMU
:
6883 case NEON_2RM_VCVTMS
:
6885 bool is_signed
= !extract32(insn
, 7, 1);
6886 TCGv_ptr fpst
= get_fpstatus_ptr(1);
6887 TCGv_i32 tcg_rmode
, tcg_shift
;
6888 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
6890 tcg_shift
= tcg_const_i32(0);
6891 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
6892 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6896 gen_helper_vfp_tosls(cpu_F0s
, cpu_F0s
,
6899 gen_helper_vfp_touls(cpu_F0s
, cpu_F0s
,
6903 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6905 tcg_temp_free_i32(tcg_rmode
);
6906 tcg_temp_free_i32(tcg_shift
);
6907 tcg_temp_free_ptr(fpst
);
6910 case NEON_2RM_VRECPE
:
6912 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6913 gen_helper_recpe_u32(tmp
, tmp
, fpstatus
);
6914 tcg_temp_free_ptr(fpstatus
);
6917 case NEON_2RM_VRSQRTE
:
6919 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6920 gen_helper_rsqrte_u32(tmp
, tmp
, fpstatus
);
6921 tcg_temp_free_ptr(fpstatus
);
6924 case NEON_2RM_VRECPE_F
:
6926 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6927 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
6928 tcg_temp_free_ptr(fpstatus
);
6931 case NEON_2RM_VRSQRTE_F
:
6933 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6934 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
6935 tcg_temp_free_ptr(fpstatus
);
6938 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
6941 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
6944 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
6945 gen_vfp_tosiz(0, 1);
6947 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
6948 gen_vfp_touiz(0, 1);
6951 /* Reserved op values were caught by the
6952 * neon_2rm_sizes[] check earlier.
6956 if (neon_2rm_is_float_op(op
)) {
6957 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
6958 neon_reg_offset(rd
, pass
));
6960 neon_store_reg(rd
, pass
, tmp
);
6965 } else if ((insn
& (1 << 10)) == 0) {
6967 int n
= ((insn
>> 8) & 3) + 1;
6968 if ((rn
+ n
) > 32) {
6969 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6970 * helper function running off the end of the register file.
6975 if (insn
& (1 << 6)) {
6976 tmp
= neon_load_reg(rd
, 0);
6978 tmp
= tcg_temp_new_i32();
6979 tcg_gen_movi_i32(tmp
, 0);
6981 tmp2
= neon_load_reg(rm
, 0);
6982 tmp4
= tcg_const_i32(rn
);
6983 tmp5
= tcg_const_i32(n
);
6984 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
6985 tcg_temp_free_i32(tmp
);
6986 if (insn
& (1 << 6)) {
6987 tmp
= neon_load_reg(rd
, 1);
6989 tmp
= tcg_temp_new_i32();
6990 tcg_gen_movi_i32(tmp
, 0);
6992 tmp3
= neon_load_reg(rm
, 1);
6993 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
6994 tcg_temp_free_i32(tmp5
);
6995 tcg_temp_free_i32(tmp4
);
6996 neon_store_reg(rd
, 0, tmp2
);
6997 neon_store_reg(rd
, 1, tmp3
);
6998 tcg_temp_free_i32(tmp
);
6999 } else if ((insn
& 0x380) == 0) {
7001 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
7004 if (insn
& (1 << 19)) {
7005 tmp
= neon_load_reg(rm
, 1);
7007 tmp
= neon_load_reg(rm
, 0);
7009 if (insn
& (1 << 16)) {
7010 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
7011 } else if (insn
& (1 << 17)) {
7012 if ((insn
>> 18) & 1)
7013 gen_neon_dup_high16(tmp
);
7015 gen_neon_dup_low16(tmp
);
7017 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7018 tmp2
= tcg_temp_new_i32();
7019 tcg_gen_mov_i32(tmp2
, tmp
);
7020 neon_store_reg(rd
, pass
, tmp2
);
7022 tcg_temp_free_i32(tmp
);
7031 static int disas_coproc_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
7033 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
7034 const ARMCPRegInfo
*ri
;
7036 cpnum
= (insn
>> 8) & 0xf;
7038 /* First check for coprocessor space used for XScale/iwMMXt insns */
7039 if (arm_feature(env
, ARM_FEATURE_XSCALE
) && (cpnum
< 2)) {
7040 if (extract32(s
->c15_cpar
, cpnum
, 1) == 0) {
7043 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
7044 return disas_iwmmxt_insn(env
, s
, insn
);
7045 } else if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
7046 return disas_dsp_insn(env
, s
, insn
);
7051 /* Otherwise treat as a generic register access */
7052 is64
= (insn
& (1 << 25)) == 0;
7053 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
7061 opc1
= (insn
>> 4) & 0xf;
7063 rt2
= (insn
>> 16) & 0xf;
7065 crn
= (insn
>> 16) & 0xf;
7066 opc1
= (insn
>> 21) & 7;
7067 opc2
= (insn
>> 5) & 7;
7070 isread
= (insn
>> 20) & 1;
7071 rt
= (insn
>> 12) & 0xf;
7073 ri
= get_arm_cp_reginfo(s
->cp_regs
,
7074 ENCODE_CP_REG(cpnum
, is64
, crn
, crm
, opc1
, opc2
));
7076 /* Check access permissions */
7077 if (!cp_access_ok(s
->current_pl
, ri
, isread
)) {
7082 (arm_feature(env
, ARM_FEATURE_XSCALE
) && cpnum
< 14)) {
7083 /* Emit code to perform further access permissions checks at
7084 * runtime; this may result in an exception.
7085 * Note that on XScale all cp0..c13 registers do an access check
7086 * call in order to handle c15_cpar.
7092 /* Note that since we are an implementation which takes an
7093 * exception on a trapped conditional instruction only if the
7094 * instruction passes its condition code check, we can take
7095 * advantage of the clause in the ARM ARM that allows us to set
7096 * the COND field in the instruction to 0xE in all cases.
7097 * We could fish the actual condition out of the insn (ARM)
7098 * or the condexec bits (Thumb) but it isn't necessary.
7103 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7106 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7107 rt
, isread
, s
->thumb
);
7112 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7115 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7116 rt
, isread
, s
->thumb
);
7120 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7121 * so this can only happen if this is an ARMv7 or earlier CPU,
7122 * in which case the syndrome information won't actually be
7125 assert(!arm_feature(env
, ARM_FEATURE_V8
));
7126 syndrome
= syn_uncategorized();
7130 gen_set_pc_im(s
, s
->pc
);
7131 tmpptr
= tcg_const_ptr(ri
);
7132 tcg_syn
= tcg_const_i32(syndrome
);
7133 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
);
7134 tcg_temp_free_ptr(tmpptr
);
7135 tcg_temp_free_i32(tcg_syn
);
7138 /* Handle special cases first */
7139 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
7146 gen_set_pc_im(s
, s
->pc
);
7147 s
->is_jmp
= DISAS_WFI
;
7153 if (use_icount
&& (ri
->type
& ARM_CP_IO
)) {
7162 if (ri
->type
& ARM_CP_CONST
) {
7163 tmp64
= tcg_const_i64(ri
->resetvalue
);
7164 } else if (ri
->readfn
) {
7166 tmp64
= tcg_temp_new_i64();
7167 tmpptr
= tcg_const_ptr(ri
);
7168 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
7169 tcg_temp_free_ptr(tmpptr
);
7171 tmp64
= tcg_temp_new_i64();
7172 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7174 tmp
= tcg_temp_new_i32();
7175 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7176 store_reg(s
, rt
, tmp
);
7177 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7178 tmp
= tcg_temp_new_i32();
7179 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7180 tcg_temp_free_i64(tmp64
);
7181 store_reg(s
, rt2
, tmp
);
7184 if (ri
->type
& ARM_CP_CONST
) {
7185 tmp
= tcg_const_i32(ri
->resetvalue
);
7186 } else if (ri
->readfn
) {
7188 tmp
= tcg_temp_new_i32();
7189 tmpptr
= tcg_const_ptr(ri
);
7190 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
7191 tcg_temp_free_ptr(tmpptr
);
7193 tmp
= load_cpu_offset(ri
->fieldoffset
);
7196 /* Destination register of r15 for 32 bit loads sets
7197 * the condition codes from the high 4 bits of the value
7200 tcg_temp_free_i32(tmp
);
7202 store_reg(s
, rt
, tmp
);
7207 if (ri
->type
& ARM_CP_CONST
) {
7208 /* If not forbidden by access permissions, treat as WI */
7213 TCGv_i32 tmplo
, tmphi
;
7214 TCGv_i64 tmp64
= tcg_temp_new_i64();
7215 tmplo
= load_reg(s
, rt
);
7216 tmphi
= load_reg(s
, rt2
);
7217 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
7218 tcg_temp_free_i32(tmplo
);
7219 tcg_temp_free_i32(tmphi
);
7221 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
7222 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
7223 tcg_temp_free_ptr(tmpptr
);
7225 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7227 tcg_temp_free_i64(tmp64
);
7232 tmp
= load_reg(s
, rt
);
7233 tmpptr
= tcg_const_ptr(ri
);
7234 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
7235 tcg_temp_free_ptr(tmpptr
);
7236 tcg_temp_free_i32(tmp
);
7238 TCGv_i32 tmp
= load_reg(s
, rt
);
7239 store_cpu_offset(tmp
, ri
->fieldoffset
);
7244 if (use_icount
&& (ri
->type
& ARM_CP_IO
)) {
7245 /* I/O operations must end the TB here (whether read or write) */
7248 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
7249 /* We default to ending the TB on a coprocessor register write,
7250 * but allow this to be suppressed by the register definition
7251 * (usually only necessary to work around guest bugs).
7259 /* Unknown register; this might be a guest error or a QEMU
7260 * unimplemented feature.
7263 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7264 "64 bit system register cp:%d opc1: %d crm:%d\n",
7265 isread
? "read" : "write", cpnum
, opc1
, crm
);
7267 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7268 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d\n",
7269 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
);
7276 /* Store a 64-bit value to a register pair. Clobbers val. */
7277 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
7280 tmp
= tcg_temp_new_i32();
7281 tcg_gen_trunc_i64_i32(tmp
, val
);
7282 store_reg(s
, rlow
, tmp
);
7283 tmp
= tcg_temp_new_i32();
7284 tcg_gen_shri_i64(val
, val
, 32);
7285 tcg_gen_trunc_i64_i32(tmp
, val
);
7286 store_reg(s
, rhigh
, tmp
);
7289 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7290 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
7295 /* Load value and extend to 64 bits. */
7296 tmp
= tcg_temp_new_i64();
7297 tmp2
= load_reg(s
, rlow
);
7298 tcg_gen_extu_i32_i64(tmp
, tmp2
);
7299 tcg_temp_free_i32(tmp2
);
7300 tcg_gen_add_i64(val
, val
, tmp
);
7301 tcg_temp_free_i64(tmp
);
7304 /* load and add a 64-bit value from a register pair. */
7305 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
7311 /* Load 64-bit value rd:rn. */
7312 tmpl
= load_reg(s
, rlow
);
7313 tmph
= load_reg(s
, rhigh
);
7314 tmp
= tcg_temp_new_i64();
7315 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
7316 tcg_temp_free_i32(tmpl
);
7317 tcg_temp_free_i32(tmph
);
7318 tcg_gen_add_i64(val
, val
, tmp
);
7319 tcg_temp_free_i64(tmp
);
7322 /* Set N and Z flags from hi|lo. */
7323 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
7325 tcg_gen_mov_i32(cpu_NF
, hi
);
7326 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
7329 /* Load/Store exclusive instructions are implemented by remembering
7330 the value/address loaded, and seeing if these are the same
7331 when the store is performed. This should be sufficient to implement
7332 the architecturally mandated semantics, and avoids having to monitor
7335 In system emulation mode only one CPU will be running at once, so
7336 this sequence is effectively atomic. In user emulation mode we
7337 throw an exception and handle the atomic operation elsewhere. */
7338 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
7339 TCGv_i32 addr
, int size
)
7341 TCGv_i32 tmp
= tcg_temp_new_i32();
7347 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
7350 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
7354 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
7361 TCGv_i32 tmp2
= tcg_temp_new_i32();
7362 TCGv_i32 tmp3
= tcg_temp_new_i32();
7364 tcg_gen_addi_i32(tmp2
, addr
, 4);
7365 gen_aa32_ld32u(tmp3
, tmp2
, get_mem_index(s
));
7366 tcg_temp_free_i32(tmp2
);
7367 tcg_gen_concat_i32_i64(cpu_exclusive_val
, tmp
, tmp3
);
7368 store_reg(s
, rt2
, tmp3
);
7370 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
7373 store_reg(s
, rt
, tmp
);
7374 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
7377 static void gen_clrex(DisasContext
*s
)
7379 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7382 #ifdef CONFIG_USER_ONLY
7383 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7384 TCGv_i32 addr
, int size
)
7386 tcg_gen_extu_i32_i64(cpu_exclusive_test
, addr
);
7387 tcg_gen_movi_i32(cpu_exclusive_info
,
7388 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
7389 gen_exception_internal_insn(s
, 4, EXCP_STREX
);
7392 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7393 TCGv_i32 addr
, int size
)
7396 TCGv_i64 val64
, extaddr
;
7400 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7406 fail_label
= gen_new_label();
7407 done_label
= gen_new_label();
7408 extaddr
= tcg_temp_new_i64();
7409 tcg_gen_extu_i32_i64(extaddr
, addr
);
7410 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
7411 tcg_temp_free_i64(extaddr
);
7413 tmp
= tcg_temp_new_i32();
7416 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
7419 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
7423 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
7429 val64
= tcg_temp_new_i64();
7431 TCGv_i32 tmp2
= tcg_temp_new_i32();
7432 TCGv_i32 tmp3
= tcg_temp_new_i32();
7433 tcg_gen_addi_i32(tmp2
, addr
, 4);
7434 gen_aa32_ld32u(tmp3
, tmp2
, get_mem_index(s
));
7435 tcg_temp_free_i32(tmp2
);
7436 tcg_gen_concat_i32_i64(val64
, tmp
, tmp3
);
7437 tcg_temp_free_i32(tmp3
);
7439 tcg_gen_extu_i32_i64(val64
, tmp
);
7441 tcg_temp_free_i32(tmp
);
7443 tcg_gen_brcond_i64(TCG_COND_NE
, val64
, cpu_exclusive_val
, fail_label
);
7444 tcg_temp_free_i64(val64
);
7446 tmp
= load_reg(s
, rt
);
7449 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
7452 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
7456 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7461 tcg_temp_free_i32(tmp
);
7463 tcg_gen_addi_i32(addr
, addr
, 4);
7464 tmp
= load_reg(s
, rt2
);
7465 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7466 tcg_temp_free_i32(tmp
);
7468 tcg_gen_movi_i32(cpu_R
[rd
], 0);
7469 tcg_gen_br(done_label
);
7470 gen_set_label(fail_label
);
7471 tcg_gen_movi_i32(cpu_R
[rd
], 1);
7472 gen_set_label(done_label
);
7473 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7480 * @mode: mode field from insn (which stack to store to)
7481 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7482 * @writeback: true if writeback bit set
7484 * Generate code for the SRS (Store Return State) insn.
7486 static void gen_srs(DisasContext
*s
,
7487 uint32_t mode
, uint32_t amode
, bool writeback
)
7490 TCGv_i32 addr
= tcg_temp_new_i32();
7491 TCGv_i32 tmp
= tcg_const_i32(mode
);
7492 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
7493 tcg_temp_free_i32(tmp
);
7510 tcg_gen_addi_i32(addr
, addr
, offset
);
7511 tmp
= load_reg(s
, 14);
7512 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7513 tcg_temp_free_i32(tmp
);
7514 tmp
= load_cpu_field(spsr
);
7515 tcg_gen_addi_i32(addr
, addr
, 4);
7516 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7517 tcg_temp_free_i32(tmp
);
7535 tcg_gen_addi_i32(addr
, addr
, offset
);
7536 tmp
= tcg_const_i32(mode
);
7537 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
7538 tcg_temp_free_i32(tmp
);
7540 tcg_temp_free_i32(addr
);
7543 static void disas_arm_insn(CPUARMState
* env
, DisasContext
*s
)
7545 unsigned int cond
, insn
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
7552 insn
= arm_ldl_code(env
, s
->pc
, s
->bswap_code
);
7555 /* M variants do not implement ARM mode. */
7560 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7561 * choose to UNDEF. In ARMv5 and above the space is used
7562 * for miscellaneous unconditional instructions.
7566 /* Unconditional instructions. */
7567 if (((insn
>> 25) & 7) == 1) {
7568 /* NEON Data processing. */
7569 if (!arm_feature(env
, ARM_FEATURE_NEON
))
7572 if (disas_neon_data_insn(env
, s
, insn
))
7576 if ((insn
& 0x0f100000) == 0x04000000) {
7577 /* NEON load/store. */
7578 if (!arm_feature(env
, ARM_FEATURE_NEON
))
7581 if (disas_neon_ls_insn(env
, s
, insn
))
7585 if ((insn
& 0x0f000e10) == 0x0e000a00) {
7587 if (disas_vfp_insn(env
, s
, insn
)) {
7592 if (((insn
& 0x0f30f000) == 0x0510f000) ||
7593 ((insn
& 0x0f30f010) == 0x0710f000)) {
7594 if ((insn
& (1 << 22)) == 0) {
7596 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
7600 /* Otherwise PLD; v5TE+ */
7604 if (((insn
& 0x0f70f000) == 0x0450f000) ||
7605 ((insn
& 0x0f70f010) == 0x0650f000)) {
7607 return; /* PLI; V7 */
7609 if (((insn
& 0x0f700000) == 0x04100000) ||
7610 ((insn
& 0x0f700010) == 0x06100000)) {
7611 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
7614 return; /* v7MP: Unallocated memory hint: must NOP */
7617 if ((insn
& 0x0ffffdff) == 0x01010000) {
7620 if (((insn
>> 9) & 1) != s
->bswap_code
) {
7621 /* Dynamic endianness switching not implemented. */
7622 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
7626 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
7627 switch ((insn
>> 4) & 0xf) {
7636 /* We don't emulate caches so these are a no-op. */
7641 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
7647 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
7649 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
7655 rn
= (insn
>> 16) & 0xf;
7656 addr
= load_reg(s
, rn
);
7657 i
= (insn
>> 23) & 3;
7659 case 0: offset
= -4; break; /* DA */
7660 case 1: offset
= 0; break; /* IA */
7661 case 2: offset
= -8; break; /* DB */
7662 case 3: offset
= 4; break; /* IB */
7666 tcg_gen_addi_i32(addr
, addr
, offset
);
7667 /* Load PC into tmp and CPSR into tmp2. */
7668 tmp
= tcg_temp_new_i32();
7669 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
7670 tcg_gen_addi_i32(addr
, addr
, 4);
7671 tmp2
= tcg_temp_new_i32();
7672 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
7673 if (insn
& (1 << 21)) {
7674 /* Base writeback. */
7676 case 0: offset
= -8; break;
7677 case 1: offset
= 4; break;
7678 case 2: offset
= -4; break;
7679 case 3: offset
= 0; break;
7683 tcg_gen_addi_i32(addr
, addr
, offset
);
7684 store_reg(s
, rn
, addr
);
7686 tcg_temp_free_i32(addr
);
7688 gen_rfe(s
, tmp
, tmp2
);
7690 } else if ((insn
& 0x0e000000) == 0x0a000000) {
7691 /* branch link and change to thumb (blx <offset>) */
7694 val
= (uint32_t)s
->pc
;
7695 tmp
= tcg_temp_new_i32();
7696 tcg_gen_movi_i32(tmp
, val
);
7697 store_reg(s
, 14, tmp
);
7698 /* Sign-extend the 24-bit offset */
7699 offset
= (((int32_t)insn
) << 8) >> 8;
7700 /* offset * 4 + bit24 * 2 + (thumb bit) */
7701 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
7702 /* pipeline offset */
7704 /* protected by ARCH(5); above, near the start of uncond block */
7707 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
7708 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
7709 /* iWMMXt register transfer. */
7710 if (extract32(s
->c15_cpar
, 1, 1)) {
7711 if (!disas_iwmmxt_insn(env
, s
, insn
)) {
7716 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
7717 /* Coprocessor double register transfer. */
7719 } else if ((insn
& 0x0f000010) == 0x0e000010) {
7720 /* Additional coprocessor register transfer. */
7721 } else if ((insn
& 0x0ff10020) == 0x01000000) {
7724 /* cps (privileged) */
7728 if (insn
& (1 << 19)) {
7729 if (insn
& (1 << 8))
7731 if (insn
& (1 << 7))
7733 if (insn
& (1 << 6))
7735 if (insn
& (1 << 18))
7738 if (insn
& (1 << 17)) {
7740 val
|= (insn
& 0x1f);
7743 gen_set_psr_im(s
, mask
, 0, val
);
7750 /* if not always execute, we generate a conditional jump to
7752 s
->condlabel
= gen_new_label();
7753 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
7756 if ((insn
& 0x0f900000) == 0x03000000) {
7757 if ((insn
& (1 << 21)) == 0) {
7759 rd
= (insn
>> 12) & 0xf;
7760 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
7761 if ((insn
& (1 << 22)) == 0) {
7763 tmp
= tcg_temp_new_i32();
7764 tcg_gen_movi_i32(tmp
, val
);
7767 tmp
= load_reg(s
, rd
);
7768 tcg_gen_ext16u_i32(tmp
, tmp
);
7769 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
7771 store_reg(s
, rd
, tmp
);
7773 if (((insn
>> 12) & 0xf) != 0xf)
7775 if (((insn
>> 16) & 0xf) == 0) {
7776 gen_nop_hint(s
, insn
& 0xff);
7778 /* CPSR = immediate */
7780 shift
= ((insn
>> 8) & 0xf) * 2;
7782 val
= (val
>> shift
) | (val
<< (32 - shift
));
7783 i
= ((insn
& (1 << 22)) != 0);
7784 if (gen_set_psr_im(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, val
))
7788 } else if ((insn
& 0x0f900000) == 0x01000000
7789 && (insn
& 0x00000090) != 0x00000090) {
7790 /* miscellaneous instructions */
7791 op1
= (insn
>> 21) & 3;
7792 sh
= (insn
>> 4) & 0xf;
7795 case 0x0: /* move program status register */
7798 tmp
= load_reg(s
, rm
);
7799 i
= ((op1
& 2) != 0);
7800 if (gen_set_psr(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
7804 rd
= (insn
>> 12) & 0xf;
7808 tmp
= load_cpu_field(spsr
);
7810 tmp
= tcg_temp_new_i32();
7811 gen_helper_cpsr_read(tmp
, cpu_env
);
7813 store_reg(s
, rd
, tmp
);
7818 /* branch/exchange thumb (bx). */
7820 tmp
= load_reg(s
, rm
);
7822 } else if (op1
== 3) {
7825 rd
= (insn
>> 12) & 0xf;
7826 tmp
= load_reg(s
, rm
);
7827 gen_helper_clz(tmp
, tmp
);
7828 store_reg(s
, rd
, tmp
);
7836 /* Trivial implementation equivalent to bx. */
7837 tmp
= load_reg(s
, rm
);
7848 /* branch link/exchange thumb (blx) */
7849 tmp
= load_reg(s
, rm
);
7850 tmp2
= tcg_temp_new_i32();
7851 tcg_gen_movi_i32(tmp2
, s
->pc
);
7852 store_reg(s
, 14, tmp2
);
7858 uint32_t c
= extract32(insn
, 8, 4);
7860 /* Check this CPU supports ARMv8 CRC instructions.
7861 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
7862 * Bits 8, 10 and 11 should be zero.
7864 if (!arm_feature(env
, ARM_FEATURE_CRC
) || op1
== 0x3 ||
7869 rn
= extract32(insn
, 16, 4);
7870 rd
= extract32(insn
, 12, 4);
7872 tmp
= load_reg(s
, rn
);
7873 tmp2
= load_reg(s
, rm
);
7875 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
7876 } else if (op1
== 1) {
7877 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
7879 tmp3
= tcg_const_i32(1 << op1
);
7881 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
7883 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
7885 tcg_temp_free_i32(tmp2
);
7886 tcg_temp_free_i32(tmp3
);
7887 store_reg(s
, rd
, tmp
);
7890 case 0x5: /* saturating add/subtract */
7892 rd
= (insn
>> 12) & 0xf;
7893 rn
= (insn
>> 16) & 0xf;
7894 tmp
= load_reg(s
, rm
);
7895 tmp2
= load_reg(s
, rn
);
7897 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
7899 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
7901 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
7902 tcg_temp_free_i32(tmp2
);
7903 store_reg(s
, rd
, tmp
);
7907 int imm16
= extract32(insn
, 0, 4) | (extract32(insn
, 8, 12) << 4);
7912 gen_exception_insn(s
, 4, EXCP_BKPT
,
7913 syn_aa32_bkpt(imm16
, false));
7916 /* Hypervisor call (v7) */
7924 /* Secure monitor call (v6+) */
7936 case 0x8: /* signed multiply */
7941 rs
= (insn
>> 8) & 0xf;
7942 rn
= (insn
>> 12) & 0xf;
7943 rd
= (insn
>> 16) & 0xf;
7945 /* (32 * 16) >> 16 */
7946 tmp
= load_reg(s
, rm
);
7947 tmp2
= load_reg(s
, rs
);
7949 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
7952 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7953 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
7954 tmp
= tcg_temp_new_i32();
7955 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7956 tcg_temp_free_i64(tmp64
);
7957 if ((sh
& 2) == 0) {
7958 tmp2
= load_reg(s
, rn
);
7959 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7960 tcg_temp_free_i32(tmp2
);
7962 store_reg(s
, rd
, tmp
);
7965 tmp
= load_reg(s
, rm
);
7966 tmp2
= load_reg(s
, rs
);
7967 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
7968 tcg_temp_free_i32(tmp2
);
7970 tmp64
= tcg_temp_new_i64();
7971 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7972 tcg_temp_free_i32(tmp
);
7973 gen_addq(s
, tmp64
, rn
, rd
);
7974 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7975 tcg_temp_free_i64(tmp64
);
7978 tmp2
= load_reg(s
, rn
);
7979 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7980 tcg_temp_free_i32(tmp2
);
7982 store_reg(s
, rd
, tmp
);
7989 } else if (((insn
& 0x0e000000) == 0 &&
7990 (insn
& 0x00000090) != 0x90) ||
7991 ((insn
& 0x0e000000) == (1 << 25))) {
7992 int set_cc
, logic_cc
, shiftop
;
7994 op1
= (insn
>> 21) & 0xf;
7995 set_cc
= (insn
>> 20) & 1;
7996 logic_cc
= table_logic_cc
[op1
] & set_cc
;
7998 /* data processing instruction */
7999 if (insn
& (1 << 25)) {
8000 /* immediate operand */
8002 shift
= ((insn
>> 8) & 0xf) * 2;
8004 val
= (val
>> shift
) | (val
<< (32 - shift
));
8006 tmp2
= tcg_temp_new_i32();
8007 tcg_gen_movi_i32(tmp2
, val
);
8008 if (logic_cc
&& shift
) {
8009 gen_set_CF_bit31(tmp2
);
8014 tmp2
= load_reg(s
, rm
);
8015 shiftop
= (insn
>> 5) & 3;
8016 if (!(insn
& (1 << 4))) {
8017 shift
= (insn
>> 7) & 0x1f;
8018 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8020 rs
= (insn
>> 8) & 0xf;
8021 tmp
= load_reg(s
, rs
);
8022 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
8025 if (op1
!= 0x0f && op1
!= 0x0d) {
8026 rn
= (insn
>> 16) & 0xf;
8027 tmp
= load_reg(s
, rn
);
8029 TCGV_UNUSED_I32(tmp
);
8031 rd
= (insn
>> 12) & 0xf;
8034 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8038 store_reg_bx(env
, s
, rd
, tmp
);
8041 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8045 store_reg_bx(env
, s
, rd
, tmp
);
8048 if (set_cc
&& rd
== 15) {
8049 /* SUBS r15, ... is used for exception return. */
8053 gen_sub_CC(tmp
, tmp
, tmp2
);
8054 gen_exception_return(s
, tmp
);
8057 gen_sub_CC(tmp
, tmp
, tmp2
);
8059 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8061 store_reg_bx(env
, s
, rd
, tmp
);
8066 gen_sub_CC(tmp
, tmp2
, tmp
);
8068 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8070 store_reg_bx(env
, s
, rd
, tmp
);
8074 gen_add_CC(tmp
, tmp
, tmp2
);
8076 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8078 store_reg_bx(env
, s
, rd
, tmp
);
8082 gen_adc_CC(tmp
, tmp
, tmp2
);
8084 gen_add_carry(tmp
, tmp
, tmp2
);
8086 store_reg_bx(env
, s
, rd
, tmp
);
8090 gen_sbc_CC(tmp
, tmp
, tmp2
);
8092 gen_sub_carry(tmp
, tmp
, tmp2
);
8094 store_reg_bx(env
, s
, rd
, tmp
);
8098 gen_sbc_CC(tmp
, tmp2
, tmp
);
8100 gen_sub_carry(tmp
, tmp2
, tmp
);
8102 store_reg_bx(env
, s
, rd
, tmp
);
8106 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8109 tcg_temp_free_i32(tmp
);
8113 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8116 tcg_temp_free_i32(tmp
);
8120 gen_sub_CC(tmp
, tmp
, tmp2
);
8122 tcg_temp_free_i32(tmp
);
8126 gen_add_CC(tmp
, tmp
, tmp2
);
8128 tcg_temp_free_i32(tmp
);
8131 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8135 store_reg_bx(env
, s
, rd
, tmp
);
8138 if (logic_cc
&& rd
== 15) {
8139 /* MOVS r15, ... is used for exception return. */
8143 gen_exception_return(s
, tmp2
);
8148 store_reg_bx(env
, s
, rd
, tmp2
);
8152 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
8156 store_reg_bx(env
, s
, rd
, tmp
);
8160 tcg_gen_not_i32(tmp2
, tmp2
);
8164 store_reg_bx(env
, s
, rd
, tmp2
);
8167 if (op1
!= 0x0f && op1
!= 0x0d) {
8168 tcg_temp_free_i32(tmp2
);
8171 /* other instructions */
8172 op1
= (insn
>> 24) & 0xf;
8176 /* multiplies, extra load/stores */
8177 sh
= (insn
>> 5) & 3;
8180 rd
= (insn
>> 16) & 0xf;
8181 rn
= (insn
>> 12) & 0xf;
8182 rs
= (insn
>> 8) & 0xf;
8184 op1
= (insn
>> 20) & 0xf;
8186 case 0: case 1: case 2: case 3: case 6:
8188 tmp
= load_reg(s
, rs
);
8189 tmp2
= load_reg(s
, rm
);
8190 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8191 tcg_temp_free_i32(tmp2
);
8192 if (insn
& (1 << 22)) {
8193 /* Subtract (mls) */
8195 tmp2
= load_reg(s
, rn
);
8196 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8197 tcg_temp_free_i32(tmp2
);
8198 } else if (insn
& (1 << 21)) {
8200 tmp2
= load_reg(s
, rn
);
8201 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8202 tcg_temp_free_i32(tmp2
);
8204 if (insn
& (1 << 20))
8206 store_reg(s
, rd
, tmp
);
8209 /* 64 bit mul double accumulate (UMAAL) */
8211 tmp
= load_reg(s
, rs
);
8212 tmp2
= load_reg(s
, rm
);
8213 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8214 gen_addq_lo(s
, tmp64
, rn
);
8215 gen_addq_lo(s
, tmp64
, rd
);
8216 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8217 tcg_temp_free_i64(tmp64
);
8219 case 8: case 9: case 10: case 11:
8220 case 12: case 13: case 14: case 15:
8221 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8222 tmp
= load_reg(s
, rs
);
8223 tmp2
= load_reg(s
, rm
);
8224 if (insn
& (1 << 22)) {
8225 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
8227 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
8229 if (insn
& (1 << 21)) { /* mult accumulate */
8230 TCGv_i32 al
= load_reg(s
, rn
);
8231 TCGv_i32 ah
= load_reg(s
, rd
);
8232 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
8233 tcg_temp_free_i32(al
);
8234 tcg_temp_free_i32(ah
);
8236 if (insn
& (1 << 20)) {
8237 gen_logicq_cc(tmp
, tmp2
);
8239 store_reg(s
, rn
, tmp
);
8240 store_reg(s
, rd
, tmp2
);
8246 rn
= (insn
>> 16) & 0xf;
8247 rd
= (insn
>> 12) & 0xf;
8248 if (insn
& (1 << 23)) {
8249 /* load/store exclusive */
8250 int op2
= (insn
>> 8) & 3;
8251 op1
= (insn
>> 21) & 0x3;
8254 case 0: /* lda/stl */
8260 case 1: /* reserved */
8262 case 2: /* ldaex/stlex */
8265 case 3: /* ldrex/strex */
8274 addr
= tcg_temp_local_new_i32();
8275 load_reg_var(s
, addr
, rn
);
8277 /* Since the emulation does not have barriers,
8278 the acquire/release semantics need no special
8281 if (insn
& (1 << 20)) {
8282 tmp
= tcg_temp_new_i32();
8285 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8288 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
8291 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
8296 store_reg(s
, rd
, tmp
);
8299 tmp
= load_reg(s
, rm
);
8302 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8305 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
8308 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
8313 tcg_temp_free_i32(tmp
);
8315 } else if (insn
& (1 << 20)) {
8318 gen_load_exclusive(s
, rd
, 15, addr
, 2);
8320 case 1: /* ldrexd */
8321 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
8323 case 2: /* ldrexb */
8324 gen_load_exclusive(s
, rd
, 15, addr
, 0);
8326 case 3: /* ldrexh */
8327 gen_load_exclusive(s
, rd
, 15, addr
, 1);
8336 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
8338 case 1: /* strexd */
8339 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
8341 case 2: /* strexb */
8342 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
8344 case 3: /* strexh */
8345 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
8351 tcg_temp_free_i32(addr
);
8353 /* SWP instruction */
8356 /* ??? This is not really atomic. However we know
8357 we never have multiple CPUs running in parallel,
8358 so it is good enough. */
8359 addr
= load_reg(s
, rn
);
8360 tmp
= load_reg(s
, rm
);
8361 tmp2
= tcg_temp_new_i32();
8362 if (insn
& (1 << 22)) {
8363 gen_aa32_ld8u(tmp2
, addr
, get_mem_index(s
));
8364 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
8366 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
8367 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8369 tcg_temp_free_i32(tmp
);
8370 tcg_temp_free_i32(addr
);
8371 store_reg(s
, rd
, tmp2
);
8377 /* Misc load/store */
8378 rn
= (insn
>> 16) & 0xf;
8379 rd
= (insn
>> 12) & 0xf;
8380 addr
= load_reg(s
, rn
);
8381 if (insn
& (1 << 24))
8382 gen_add_datah_offset(s
, insn
, 0, addr
);
8384 if (insn
& (1 << 20)) {
8386 tmp
= tcg_temp_new_i32();
8389 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
8392 gen_aa32_ld8s(tmp
, addr
, get_mem_index(s
));
8396 gen_aa32_ld16s(tmp
, addr
, get_mem_index(s
));
8400 } else if (sh
& 2) {
8405 tmp
= load_reg(s
, rd
);
8406 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8407 tcg_temp_free_i32(tmp
);
8408 tcg_gen_addi_i32(addr
, addr
, 4);
8409 tmp
= load_reg(s
, rd
+ 1);
8410 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8411 tcg_temp_free_i32(tmp
);
8415 tmp
= tcg_temp_new_i32();
8416 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8417 store_reg(s
, rd
, tmp
);
8418 tcg_gen_addi_i32(addr
, addr
, 4);
8419 tmp
= tcg_temp_new_i32();
8420 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8424 address_offset
= -4;
8427 tmp
= load_reg(s
, rd
);
8428 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
8429 tcg_temp_free_i32(tmp
);
8432 /* Perform base writeback before the loaded value to
8433 ensure correct behavior with overlapping index registers.
8434 ldrd with base writeback is is undefined if the
8435 destination and index registers overlap. */
8436 if (!(insn
& (1 << 24))) {
8437 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
8438 store_reg(s
, rn
, addr
);
8439 } else if (insn
& (1 << 21)) {
8441 tcg_gen_addi_i32(addr
, addr
, address_offset
);
8442 store_reg(s
, rn
, addr
);
8444 tcg_temp_free_i32(addr
);
8447 /* Complete the load. */
8448 store_reg(s
, rd
, tmp
);
8457 if (insn
& (1 << 4)) {
8459 /* Armv6 Media instructions. */
8461 rn
= (insn
>> 16) & 0xf;
8462 rd
= (insn
>> 12) & 0xf;
8463 rs
= (insn
>> 8) & 0xf;
8464 switch ((insn
>> 23) & 3) {
8465 case 0: /* Parallel add/subtract. */
8466 op1
= (insn
>> 20) & 7;
8467 tmp
= load_reg(s
, rn
);
8468 tmp2
= load_reg(s
, rm
);
8469 sh
= (insn
>> 5) & 7;
8470 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
8472 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
8473 tcg_temp_free_i32(tmp2
);
8474 store_reg(s
, rd
, tmp
);
8477 if ((insn
& 0x00700020) == 0) {
8478 /* Halfword pack. */
8479 tmp
= load_reg(s
, rn
);
8480 tmp2
= load_reg(s
, rm
);
8481 shift
= (insn
>> 7) & 0x1f;
8482 if (insn
& (1 << 6)) {
8486 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8487 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8488 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8492 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8493 tcg_gen_ext16u_i32(tmp
, tmp
);
8494 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8496 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8497 tcg_temp_free_i32(tmp2
);
8498 store_reg(s
, rd
, tmp
);
8499 } else if ((insn
& 0x00200020) == 0x00200000) {
8501 tmp
= load_reg(s
, rm
);
8502 shift
= (insn
>> 7) & 0x1f;
8503 if (insn
& (1 << 6)) {
8506 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8508 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8510 sh
= (insn
>> 16) & 0x1f;
8511 tmp2
= tcg_const_i32(sh
);
8512 if (insn
& (1 << 22))
8513 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
8515 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
8516 tcg_temp_free_i32(tmp2
);
8517 store_reg(s
, rd
, tmp
);
8518 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
8520 tmp
= load_reg(s
, rm
);
8521 sh
= (insn
>> 16) & 0x1f;
8522 tmp2
= tcg_const_i32(sh
);
8523 if (insn
& (1 << 22))
8524 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
8526 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
8527 tcg_temp_free_i32(tmp2
);
8528 store_reg(s
, rd
, tmp
);
8529 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
8531 tmp
= load_reg(s
, rn
);
8532 tmp2
= load_reg(s
, rm
);
8533 tmp3
= tcg_temp_new_i32();
8534 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
8535 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
8536 tcg_temp_free_i32(tmp3
);
8537 tcg_temp_free_i32(tmp2
);
8538 store_reg(s
, rd
, tmp
);
8539 } else if ((insn
& 0x000003e0) == 0x00000060) {
8540 tmp
= load_reg(s
, rm
);
8541 shift
= (insn
>> 10) & 3;
8542 /* ??? In many cases it's not necessary to do a
8543 rotate, a shift is sufficient. */
8545 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
8546 op1
= (insn
>> 20) & 7;
8548 case 0: gen_sxtb16(tmp
); break;
8549 case 2: gen_sxtb(tmp
); break;
8550 case 3: gen_sxth(tmp
); break;
8551 case 4: gen_uxtb16(tmp
); break;
8552 case 6: gen_uxtb(tmp
); break;
8553 case 7: gen_uxth(tmp
); break;
8554 default: goto illegal_op
;
8557 tmp2
= load_reg(s
, rn
);
8558 if ((op1
& 3) == 0) {
8559 gen_add16(tmp
, tmp2
);
8561 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8562 tcg_temp_free_i32(tmp2
);
8565 store_reg(s
, rd
, tmp
);
8566 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
8568 tmp
= load_reg(s
, rm
);
8569 if (insn
& (1 << 22)) {
8570 if (insn
& (1 << 7)) {
8574 gen_helper_rbit(tmp
, tmp
);
8577 if (insn
& (1 << 7))
8580 tcg_gen_bswap32_i32(tmp
, tmp
);
8582 store_reg(s
, rd
, tmp
);
8587 case 2: /* Multiplies (Type 3). */
8588 switch ((insn
>> 20) & 0x7) {
8590 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
8591 /* op2 not 00x or 11x : UNDEF */
8594 /* Signed multiply most significant [accumulate].
8595 (SMMUL, SMMLA, SMMLS) */
8596 tmp
= load_reg(s
, rm
);
8597 tmp2
= load_reg(s
, rs
);
8598 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8601 tmp
= load_reg(s
, rd
);
8602 if (insn
& (1 << 6)) {
8603 tmp64
= gen_subq_msw(tmp64
, tmp
);
8605 tmp64
= gen_addq_msw(tmp64
, tmp
);
8608 if (insn
& (1 << 5)) {
8609 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
8611 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
8612 tmp
= tcg_temp_new_i32();
8613 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8614 tcg_temp_free_i64(tmp64
);
8615 store_reg(s
, rn
, tmp
);
8619 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8620 if (insn
& (1 << 7)) {
8623 tmp
= load_reg(s
, rm
);
8624 tmp2
= load_reg(s
, rs
);
8625 if (insn
& (1 << 5))
8626 gen_swap_half(tmp2
);
8627 gen_smul_dual(tmp
, tmp2
);
8628 if (insn
& (1 << 22)) {
8629 /* smlald, smlsld */
8632 tmp64
= tcg_temp_new_i64();
8633 tmp64_2
= tcg_temp_new_i64();
8634 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8635 tcg_gen_ext_i32_i64(tmp64_2
, tmp2
);
8636 tcg_temp_free_i32(tmp
);
8637 tcg_temp_free_i32(tmp2
);
8638 if (insn
& (1 << 6)) {
8639 tcg_gen_sub_i64(tmp64
, tmp64
, tmp64_2
);
8641 tcg_gen_add_i64(tmp64
, tmp64
, tmp64_2
);
8643 tcg_temp_free_i64(tmp64_2
);
8644 gen_addq(s
, tmp64
, rd
, rn
);
8645 gen_storeq_reg(s
, rd
, rn
, tmp64
);
8646 tcg_temp_free_i64(tmp64
);
8648 /* smuad, smusd, smlad, smlsd */
8649 if (insn
& (1 << 6)) {
8650 /* This subtraction cannot overflow. */
8651 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8653 /* This addition cannot overflow 32 bits;
8654 * however it may overflow considered as a
8655 * signed operation, in which case we must set
8658 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8660 tcg_temp_free_i32(tmp2
);
8663 tmp2
= load_reg(s
, rd
);
8664 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8665 tcg_temp_free_i32(tmp2
);
8667 store_reg(s
, rn
, tmp
);
8673 if (!arm_feature(env
, ARM_FEATURE_ARM_DIV
)) {
8676 if (((insn
>> 5) & 7) || (rd
!= 15)) {
8679 tmp
= load_reg(s
, rm
);
8680 tmp2
= load_reg(s
, rs
);
8681 if (insn
& (1 << 21)) {
8682 gen_helper_udiv(tmp
, tmp
, tmp2
);
8684 gen_helper_sdiv(tmp
, tmp
, tmp2
);
8686 tcg_temp_free_i32(tmp2
);
8687 store_reg(s
, rn
, tmp
);
8694 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
8696 case 0: /* Unsigned sum of absolute differences. */
8698 tmp
= load_reg(s
, rm
);
8699 tmp2
= load_reg(s
, rs
);
8700 gen_helper_usad8(tmp
, tmp
, tmp2
);
8701 tcg_temp_free_i32(tmp2
);
8703 tmp2
= load_reg(s
, rd
);
8704 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8705 tcg_temp_free_i32(tmp2
);
8707 store_reg(s
, rn
, tmp
);
8709 case 0x20: case 0x24: case 0x28: case 0x2c:
8710 /* Bitfield insert/clear. */
8712 shift
= (insn
>> 7) & 0x1f;
8713 i
= (insn
>> 16) & 0x1f;
8716 tmp
= tcg_temp_new_i32();
8717 tcg_gen_movi_i32(tmp
, 0);
8719 tmp
= load_reg(s
, rm
);
8722 tmp2
= load_reg(s
, rd
);
8723 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
8724 tcg_temp_free_i32(tmp2
);
8726 store_reg(s
, rd
, tmp
);
8728 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8729 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8731 tmp
= load_reg(s
, rm
);
8732 shift
= (insn
>> 7) & 0x1f;
8733 i
= ((insn
>> 16) & 0x1f) + 1;
8738 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
8740 gen_sbfx(tmp
, shift
, i
);
8743 store_reg(s
, rd
, tmp
);
8753 /* Check for undefined extension instructions
8754 * per the ARM Bible IE:
8755 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8757 sh
= (0xf << 20) | (0xf << 4);
8758 if (op1
== 0x7 && ((insn
& sh
) == sh
))
8762 /* load/store byte/word */
8763 rn
= (insn
>> 16) & 0xf;
8764 rd
= (insn
>> 12) & 0xf;
8765 tmp2
= load_reg(s
, rn
);
8766 if ((insn
& 0x01200000) == 0x00200000) {
8770 i
= get_mem_index(s
);
8772 if (insn
& (1 << 24))
8773 gen_add_data_offset(s
, insn
, tmp2
);
8774 if (insn
& (1 << 20)) {
8776 tmp
= tcg_temp_new_i32();
8777 if (insn
& (1 << 22)) {
8778 gen_aa32_ld8u(tmp
, tmp2
, i
);
8780 gen_aa32_ld32u(tmp
, tmp2
, i
);
8784 tmp
= load_reg(s
, rd
);
8785 if (insn
& (1 << 22)) {
8786 gen_aa32_st8(tmp
, tmp2
, i
);
8788 gen_aa32_st32(tmp
, tmp2
, i
);
8790 tcg_temp_free_i32(tmp
);
8792 if (!(insn
& (1 << 24))) {
8793 gen_add_data_offset(s
, insn
, tmp2
);
8794 store_reg(s
, rn
, tmp2
);
8795 } else if (insn
& (1 << 21)) {
8796 store_reg(s
, rn
, tmp2
);
8798 tcg_temp_free_i32(tmp2
);
8800 if (insn
& (1 << 20)) {
8801 /* Complete the load. */
8802 store_reg_from_load(env
, s
, rd
, tmp
);
8808 int j
, n
, user
, loaded_base
;
8809 TCGv_i32 loaded_var
;
8810 /* load/store multiple words */
8811 /* XXX: store correct base if write back */
8813 if (insn
& (1 << 22)) {
8815 goto illegal_op
; /* only usable in supervisor mode */
8817 if ((insn
& (1 << 15)) == 0)
8820 rn
= (insn
>> 16) & 0xf;
8821 addr
= load_reg(s
, rn
);
8823 /* compute total size */
8825 TCGV_UNUSED_I32(loaded_var
);
8828 if (insn
& (1 << i
))
8831 /* XXX: test invalid n == 0 case ? */
8832 if (insn
& (1 << 23)) {
8833 if (insn
& (1 << 24)) {
8835 tcg_gen_addi_i32(addr
, addr
, 4);
8837 /* post increment */
8840 if (insn
& (1 << 24)) {
8842 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
8844 /* post decrement */
8846 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
8851 if (insn
& (1 << i
)) {
8852 if (insn
& (1 << 20)) {
8854 tmp
= tcg_temp_new_i32();
8855 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8857 tmp2
= tcg_const_i32(i
);
8858 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
8859 tcg_temp_free_i32(tmp2
);
8860 tcg_temp_free_i32(tmp
);
8861 } else if (i
== rn
) {
8865 store_reg_from_load(env
, s
, i
, tmp
);
8870 /* special case: r15 = PC + 8 */
8871 val
= (long)s
->pc
+ 4;
8872 tmp
= tcg_temp_new_i32();
8873 tcg_gen_movi_i32(tmp
, val
);
8875 tmp
= tcg_temp_new_i32();
8876 tmp2
= tcg_const_i32(i
);
8877 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
8878 tcg_temp_free_i32(tmp2
);
8880 tmp
= load_reg(s
, i
);
8882 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8883 tcg_temp_free_i32(tmp
);
8886 /* no need to add after the last transfer */
8888 tcg_gen_addi_i32(addr
, addr
, 4);
8891 if (insn
& (1 << 21)) {
8893 if (insn
& (1 << 23)) {
8894 if (insn
& (1 << 24)) {
8897 /* post increment */
8898 tcg_gen_addi_i32(addr
, addr
, 4);
8901 if (insn
& (1 << 24)) {
8904 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
8906 /* post decrement */
8907 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
8910 store_reg(s
, rn
, addr
);
8912 tcg_temp_free_i32(addr
);
8915 store_reg(s
, rn
, loaded_var
);
8917 if ((insn
& (1 << 22)) && !user
) {
8918 /* Restore CPSR from SPSR. */
8919 tmp
= load_cpu_field(spsr
);
8920 gen_set_cpsr(tmp
, CPSR_ERET_MASK
);
8921 tcg_temp_free_i32(tmp
);
8922 s
->is_jmp
= DISAS_UPDATE
;
8931 /* branch (and link) */
8932 val
= (int32_t)s
->pc
;
8933 if (insn
& (1 << 24)) {
8934 tmp
= tcg_temp_new_i32();
8935 tcg_gen_movi_i32(tmp
, val
);
8936 store_reg(s
, 14, tmp
);
8938 offset
= sextract32(insn
<< 2, 0, 26);
8946 if (((insn
>> 8) & 0xe) == 10) {
8948 if (disas_vfp_insn(env
, s
, insn
)) {
8951 } else if (disas_coproc_insn(env
, s
, insn
)) {
8958 gen_set_pc_im(s
, s
->pc
);
8959 s
->svc_imm
= extract32(insn
, 0, 24);
8960 s
->is_jmp
= DISAS_SWI
;
8964 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized());
8970 /* Return true if this is a Thumb-2 logical op. */
8972 thumb2_logic_op(int op
)
8977 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
8978 then set condition code flags based on the result of the operation.
8979 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8980 to the high bit of T1.
8981 Returns zero if the opcode is valid. */
8984 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
8985 TCGv_i32 t0
, TCGv_i32 t1
)
8992 tcg_gen_and_i32(t0
, t0
, t1
);
8996 tcg_gen_andc_i32(t0
, t0
, t1
);
9000 tcg_gen_or_i32(t0
, t0
, t1
);
9004 tcg_gen_orc_i32(t0
, t0
, t1
);
9008 tcg_gen_xor_i32(t0
, t0
, t1
);
9013 gen_add_CC(t0
, t0
, t1
);
9015 tcg_gen_add_i32(t0
, t0
, t1
);
9019 gen_adc_CC(t0
, t0
, t1
);
9025 gen_sbc_CC(t0
, t0
, t1
);
9027 gen_sub_carry(t0
, t0
, t1
);
9032 gen_sub_CC(t0
, t0
, t1
);
9034 tcg_gen_sub_i32(t0
, t0
, t1
);
9038 gen_sub_CC(t0
, t1
, t0
);
9040 tcg_gen_sub_i32(t0
, t1
, t0
);
9042 default: /* 5, 6, 7, 9, 12, 15. */
9048 gen_set_CF_bit31(t1
);
9053 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
9055 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
9057 uint32_t insn
, imm
, shift
, offset
;
9058 uint32_t rd
, rn
, rm
, rs
;
9069 if (!(arm_feature(env
, ARM_FEATURE_THUMB2
)
9070 || arm_feature (env
, ARM_FEATURE_M
))) {
9071 /* Thumb-1 cores may need to treat bl and blx as a pair of
9072 16-bit instructions to get correct prefetch abort behavior. */
9074 if ((insn
& (1 << 12)) == 0) {
9076 /* Second half of blx. */
9077 offset
= ((insn
& 0x7ff) << 1);
9078 tmp
= load_reg(s
, 14);
9079 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9080 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
9082 tmp2
= tcg_temp_new_i32();
9083 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9084 store_reg(s
, 14, tmp2
);
9088 if (insn
& (1 << 11)) {
9089 /* Second half of bl. */
9090 offset
= ((insn
& 0x7ff) << 1) | 1;
9091 tmp
= load_reg(s
, 14);
9092 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9094 tmp2
= tcg_temp_new_i32();
9095 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9096 store_reg(s
, 14, tmp2
);
9100 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
9101 /* Instruction spans a page boundary. Implement it as two
9102 16-bit instructions in case the second half causes an
9104 offset
= ((int32_t)insn
<< 21) >> 9;
9105 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
9108 /* Fall through to 32-bit decode. */
9111 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
9113 insn
|= (uint32_t)insn_hw1
<< 16;
9115 if ((insn
& 0xf800e800) != 0xf000e800) {
9119 rn
= (insn
>> 16) & 0xf;
9120 rs
= (insn
>> 12) & 0xf;
9121 rd
= (insn
>> 8) & 0xf;
9123 switch ((insn
>> 25) & 0xf) {
9124 case 0: case 1: case 2: case 3:
9125 /* 16-bit instructions. Should never happen. */
9128 if (insn
& (1 << 22)) {
9129 /* Other load/store, table branch. */
9130 if (insn
& 0x01200000) {
9131 /* Load/store doubleword. */
9133 addr
= tcg_temp_new_i32();
9134 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
9136 addr
= load_reg(s
, rn
);
9138 offset
= (insn
& 0xff) * 4;
9139 if ((insn
& (1 << 23)) == 0)
9141 if (insn
& (1 << 24)) {
9142 tcg_gen_addi_i32(addr
, addr
, offset
);
9145 if (insn
& (1 << 20)) {
9147 tmp
= tcg_temp_new_i32();
9148 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9149 store_reg(s
, rs
, tmp
);
9150 tcg_gen_addi_i32(addr
, addr
, 4);
9151 tmp
= tcg_temp_new_i32();
9152 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9153 store_reg(s
, rd
, tmp
);
9156 tmp
= load_reg(s
, rs
);
9157 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9158 tcg_temp_free_i32(tmp
);
9159 tcg_gen_addi_i32(addr
, addr
, 4);
9160 tmp
= load_reg(s
, rd
);
9161 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9162 tcg_temp_free_i32(tmp
);
9164 if (insn
& (1 << 21)) {
9165 /* Base writeback. */
9168 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
9169 store_reg(s
, rn
, addr
);
9171 tcg_temp_free_i32(addr
);
9173 } else if ((insn
& (1 << 23)) == 0) {
9174 /* Load/store exclusive word. */
9175 addr
= tcg_temp_local_new_i32();
9176 load_reg_var(s
, addr
, rn
);
9177 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
9178 if (insn
& (1 << 20)) {
9179 gen_load_exclusive(s
, rs
, 15, addr
, 2);
9181 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
9183 tcg_temp_free_i32(addr
);
9184 } else if ((insn
& (7 << 5)) == 0) {
9187 addr
= tcg_temp_new_i32();
9188 tcg_gen_movi_i32(addr
, s
->pc
);
9190 addr
= load_reg(s
, rn
);
9192 tmp
= load_reg(s
, rm
);
9193 tcg_gen_add_i32(addr
, addr
, tmp
);
9194 if (insn
& (1 << 4)) {
9196 tcg_gen_add_i32(addr
, addr
, tmp
);
9197 tcg_temp_free_i32(tmp
);
9198 tmp
= tcg_temp_new_i32();
9199 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
9201 tcg_temp_free_i32(tmp
);
9202 tmp
= tcg_temp_new_i32();
9203 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
9205 tcg_temp_free_i32(addr
);
9206 tcg_gen_shli_i32(tmp
, tmp
, 1);
9207 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
9208 store_reg(s
, 15, tmp
);
9210 int op2
= (insn
>> 6) & 0x3;
9211 op
= (insn
>> 4) & 0x3;
9216 /* Load/store exclusive byte/halfword/doubleword */
9223 /* Load-acquire/store-release */
9229 /* Load-acquire/store-release exclusive */
9233 addr
= tcg_temp_local_new_i32();
9234 load_reg_var(s
, addr
, rn
);
9236 if (insn
& (1 << 20)) {
9237 tmp
= tcg_temp_new_i32();
9240 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
9243 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
9246 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9251 store_reg(s
, rs
, tmp
);
9253 tmp
= load_reg(s
, rs
);
9256 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
9259 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
9262 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9267 tcg_temp_free_i32(tmp
);
9269 } else if (insn
& (1 << 20)) {
9270 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
9272 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
9274 tcg_temp_free_i32(addr
);
9277 /* Load/store multiple, RFE, SRS. */
9278 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
9279 /* RFE, SRS: not available in user mode or on M profile */
9280 if (IS_USER(s
) || IS_M(env
)) {
9283 if (insn
& (1 << 20)) {
9285 addr
= load_reg(s
, rn
);
9286 if ((insn
& (1 << 24)) == 0)
9287 tcg_gen_addi_i32(addr
, addr
, -8);
9288 /* Load PC into tmp and CPSR into tmp2. */
9289 tmp
= tcg_temp_new_i32();
9290 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9291 tcg_gen_addi_i32(addr
, addr
, 4);
9292 tmp2
= tcg_temp_new_i32();
9293 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
9294 if (insn
& (1 << 21)) {
9295 /* Base writeback. */
9296 if (insn
& (1 << 24)) {
9297 tcg_gen_addi_i32(addr
, addr
, 4);
9299 tcg_gen_addi_i32(addr
, addr
, -4);
9301 store_reg(s
, rn
, addr
);
9303 tcg_temp_free_i32(addr
);
9305 gen_rfe(s
, tmp
, tmp2
);
9308 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
9312 int i
, loaded_base
= 0;
9313 TCGv_i32 loaded_var
;
9314 /* Load/store multiple. */
9315 addr
= load_reg(s
, rn
);
9317 for (i
= 0; i
< 16; i
++) {
9318 if (insn
& (1 << i
))
9321 if (insn
& (1 << 24)) {
9322 tcg_gen_addi_i32(addr
, addr
, -offset
);
9325 TCGV_UNUSED_I32(loaded_var
);
9326 for (i
= 0; i
< 16; i
++) {
9327 if ((insn
& (1 << i
)) == 0)
9329 if (insn
& (1 << 20)) {
9331 tmp
= tcg_temp_new_i32();
9332 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9335 } else if (i
== rn
) {
9339 store_reg(s
, i
, tmp
);
9343 tmp
= load_reg(s
, i
);
9344 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9345 tcg_temp_free_i32(tmp
);
9347 tcg_gen_addi_i32(addr
, addr
, 4);
9350 store_reg(s
, rn
, loaded_var
);
9352 if (insn
& (1 << 21)) {
9353 /* Base register writeback. */
9354 if (insn
& (1 << 24)) {
9355 tcg_gen_addi_i32(addr
, addr
, -offset
);
9357 /* Fault if writeback register is in register list. */
9358 if (insn
& (1 << rn
))
9360 store_reg(s
, rn
, addr
);
9362 tcg_temp_free_i32(addr
);
9369 op
= (insn
>> 21) & 0xf;
9371 /* Halfword pack. */
9372 tmp
= load_reg(s
, rn
);
9373 tmp2
= load_reg(s
, rm
);
9374 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
9375 if (insn
& (1 << 5)) {
9379 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9380 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9381 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9385 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9386 tcg_gen_ext16u_i32(tmp
, tmp
);
9387 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9389 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9390 tcg_temp_free_i32(tmp2
);
9391 store_reg(s
, rd
, tmp
);
9393 /* Data processing register constant shift. */
9395 tmp
= tcg_temp_new_i32();
9396 tcg_gen_movi_i32(tmp
, 0);
9398 tmp
= load_reg(s
, rn
);
9400 tmp2
= load_reg(s
, rm
);
9402 shiftop
= (insn
>> 4) & 3;
9403 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
9404 conds
= (insn
& (1 << 20)) != 0;
9405 logic_cc
= (conds
&& thumb2_logic_op(op
));
9406 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
9407 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
9409 tcg_temp_free_i32(tmp2
);
9411 store_reg(s
, rd
, tmp
);
9413 tcg_temp_free_i32(tmp
);
9417 case 13: /* Misc data processing. */
9418 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
9419 if (op
< 4 && (insn
& 0xf000) != 0xf000)
9422 case 0: /* Register controlled shift. */
9423 tmp
= load_reg(s
, rn
);
9424 tmp2
= load_reg(s
, rm
);
9425 if ((insn
& 0x70) != 0)
9427 op
= (insn
>> 21) & 3;
9428 logic_cc
= (insn
& (1 << 20)) != 0;
9429 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
9432 store_reg_bx(env
, s
, rd
, tmp
);
9434 case 1: /* Sign/zero extend. */
9435 tmp
= load_reg(s
, rm
);
9436 shift
= (insn
>> 4) & 3;
9437 /* ??? In many cases it's not necessary to do a
9438 rotate, a shift is sufficient. */
9440 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9441 op
= (insn
>> 20) & 7;
9443 case 0: gen_sxth(tmp
); break;
9444 case 1: gen_uxth(tmp
); break;
9445 case 2: gen_sxtb16(tmp
); break;
9446 case 3: gen_uxtb16(tmp
); break;
9447 case 4: gen_sxtb(tmp
); break;
9448 case 5: gen_uxtb(tmp
); break;
9449 default: goto illegal_op
;
9452 tmp2
= load_reg(s
, rn
);
9453 if ((op
>> 1) == 1) {
9454 gen_add16(tmp
, tmp2
);
9456 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9457 tcg_temp_free_i32(tmp2
);
9460 store_reg(s
, rd
, tmp
);
9462 case 2: /* SIMD add/subtract. */
9463 op
= (insn
>> 20) & 7;
9464 shift
= (insn
>> 4) & 7;
9465 if ((op
& 3) == 3 || (shift
& 3) == 3)
9467 tmp
= load_reg(s
, rn
);
9468 tmp2
= load_reg(s
, rm
);
9469 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
9470 tcg_temp_free_i32(tmp2
);
9471 store_reg(s
, rd
, tmp
);
9473 case 3: /* Other data processing. */
9474 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
9476 /* Saturating add/subtract. */
9477 tmp
= load_reg(s
, rn
);
9478 tmp2
= load_reg(s
, rm
);
9480 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
9482 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
9484 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
9485 tcg_temp_free_i32(tmp2
);
9487 tmp
= load_reg(s
, rn
);
9489 case 0x0a: /* rbit */
9490 gen_helper_rbit(tmp
, tmp
);
9492 case 0x08: /* rev */
9493 tcg_gen_bswap32_i32(tmp
, tmp
);
9495 case 0x09: /* rev16 */
9498 case 0x0b: /* revsh */
9501 case 0x10: /* sel */
9502 tmp2
= load_reg(s
, rm
);
9503 tmp3
= tcg_temp_new_i32();
9504 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
9505 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
9506 tcg_temp_free_i32(tmp3
);
9507 tcg_temp_free_i32(tmp2
);
9509 case 0x18: /* clz */
9510 gen_helper_clz(tmp
, tmp
);
9520 uint32_t sz
= op
& 0x3;
9521 uint32_t c
= op
& 0x8;
9523 if (!arm_feature(env
, ARM_FEATURE_CRC
)) {
9527 tmp2
= load_reg(s
, rm
);
9529 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
9530 } else if (sz
== 1) {
9531 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
9533 tmp3
= tcg_const_i32(1 << sz
);
9535 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
9537 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
9539 tcg_temp_free_i32(tmp2
);
9540 tcg_temp_free_i32(tmp3
);
9547 store_reg(s
, rd
, tmp
);
9549 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
9550 op
= (insn
>> 4) & 0xf;
9551 tmp
= load_reg(s
, rn
);
9552 tmp2
= load_reg(s
, rm
);
9553 switch ((insn
>> 20) & 7) {
9554 case 0: /* 32 x 32 -> 32 */
9555 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
9556 tcg_temp_free_i32(tmp2
);
9558 tmp2
= load_reg(s
, rs
);
9560 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
9562 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9563 tcg_temp_free_i32(tmp2
);
9566 case 1: /* 16 x 16 -> 32 */
9567 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
9568 tcg_temp_free_i32(tmp2
);
9570 tmp2
= load_reg(s
, rs
);
9571 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9572 tcg_temp_free_i32(tmp2
);
9575 case 2: /* Dual multiply add. */
9576 case 4: /* Dual multiply subtract. */
9578 gen_swap_half(tmp2
);
9579 gen_smul_dual(tmp
, tmp2
);
9580 if (insn
& (1 << 22)) {
9581 /* This subtraction cannot overflow. */
9582 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9584 /* This addition cannot overflow 32 bits;
9585 * however it may overflow considered as a signed
9586 * operation, in which case we must set the Q flag.
9588 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9590 tcg_temp_free_i32(tmp2
);
9593 tmp2
= load_reg(s
, rs
);
9594 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9595 tcg_temp_free_i32(tmp2
);
9598 case 3: /* 32 * 16 -> 32msb */
9600 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
9603 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9604 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
9605 tmp
= tcg_temp_new_i32();
9606 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
9607 tcg_temp_free_i64(tmp64
);
9610 tmp2
= load_reg(s
, rs
);
9611 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9612 tcg_temp_free_i32(tmp2
);
9615 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9616 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9618 tmp
= load_reg(s
, rs
);
9619 if (insn
& (1 << 20)) {
9620 tmp64
= gen_addq_msw(tmp64
, tmp
);
9622 tmp64
= gen_subq_msw(tmp64
, tmp
);
9625 if (insn
& (1 << 4)) {
9626 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
9628 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
9629 tmp
= tcg_temp_new_i32();
9630 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
9631 tcg_temp_free_i64(tmp64
);
9633 case 7: /* Unsigned sum of absolute differences. */
9634 gen_helper_usad8(tmp
, tmp
, tmp2
);
9635 tcg_temp_free_i32(tmp2
);
9637 tmp2
= load_reg(s
, rs
);
9638 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9639 tcg_temp_free_i32(tmp2
);
9643 store_reg(s
, rd
, tmp
);
9645 case 6: case 7: /* 64-bit multiply, Divide. */
9646 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
9647 tmp
= load_reg(s
, rn
);
9648 tmp2
= load_reg(s
, rm
);
9649 if ((op
& 0x50) == 0x10) {
9651 if (!arm_feature(env
, ARM_FEATURE_THUMB_DIV
)) {
9655 gen_helper_udiv(tmp
, tmp
, tmp2
);
9657 gen_helper_sdiv(tmp
, tmp
, tmp2
);
9658 tcg_temp_free_i32(tmp2
);
9659 store_reg(s
, rd
, tmp
);
9660 } else if ((op
& 0xe) == 0xc) {
9661 /* Dual multiply accumulate long. */
9663 gen_swap_half(tmp2
);
9664 gen_smul_dual(tmp
, tmp2
);
9666 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9668 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9670 tcg_temp_free_i32(tmp2
);
9672 tmp64
= tcg_temp_new_i64();
9673 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9674 tcg_temp_free_i32(tmp
);
9675 gen_addq(s
, tmp64
, rs
, rd
);
9676 gen_storeq_reg(s
, rs
, rd
, tmp64
);
9677 tcg_temp_free_i64(tmp64
);
9680 /* Unsigned 64-bit multiply */
9681 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
9685 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
9686 tcg_temp_free_i32(tmp2
);
9687 tmp64
= tcg_temp_new_i64();
9688 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9689 tcg_temp_free_i32(tmp
);
9691 /* Signed 64-bit multiply */
9692 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9697 gen_addq_lo(s
, tmp64
, rs
);
9698 gen_addq_lo(s
, tmp64
, rd
);
9699 } else if (op
& 0x40) {
9700 /* 64-bit accumulate. */
9701 gen_addq(s
, tmp64
, rs
, rd
);
9703 gen_storeq_reg(s
, rs
, rd
, tmp64
);
9704 tcg_temp_free_i64(tmp64
);
9709 case 6: case 7: case 14: case 15:
9711 if (((insn
>> 24) & 3) == 3) {
9712 /* Translate into the equivalent ARM encoding. */
9713 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
9714 if (disas_neon_data_insn(env
, s
, insn
))
9716 } else if (((insn
>> 8) & 0xe) == 10) {
9717 if (disas_vfp_insn(env
, s
, insn
)) {
9721 if (insn
& (1 << 28))
9723 if (disas_coproc_insn (env
, s
, insn
))
9727 case 8: case 9: case 10: case 11:
9728 if (insn
& (1 << 15)) {
9729 /* Branches, misc control. */
9730 if (insn
& 0x5000) {
9731 /* Unconditional branch. */
9732 /* signextend(hw1[10:0]) -> offset[:12]. */
9733 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
9734 /* hw1[10:0] -> offset[11:1]. */
9735 offset
|= (insn
& 0x7ff) << 1;
9736 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9737 offset[24:22] already have the same value because of the
9738 sign extension above. */
9739 offset
^= ((~insn
) & (1 << 13)) << 10;
9740 offset
^= ((~insn
) & (1 << 11)) << 11;
9742 if (insn
& (1 << 14)) {
9743 /* Branch and link. */
9744 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
9748 if (insn
& (1 << 12)) {
9753 offset
&= ~(uint32_t)2;
9754 /* thumb2 bx, no need to check */
9755 gen_bx_im(s
, offset
);
9757 } else if (((insn
>> 23) & 7) == 7) {
9759 if (insn
& (1 << 13))
9762 if (insn
& (1 << 26)) {
9763 if (!(insn
& (1 << 20))) {
9764 /* Hypervisor call (v7) */
9765 int imm16
= extract32(insn
, 16, 4) << 12
9766 | extract32(insn
, 0, 12);
9773 /* Secure monitor call (v6+) */
9781 op
= (insn
>> 20) & 7;
9783 case 0: /* msr cpsr. */
9785 tmp
= load_reg(s
, rn
);
9786 addr
= tcg_const_i32(insn
& 0xff);
9787 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9788 tcg_temp_free_i32(addr
);
9789 tcg_temp_free_i32(tmp
);
9794 case 1: /* msr spsr. */
9797 tmp
= load_reg(s
, rn
);
9799 msr_mask(env
, s
, (insn
>> 8) & 0xf, op
== 1),
9803 case 2: /* cps, nop-hint. */
9804 if (((insn
>> 8) & 7) == 0) {
9805 gen_nop_hint(s
, insn
& 0xff);
9807 /* Implemented as NOP in user mode. */
9812 if (insn
& (1 << 10)) {
9813 if (insn
& (1 << 7))
9815 if (insn
& (1 << 6))
9817 if (insn
& (1 << 5))
9819 if (insn
& (1 << 9))
9820 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
9822 if (insn
& (1 << 8)) {
9824 imm
|= (insn
& 0x1f);
9827 gen_set_psr_im(s
, offset
, 0, imm
);
9830 case 3: /* Special control operations. */
9832 op
= (insn
>> 4) & 0xf;
9840 /* These execute as NOPs. */
9847 /* Trivial implementation equivalent to bx. */
9848 tmp
= load_reg(s
, rn
);
9851 case 5: /* Exception return. */
9855 if (rn
!= 14 || rd
!= 15) {
9858 tmp
= load_reg(s
, rn
);
9859 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
9860 gen_exception_return(s
, tmp
);
9862 case 6: /* mrs cpsr. */
9863 tmp
= tcg_temp_new_i32();
9865 addr
= tcg_const_i32(insn
& 0xff);
9866 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
9867 tcg_temp_free_i32(addr
);
9869 gen_helper_cpsr_read(tmp
, cpu_env
);
9871 store_reg(s
, rd
, tmp
);
9873 case 7: /* mrs spsr. */
9874 /* Not accessible in user mode. */
9875 if (IS_USER(s
) || IS_M(env
))
9877 tmp
= load_cpu_field(spsr
);
9878 store_reg(s
, rd
, tmp
);
9883 /* Conditional branch. */
9884 op
= (insn
>> 22) & 0xf;
9885 /* Generate a conditional jump to next instruction. */
9886 s
->condlabel
= gen_new_label();
9887 arm_gen_test_cc(op
^ 1, s
->condlabel
);
9890 /* offset[11:1] = insn[10:0] */
9891 offset
= (insn
& 0x7ff) << 1;
9892 /* offset[17:12] = insn[21:16]. */
9893 offset
|= (insn
& 0x003f0000) >> 4;
9894 /* offset[31:20] = insn[26]. */
9895 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
9896 /* offset[18] = insn[13]. */
9897 offset
|= (insn
& (1 << 13)) << 5;
9898 /* offset[19] = insn[11]. */
9899 offset
|= (insn
& (1 << 11)) << 8;
9901 /* jump to the offset */
9902 gen_jmp(s
, s
->pc
+ offset
);
9905 /* Data processing immediate. */
9906 if (insn
& (1 << 25)) {
9907 if (insn
& (1 << 24)) {
9908 if (insn
& (1 << 20))
9910 /* Bitfield/Saturate. */
9911 op
= (insn
>> 21) & 7;
9913 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
9915 tmp
= tcg_temp_new_i32();
9916 tcg_gen_movi_i32(tmp
, 0);
9918 tmp
= load_reg(s
, rn
);
9921 case 2: /* Signed bitfield extract. */
9923 if (shift
+ imm
> 32)
9926 gen_sbfx(tmp
, shift
, imm
);
9928 case 6: /* Unsigned bitfield extract. */
9930 if (shift
+ imm
> 32)
9933 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
9935 case 3: /* Bitfield insert/clear. */
9938 imm
= imm
+ 1 - shift
;
9940 tmp2
= load_reg(s
, rd
);
9941 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
9942 tcg_temp_free_i32(tmp2
);
9947 default: /* Saturate. */
9950 tcg_gen_sari_i32(tmp
, tmp
, shift
);
9952 tcg_gen_shli_i32(tmp
, tmp
, shift
);
9954 tmp2
= tcg_const_i32(imm
);
9957 if ((op
& 1) && shift
== 0)
9958 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
9960 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
9963 if ((op
& 1) && shift
== 0)
9964 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
9966 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
9968 tcg_temp_free_i32(tmp2
);
9971 store_reg(s
, rd
, tmp
);
9973 imm
= ((insn
& 0x04000000) >> 15)
9974 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
9975 if (insn
& (1 << 22)) {
9976 /* 16-bit immediate. */
9977 imm
|= (insn
>> 4) & 0xf000;
9978 if (insn
& (1 << 23)) {
9980 tmp
= load_reg(s
, rd
);
9981 tcg_gen_ext16u_i32(tmp
, tmp
);
9982 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
9985 tmp
= tcg_temp_new_i32();
9986 tcg_gen_movi_i32(tmp
, imm
);
9989 /* Add/sub 12-bit immediate. */
9991 offset
= s
->pc
& ~(uint32_t)3;
9992 if (insn
& (1 << 23))
9996 tmp
= tcg_temp_new_i32();
9997 tcg_gen_movi_i32(tmp
, offset
);
9999 tmp
= load_reg(s
, rn
);
10000 if (insn
& (1 << 23))
10001 tcg_gen_subi_i32(tmp
, tmp
, imm
);
10003 tcg_gen_addi_i32(tmp
, tmp
, imm
);
10006 store_reg(s
, rd
, tmp
);
10009 int shifter_out
= 0;
10010 /* modified 12-bit immediate. */
10011 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
10012 imm
= (insn
& 0xff);
10015 /* Nothing to do. */
10017 case 1: /* 00XY00XY */
10020 case 2: /* XY00XY00 */
10024 case 3: /* XYXYXYXY */
10028 default: /* Rotated constant. */
10029 shift
= (shift
<< 1) | (imm
>> 7);
10031 imm
= imm
<< (32 - shift
);
10035 tmp2
= tcg_temp_new_i32();
10036 tcg_gen_movi_i32(tmp2
, imm
);
10037 rn
= (insn
>> 16) & 0xf;
10039 tmp
= tcg_temp_new_i32();
10040 tcg_gen_movi_i32(tmp
, 0);
10042 tmp
= load_reg(s
, rn
);
10044 op
= (insn
>> 21) & 0xf;
10045 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
10046 shifter_out
, tmp
, tmp2
))
10048 tcg_temp_free_i32(tmp2
);
10049 rd
= (insn
>> 8) & 0xf;
10051 store_reg(s
, rd
, tmp
);
10053 tcg_temp_free_i32(tmp
);
10058 case 12: /* Load/store single data item. */
10063 if ((insn
& 0x01100000) == 0x01000000) {
10064 if (disas_neon_ls_insn(env
, s
, insn
))
10068 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
10070 if (!(insn
& (1 << 20))) {
10074 /* Byte or halfword load space with dest == r15 : memory hints.
10075 * Catch them early so we don't emit pointless addressing code.
10076 * This space is a mix of:
10077 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10078 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10080 * unallocated hints, which must be treated as NOPs
10081 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10082 * which is easiest for the decoding logic
10083 * Some space which must UNDEF
10085 int op1
= (insn
>> 23) & 3;
10086 int op2
= (insn
>> 6) & 0x3f;
10091 /* UNPREDICTABLE, unallocated hint or
10092 * PLD/PLDW/PLI (literal)
10097 return 0; /* PLD/PLDW/PLI or unallocated hint */
10099 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
10100 return 0; /* PLD/PLDW/PLI or unallocated hint */
10102 /* UNDEF space, or an UNPREDICTABLE */
10106 memidx
= get_mem_index(s
);
10108 addr
= tcg_temp_new_i32();
10110 /* s->pc has already been incremented by 4. */
10111 imm
= s
->pc
& 0xfffffffc;
10112 if (insn
& (1 << 23))
10113 imm
+= insn
& 0xfff;
10115 imm
-= insn
& 0xfff;
10116 tcg_gen_movi_i32(addr
, imm
);
10118 addr
= load_reg(s
, rn
);
10119 if (insn
& (1 << 23)) {
10120 /* Positive offset. */
10121 imm
= insn
& 0xfff;
10122 tcg_gen_addi_i32(addr
, addr
, imm
);
10125 switch ((insn
>> 8) & 0xf) {
10126 case 0x0: /* Shifted Register. */
10127 shift
= (insn
>> 4) & 0xf;
10129 tcg_temp_free_i32(addr
);
10132 tmp
= load_reg(s
, rm
);
10134 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10135 tcg_gen_add_i32(addr
, addr
, tmp
);
10136 tcg_temp_free_i32(tmp
);
10138 case 0xc: /* Negative offset. */
10139 tcg_gen_addi_i32(addr
, addr
, -imm
);
10141 case 0xe: /* User privilege. */
10142 tcg_gen_addi_i32(addr
, addr
, imm
);
10143 memidx
= MMU_USER_IDX
;
10145 case 0x9: /* Post-decrement. */
10147 /* Fall through. */
10148 case 0xb: /* Post-increment. */
10152 case 0xd: /* Pre-decrement. */
10154 /* Fall through. */
10155 case 0xf: /* Pre-increment. */
10156 tcg_gen_addi_i32(addr
, addr
, imm
);
10160 tcg_temp_free_i32(addr
);
10165 if (insn
& (1 << 20)) {
10167 tmp
= tcg_temp_new_i32();
10170 gen_aa32_ld8u(tmp
, addr
, memidx
);
10173 gen_aa32_ld8s(tmp
, addr
, memidx
);
10176 gen_aa32_ld16u(tmp
, addr
, memidx
);
10179 gen_aa32_ld16s(tmp
, addr
, memidx
);
10182 gen_aa32_ld32u(tmp
, addr
, memidx
);
10185 tcg_temp_free_i32(tmp
);
10186 tcg_temp_free_i32(addr
);
10192 store_reg(s
, rs
, tmp
);
10196 tmp
= load_reg(s
, rs
);
10199 gen_aa32_st8(tmp
, addr
, memidx
);
10202 gen_aa32_st16(tmp
, addr
, memidx
);
10205 gen_aa32_st32(tmp
, addr
, memidx
);
10208 tcg_temp_free_i32(tmp
);
10209 tcg_temp_free_i32(addr
);
10212 tcg_temp_free_i32(tmp
);
10215 tcg_gen_addi_i32(addr
, addr
, imm
);
10217 store_reg(s
, rn
, addr
);
10219 tcg_temp_free_i32(addr
);
10231 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
10233 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
10240 if (s
->condexec_mask
) {
10241 cond
= s
->condexec_cond
;
10242 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
10243 s
->condlabel
= gen_new_label();
10244 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
10249 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
10252 switch (insn
>> 12) {
10256 op
= (insn
>> 11) & 3;
10259 rn
= (insn
>> 3) & 7;
10260 tmp
= load_reg(s
, rn
);
10261 if (insn
& (1 << 10)) {
10263 tmp2
= tcg_temp_new_i32();
10264 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
10267 rm
= (insn
>> 6) & 7;
10268 tmp2
= load_reg(s
, rm
);
10270 if (insn
& (1 << 9)) {
10271 if (s
->condexec_mask
)
10272 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10274 gen_sub_CC(tmp
, tmp
, tmp2
);
10276 if (s
->condexec_mask
)
10277 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10279 gen_add_CC(tmp
, tmp
, tmp2
);
10281 tcg_temp_free_i32(tmp2
);
10282 store_reg(s
, rd
, tmp
);
10284 /* shift immediate */
10285 rm
= (insn
>> 3) & 7;
10286 shift
= (insn
>> 6) & 0x1f;
10287 tmp
= load_reg(s
, rm
);
10288 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
10289 if (!s
->condexec_mask
)
10291 store_reg(s
, rd
, tmp
);
10295 /* arithmetic large immediate */
10296 op
= (insn
>> 11) & 3;
10297 rd
= (insn
>> 8) & 0x7;
10298 if (op
== 0) { /* mov */
10299 tmp
= tcg_temp_new_i32();
10300 tcg_gen_movi_i32(tmp
, insn
& 0xff);
10301 if (!s
->condexec_mask
)
10303 store_reg(s
, rd
, tmp
);
10305 tmp
= load_reg(s
, rd
);
10306 tmp2
= tcg_temp_new_i32();
10307 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
10310 gen_sub_CC(tmp
, tmp
, tmp2
);
10311 tcg_temp_free_i32(tmp
);
10312 tcg_temp_free_i32(tmp2
);
10315 if (s
->condexec_mask
)
10316 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10318 gen_add_CC(tmp
, tmp
, tmp2
);
10319 tcg_temp_free_i32(tmp2
);
10320 store_reg(s
, rd
, tmp
);
10323 if (s
->condexec_mask
)
10324 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10326 gen_sub_CC(tmp
, tmp
, tmp2
);
10327 tcg_temp_free_i32(tmp2
);
10328 store_reg(s
, rd
, tmp
);
10334 if (insn
& (1 << 11)) {
10335 rd
= (insn
>> 8) & 7;
10336 /* load pc-relative. Bit 1 of PC is ignored. */
10337 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
10338 val
&= ~(uint32_t)2;
10339 addr
= tcg_temp_new_i32();
10340 tcg_gen_movi_i32(addr
, val
);
10341 tmp
= tcg_temp_new_i32();
10342 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10343 tcg_temp_free_i32(addr
);
10344 store_reg(s
, rd
, tmp
);
10347 if (insn
& (1 << 10)) {
10348 /* data processing extended or blx */
10349 rd
= (insn
& 7) | ((insn
>> 4) & 8);
10350 rm
= (insn
>> 3) & 0xf;
10351 op
= (insn
>> 8) & 3;
10354 tmp
= load_reg(s
, rd
);
10355 tmp2
= load_reg(s
, rm
);
10356 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10357 tcg_temp_free_i32(tmp2
);
10358 store_reg(s
, rd
, tmp
);
10361 tmp
= load_reg(s
, rd
);
10362 tmp2
= load_reg(s
, rm
);
10363 gen_sub_CC(tmp
, tmp
, tmp2
);
10364 tcg_temp_free_i32(tmp2
);
10365 tcg_temp_free_i32(tmp
);
10367 case 2: /* mov/cpy */
10368 tmp
= load_reg(s
, rm
);
10369 store_reg(s
, rd
, tmp
);
10371 case 3:/* branch [and link] exchange thumb register */
10372 tmp
= load_reg(s
, rm
);
10373 if (insn
& (1 << 7)) {
10375 val
= (uint32_t)s
->pc
| 1;
10376 tmp2
= tcg_temp_new_i32();
10377 tcg_gen_movi_i32(tmp2
, val
);
10378 store_reg(s
, 14, tmp2
);
10380 /* already thumb, no need to check */
10387 /* data processing register */
10389 rm
= (insn
>> 3) & 7;
10390 op
= (insn
>> 6) & 0xf;
10391 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
10392 /* the shift/rotate ops want the operands backwards */
10401 if (op
== 9) { /* neg */
10402 tmp
= tcg_temp_new_i32();
10403 tcg_gen_movi_i32(tmp
, 0);
10404 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
10405 tmp
= load_reg(s
, rd
);
10407 TCGV_UNUSED_I32(tmp
);
10410 tmp2
= load_reg(s
, rm
);
10412 case 0x0: /* and */
10413 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
10414 if (!s
->condexec_mask
)
10417 case 0x1: /* eor */
10418 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
10419 if (!s
->condexec_mask
)
10422 case 0x2: /* lsl */
10423 if (s
->condexec_mask
) {
10424 gen_shl(tmp2
, tmp2
, tmp
);
10426 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10427 gen_logic_CC(tmp2
);
10430 case 0x3: /* lsr */
10431 if (s
->condexec_mask
) {
10432 gen_shr(tmp2
, tmp2
, tmp
);
10434 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10435 gen_logic_CC(tmp2
);
10438 case 0x4: /* asr */
10439 if (s
->condexec_mask
) {
10440 gen_sar(tmp2
, tmp2
, tmp
);
10442 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10443 gen_logic_CC(tmp2
);
10446 case 0x5: /* adc */
10447 if (s
->condexec_mask
) {
10448 gen_adc(tmp
, tmp2
);
10450 gen_adc_CC(tmp
, tmp
, tmp2
);
10453 case 0x6: /* sbc */
10454 if (s
->condexec_mask
) {
10455 gen_sub_carry(tmp
, tmp
, tmp2
);
10457 gen_sbc_CC(tmp
, tmp
, tmp2
);
10460 case 0x7: /* ror */
10461 if (s
->condexec_mask
) {
10462 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
10463 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
10465 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10466 gen_logic_CC(tmp2
);
10469 case 0x8: /* tst */
10470 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
10474 case 0x9: /* neg */
10475 if (s
->condexec_mask
)
10476 tcg_gen_neg_i32(tmp
, tmp2
);
10478 gen_sub_CC(tmp
, tmp
, tmp2
);
10480 case 0xa: /* cmp */
10481 gen_sub_CC(tmp
, tmp
, tmp2
);
10484 case 0xb: /* cmn */
10485 gen_add_CC(tmp
, tmp
, tmp2
);
10488 case 0xc: /* orr */
10489 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
10490 if (!s
->condexec_mask
)
10493 case 0xd: /* mul */
10494 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
10495 if (!s
->condexec_mask
)
10498 case 0xe: /* bic */
10499 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
10500 if (!s
->condexec_mask
)
10503 case 0xf: /* mvn */
10504 tcg_gen_not_i32(tmp2
, tmp2
);
10505 if (!s
->condexec_mask
)
10506 gen_logic_CC(tmp2
);
10513 store_reg(s
, rm
, tmp2
);
10515 tcg_temp_free_i32(tmp
);
10517 store_reg(s
, rd
, tmp
);
10518 tcg_temp_free_i32(tmp2
);
10521 tcg_temp_free_i32(tmp
);
10522 tcg_temp_free_i32(tmp2
);
10527 /* load/store register offset. */
10529 rn
= (insn
>> 3) & 7;
10530 rm
= (insn
>> 6) & 7;
10531 op
= (insn
>> 9) & 7;
10532 addr
= load_reg(s
, rn
);
10533 tmp
= load_reg(s
, rm
);
10534 tcg_gen_add_i32(addr
, addr
, tmp
);
10535 tcg_temp_free_i32(tmp
);
10537 if (op
< 3) { /* store */
10538 tmp
= load_reg(s
, rd
);
10540 tmp
= tcg_temp_new_i32();
10545 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10548 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
10551 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
10553 case 3: /* ldrsb */
10554 gen_aa32_ld8s(tmp
, addr
, get_mem_index(s
));
10557 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10560 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
10563 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
10565 case 7: /* ldrsh */
10566 gen_aa32_ld16s(tmp
, addr
, get_mem_index(s
));
10569 if (op
>= 3) { /* load */
10570 store_reg(s
, rd
, tmp
);
10572 tcg_temp_free_i32(tmp
);
10574 tcg_temp_free_i32(addr
);
10578 /* load/store word immediate offset */
10580 rn
= (insn
>> 3) & 7;
10581 addr
= load_reg(s
, rn
);
10582 val
= (insn
>> 4) & 0x7c;
10583 tcg_gen_addi_i32(addr
, addr
, val
);
10585 if (insn
& (1 << 11)) {
10587 tmp
= tcg_temp_new_i32();
10588 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10589 store_reg(s
, rd
, tmp
);
10592 tmp
= load_reg(s
, rd
);
10593 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10594 tcg_temp_free_i32(tmp
);
10596 tcg_temp_free_i32(addr
);
10600 /* load/store byte immediate offset */
10602 rn
= (insn
>> 3) & 7;
10603 addr
= load_reg(s
, rn
);
10604 val
= (insn
>> 6) & 0x1f;
10605 tcg_gen_addi_i32(addr
, addr
, val
);
10607 if (insn
& (1 << 11)) {
10609 tmp
= tcg_temp_new_i32();
10610 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
10611 store_reg(s
, rd
, tmp
);
10614 tmp
= load_reg(s
, rd
);
10615 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
10616 tcg_temp_free_i32(tmp
);
10618 tcg_temp_free_i32(addr
);
10622 /* load/store halfword immediate offset */
10624 rn
= (insn
>> 3) & 7;
10625 addr
= load_reg(s
, rn
);
10626 val
= (insn
>> 5) & 0x3e;
10627 tcg_gen_addi_i32(addr
, addr
, val
);
10629 if (insn
& (1 << 11)) {
10631 tmp
= tcg_temp_new_i32();
10632 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
10633 store_reg(s
, rd
, tmp
);
10636 tmp
= load_reg(s
, rd
);
10637 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
10638 tcg_temp_free_i32(tmp
);
10640 tcg_temp_free_i32(addr
);
10644 /* load/store from stack */
10645 rd
= (insn
>> 8) & 7;
10646 addr
= load_reg(s
, 13);
10647 val
= (insn
& 0xff) * 4;
10648 tcg_gen_addi_i32(addr
, addr
, val
);
10650 if (insn
& (1 << 11)) {
10652 tmp
= tcg_temp_new_i32();
10653 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10654 store_reg(s
, rd
, tmp
);
10657 tmp
= load_reg(s
, rd
);
10658 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10659 tcg_temp_free_i32(tmp
);
10661 tcg_temp_free_i32(addr
);
10665 /* add to high reg */
10666 rd
= (insn
>> 8) & 7;
10667 if (insn
& (1 << 11)) {
10669 tmp
= load_reg(s
, 13);
10671 /* PC. bit 1 is ignored. */
10672 tmp
= tcg_temp_new_i32();
10673 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
10675 val
= (insn
& 0xff) * 4;
10676 tcg_gen_addi_i32(tmp
, tmp
, val
);
10677 store_reg(s
, rd
, tmp
);
10682 op
= (insn
>> 8) & 0xf;
10685 /* adjust stack pointer */
10686 tmp
= load_reg(s
, 13);
10687 val
= (insn
& 0x7f) * 4;
10688 if (insn
& (1 << 7))
10689 val
= -(int32_t)val
;
10690 tcg_gen_addi_i32(tmp
, tmp
, val
);
10691 store_reg(s
, 13, tmp
);
10694 case 2: /* sign/zero extend. */
10697 rm
= (insn
>> 3) & 7;
10698 tmp
= load_reg(s
, rm
);
10699 switch ((insn
>> 6) & 3) {
10700 case 0: gen_sxth(tmp
); break;
10701 case 1: gen_sxtb(tmp
); break;
10702 case 2: gen_uxth(tmp
); break;
10703 case 3: gen_uxtb(tmp
); break;
10705 store_reg(s
, rd
, tmp
);
10707 case 4: case 5: case 0xc: case 0xd:
10709 addr
= load_reg(s
, 13);
10710 if (insn
& (1 << 8))
10714 for (i
= 0; i
< 8; i
++) {
10715 if (insn
& (1 << i
))
10718 if ((insn
& (1 << 11)) == 0) {
10719 tcg_gen_addi_i32(addr
, addr
, -offset
);
10721 for (i
= 0; i
< 8; i
++) {
10722 if (insn
& (1 << i
)) {
10723 if (insn
& (1 << 11)) {
10725 tmp
= tcg_temp_new_i32();
10726 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10727 store_reg(s
, i
, tmp
);
10730 tmp
= load_reg(s
, i
);
10731 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10732 tcg_temp_free_i32(tmp
);
10734 /* advance to the next address. */
10735 tcg_gen_addi_i32(addr
, addr
, 4);
10738 TCGV_UNUSED_I32(tmp
);
10739 if (insn
& (1 << 8)) {
10740 if (insn
& (1 << 11)) {
10742 tmp
= tcg_temp_new_i32();
10743 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10744 /* don't set the pc until the rest of the instruction
10748 tmp
= load_reg(s
, 14);
10749 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10750 tcg_temp_free_i32(tmp
);
10752 tcg_gen_addi_i32(addr
, addr
, 4);
10754 if ((insn
& (1 << 11)) == 0) {
10755 tcg_gen_addi_i32(addr
, addr
, -offset
);
10757 /* write back the new stack pointer */
10758 store_reg(s
, 13, addr
);
10759 /* set the new PC value */
10760 if ((insn
& 0x0900) == 0x0900) {
10761 store_reg_from_load(env
, s
, 15, tmp
);
10765 case 1: case 3: case 9: case 11: /* czb */
10767 tmp
= load_reg(s
, rm
);
10768 s
->condlabel
= gen_new_label();
10770 if (insn
& (1 << 11))
10771 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
10773 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
10774 tcg_temp_free_i32(tmp
);
10775 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
10776 val
= (uint32_t)s
->pc
+ 2;
10781 case 15: /* IT, nop-hint. */
10782 if ((insn
& 0xf) == 0) {
10783 gen_nop_hint(s
, (insn
>> 4) & 0xf);
10787 s
->condexec_cond
= (insn
>> 4) & 0xe;
10788 s
->condexec_mask
= insn
& 0x1f;
10789 /* No actual code generated for this insn, just setup state. */
10792 case 0xe: /* bkpt */
10794 int imm8
= extract32(insn
, 0, 8);
10796 gen_exception_insn(s
, 2, EXCP_BKPT
, syn_aa32_bkpt(imm8
, true));
10800 case 0xa: /* rev */
10802 rn
= (insn
>> 3) & 0x7;
10804 tmp
= load_reg(s
, rn
);
10805 switch ((insn
>> 6) & 3) {
10806 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
10807 case 1: gen_rev16(tmp
); break;
10808 case 3: gen_revsh(tmp
); break;
10809 default: goto illegal_op
;
10811 store_reg(s
, rd
, tmp
);
10815 switch ((insn
>> 5) & 7) {
10819 if (((insn
>> 3) & 1) != s
->bswap_code
) {
10820 /* Dynamic endianness switching not implemented. */
10821 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
10832 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
10835 addr
= tcg_const_i32(19);
10836 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10837 tcg_temp_free_i32(addr
);
10841 addr
= tcg_const_i32(16);
10842 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10843 tcg_temp_free_i32(addr
);
10845 tcg_temp_free_i32(tmp
);
10848 if (insn
& (1 << 4)) {
10849 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
10853 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
10868 /* load/store multiple */
10869 TCGv_i32 loaded_var
;
10870 TCGV_UNUSED_I32(loaded_var
);
10871 rn
= (insn
>> 8) & 0x7;
10872 addr
= load_reg(s
, rn
);
10873 for (i
= 0; i
< 8; i
++) {
10874 if (insn
& (1 << i
)) {
10875 if (insn
& (1 << 11)) {
10877 tmp
= tcg_temp_new_i32();
10878 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10882 store_reg(s
, i
, tmp
);
10886 tmp
= load_reg(s
, i
);
10887 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10888 tcg_temp_free_i32(tmp
);
10890 /* advance to the next address */
10891 tcg_gen_addi_i32(addr
, addr
, 4);
10894 if ((insn
& (1 << rn
)) == 0) {
10895 /* base reg not in list: base register writeback */
10896 store_reg(s
, rn
, addr
);
10898 /* base reg in list: if load, complete it now */
10899 if (insn
& (1 << 11)) {
10900 store_reg(s
, rn
, loaded_var
);
10902 tcg_temp_free_i32(addr
);
10907 /* conditional branch or swi */
10908 cond
= (insn
>> 8) & 0xf;
10914 gen_set_pc_im(s
, s
->pc
);
10915 s
->svc_imm
= extract32(insn
, 0, 8);
10916 s
->is_jmp
= DISAS_SWI
;
10919 /* generate a conditional jump to next instruction */
10920 s
->condlabel
= gen_new_label();
10921 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
10924 /* jump to the offset */
10925 val
= (uint32_t)s
->pc
+ 2;
10926 offset
= ((int32_t)insn
<< 24) >> 24;
10927 val
+= offset
<< 1;
10932 if (insn
& (1 << 11)) {
10933 if (disas_thumb2_insn(env
, s
, insn
))
10937 /* unconditional branch */
10938 val
= (uint32_t)s
->pc
;
10939 offset
= ((int32_t)insn
<< 21) >> 21;
10940 val
+= (offset
<< 1) + 2;
10945 if (disas_thumb2_insn(env
, s
, insn
))
10951 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized());
10955 gen_exception_insn(s
, 2, EXCP_UDEF
, syn_uncategorized());
10958 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
10959 basic block 'tb'. If search_pc is TRUE, also generate PC
10960 information for each intermediate instruction. */
10961 static inline void gen_intermediate_code_internal(ARMCPU
*cpu
,
10962 TranslationBlock
*tb
,
10965 CPUState
*cs
= CPU(cpu
);
10966 CPUARMState
*env
= &cpu
->env
;
10967 DisasContext dc1
, *dc
= &dc1
;
10969 uint16_t *gen_opc_end
;
10971 target_ulong pc_start
;
10972 target_ulong next_page_start
;
10976 /* generate intermediate code */
10978 /* The A64 decoder has its own top level loop, because it doesn't need
10979 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
10981 if (ARM_TBFLAG_AARCH64_STATE(tb
->flags
)) {
10982 gen_intermediate_code_internal_a64(cpu
, tb
, search_pc
);
10990 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
10992 dc
->is_jmp
= DISAS_NEXT
;
10994 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
10998 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
10999 dc
->bswap_code
= ARM_TBFLAG_BSWAP_CODE(tb
->flags
);
11000 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
11001 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
11002 #if !defined(CONFIG_USER_ONLY)
11003 dc
->user
= (ARM_TBFLAG_PRIV(tb
->flags
) == 0);
11005 dc
->cpacr_fpen
= ARM_TBFLAG_CPACR_FPEN(tb
->flags
);
11006 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
11007 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
11008 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
11009 dc
->c15_cpar
= ARM_TBFLAG_XSCALE_CPAR(tb
->flags
);
11010 dc
->cp_regs
= cpu
->cp_regs
;
11011 dc
->current_pl
= arm_current_pl(env
);
11012 dc
->features
= env
->features
;
11014 /* Single step state. The code-generation logic here is:
11016 * generate code with no special handling for single-stepping (except
11017 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11018 * this happens anyway because those changes are all system register or
11020 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11021 * emit code for one insn
11022 * emit code to clear PSTATE.SS
11023 * emit code to generate software step exception for completed step
11024 * end TB (as usual for having generated an exception)
11025 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11026 * emit code to generate a software step exception
11029 dc
->ss_active
= ARM_TBFLAG_SS_ACTIVE(tb
->flags
);
11030 dc
->pstate_ss
= ARM_TBFLAG_PSTATE_SS(tb
->flags
);
11031 dc
->is_ldex
= false;
11032 dc
->ss_same_el
= false; /* Can't be true since EL_d must be AArch64 */
11034 cpu_F0s
= tcg_temp_new_i32();
11035 cpu_F1s
= tcg_temp_new_i32();
11036 cpu_F0d
= tcg_temp_new_i64();
11037 cpu_F1d
= tcg_temp_new_i64();
11040 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11041 cpu_M0
= tcg_temp_new_i64();
11042 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
11045 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
11046 if (max_insns
== 0)
11047 max_insns
= CF_COUNT_MASK
;
11051 tcg_clear_temp_count();
11053 /* A note on handling of the condexec (IT) bits:
11055 * We want to avoid the overhead of having to write the updated condexec
11056 * bits back to the CPUARMState for every instruction in an IT block. So:
11057 * (1) if the condexec bits are not already zero then we write
11058 * zero back into the CPUARMState now. This avoids complications trying
11059 * to do it at the end of the block. (For example if we don't do this
11060 * it's hard to identify whether we can safely skip writing condexec
11061 * at the end of the TB, which we definitely want to do for the case
11062 * where a TB doesn't do anything with the IT state at all.)
11063 * (2) if we are going to leave the TB then we call gen_set_condexec()
11064 * which will write the correct value into CPUARMState if zero is wrong.
11065 * This is done both for leaving the TB at the end, and for leaving
11066 * it because of an exception we know will happen, which is done in
11067 * gen_exception_insn(). The latter is necessary because we need to
11068 * leave the TB with the PC/IT state just prior to execution of the
11069 * instruction which caused the exception.
11070 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11071 * then the CPUARMState will be wrong and we need to reset it.
11072 * This is handled in the same way as restoration of the
11073 * PC in these situations: we will be called again with search_pc=1
11074 * and generate a mapping of the condexec bits for each PC in
11075 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
11076 * this to restore the condexec bits.
11078 * Note that there are no instructions which can read the condexec
11079 * bits, and none which can write non-static values to them, so
11080 * we don't need to care about whether CPUARMState is correct in the
11084 /* Reset the conditional execution bits immediately. This avoids
11085 complications trying to do it at the end of the block. */
11086 if (dc
->condexec_mask
|| dc
->condexec_cond
)
11088 TCGv_i32 tmp
= tcg_temp_new_i32();
11089 tcg_gen_movi_i32(tmp
, 0);
11090 store_cpu_field(tmp
, condexec_bits
);
11093 #ifdef CONFIG_USER_ONLY
11094 /* Intercept jump to the magic kernel page. */
11095 if (dc
->pc
>= 0xffff0000) {
11096 /* We always get here via a jump, so know we are not in a
11097 conditional execution block. */
11098 gen_exception_internal(EXCP_KERNEL_TRAP
);
11099 dc
->is_jmp
= DISAS_UPDATE
;
11103 if (dc
->pc
>= 0xfffffff0 && IS_M(env
)) {
11104 /* We always get here via a jump, so know we are not in a
11105 conditional execution block. */
11106 gen_exception_internal(EXCP_EXCEPTION_EXIT
);
11107 dc
->is_jmp
= DISAS_UPDATE
;
11112 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
11113 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
11114 if (bp
->pc
== dc
->pc
) {
11115 gen_exception_internal_insn(dc
, 0, EXCP_DEBUG
);
11116 /* Advance PC so that clearing the breakpoint will
11117 invalidate this TB. */
11119 goto done_generating
;
11124 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
11128 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
11130 tcg_ctx
.gen_opc_pc
[lj
] = dc
->pc
;
11131 gen_opc_condexec_bits
[lj
] = (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1);
11132 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
11133 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
11136 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
11139 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
11140 tcg_gen_debug_insn_start(dc
->pc
);
11143 if (dc
->ss_active
&& !dc
->pstate_ss
) {
11144 /* Singlestep state is Active-pending.
11145 * If we're in this state at the start of a TB then either
11146 * a) we just took an exception to an EL which is being debugged
11147 * and this is the first insn in the exception handler
11148 * b) debug exceptions were masked and we just unmasked them
11149 * without changing EL (eg by clearing PSTATE.D)
11150 * In either case we're going to take a swstep exception in the
11151 * "did not step an insn" case, and so the syndrome ISV and EX
11152 * bits should be zero.
11154 assert(num_insns
== 0);
11155 gen_exception(EXCP_UDEF
, syn_swstep(dc
->ss_same_el
, 0, 0));
11156 goto done_generating
;
11160 disas_thumb_insn(env
, dc
);
11161 if (dc
->condexec_mask
) {
11162 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
11163 | ((dc
->condexec_mask
>> 4) & 1);
11164 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
11165 if (dc
->condexec_mask
== 0) {
11166 dc
->condexec_cond
= 0;
11170 disas_arm_insn(env
, dc
);
11173 if (dc
->condjmp
&& !dc
->is_jmp
) {
11174 gen_set_label(dc
->condlabel
);
11178 if (tcg_check_temp_count()) {
11179 fprintf(stderr
, "TCG temporary leak before "TARGET_FMT_lx
"\n",
11183 /* Translation stops when a conditional branch is encountered.
11184 * Otherwise the subsequent code could get translated several times.
11185 * Also stop translation when a page boundary is reached. This
11186 * ensures prefetch aborts occur at the right place. */
11188 } while (!dc
->is_jmp
&& tcg_ctx
.gen_opc_ptr
< gen_opc_end
&&
11189 !cs
->singlestep_enabled
&&
11192 dc
->pc
< next_page_start
&&
11193 num_insns
< max_insns
);
11195 if (tb
->cflags
& CF_LAST_IO
) {
11197 /* FIXME: This can theoretically happen with self-modifying
11199 cpu_abort(cs
, "IO on conditional branch instruction");
11204 /* At this stage dc->condjmp will only be set when the skipped
11205 instruction was a conditional branch or trap, and the PC has
11206 already been written. */
11207 if (unlikely(cs
->singlestep_enabled
|| dc
->ss_active
)) {
11208 /* Make sure the pc is updated, and raise a debug exception. */
11210 gen_set_condexec(dc
);
11211 if (dc
->is_jmp
== DISAS_SWI
) {
11212 gen_ss_advance(dc
);
11213 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
));
11214 } else if (dc
->is_jmp
== DISAS_HVC
) {
11215 gen_ss_advance(dc
);
11216 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
));
11217 } else if (dc
->is_jmp
== DISAS_SMC
) {
11218 gen_ss_advance(dc
);
11219 gen_exception(EXCP_SMC
, syn_aa32_smc());
11220 } else if (dc
->ss_active
) {
11221 gen_step_complete_exception(dc
);
11223 gen_exception_internal(EXCP_DEBUG
);
11225 gen_set_label(dc
->condlabel
);
11227 if (dc
->condjmp
|| !dc
->is_jmp
) {
11228 gen_set_pc_im(dc
, dc
->pc
);
11231 gen_set_condexec(dc
);
11232 if (dc
->is_jmp
== DISAS_SWI
&& !dc
->condjmp
) {
11233 gen_ss_advance(dc
);
11234 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
));
11235 } else if (dc
->is_jmp
== DISAS_HVC
&& !dc
->condjmp
) {
11236 gen_ss_advance(dc
);
11237 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
));
11238 } else if (dc
->is_jmp
== DISAS_SMC
&& !dc
->condjmp
) {
11239 gen_ss_advance(dc
);
11240 gen_exception(EXCP_SMC
, syn_aa32_smc());
11241 } else if (dc
->ss_active
) {
11242 gen_step_complete_exception(dc
);
11244 /* FIXME: Single stepping a WFI insn will not halt
11246 gen_exception_internal(EXCP_DEBUG
);
11249 /* While branches must always occur at the end of an IT block,
11250 there are a few other things that can cause us to terminate
11251 the TB in the middle of an IT block:
11252 - Exception generating instructions (bkpt, swi, undefined).
11254 - Hardware watchpoints.
11255 Hardware breakpoints have already been handled and skip this code.
11257 gen_set_condexec(dc
);
11258 switch(dc
->is_jmp
) {
11260 gen_goto_tb(dc
, 1, dc
->pc
);
11265 /* indicate that the hash table must be used to find the next TB */
11266 tcg_gen_exit_tb(0);
11268 case DISAS_TB_JUMP
:
11269 /* nothing more to generate */
11272 gen_helper_wfi(cpu_env
);
11275 gen_helper_wfe(cpu_env
);
11278 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
));
11281 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
));
11284 gen_exception(EXCP_SMC
, syn_aa32_smc());
11288 gen_set_label(dc
->condlabel
);
11289 gen_set_condexec(dc
);
11290 gen_goto_tb(dc
, 1, dc
->pc
);
11296 gen_tb_end(tb
, num_insns
);
11297 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
11300 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
11301 qemu_log("----------------\n");
11302 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
11303 log_target_disas(env
, pc_start
, dc
->pc
- pc_start
,
11304 dc
->thumb
| (dc
->bswap_code
<< 1));
11309 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
11312 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
11314 tb
->size
= dc
->pc
- pc_start
;
11315 tb
->icount
= num_insns
;
11319 void gen_intermediate_code(CPUARMState
*env
, TranslationBlock
*tb
)
11321 gen_intermediate_code_internal(arm_env_get_cpu(env
), tb
, false);
11324 void gen_intermediate_code_pc(CPUARMState
*env
, TranslationBlock
*tb
)
11326 gen_intermediate_code_internal(arm_env_get_cpu(env
), tb
, true);
11329 static const char *cpu_mode_names
[16] = {
11330 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
11331 "???", "???", "hyp", "und", "???", "???", "???", "sys"
11334 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
11337 ARMCPU
*cpu
= ARM_CPU(cs
);
11338 CPUARMState
*env
= &cpu
->env
;
11343 aarch64_cpu_dump_state(cs
, f
, cpu_fprintf
, flags
);
11347 for(i
=0;i
<16;i
++) {
11348 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
11350 cpu_fprintf(f
, "\n");
11352 cpu_fprintf(f
, " ");
11354 psr
= cpsr_read(env
);
11355 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%d\n",
11357 psr
& (1 << 31) ? 'N' : '-',
11358 psr
& (1 << 30) ? 'Z' : '-',
11359 psr
& (1 << 29) ? 'C' : '-',
11360 psr
& (1 << 28) ? 'V' : '-',
11361 psr
& CPSR_T
? 'T' : 'A',
11362 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
11364 if (flags
& CPU_DUMP_FPU
) {
11365 int numvfpregs
= 0;
11366 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
11369 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
11372 for (i
= 0; i
< numvfpregs
; i
++) {
11373 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
11374 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
11375 i
* 2, (uint32_t)v
,
11376 i
* 2 + 1, (uint32_t)(v
>> 32),
11379 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
11383 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
, int pc_pos
)
11386 env
->pc
= tcg_ctx
.gen_opc_pc
[pc_pos
];
11387 env
->condexec_bits
= 0;
11389 env
->regs
[15] = tcg_ctx
.gen_opc_pc
[pc_pos
];
11390 env
->condexec_bits
= gen_opc_condexec_bits
[pc_pos
];