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/>.
21 #include "qemu/osdep.h"
24 #include "internals.h"
25 #include "disas/disas.h"
26 #include "exec/exec-all.h"
27 #include "tcg/tcg-op.h"
28 #include "tcg/tcg-op-gvec.h"
30 #include "qemu/bitops.h"
32 #include "hw/semihosting/semihost.h"
34 #include "exec/helper-proto.h"
35 #include "exec/helper-gen.h"
37 #include "trace-tcg.h"
41 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
42 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
43 /* currently all emulated v5 cores are also v5TE, so don't bother */
44 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
45 #define ENABLE_ARCH_5J dc_isar_feature(aa32_jazelle, s)
46 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
47 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
48 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
49 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
50 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
52 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
54 #include "translate.h"
56 #if defined(CONFIG_USER_ONLY)
59 #define IS_USER(s) (s->user)
62 /* We reuse the same 64-bit temporaries for efficiency. */
63 static TCGv_i64 cpu_V0
, cpu_V1
, cpu_M0
;
64 static TCGv_i32 cpu_R
[16];
65 TCGv_i32 cpu_CF
, cpu_NF
, cpu_VF
, cpu_ZF
;
66 TCGv_i64 cpu_exclusive_addr
;
67 TCGv_i64 cpu_exclusive_val
;
69 #include "exec/gen-icount.h"
71 static const char * const regnames
[] =
72 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
73 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
75 /* Function prototypes for gen_ functions calling Neon helpers. */
76 typedef void NeonGenThreeOpEnvFn(TCGv_i32
, TCGv_env
, TCGv_i32
,
78 /* Function prototypes for gen_ functions for fix point conversions */
79 typedef void VFPGenFixPointFn(TCGv_i32
, TCGv_i32
, TCGv_i32
, TCGv_ptr
);
81 /* initialize TCG globals. */
82 void arm_translate_init(void)
86 for (i
= 0; i
< 16; i
++) {
87 cpu_R
[i
] = tcg_global_mem_new_i32(cpu_env
,
88 offsetof(CPUARMState
, regs
[i
]),
91 cpu_CF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, CF
), "CF");
92 cpu_NF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, NF
), "NF");
93 cpu_VF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, VF
), "VF");
94 cpu_ZF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, ZF
), "ZF");
96 cpu_exclusive_addr
= tcg_global_mem_new_i64(cpu_env
,
97 offsetof(CPUARMState
, exclusive_addr
), "exclusive_addr");
98 cpu_exclusive_val
= tcg_global_mem_new_i64(cpu_env
,
99 offsetof(CPUARMState
, exclusive_val
), "exclusive_val");
101 a64_translate_init();
104 /* Flags for the disas_set_da_iss info argument:
105 * lower bits hold the Rt register number, higher bits are flags.
107 typedef enum ISSInfo
{
110 ISSInvalid
= (1 << 5),
111 ISSIsAcqRel
= (1 << 6),
112 ISSIsWrite
= (1 << 7),
113 ISSIs16Bit
= (1 << 8),
116 /* Save the syndrome information for a Data Abort */
117 static void disas_set_da_iss(DisasContext
*s
, MemOp memop
, ISSInfo issinfo
)
120 int sas
= memop
& MO_SIZE
;
121 bool sse
= memop
& MO_SIGN
;
122 bool is_acqrel
= issinfo
& ISSIsAcqRel
;
123 bool is_write
= issinfo
& ISSIsWrite
;
124 bool is_16bit
= issinfo
& ISSIs16Bit
;
125 int srt
= issinfo
& ISSRegMask
;
127 if (issinfo
& ISSInvalid
) {
128 /* Some callsites want to conditionally provide ISS info,
129 * eg "only if this was not a writeback"
135 /* For AArch32, insns where the src/dest is R15 never generate
136 * ISS information. Catching that here saves checking at all
142 syn
= syn_data_abort_with_iss(0, sas
, sse
, srt
, 0, is_acqrel
,
143 0, 0, 0, is_write
, 0, is_16bit
);
144 disas_set_insn_syndrome(s
, syn
);
147 static inline int get_a32_user_mem_index(DisasContext
*s
)
149 /* Return the core mmu_idx to use for A32/T32 "unprivileged load/store"
151 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
152 * otherwise, access as if at PL0.
154 switch (s
->mmu_idx
) {
155 case ARMMMUIdx_E2
: /* this one is UNPREDICTABLE */
156 case ARMMMUIdx_E10_0
:
157 case ARMMMUIdx_E10_1
:
158 case ARMMMUIdx_E10_1_PAN
:
159 return arm_to_core_mmu_idx(ARMMMUIdx_E10_0
);
161 case ARMMMUIdx_SE10_0
:
162 case ARMMMUIdx_SE10_1
:
163 case ARMMMUIdx_SE10_1_PAN
:
164 return arm_to_core_mmu_idx(ARMMMUIdx_SE10_0
);
165 case ARMMMUIdx_MUser
:
166 case ARMMMUIdx_MPriv
:
167 return arm_to_core_mmu_idx(ARMMMUIdx_MUser
);
168 case ARMMMUIdx_MUserNegPri
:
169 case ARMMMUIdx_MPrivNegPri
:
170 return arm_to_core_mmu_idx(ARMMMUIdx_MUserNegPri
);
171 case ARMMMUIdx_MSUser
:
172 case ARMMMUIdx_MSPriv
:
173 return arm_to_core_mmu_idx(ARMMMUIdx_MSUser
);
174 case ARMMMUIdx_MSUserNegPri
:
175 case ARMMMUIdx_MSPrivNegPri
:
176 return arm_to_core_mmu_idx(ARMMMUIdx_MSUserNegPri
);
178 g_assert_not_reached();
182 static inline TCGv_i32
load_cpu_offset(int offset
)
184 TCGv_i32 tmp
= tcg_temp_new_i32();
185 tcg_gen_ld_i32(tmp
, cpu_env
, offset
);
189 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
191 static inline void store_cpu_offset(TCGv_i32 var
, int offset
)
193 tcg_gen_st_i32(var
, cpu_env
, offset
);
194 tcg_temp_free_i32(var
);
197 #define store_cpu_field(var, name) \
198 store_cpu_offset(var, offsetof(CPUARMState, name))
200 /* The architectural value of PC. */
201 static uint32_t read_pc(DisasContext
*s
)
203 return s
->pc_curr
+ (s
->thumb
? 4 : 8);
206 /* Set a variable to the value of a CPU register. */
207 static void load_reg_var(DisasContext
*s
, TCGv_i32 var
, int reg
)
210 tcg_gen_movi_i32(var
, read_pc(s
));
212 tcg_gen_mov_i32(var
, cpu_R
[reg
]);
216 /* Create a new temporary and set it to the value of a CPU register. */
217 static inline TCGv_i32
load_reg(DisasContext
*s
, int reg
)
219 TCGv_i32 tmp
= tcg_temp_new_i32();
220 load_reg_var(s
, tmp
, reg
);
225 * Create a new temp, REG + OFS, except PC is ALIGN(PC, 4).
226 * This is used for load/store for which use of PC implies (literal),
227 * or ADD that implies ADR.
229 static TCGv_i32
add_reg_for_lit(DisasContext
*s
, int reg
, int ofs
)
231 TCGv_i32 tmp
= tcg_temp_new_i32();
234 tcg_gen_movi_i32(tmp
, (read_pc(s
) & ~3) + ofs
);
236 tcg_gen_addi_i32(tmp
, cpu_R
[reg
], ofs
);
241 /* Set a CPU register. The source must be a temporary and will be
243 static void store_reg(DisasContext
*s
, int reg
, TCGv_i32 var
)
246 /* In Thumb mode, we must ignore bit 0.
247 * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0]
248 * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0].
249 * We choose to ignore [1:0] in ARM mode for all architecture versions.
251 tcg_gen_andi_i32(var
, var
, s
->thumb
? ~1 : ~3);
252 s
->base
.is_jmp
= DISAS_JUMP
;
254 tcg_gen_mov_i32(cpu_R
[reg
], var
);
255 tcg_temp_free_i32(var
);
259 * Variant of store_reg which applies v8M stack-limit checks before updating
260 * SP. If the check fails this will result in an exception being taken.
261 * We disable the stack checks for CONFIG_USER_ONLY because we have
262 * no idea what the stack limits should be in that case.
263 * If stack checking is not being done this just acts like store_reg().
265 static void store_sp_checked(DisasContext
*s
, TCGv_i32 var
)
267 #ifndef CONFIG_USER_ONLY
268 if (s
->v8m_stackcheck
) {
269 gen_helper_v8m_stackcheck(cpu_env
, var
);
272 store_reg(s
, 13, var
);
275 /* Value extensions. */
276 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
277 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
278 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
279 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
281 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
282 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
285 static inline void gen_set_cpsr(TCGv_i32 var
, uint32_t mask
)
287 TCGv_i32 tmp_mask
= tcg_const_i32(mask
);
288 gen_helper_cpsr_write(cpu_env
, var
, tmp_mask
);
289 tcg_temp_free_i32(tmp_mask
);
291 /* Set NZCV flags from the high 4 bits of var. */
292 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
294 static void gen_exception_internal(int excp
)
296 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
298 assert(excp_is_internal(excp
));
299 gen_helper_exception_internal(cpu_env
, tcg_excp
);
300 tcg_temp_free_i32(tcg_excp
);
303 static void gen_step_complete_exception(DisasContext
*s
)
305 /* We just completed step of an insn. Move from Active-not-pending
306 * to Active-pending, and then also take the swstep exception.
307 * This corresponds to making the (IMPDEF) choice to prioritize
308 * swstep exceptions over asynchronous exceptions taken to an exception
309 * level where debug is disabled. This choice has the advantage that
310 * we do not need to maintain internal state corresponding to the
311 * ISV/EX syndrome bits between completion of the step and generation
312 * of the exception, and our syndrome information is always correct.
315 gen_swstep_exception(s
, 1, s
->is_ldex
);
316 s
->base
.is_jmp
= DISAS_NORETURN
;
319 static void gen_singlestep_exception(DisasContext
*s
)
321 /* Generate the right kind of exception for singlestep, which is
322 * either the architectural singlestep or EXCP_DEBUG for QEMU's
323 * gdb singlestepping.
326 gen_step_complete_exception(s
);
328 gen_exception_internal(EXCP_DEBUG
);
332 static inline bool is_singlestepping(DisasContext
*s
)
334 /* Return true if we are singlestepping either because of
335 * architectural singlestep or QEMU gdbstub singlestep. This does
336 * not include the command line '-singlestep' mode which is rather
337 * misnamed as it only means "one instruction per TB" and doesn't
338 * affect the code we generate.
340 return s
->base
.singlestep_enabled
|| s
->ss_active
;
343 static void gen_smul_dual(TCGv_i32 a
, TCGv_i32 b
)
345 TCGv_i32 tmp1
= tcg_temp_new_i32();
346 TCGv_i32 tmp2
= tcg_temp_new_i32();
347 tcg_gen_ext16s_i32(tmp1
, a
);
348 tcg_gen_ext16s_i32(tmp2
, b
);
349 tcg_gen_mul_i32(tmp1
, tmp1
, tmp2
);
350 tcg_temp_free_i32(tmp2
);
351 tcg_gen_sari_i32(a
, a
, 16);
352 tcg_gen_sari_i32(b
, b
, 16);
353 tcg_gen_mul_i32(b
, b
, a
);
354 tcg_gen_mov_i32(a
, tmp1
);
355 tcg_temp_free_i32(tmp1
);
358 /* Byteswap each halfword. */
359 static void gen_rev16(TCGv_i32 dest
, TCGv_i32 var
)
361 TCGv_i32 tmp
= tcg_temp_new_i32();
362 TCGv_i32 mask
= tcg_const_i32(0x00ff00ff);
363 tcg_gen_shri_i32(tmp
, var
, 8);
364 tcg_gen_and_i32(tmp
, tmp
, mask
);
365 tcg_gen_and_i32(var
, var
, mask
);
366 tcg_gen_shli_i32(var
, var
, 8);
367 tcg_gen_or_i32(dest
, var
, tmp
);
368 tcg_temp_free_i32(mask
);
369 tcg_temp_free_i32(tmp
);
372 /* Byteswap low halfword and sign extend. */
373 static void gen_revsh(TCGv_i32 dest
, TCGv_i32 var
)
375 tcg_gen_ext16u_i32(var
, var
);
376 tcg_gen_bswap16_i32(var
, var
);
377 tcg_gen_ext16s_i32(dest
, var
);
380 /* Swap low and high halfwords. */
381 static void gen_swap_half(TCGv_i32 var
)
383 tcg_gen_rotri_i32(var
, var
, 16);
386 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
387 tmp = (t0 ^ t1) & 0x8000;
390 t0 = (t0 + t1) ^ tmp;
393 static void gen_add16(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
395 TCGv_i32 tmp
= tcg_temp_new_i32();
396 tcg_gen_xor_i32(tmp
, t0
, t1
);
397 tcg_gen_andi_i32(tmp
, tmp
, 0x8000);
398 tcg_gen_andi_i32(t0
, t0
, ~0x8000);
399 tcg_gen_andi_i32(t1
, t1
, ~0x8000);
400 tcg_gen_add_i32(t0
, t0
, t1
);
401 tcg_gen_xor_i32(dest
, t0
, tmp
);
402 tcg_temp_free_i32(tmp
);
405 /* Set N and Z flags from var. */
406 static inline void gen_logic_CC(TCGv_i32 var
)
408 tcg_gen_mov_i32(cpu_NF
, var
);
409 tcg_gen_mov_i32(cpu_ZF
, var
);
412 /* dest = T0 + T1 + CF. */
413 static void gen_add_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
415 tcg_gen_add_i32(dest
, t0
, t1
);
416 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
419 /* dest = T0 - T1 + CF - 1. */
420 static void gen_sub_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
422 tcg_gen_sub_i32(dest
, t0
, t1
);
423 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
424 tcg_gen_subi_i32(dest
, dest
, 1);
427 /* dest = T0 + T1. Compute C, N, V and Z flags */
428 static void gen_add_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
430 TCGv_i32 tmp
= tcg_temp_new_i32();
431 tcg_gen_movi_i32(tmp
, 0);
432 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, t1
, tmp
);
433 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
434 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
435 tcg_gen_xor_i32(tmp
, t0
, t1
);
436 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
437 tcg_temp_free_i32(tmp
);
438 tcg_gen_mov_i32(dest
, cpu_NF
);
441 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
442 static void gen_adc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
444 TCGv_i32 tmp
= tcg_temp_new_i32();
445 if (TCG_TARGET_HAS_add2_i32
) {
446 tcg_gen_movi_i32(tmp
, 0);
447 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, cpu_CF
, tmp
);
448 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, cpu_NF
, cpu_CF
, t1
, tmp
);
450 TCGv_i64 q0
= tcg_temp_new_i64();
451 TCGv_i64 q1
= tcg_temp_new_i64();
452 tcg_gen_extu_i32_i64(q0
, t0
);
453 tcg_gen_extu_i32_i64(q1
, t1
);
454 tcg_gen_add_i64(q0
, q0
, q1
);
455 tcg_gen_extu_i32_i64(q1
, cpu_CF
);
456 tcg_gen_add_i64(q0
, q0
, q1
);
457 tcg_gen_extr_i64_i32(cpu_NF
, cpu_CF
, q0
);
458 tcg_temp_free_i64(q0
);
459 tcg_temp_free_i64(q1
);
461 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
462 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
463 tcg_gen_xor_i32(tmp
, t0
, t1
);
464 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
465 tcg_temp_free_i32(tmp
);
466 tcg_gen_mov_i32(dest
, cpu_NF
);
469 /* dest = T0 - T1. Compute C, N, V and Z flags */
470 static void gen_sub_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
473 tcg_gen_sub_i32(cpu_NF
, t0
, t1
);
474 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
475 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_CF
, t0
, t1
);
476 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
477 tmp
= tcg_temp_new_i32();
478 tcg_gen_xor_i32(tmp
, t0
, t1
);
479 tcg_gen_and_i32(cpu_VF
, cpu_VF
, tmp
);
480 tcg_temp_free_i32(tmp
);
481 tcg_gen_mov_i32(dest
, cpu_NF
);
484 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
485 static void gen_sbc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
487 TCGv_i32 tmp
= tcg_temp_new_i32();
488 tcg_gen_not_i32(tmp
, t1
);
489 gen_adc_CC(dest
, t0
, tmp
);
490 tcg_temp_free_i32(tmp
);
493 #define GEN_SHIFT(name) \
494 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
496 TCGv_i32 tmp1, tmp2, tmp3; \
497 tmp1 = tcg_temp_new_i32(); \
498 tcg_gen_andi_i32(tmp1, t1, 0xff); \
499 tmp2 = tcg_const_i32(0); \
500 tmp3 = tcg_const_i32(0x1f); \
501 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
502 tcg_temp_free_i32(tmp3); \
503 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
504 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
505 tcg_temp_free_i32(tmp2); \
506 tcg_temp_free_i32(tmp1); \
512 static void gen_sar(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
515 tmp1
= tcg_temp_new_i32();
516 tcg_gen_andi_i32(tmp1
, t1
, 0xff);
517 tmp2
= tcg_const_i32(0x1f);
518 tcg_gen_movcond_i32(TCG_COND_GTU
, tmp1
, tmp1
, tmp2
, tmp2
, tmp1
);
519 tcg_temp_free_i32(tmp2
);
520 tcg_gen_sar_i32(dest
, t0
, tmp1
);
521 tcg_temp_free_i32(tmp1
);
524 static void shifter_out_im(TCGv_i32 var
, int shift
)
526 tcg_gen_extract_i32(cpu_CF
, var
, shift
, 1);
529 /* Shift by immediate. Includes special handling for shift == 0. */
530 static inline void gen_arm_shift_im(TCGv_i32 var
, int shiftop
,
531 int shift
, int flags
)
537 shifter_out_im(var
, 32 - shift
);
538 tcg_gen_shli_i32(var
, var
, shift
);
544 tcg_gen_shri_i32(cpu_CF
, var
, 31);
546 tcg_gen_movi_i32(var
, 0);
549 shifter_out_im(var
, shift
- 1);
550 tcg_gen_shri_i32(var
, var
, shift
);
557 shifter_out_im(var
, shift
- 1);
560 tcg_gen_sari_i32(var
, var
, shift
);
562 case 3: /* ROR/RRX */
565 shifter_out_im(var
, shift
- 1);
566 tcg_gen_rotri_i32(var
, var
, shift
); break;
568 TCGv_i32 tmp
= tcg_temp_new_i32();
569 tcg_gen_shli_i32(tmp
, cpu_CF
, 31);
571 shifter_out_im(var
, 0);
572 tcg_gen_shri_i32(var
, var
, 1);
573 tcg_gen_or_i32(var
, var
, tmp
);
574 tcg_temp_free_i32(tmp
);
579 static inline void gen_arm_shift_reg(TCGv_i32 var
, int shiftop
,
580 TCGv_i32 shift
, int flags
)
584 case 0: gen_helper_shl_cc(var
, cpu_env
, var
, shift
); break;
585 case 1: gen_helper_shr_cc(var
, cpu_env
, var
, shift
); break;
586 case 2: gen_helper_sar_cc(var
, cpu_env
, var
, shift
); break;
587 case 3: gen_helper_ror_cc(var
, cpu_env
, var
, shift
); break;
592 gen_shl(var
, var
, shift
);
595 gen_shr(var
, var
, shift
);
598 gen_sar(var
, var
, shift
);
600 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
601 tcg_gen_rotr_i32(var
, var
, shift
); break;
604 tcg_temp_free_i32(shift
);
608 * Generate a conditional based on ARM condition code cc.
609 * This is common between ARM and Aarch64 targets.
611 void arm_test_cc(DisasCompare
*cmp
, int cc
)
642 case 8: /* hi: C && !Z */
643 case 9: /* ls: !C || Z -> !(C && !Z) */
645 value
= tcg_temp_new_i32();
647 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
648 ZF is non-zero for !Z; so AND the two subexpressions. */
649 tcg_gen_neg_i32(value
, cpu_CF
);
650 tcg_gen_and_i32(value
, value
, cpu_ZF
);
653 case 10: /* ge: N == V -> N ^ V == 0 */
654 case 11: /* lt: N != V -> N ^ V != 0 */
655 /* Since we're only interested in the sign bit, == 0 is >= 0. */
657 value
= tcg_temp_new_i32();
659 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
662 case 12: /* gt: !Z && N == V */
663 case 13: /* le: Z || N != V */
665 value
= tcg_temp_new_i32();
667 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
668 * the sign bit then AND with ZF to yield the result. */
669 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
670 tcg_gen_sari_i32(value
, value
, 31);
671 tcg_gen_andc_i32(value
, cpu_ZF
, value
);
674 case 14: /* always */
675 case 15: /* always */
676 /* Use the ALWAYS condition, which will fold early.
677 * It doesn't matter what we use for the value. */
678 cond
= TCG_COND_ALWAYS
;
683 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
688 cond
= tcg_invert_cond(cond
);
694 cmp
->value_global
= global
;
697 void arm_free_cc(DisasCompare
*cmp
)
699 if (!cmp
->value_global
) {
700 tcg_temp_free_i32(cmp
->value
);
704 void arm_jump_cc(DisasCompare
*cmp
, TCGLabel
*label
)
706 tcg_gen_brcondi_i32(cmp
->cond
, cmp
->value
, 0, label
);
709 void arm_gen_test_cc(int cc
, TCGLabel
*label
)
712 arm_test_cc(&cmp
, cc
);
713 arm_jump_cc(&cmp
, label
);
717 static inline void gen_set_condexec(DisasContext
*s
)
719 if (s
->condexec_mask
) {
720 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
721 TCGv_i32 tmp
= tcg_temp_new_i32();
722 tcg_gen_movi_i32(tmp
, val
);
723 store_cpu_field(tmp
, condexec_bits
);
727 static inline void gen_set_pc_im(DisasContext
*s
, target_ulong val
)
729 tcg_gen_movi_i32(cpu_R
[15], val
);
732 /* Set PC and Thumb state from var. var is marked as dead. */
733 static inline void gen_bx(DisasContext
*s
, TCGv_i32 var
)
735 s
->base
.is_jmp
= DISAS_JUMP
;
736 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
737 tcg_gen_andi_i32(var
, var
, 1);
738 store_cpu_field(var
, thumb
);
742 * Set PC and Thumb state from var. var is marked as dead.
743 * For M-profile CPUs, include logic to detect exception-return
744 * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
745 * and BX reg, and no others, and happens only for code in Handler mode.
746 * The Security Extension also requires us to check for the FNC_RETURN
747 * which signals a function return from non-secure state; this can happen
748 * in both Handler and Thread mode.
749 * To avoid having to do multiple comparisons in inline generated code,
750 * we make the check we do here loose, so it will match for EXC_RETURN
751 * in Thread mode. For system emulation do_v7m_exception_exit() checks
752 * for these spurious cases and returns without doing anything (giving
753 * the same behaviour as for a branch to a non-magic address).
755 * In linux-user mode it is unclear what the right behaviour for an
756 * attempted FNC_RETURN should be, because in real hardware this will go
757 * directly to Secure code (ie not the Linux kernel) which will then treat
758 * the error in any way it chooses. For QEMU we opt to make the FNC_RETURN
759 * attempt behave the way it would on a CPU without the security extension,
760 * which is to say "like a normal branch". That means we can simply treat
761 * all branches as normal with no magic address behaviour.
763 static inline void gen_bx_excret(DisasContext
*s
, TCGv_i32 var
)
765 /* Generate the same code here as for a simple bx, but flag via
766 * s->base.is_jmp that we need to do the rest of the work later.
769 #ifndef CONFIG_USER_ONLY
770 if (arm_dc_feature(s
, ARM_FEATURE_M_SECURITY
) ||
771 (s
->v7m_handler_mode
&& arm_dc_feature(s
, ARM_FEATURE_M
))) {
772 s
->base
.is_jmp
= DISAS_BX_EXCRET
;
777 static inline void gen_bx_excret_final_code(DisasContext
*s
)
779 /* Generate the code to finish possible exception return and end the TB */
780 TCGLabel
*excret_label
= gen_new_label();
783 if (arm_dc_feature(s
, ARM_FEATURE_M_SECURITY
)) {
784 /* Covers FNC_RETURN and EXC_RETURN magic */
785 min_magic
= FNC_RETURN_MIN_MAGIC
;
787 /* EXC_RETURN magic only */
788 min_magic
= EXC_RETURN_MIN_MAGIC
;
791 /* Is the new PC value in the magic range indicating exception return? */
792 tcg_gen_brcondi_i32(TCG_COND_GEU
, cpu_R
[15], min_magic
, excret_label
);
793 /* No: end the TB as we would for a DISAS_JMP */
794 if (is_singlestepping(s
)) {
795 gen_singlestep_exception(s
);
797 tcg_gen_exit_tb(NULL
, 0);
799 gen_set_label(excret_label
);
800 /* Yes: this is an exception return.
801 * At this point in runtime env->regs[15] and env->thumb will hold
802 * the exception-return magic number, which do_v7m_exception_exit()
803 * will read. Nothing else will be able to see those values because
804 * the cpu-exec main loop guarantees that we will always go straight
805 * from raising the exception to the exception-handling code.
807 * gen_ss_advance(s) does nothing on M profile currently but
808 * calling it is conceptually the right thing as we have executed
809 * this instruction (compare SWI, HVC, SMC handling).
812 gen_exception_internal(EXCP_EXCEPTION_EXIT
);
815 static inline void gen_bxns(DisasContext
*s
, int rm
)
817 TCGv_i32 var
= load_reg(s
, rm
);
819 /* The bxns helper may raise an EXCEPTION_EXIT exception, so in theory
820 * we need to sync state before calling it, but:
821 * - we don't need to do gen_set_pc_im() because the bxns helper will
822 * always set the PC itself
823 * - we don't need to do gen_set_condexec() because BXNS is UNPREDICTABLE
824 * unless it's outside an IT block or the last insn in an IT block,
825 * so we know that condexec == 0 (already set at the top of the TB)
826 * is correct in the non-UNPREDICTABLE cases, and we can choose
827 * "zeroes the IT bits" as our UNPREDICTABLE behaviour otherwise.
829 gen_helper_v7m_bxns(cpu_env
, var
);
830 tcg_temp_free_i32(var
);
831 s
->base
.is_jmp
= DISAS_EXIT
;
834 static inline void gen_blxns(DisasContext
*s
, int rm
)
836 TCGv_i32 var
= load_reg(s
, rm
);
838 /* We don't need to sync condexec state, for the same reason as bxns.
839 * We do however need to set the PC, because the blxns helper reads it.
840 * The blxns helper may throw an exception.
842 gen_set_pc_im(s
, s
->base
.pc_next
);
843 gen_helper_v7m_blxns(cpu_env
, var
);
844 tcg_temp_free_i32(var
);
845 s
->base
.is_jmp
= DISAS_EXIT
;
848 /* Variant of store_reg which uses branch&exchange logic when storing
849 to r15 in ARM architecture v7 and above. The source must be a temporary
850 and will be marked as dead. */
851 static inline void store_reg_bx(DisasContext
*s
, int reg
, TCGv_i32 var
)
853 if (reg
== 15 && ENABLE_ARCH_7
) {
856 store_reg(s
, reg
, var
);
860 /* Variant of store_reg which uses branch&exchange logic when storing
861 * to r15 in ARM architecture v5T and above. This is used for storing
862 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
863 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
864 static inline void store_reg_from_load(DisasContext
*s
, int reg
, TCGv_i32 var
)
866 if (reg
== 15 && ENABLE_ARCH_5
) {
867 gen_bx_excret(s
, var
);
869 store_reg(s
, reg
, var
);
873 #ifdef CONFIG_USER_ONLY
874 #define IS_USER_ONLY 1
876 #define IS_USER_ONLY 0
879 /* Abstractions of "generate code to do a guest load/store for
880 * AArch32", where a vaddr is always 32 bits (and is zero
881 * extended if we're a 64 bit core) and data is also
882 * 32 bits unless specifically doing a 64 bit access.
883 * These functions work like tcg_gen_qemu_{ld,st}* except
884 * that the address argument is TCGv_i32 rather than TCGv.
887 static inline TCGv
gen_aa32_addr(DisasContext
*s
, TCGv_i32 a32
, MemOp op
)
889 TCGv addr
= tcg_temp_new();
890 tcg_gen_extu_i32_tl(addr
, a32
);
892 /* Not needed for user-mode BE32, where we use MO_BE instead. */
893 if (!IS_USER_ONLY
&& s
->sctlr_b
&& (op
& MO_SIZE
) < MO_32
) {
894 tcg_gen_xori_tl(addr
, addr
, 4 - (1 << (op
& MO_SIZE
)));
899 static void gen_aa32_ld_i32(DisasContext
*s
, TCGv_i32 val
, TCGv_i32 a32
,
900 int index
, MemOp opc
)
904 if (arm_dc_feature(s
, ARM_FEATURE_M
) &&
905 !arm_dc_feature(s
, ARM_FEATURE_M_MAIN
)) {
909 addr
= gen_aa32_addr(s
, a32
, opc
);
910 tcg_gen_qemu_ld_i32(val
, addr
, index
, opc
);
914 static void gen_aa32_st_i32(DisasContext
*s
, TCGv_i32 val
, TCGv_i32 a32
,
915 int index
, MemOp opc
)
919 if (arm_dc_feature(s
, ARM_FEATURE_M
) &&
920 !arm_dc_feature(s
, ARM_FEATURE_M_MAIN
)) {
924 addr
= gen_aa32_addr(s
, a32
, opc
);
925 tcg_gen_qemu_st_i32(val
, addr
, index
, opc
);
929 #define DO_GEN_LD(SUFF, OPC) \
930 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
931 TCGv_i32 a32, int index) \
933 gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
936 #define DO_GEN_ST(SUFF, OPC) \
937 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
938 TCGv_i32 a32, int index) \
940 gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
943 static inline void gen_aa32_frob64(DisasContext
*s
, TCGv_i64 val
)
945 /* Not needed for user-mode BE32, where we use MO_BE instead. */
946 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
947 tcg_gen_rotri_i64(val
, val
, 32);
951 static void gen_aa32_ld_i64(DisasContext
*s
, TCGv_i64 val
, TCGv_i32 a32
,
952 int index
, MemOp opc
)
954 TCGv addr
= gen_aa32_addr(s
, a32
, opc
);
955 tcg_gen_qemu_ld_i64(val
, addr
, index
, opc
);
956 gen_aa32_frob64(s
, val
);
960 static inline void gen_aa32_ld64(DisasContext
*s
, TCGv_i64 val
,
961 TCGv_i32 a32
, int index
)
963 gen_aa32_ld_i64(s
, val
, a32
, index
, MO_Q
| s
->be_data
);
966 static void gen_aa32_st_i64(DisasContext
*s
, TCGv_i64 val
, TCGv_i32 a32
,
967 int index
, MemOp opc
)
969 TCGv addr
= gen_aa32_addr(s
, a32
, opc
);
971 /* Not needed for user-mode BE32, where we use MO_BE instead. */
972 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
973 TCGv_i64 tmp
= tcg_temp_new_i64();
974 tcg_gen_rotri_i64(tmp
, val
, 32);
975 tcg_gen_qemu_st_i64(tmp
, addr
, index
, opc
);
976 tcg_temp_free_i64(tmp
);
978 tcg_gen_qemu_st_i64(val
, addr
, index
, opc
);
983 static inline void gen_aa32_st64(DisasContext
*s
, TCGv_i64 val
,
984 TCGv_i32 a32
, int index
)
986 gen_aa32_st_i64(s
, val
, a32
, index
, MO_Q
| s
->be_data
);
990 DO_GEN_LD(16u, MO_UW
)
991 DO_GEN_LD(32u, MO_UL
)
996 static inline void gen_hvc(DisasContext
*s
, int imm16
)
998 /* The pre HVC helper handles cases when HVC gets trapped
999 * as an undefined insn by runtime configuration (ie before
1000 * the insn really executes).
1002 gen_set_pc_im(s
, s
->pc_curr
);
1003 gen_helper_pre_hvc(cpu_env
);
1004 /* Otherwise we will treat this as a real exception which
1005 * happens after execution of the insn. (The distinction matters
1006 * for the PC value reported to the exception handler and also
1007 * for single stepping.)
1010 gen_set_pc_im(s
, s
->base
.pc_next
);
1011 s
->base
.is_jmp
= DISAS_HVC
;
1014 static inline void gen_smc(DisasContext
*s
)
1016 /* As with HVC, we may take an exception either before or after
1017 * the insn executes.
1021 gen_set_pc_im(s
, s
->pc_curr
);
1022 tmp
= tcg_const_i32(syn_aa32_smc());
1023 gen_helper_pre_smc(cpu_env
, tmp
);
1024 tcg_temp_free_i32(tmp
);
1025 gen_set_pc_im(s
, s
->base
.pc_next
);
1026 s
->base
.is_jmp
= DISAS_SMC
;
1029 static void gen_exception_internal_insn(DisasContext
*s
, uint32_t pc
, int excp
)
1031 gen_set_condexec(s
);
1032 gen_set_pc_im(s
, pc
);
1033 gen_exception_internal(excp
);
1034 s
->base
.is_jmp
= DISAS_NORETURN
;
1037 static void gen_exception_insn(DisasContext
*s
, uint32_t pc
, int excp
,
1038 int syn
, uint32_t target_el
)
1040 gen_set_condexec(s
);
1041 gen_set_pc_im(s
, pc
);
1042 gen_exception(excp
, syn
, target_el
);
1043 s
->base
.is_jmp
= DISAS_NORETURN
;
1046 static void gen_exception_bkpt_insn(DisasContext
*s
, uint32_t syn
)
1050 gen_set_condexec(s
);
1051 gen_set_pc_im(s
, s
->pc_curr
);
1052 tcg_syn
= tcg_const_i32(syn
);
1053 gen_helper_exception_bkpt_insn(cpu_env
, tcg_syn
);
1054 tcg_temp_free_i32(tcg_syn
);
1055 s
->base
.is_jmp
= DISAS_NORETURN
;
1058 static void unallocated_encoding(DisasContext
*s
)
1060 /* Unallocated and reserved encodings are uncategorized */
1061 gen_exception_insn(s
, s
->pc_curr
, EXCP_UDEF
, syn_uncategorized(),
1062 default_exception_el(s
));
1065 /* Force a TB lookup after an instruction that changes the CPU state. */
1066 static inline void gen_lookup_tb(DisasContext
*s
)
1068 tcg_gen_movi_i32(cpu_R
[15], s
->base
.pc_next
);
1069 s
->base
.is_jmp
= DISAS_EXIT
;
1072 static inline void gen_hlt(DisasContext
*s
, int imm
)
1074 /* HLT. This has two purposes.
1075 * Architecturally, it is an external halting debug instruction.
1076 * Since QEMU doesn't implement external debug, we treat this as
1077 * it is required for halting debug disabled: it will UNDEF.
1078 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1079 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1080 * must trigger semihosting even for ARMv7 and earlier, where
1081 * HLT was an undefined encoding.
1082 * In system mode, we don't allow userspace access to
1083 * semihosting, to provide some semblance of security
1084 * (and for consistency with our 32-bit semihosting).
1086 if (semihosting_enabled() &&
1087 #ifndef CONFIG_USER_ONLY
1088 s
->current_el
!= 0 &&
1090 (imm
== (s
->thumb
? 0x3c : 0xf000))) {
1091 gen_exception_internal_insn(s
, s
->pc_curr
, EXCP_SEMIHOST
);
1095 unallocated_encoding(s
);
1098 static TCGv_ptr
get_fpstatus_ptr(int neon
)
1100 TCGv_ptr statusptr
= tcg_temp_new_ptr();
1103 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
1105 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
1107 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
1111 static inline long vfp_reg_offset(bool dp
, unsigned reg
)
1114 return offsetof(CPUARMState
, vfp
.zregs
[reg
>> 1].d
[reg
& 1]);
1116 long ofs
= offsetof(CPUARMState
, vfp
.zregs
[reg
>> 2].d
[(reg
>> 1) & 1]);
1118 ofs
+= offsetof(CPU_DoubleU
, l
.upper
);
1120 ofs
+= offsetof(CPU_DoubleU
, l
.lower
);
1126 /* Return the offset of a 32-bit piece of a NEON register.
1127 zero is the least significant end of the register. */
1129 neon_reg_offset (int reg
, int n
)
1133 return vfp_reg_offset(0, sreg
);
1136 /* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
1137 * where 0 is the least significant end of the register.
1140 neon_element_offset(int reg
, int element
, MemOp size
)
1142 int element_size
= 1 << size
;
1143 int ofs
= element
* element_size
;
1144 #ifdef HOST_WORDS_BIGENDIAN
1145 /* Calculate the offset assuming fully little-endian,
1146 * then XOR to account for the order of the 8-byte units.
1148 if (element_size
< 8) {
1149 ofs
^= 8 - element_size
;
1152 return neon_reg_offset(reg
, 0) + ofs
;
1155 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1157 TCGv_i32 tmp
= tcg_temp_new_i32();
1158 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1162 static void neon_load_element(TCGv_i32 var
, int reg
, int ele
, MemOp mop
)
1164 long offset
= neon_element_offset(reg
, ele
, mop
& MO_SIZE
);
1168 tcg_gen_ld8u_i32(var
, cpu_env
, offset
);
1171 tcg_gen_ld16u_i32(var
, cpu_env
, offset
);
1174 tcg_gen_ld_i32(var
, cpu_env
, offset
);
1177 g_assert_not_reached();
1181 static void neon_load_element64(TCGv_i64 var
, int reg
, int ele
, MemOp mop
)
1183 long offset
= neon_element_offset(reg
, ele
, mop
& MO_SIZE
);
1187 tcg_gen_ld8u_i64(var
, cpu_env
, offset
);
1190 tcg_gen_ld16u_i64(var
, cpu_env
, offset
);
1193 tcg_gen_ld32u_i64(var
, cpu_env
, offset
);
1196 tcg_gen_ld_i64(var
, cpu_env
, offset
);
1199 g_assert_not_reached();
1203 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1205 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1206 tcg_temp_free_i32(var
);
1209 static void neon_store_element(int reg
, int ele
, MemOp size
, TCGv_i32 var
)
1211 long offset
= neon_element_offset(reg
, ele
, size
);
1215 tcg_gen_st8_i32(var
, cpu_env
, offset
);
1218 tcg_gen_st16_i32(var
, cpu_env
, offset
);
1221 tcg_gen_st_i32(var
, cpu_env
, offset
);
1224 g_assert_not_reached();
1228 static void neon_store_element64(int reg
, int ele
, MemOp size
, TCGv_i64 var
)
1230 long offset
= neon_element_offset(reg
, ele
, size
);
1234 tcg_gen_st8_i64(var
, cpu_env
, offset
);
1237 tcg_gen_st16_i64(var
, cpu_env
, offset
);
1240 tcg_gen_st32_i64(var
, cpu_env
, offset
);
1243 tcg_gen_st_i64(var
, cpu_env
, offset
);
1246 g_assert_not_reached();
1250 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1252 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1255 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1257 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1260 static inline void neon_load_reg32(TCGv_i32 var
, int reg
)
1262 tcg_gen_ld_i32(var
, cpu_env
, vfp_reg_offset(false, reg
));
1265 static inline void neon_store_reg32(TCGv_i32 var
, int reg
)
1267 tcg_gen_st_i32(var
, cpu_env
, vfp_reg_offset(false, reg
));
1270 static TCGv_ptr
vfp_reg_ptr(bool dp
, int reg
)
1272 TCGv_ptr ret
= tcg_temp_new_ptr();
1273 tcg_gen_addi_ptr(ret
, cpu_env
, vfp_reg_offset(dp
, reg
));
1277 #define ARM_CP_RW_BIT (1 << 20)
1279 /* Include the VFP and Neon decoders */
1280 #include "translate-vfp.inc.c"
1281 #include "translate-neon.inc.c"
1283 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1285 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1288 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1290 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1293 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1295 TCGv_i32 var
= tcg_temp_new_i32();
1296 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1300 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1302 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1303 tcg_temp_free_i32(var
);
1306 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1308 iwmmxt_store_reg(cpu_M0
, rn
);
1311 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1313 iwmmxt_load_reg(cpu_M0
, rn
);
1316 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1318 iwmmxt_load_reg(cpu_V1
, rn
);
1319 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1322 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1324 iwmmxt_load_reg(cpu_V1
, rn
);
1325 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1328 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1330 iwmmxt_load_reg(cpu_V1
, rn
);
1331 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1334 #define IWMMXT_OP(name) \
1335 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1337 iwmmxt_load_reg(cpu_V1, rn); \
1338 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1341 #define IWMMXT_OP_ENV(name) \
1342 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1344 iwmmxt_load_reg(cpu_V1, rn); \
1345 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1348 #define IWMMXT_OP_ENV_SIZE(name) \
1349 IWMMXT_OP_ENV(name##b) \
1350 IWMMXT_OP_ENV(name##w) \
1351 IWMMXT_OP_ENV(name##l)
1353 #define IWMMXT_OP_ENV1(name) \
1354 static inline void gen_op_iwmmxt_##name##_M0(void) \
1356 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1370 IWMMXT_OP_ENV_SIZE(unpackl
)
1371 IWMMXT_OP_ENV_SIZE(unpackh
)
1373 IWMMXT_OP_ENV1(unpacklub
)
1374 IWMMXT_OP_ENV1(unpackluw
)
1375 IWMMXT_OP_ENV1(unpacklul
)
1376 IWMMXT_OP_ENV1(unpackhub
)
1377 IWMMXT_OP_ENV1(unpackhuw
)
1378 IWMMXT_OP_ENV1(unpackhul
)
1379 IWMMXT_OP_ENV1(unpacklsb
)
1380 IWMMXT_OP_ENV1(unpacklsw
)
1381 IWMMXT_OP_ENV1(unpacklsl
)
1382 IWMMXT_OP_ENV1(unpackhsb
)
1383 IWMMXT_OP_ENV1(unpackhsw
)
1384 IWMMXT_OP_ENV1(unpackhsl
)
1386 IWMMXT_OP_ENV_SIZE(cmpeq
)
1387 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1388 IWMMXT_OP_ENV_SIZE(cmpgts
)
1390 IWMMXT_OP_ENV_SIZE(mins
)
1391 IWMMXT_OP_ENV_SIZE(minu
)
1392 IWMMXT_OP_ENV_SIZE(maxs
)
1393 IWMMXT_OP_ENV_SIZE(maxu
)
1395 IWMMXT_OP_ENV_SIZE(subn
)
1396 IWMMXT_OP_ENV_SIZE(addn
)
1397 IWMMXT_OP_ENV_SIZE(subu
)
1398 IWMMXT_OP_ENV_SIZE(addu
)
1399 IWMMXT_OP_ENV_SIZE(subs
)
1400 IWMMXT_OP_ENV_SIZE(adds
)
1402 IWMMXT_OP_ENV(avgb0
)
1403 IWMMXT_OP_ENV(avgb1
)
1404 IWMMXT_OP_ENV(avgw0
)
1405 IWMMXT_OP_ENV(avgw1
)
1407 IWMMXT_OP_ENV(packuw
)
1408 IWMMXT_OP_ENV(packul
)
1409 IWMMXT_OP_ENV(packuq
)
1410 IWMMXT_OP_ENV(packsw
)
1411 IWMMXT_OP_ENV(packsl
)
1412 IWMMXT_OP_ENV(packsq
)
1414 static void gen_op_iwmmxt_set_mup(void)
1417 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1418 tcg_gen_ori_i32(tmp
, tmp
, 2);
1419 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1422 static void gen_op_iwmmxt_set_cup(void)
1425 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1426 tcg_gen_ori_i32(tmp
, tmp
, 1);
1427 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1430 static void gen_op_iwmmxt_setpsr_nz(void)
1432 TCGv_i32 tmp
= tcg_temp_new_i32();
1433 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1434 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1437 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1439 iwmmxt_load_reg(cpu_V1
, rn
);
1440 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1441 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1444 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1451 rd
= (insn
>> 16) & 0xf;
1452 tmp
= load_reg(s
, rd
);
1454 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1455 if (insn
& (1 << 24)) {
1457 if (insn
& (1 << 23))
1458 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1460 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1461 tcg_gen_mov_i32(dest
, tmp
);
1462 if (insn
& (1 << 21))
1463 store_reg(s
, rd
, tmp
);
1465 tcg_temp_free_i32(tmp
);
1466 } else if (insn
& (1 << 21)) {
1468 tcg_gen_mov_i32(dest
, tmp
);
1469 if (insn
& (1 << 23))
1470 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1472 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1473 store_reg(s
, rd
, tmp
);
1474 } else if (!(insn
& (1 << 23)))
1479 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1481 int rd
= (insn
>> 0) & 0xf;
1484 if (insn
& (1 << 8)) {
1485 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1488 tmp
= iwmmxt_load_creg(rd
);
1491 tmp
= tcg_temp_new_i32();
1492 iwmmxt_load_reg(cpu_V0
, rd
);
1493 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
1495 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1496 tcg_gen_mov_i32(dest
, tmp
);
1497 tcg_temp_free_i32(tmp
);
1501 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1502 (ie. an undefined instruction). */
1503 static int disas_iwmmxt_insn(DisasContext
*s
, uint32_t insn
)
1506 int rdhi
, rdlo
, rd0
, rd1
, i
;
1508 TCGv_i32 tmp
, tmp2
, tmp3
;
1510 if ((insn
& 0x0e000e00) == 0x0c000000) {
1511 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1513 rdlo
= (insn
>> 12) & 0xf;
1514 rdhi
= (insn
>> 16) & 0xf;
1515 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1516 iwmmxt_load_reg(cpu_V0
, wrd
);
1517 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1518 tcg_gen_extrh_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1519 } else { /* TMCRR */
1520 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1521 iwmmxt_store_reg(cpu_V0
, wrd
);
1522 gen_op_iwmmxt_set_mup();
1527 wrd
= (insn
>> 12) & 0xf;
1528 addr
= tcg_temp_new_i32();
1529 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1530 tcg_temp_free_i32(addr
);
1533 if (insn
& ARM_CP_RW_BIT
) {
1534 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1535 tmp
= tcg_temp_new_i32();
1536 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1537 iwmmxt_store_creg(wrd
, tmp
);
1540 if (insn
& (1 << 8)) {
1541 if (insn
& (1 << 22)) { /* WLDRD */
1542 gen_aa32_ld64(s
, cpu_M0
, addr
, get_mem_index(s
));
1544 } else { /* WLDRW wRd */
1545 tmp
= tcg_temp_new_i32();
1546 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1549 tmp
= tcg_temp_new_i32();
1550 if (insn
& (1 << 22)) { /* WLDRH */
1551 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
1552 } else { /* WLDRB */
1553 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
1557 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1558 tcg_temp_free_i32(tmp
);
1560 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1563 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1564 tmp
= iwmmxt_load_creg(wrd
);
1565 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1567 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1568 tmp
= tcg_temp_new_i32();
1569 if (insn
& (1 << 8)) {
1570 if (insn
& (1 << 22)) { /* WSTRD */
1571 gen_aa32_st64(s
, cpu_M0
, addr
, get_mem_index(s
));
1572 } else { /* WSTRW wRd */
1573 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1574 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1577 if (insn
& (1 << 22)) { /* WSTRH */
1578 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1579 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
1580 } else { /* WSTRB */
1581 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1582 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
1586 tcg_temp_free_i32(tmp
);
1588 tcg_temp_free_i32(addr
);
1592 if ((insn
& 0x0f000000) != 0x0e000000)
1595 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1596 case 0x000: /* WOR */
1597 wrd
= (insn
>> 12) & 0xf;
1598 rd0
= (insn
>> 0) & 0xf;
1599 rd1
= (insn
>> 16) & 0xf;
1600 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1601 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1602 gen_op_iwmmxt_setpsr_nz();
1603 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1604 gen_op_iwmmxt_set_mup();
1605 gen_op_iwmmxt_set_cup();
1607 case 0x011: /* TMCR */
1610 rd
= (insn
>> 12) & 0xf;
1611 wrd
= (insn
>> 16) & 0xf;
1613 case ARM_IWMMXT_wCID
:
1614 case ARM_IWMMXT_wCASF
:
1616 case ARM_IWMMXT_wCon
:
1617 gen_op_iwmmxt_set_cup();
1619 case ARM_IWMMXT_wCSSF
:
1620 tmp
= iwmmxt_load_creg(wrd
);
1621 tmp2
= load_reg(s
, rd
);
1622 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1623 tcg_temp_free_i32(tmp2
);
1624 iwmmxt_store_creg(wrd
, tmp
);
1626 case ARM_IWMMXT_wCGR0
:
1627 case ARM_IWMMXT_wCGR1
:
1628 case ARM_IWMMXT_wCGR2
:
1629 case ARM_IWMMXT_wCGR3
:
1630 gen_op_iwmmxt_set_cup();
1631 tmp
= load_reg(s
, rd
);
1632 iwmmxt_store_creg(wrd
, tmp
);
1638 case 0x100: /* WXOR */
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_xorq_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 0x111: /* TMRC */
1652 rd
= (insn
>> 12) & 0xf;
1653 wrd
= (insn
>> 16) & 0xf;
1654 tmp
= iwmmxt_load_creg(wrd
);
1655 store_reg(s
, rd
, tmp
);
1657 case 0x300: /* WANDN */
1658 wrd
= (insn
>> 12) & 0xf;
1659 rd0
= (insn
>> 0) & 0xf;
1660 rd1
= (insn
>> 16) & 0xf;
1661 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1662 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1663 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1664 gen_op_iwmmxt_setpsr_nz();
1665 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1666 gen_op_iwmmxt_set_mup();
1667 gen_op_iwmmxt_set_cup();
1669 case 0x200: /* WAND */
1670 wrd
= (insn
>> 12) & 0xf;
1671 rd0
= (insn
>> 0) & 0xf;
1672 rd1
= (insn
>> 16) & 0xf;
1673 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1674 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1675 gen_op_iwmmxt_setpsr_nz();
1676 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1677 gen_op_iwmmxt_set_mup();
1678 gen_op_iwmmxt_set_cup();
1680 case 0x810: case 0xa10: /* WMADD */
1681 wrd
= (insn
>> 12) & 0xf;
1682 rd0
= (insn
>> 0) & 0xf;
1683 rd1
= (insn
>> 16) & 0xf;
1684 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1685 if (insn
& (1 << 21))
1686 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1688 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1689 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1690 gen_op_iwmmxt_set_mup();
1692 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1693 wrd
= (insn
>> 12) & 0xf;
1694 rd0
= (insn
>> 16) & 0xf;
1695 rd1
= (insn
>> 0) & 0xf;
1696 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1697 switch ((insn
>> 22) & 3) {
1699 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1702 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1705 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1710 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1711 gen_op_iwmmxt_set_mup();
1712 gen_op_iwmmxt_set_cup();
1714 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1715 wrd
= (insn
>> 12) & 0xf;
1716 rd0
= (insn
>> 16) & 0xf;
1717 rd1
= (insn
>> 0) & 0xf;
1718 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1719 switch ((insn
>> 22) & 3) {
1721 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1724 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1727 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1732 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1733 gen_op_iwmmxt_set_mup();
1734 gen_op_iwmmxt_set_cup();
1736 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1737 wrd
= (insn
>> 12) & 0xf;
1738 rd0
= (insn
>> 16) & 0xf;
1739 rd1
= (insn
>> 0) & 0xf;
1740 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1741 if (insn
& (1 << 22))
1742 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1744 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1745 if (!(insn
& (1 << 20)))
1746 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1747 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1748 gen_op_iwmmxt_set_mup();
1750 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1751 wrd
= (insn
>> 12) & 0xf;
1752 rd0
= (insn
>> 16) & 0xf;
1753 rd1
= (insn
>> 0) & 0xf;
1754 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1755 if (insn
& (1 << 21)) {
1756 if (insn
& (1 << 20))
1757 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1759 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1761 if (insn
& (1 << 20))
1762 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1764 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1766 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1767 gen_op_iwmmxt_set_mup();
1769 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1770 wrd
= (insn
>> 12) & 0xf;
1771 rd0
= (insn
>> 16) & 0xf;
1772 rd1
= (insn
>> 0) & 0xf;
1773 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1774 if (insn
& (1 << 21))
1775 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1777 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1778 if (!(insn
& (1 << 20))) {
1779 iwmmxt_load_reg(cpu_V1
, wrd
);
1780 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1782 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1783 gen_op_iwmmxt_set_mup();
1785 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1786 wrd
= (insn
>> 12) & 0xf;
1787 rd0
= (insn
>> 16) & 0xf;
1788 rd1
= (insn
>> 0) & 0xf;
1789 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1790 switch ((insn
>> 22) & 3) {
1792 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
1795 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1798 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
1803 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1804 gen_op_iwmmxt_set_mup();
1805 gen_op_iwmmxt_set_cup();
1807 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1808 wrd
= (insn
>> 12) & 0xf;
1809 rd0
= (insn
>> 16) & 0xf;
1810 rd1
= (insn
>> 0) & 0xf;
1811 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1812 if (insn
& (1 << 22)) {
1813 if (insn
& (1 << 20))
1814 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1816 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1818 if (insn
& (1 << 20))
1819 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1821 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
1823 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1824 gen_op_iwmmxt_set_mup();
1825 gen_op_iwmmxt_set_cup();
1827 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1828 wrd
= (insn
>> 12) & 0xf;
1829 rd0
= (insn
>> 16) & 0xf;
1830 rd1
= (insn
>> 0) & 0xf;
1831 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1832 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
1833 tcg_gen_andi_i32(tmp
, tmp
, 7);
1834 iwmmxt_load_reg(cpu_V1
, rd1
);
1835 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
1836 tcg_temp_free_i32(tmp
);
1837 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1838 gen_op_iwmmxt_set_mup();
1840 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1841 if (((insn
>> 6) & 3) == 3)
1843 rd
= (insn
>> 12) & 0xf;
1844 wrd
= (insn
>> 16) & 0xf;
1845 tmp
= load_reg(s
, rd
);
1846 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1847 switch ((insn
>> 6) & 3) {
1849 tmp2
= tcg_const_i32(0xff);
1850 tmp3
= tcg_const_i32((insn
& 7) << 3);
1853 tmp2
= tcg_const_i32(0xffff);
1854 tmp3
= tcg_const_i32((insn
& 3) << 4);
1857 tmp2
= tcg_const_i32(0xffffffff);
1858 tmp3
= tcg_const_i32((insn
& 1) << 5);
1864 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
1865 tcg_temp_free_i32(tmp3
);
1866 tcg_temp_free_i32(tmp2
);
1867 tcg_temp_free_i32(tmp
);
1868 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1869 gen_op_iwmmxt_set_mup();
1871 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1872 rd
= (insn
>> 12) & 0xf;
1873 wrd
= (insn
>> 16) & 0xf;
1874 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
1876 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1877 tmp
= tcg_temp_new_i32();
1878 switch ((insn
>> 22) & 3) {
1880 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
1881 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1883 tcg_gen_ext8s_i32(tmp
, tmp
);
1885 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
1889 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
1890 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1892 tcg_gen_ext16s_i32(tmp
, tmp
);
1894 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
1898 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
1899 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1902 store_reg(s
, rd
, tmp
);
1904 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1905 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1907 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1908 switch ((insn
>> 22) & 3) {
1910 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
1913 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
1916 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
1919 tcg_gen_shli_i32(tmp
, tmp
, 28);
1921 tcg_temp_free_i32(tmp
);
1923 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1924 if (((insn
>> 6) & 3) == 3)
1926 rd
= (insn
>> 12) & 0xf;
1927 wrd
= (insn
>> 16) & 0xf;
1928 tmp
= load_reg(s
, rd
);
1929 switch ((insn
>> 6) & 3) {
1931 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
1934 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
1937 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
1940 tcg_temp_free_i32(tmp
);
1941 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1942 gen_op_iwmmxt_set_mup();
1944 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1945 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1947 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1948 tmp2
= tcg_temp_new_i32();
1949 tcg_gen_mov_i32(tmp2
, tmp
);
1950 switch ((insn
>> 22) & 3) {
1952 for (i
= 0; i
< 7; i
++) {
1953 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1954 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1958 for (i
= 0; i
< 3; i
++) {
1959 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1960 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1964 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1965 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1969 tcg_temp_free_i32(tmp2
);
1970 tcg_temp_free_i32(tmp
);
1972 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1973 wrd
= (insn
>> 12) & 0xf;
1974 rd0
= (insn
>> 16) & 0xf;
1975 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1976 switch ((insn
>> 22) & 3) {
1978 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
1981 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
1984 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
1989 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1990 gen_op_iwmmxt_set_mup();
1992 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1993 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1995 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1996 tmp2
= tcg_temp_new_i32();
1997 tcg_gen_mov_i32(tmp2
, tmp
);
1998 switch ((insn
>> 22) & 3) {
2000 for (i
= 0; i
< 7; i
++) {
2001 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2002 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2006 for (i
= 0; i
< 3; i
++) {
2007 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2008 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2012 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2013 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2017 tcg_temp_free_i32(tmp2
);
2018 tcg_temp_free_i32(tmp
);
2020 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2021 rd
= (insn
>> 12) & 0xf;
2022 rd0
= (insn
>> 16) & 0xf;
2023 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
2025 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2026 tmp
= tcg_temp_new_i32();
2027 switch ((insn
>> 22) & 3) {
2029 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
2032 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
2035 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
2038 store_reg(s
, rd
, tmp
);
2040 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2041 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2042 wrd
= (insn
>> 12) & 0xf;
2043 rd0
= (insn
>> 16) & 0xf;
2044 rd1
= (insn
>> 0) & 0xf;
2045 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2046 switch ((insn
>> 22) & 3) {
2048 if (insn
& (1 << 21))
2049 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
2051 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
2054 if (insn
& (1 << 21))
2055 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2057 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2060 if (insn
& (1 << 21))
2061 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2063 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2068 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2069 gen_op_iwmmxt_set_mup();
2070 gen_op_iwmmxt_set_cup();
2072 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2073 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2074 wrd
= (insn
>> 12) & 0xf;
2075 rd0
= (insn
>> 16) & 0xf;
2076 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2077 switch ((insn
>> 22) & 3) {
2079 if (insn
& (1 << 21))
2080 gen_op_iwmmxt_unpacklsb_M0();
2082 gen_op_iwmmxt_unpacklub_M0();
2085 if (insn
& (1 << 21))
2086 gen_op_iwmmxt_unpacklsw_M0();
2088 gen_op_iwmmxt_unpackluw_M0();
2091 if (insn
& (1 << 21))
2092 gen_op_iwmmxt_unpacklsl_M0();
2094 gen_op_iwmmxt_unpacklul_M0();
2099 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2100 gen_op_iwmmxt_set_mup();
2101 gen_op_iwmmxt_set_cup();
2103 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2104 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2105 wrd
= (insn
>> 12) & 0xf;
2106 rd0
= (insn
>> 16) & 0xf;
2107 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2108 switch ((insn
>> 22) & 3) {
2110 if (insn
& (1 << 21))
2111 gen_op_iwmmxt_unpackhsb_M0();
2113 gen_op_iwmmxt_unpackhub_M0();
2116 if (insn
& (1 << 21))
2117 gen_op_iwmmxt_unpackhsw_M0();
2119 gen_op_iwmmxt_unpackhuw_M0();
2122 if (insn
& (1 << 21))
2123 gen_op_iwmmxt_unpackhsl_M0();
2125 gen_op_iwmmxt_unpackhul_M0();
2130 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2131 gen_op_iwmmxt_set_mup();
2132 gen_op_iwmmxt_set_cup();
2134 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2135 case 0x214: case 0x614: case 0xa14: case 0xe14:
2136 if (((insn
>> 22) & 3) == 0)
2138 wrd
= (insn
>> 12) & 0xf;
2139 rd0
= (insn
>> 16) & 0xf;
2140 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2141 tmp
= tcg_temp_new_i32();
2142 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2143 tcg_temp_free_i32(tmp
);
2146 switch ((insn
>> 22) & 3) {
2148 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2151 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2154 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2157 tcg_temp_free_i32(tmp
);
2158 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2159 gen_op_iwmmxt_set_mup();
2160 gen_op_iwmmxt_set_cup();
2162 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2163 case 0x014: case 0x414: case 0x814: case 0xc14:
2164 if (((insn
>> 22) & 3) == 0)
2166 wrd
= (insn
>> 12) & 0xf;
2167 rd0
= (insn
>> 16) & 0xf;
2168 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2169 tmp
= tcg_temp_new_i32();
2170 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2171 tcg_temp_free_i32(tmp
);
2174 switch ((insn
>> 22) & 3) {
2176 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2179 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2182 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2185 tcg_temp_free_i32(tmp
);
2186 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2187 gen_op_iwmmxt_set_mup();
2188 gen_op_iwmmxt_set_cup();
2190 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2191 case 0x114: case 0x514: case 0x914: case 0xd14:
2192 if (((insn
>> 22) & 3) == 0)
2194 wrd
= (insn
>> 12) & 0xf;
2195 rd0
= (insn
>> 16) & 0xf;
2196 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2197 tmp
= tcg_temp_new_i32();
2198 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2199 tcg_temp_free_i32(tmp
);
2202 switch ((insn
>> 22) & 3) {
2204 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2207 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2210 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2213 tcg_temp_free_i32(tmp
);
2214 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2215 gen_op_iwmmxt_set_mup();
2216 gen_op_iwmmxt_set_cup();
2218 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2219 case 0x314: case 0x714: case 0xb14: case 0xf14:
2220 if (((insn
>> 22) & 3) == 0)
2222 wrd
= (insn
>> 12) & 0xf;
2223 rd0
= (insn
>> 16) & 0xf;
2224 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2225 tmp
= tcg_temp_new_i32();
2226 switch ((insn
>> 22) & 3) {
2228 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2229 tcg_temp_free_i32(tmp
);
2232 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2235 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2236 tcg_temp_free_i32(tmp
);
2239 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2242 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2243 tcg_temp_free_i32(tmp
);
2246 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2249 tcg_temp_free_i32(tmp
);
2250 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2251 gen_op_iwmmxt_set_mup();
2252 gen_op_iwmmxt_set_cup();
2254 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2255 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2256 wrd
= (insn
>> 12) & 0xf;
2257 rd0
= (insn
>> 16) & 0xf;
2258 rd1
= (insn
>> 0) & 0xf;
2259 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2260 switch ((insn
>> 22) & 3) {
2262 if (insn
& (1 << 21))
2263 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2265 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2268 if (insn
& (1 << 21))
2269 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2271 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2274 if (insn
& (1 << 21))
2275 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2277 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2282 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2283 gen_op_iwmmxt_set_mup();
2285 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2286 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2287 wrd
= (insn
>> 12) & 0xf;
2288 rd0
= (insn
>> 16) & 0xf;
2289 rd1
= (insn
>> 0) & 0xf;
2290 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2291 switch ((insn
>> 22) & 3) {
2293 if (insn
& (1 << 21))
2294 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2296 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2299 if (insn
& (1 << 21))
2300 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2302 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2305 if (insn
& (1 << 21))
2306 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2308 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2313 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2314 gen_op_iwmmxt_set_mup();
2316 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2317 case 0x402: case 0x502: case 0x602: case 0x702:
2318 wrd
= (insn
>> 12) & 0xf;
2319 rd0
= (insn
>> 16) & 0xf;
2320 rd1
= (insn
>> 0) & 0xf;
2321 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2322 tmp
= tcg_const_i32((insn
>> 20) & 3);
2323 iwmmxt_load_reg(cpu_V1
, rd1
);
2324 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2325 tcg_temp_free_i32(tmp
);
2326 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2327 gen_op_iwmmxt_set_mup();
2329 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2330 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2331 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2332 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2333 wrd
= (insn
>> 12) & 0xf;
2334 rd0
= (insn
>> 16) & 0xf;
2335 rd1
= (insn
>> 0) & 0xf;
2336 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2337 switch ((insn
>> 20) & 0xf) {
2339 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2342 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2345 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2348 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2351 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2354 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2357 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2360 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2363 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2368 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2369 gen_op_iwmmxt_set_mup();
2370 gen_op_iwmmxt_set_cup();
2372 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2373 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2374 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2375 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2376 wrd
= (insn
>> 12) & 0xf;
2377 rd0
= (insn
>> 16) & 0xf;
2378 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2379 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2380 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2381 tcg_temp_free_i32(tmp
);
2382 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2383 gen_op_iwmmxt_set_mup();
2384 gen_op_iwmmxt_set_cup();
2386 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2387 case 0x418: case 0x518: case 0x618: case 0x718:
2388 case 0x818: case 0x918: case 0xa18: case 0xb18:
2389 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2390 wrd
= (insn
>> 12) & 0xf;
2391 rd0
= (insn
>> 16) & 0xf;
2392 rd1
= (insn
>> 0) & 0xf;
2393 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2394 switch ((insn
>> 20) & 0xf) {
2396 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2399 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2402 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2405 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2408 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2411 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2414 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2417 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2420 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2425 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2426 gen_op_iwmmxt_set_mup();
2427 gen_op_iwmmxt_set_cup();
2429 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2430 case 0x408: case 0x508: case 0x608: case 0x708:
2431 case 0x808: case 0x908: case 0xa08: case 0xb08:
2432 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2433 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2435 wrd
= (insn
>> 12) & 0xf;
2436 rd0
= (insn
>> 16) & 0xf;
2437 rd1
= (insn
>> 0) & 0xf;
2438 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2439 switch ((insn
>> 22) & 3) {
2441 if (insn
& (1 << 21))
2442 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2444 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2447 if (insn
& (1 << 21))
2448 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2450 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2453 if (insn
& (1 << 21))
2454 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2456 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2459 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2460 gen_op_iwmmxt_set_mup();
2461 gen_op_iwmmxt_set_cup();
2463 case 0x201: case 0x203: case 0x205: case 0x207:
2464 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2465 case 0x211: case 0x213: case 0x215: case 0x217:
2466 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2467 wrd
= (insn
>> 5) & 0xf;
2468 rd0
= (insn
>> 12) & 0xf;
2469 rd1
= (insn
>> 0) & 0xf;
2470 if (rd0
== 0xf || rd1
== 0xf)
2472 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2473 tmp
= load_reg(s
, rd0
);
2474 tmp2
= load_reg(s
, rd1
);
2475 switch ((insn
>> 16) & 0xf) {
2476 case 0x0: /* TMIA */
2477 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2479 case 0x8: /* TMIAPH */
2480 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2482 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2483 if (insn
& (1 << 16))
2484 tcg_gen_shri_i32(tmp
, tmp
, 16);
2485 if (insn
& (1 << 17))
2486 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2487 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2490 tcg_temp_free_i32(tmp2
);
2491 tcg_temp_free_i32(tmp
);
2494 tcg_temp_free_i32(tmp2
);
2495 tcg_temp_free_i32(tmp
);
2496 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2497 gen_op_iwmmxt_set_mup();
2506 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2507 (ie. an undefined instruction). */
2508 static int disas_dsp_insn(DisasContext
*s
, uint32_t insn
)
2510 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2513 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2514 /* Multiply with Internal Accumulate Format */
2515 rd0
= (insn
>> 12) & 0xf;
2517 acc
= (insn
>> 5) & 7;
2522 tmp
= load_reg(s
, rd0
);
2523 tmp2
= load_reg(s
, rd1
);
2524 switch ((insn
>> 16) & 0xf) {
2526 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2528 case 0x8: /* MIAPH */
2529 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2531 case 0xc: /* MIABB */
2532 case 0xd: /* MIABT */
2533 case 0xe: /* MIATB */
2534 case 0xf: /* MIATT */
2535 if (insn
& (1 << 16))
2536 tcg_gen_shri_i32(tmp
, tmp
, 16);
2537 if (insn
& (1 << 17))
2538 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2539 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2544 tcg_temp_free_i32(tmp2
);
2545 tcg_temp_free_i32(tmp
);
2547 gen_op_iwmmxt_movq_wRn_M0(acc
);
2551 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2552 /* Internal Accumulator Access Format */
2553 rdhi
= (insn
>> 16) & 0xf;
2554 rdlo
= (insn
>> 12) & 0xf;
2560 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2561 iwmmxt_load_reg(cpu_V0
, acc
);
2562 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2563 tcg_gen_extrh_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2564 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2566 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2567 iwmmxt_store_reg(cpu_V0
, acc
);
2575 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2576 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2577 if (dc_isar_feature(aa32_simd_r32, s)) { \
2578 reg = (((insn) >> (bigbit)) & 0x0f) \
2579 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2581 if (insn & (1 << (smallbit))) \
2583 reg = ((insn) >> (bigbit)) & 0x0f; \
2586 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2587 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2588 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2590 static inline bool use_goto_tb(DisasContext
*s
, target_ulong dest
)
2592 #ifndef CONFIG_USER_ONLY
2593 return (s
->base
.tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) ||
2594 ((s
->base
.pc_next
- 1) & TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
2600 static void gen_goto_ptr(void)
2602 tcg_gen_lookup_and_goto_ptr();
2605 /* This will end the TB but doesn't guarantee we'll return to
2606 * cpu_loop_exec. Any live exit_requests will be processed as we
2607 * enter the next TB.
2609 static void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
2611 if (use_goto_tb(s
, dest
)) {
2613 gen_set_pc_im(s
, dest
);
2614 tcg_gen_exit_tb(s
->base
.tb
, n
);
2616 gen_set_pc_im(s
, dest
);
2619 s
->base
.is_jmp
= DISAS_NORETURN
;
2622 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
2624 if (unlikely(is_singlestepping(s
))) {
2625 /* An indirect jump so that we still trigger the debug exception. */
2626 gen_set_pc_im(s
, dest
);
2627 s
->base
.is_jmp
= DISAS_JUMP
;
2629 gen_goto_tb(s
, 0, dest
);
2633 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
2636 tcg_gen_sari_i32(t0
, t0
, 16);
2640 tcg_gen_sari_i32(t1
, t1
, 16);
2643 tcg_gen_mul_i32(t0
, t0
, t1
);
2646 /* Return the mask of PSR bits set by a MSR instruction. */
2647 static uint32_t msr_mask(DisasContext
*s
, int flags
, int spsr
)
2651 if (flags
& (1 << 0)) {
2654 if (flags
& (1 << 1)) {
2657 if (flags
& (1 << 2)) {
2660 if (flags
& (1 << 3)) {
2664 /* Mask out undefined and reserved bits. */
2665 mask
&= aarch32_cpsr_valid_mask(s
->features
, s
->isar
);
2667 /* Mask out execution state. */
2672 /* Mask out privileged bits. */
2679 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
2680 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
2684 /* ??? This is also undefined in system mode. */
2688 tmp
= load_cpu_field(spsr
);
2689 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
2690 tcg_gen_andi_i32(t0
, t0
, mask
);
2691 tcg_gen_or_i32(tmp
, tmp
, t0
);
2692 store_cpu_field(tmp
, spsr
);
2694 gen_set_cpsr(t0
, mask
);
2696 tcg_temp_free_i32(t0
);
2701 /* Returns nonzero if access to the PSR is not permitted. */
2702 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
2705 tmp
= tcg_temp_new_i32();
2706 tcg_gen_movi_i32(tmp
, val
);
2707 return gen_set_psr(s
, mask
, spsr
, tmp
);
2710 static bool msr_banked_access_decode(DisasContext
*s
, int r
, int sysm
, int rn
,
2711 int *tgtmode
, int *regno
)
2713 /* Decode the r and sysm fields of MSR/MRS banked accesses into
2714 * the target mode and register number, and identify the various
2715 * unpredictable cases.
2716 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
2717 * + executed in user mode
2718 * + using R15 as the src/dest register
2719 * + accessing an unimplemented register
2720 * + accessing a register that's inaccessible at current PL/security state*
2721 * + accessing a register that you could access with a different insn
2722 * We choose to UNDEF in all these cases.
2723 * Since we don't know which of the various AArch32 modes we are in
2724 * we have to defer some checks to runtime.
2725 * Accesses to Monitor mode registers from Secure EL1 (which implies
2726 * that EL3 is AArch64) must trap to EL3.
2728 * If the access checks fail this function will emit code to take
2729 * an exception and return false. Otherwise it will return true,
2730 * and set *tgtmode and *regno appropriately.
2732 int exc_target
= default_exception_el(s
);
2734 /* These instructions are present only in ARMv8, or in ARMv7 with the
2735 * Virtualization Extensions.
2737 if (!arm_dc_feature(s
, ARM_FEATURE_V8
) &&
2738 !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
2742 if (IS_USER(s
) || rn
== 15) {
2746 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
2747 * of registers into (r, sysm).
2750 /* SPSRs for other modes */
2752 case 0xe: /* SPSR_fiq */
2753 *tgtmode
= ARM_CPU_MODE_FIQ
;
2755 case 0x10: /* SPSR_irq */
2756 *tgtmode
= ARM_CPU_MODE_IRQ
;
2758 case 0x12: /* SPSR_svc */
2759 *tgtmode
= ARM_CPU_MODE_SVC
;
2761 case 0x14: /* SPSR_abt */
2762 *tgtmode
= ARM_CPU_MODE_ABT
;
2764 case 0x16: /* SPSR_und */
2765 *tgtmode
= ARM_CPU_MODE_UND
;
2767 case 0x1c: /* SPSR_mon */
2768 *tgtmode
= ARM_CPU_MODE_MON
;
2770 case 0x1e: /* SPSR_hyp */
2771 *tgtmode
= ARM_CPU_MODE_HYP
;
2773 default: /* unallocated */
2776 /* We arbitrarily assign SPSR a register number of 16. */
2779 /* general purpose registers for other modes */
2781 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
2782 *tgtmode
= ARM_CPU_MODE_USR
;
2785 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
2786 *tgtmode
= ARM_CPU_MODE_FIQ
;
2789 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
2790 *tgtmode
= ARM_CPU_MODE_IRQ
;
2791 *regno
= sysm
& 1 ? 13 : 14;
2793 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
2794 *tgtmode
= ARM_CPU_MODE_SVC
;
2795 *regno
= sysm
& 1 ? 13 : 14;
2797 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
2798 *tgtmode
= ARM_CPU_MODE_ABT
;
2799 *regno
= sysm
& 1 ? 13 : 14;
2801 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
2802 *tgtmode
= ARM_CPU_MODE_UND
;
2803 *regno
= sysm
& 1 ? 13 : 14;
2805 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
2806 *tgtmode
= ARM_CPU_MODE_MON
;
2807 *regno
= sysm
& 1 ? 13 : 14;
2809 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
2810 *tgtmode
= ARM_CPU_MODE_HYP
;
2811 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
2812 *regno
= sysm
& 1 ? 13 : 17;
2814 default: /* unallocated */
2819 /* Catch the 'accessing inaccessible register' cases we can detect
2820 * at translate time.
2823 case ARM_CPU_MODE_MON
:
2824 if (!arm_dc_feature(s
, ARM_FEATURE_EL3
) || s
->ns
) {
2827 if (s
->current_el
== 1) {
2828 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
2829 * then accesses to Mon registers trap to EL3
2835 case ARM_CPU_MODE_HYP
:
2837 * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
2838 * (and so we can forbid accesses from EL2 or below). elr_hyp
2839 * can be accessed also from Hyp mode, so forbid accesses from
2842 if (!arm_dc_feature(s
, ARM_FEATURE_EL2
) || s
->current_el
< 2 ||
2843 (s
->current_el
< 3 && *regno
!= 17)) {
2854 /* If we get here then some access check did not pass */
2855 gen_exception_insn(s
, s
->pc_curr
, EXCP_UDEF
,
2856 syn_uncategorized(), exc_target
);
2860 static void gen_msr_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
2862 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
2863 int tgtmode
= 0, regno
= 0;
2865 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
2869 /* Sync state because msr_banked() can raise exceptions */
2870 gen_set_condexec(s
);
2871 gen_set_pc_im(s
, s
->pc_curr
);
2872 tcg_reg
= load_reg(s
, rn
);
2873 tcg_tgtmode
= tcg_const_i32(tgtmode
);
2874 tcg_regno
= tcg_const_i32(regno
);
2875 gen_helper_msr_banked(cpu_env
, tcg_reg
, tcg_tgtmode
, tcg_regno
);
2876 tcg_temp_free_i32(tcg_tgtmode
);
2877 tcg_temp_free_i32(tcg_regno
);
2878 tcg_temp_free_i32(tcg_reg
);
2879 s
->base
.is_jmp
= DISAS_UPDATE
;
2882 static void gen_mrs_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
2884 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
2885 int tgtmode
= 0, regno
= 0;
2887 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
2891 /* Sync state because mrs_banked() can raise exceptions */
2892 gen_set_condexec(s
);
2893 gen_set_pc_im(s
, s
->pc_curr
);
2894 tcg_reg
= tcg_temp_new_i32();
2895 tcg_tgtmode
= tcg_const_i32(tgtmode
);
2896 tcg_regno
= tcg_const_i32(regno
);
2897 gen_helper_mrs_banked(tcg_reg
, cpu_env
, tcg_tgtmode
, tcg_regno
);
2898 tcg_temp_free_i32(tcg_tgtmode
);
2899 tcg_temp_free_i32(tcg_regno
);
2900 store_reg(s
, rn
, tcg_reg
);
2901 s
->base
.is_jmp
= DISAS_UPDATE
;
2904 /* Store value to PC as for an exception return (ie don't
2905 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
2906 * will do the masking based on the new value of the Thumb bit.
2908 static void store_pc_exc_ret(DisasContext
*s
, TCGv_i32 pc
)
2910 tcg_gen_mov_i32(cpu_R
[15], pc
);
2911 tcg_temp_free_i32(pc
);
2914 /* Generate a v6 exception return. Marks both values as dead. */
2915 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
2917 store_pc_exc_ret(s
, pc
);
2918 /* The cpsr_write_eret helper will mask the low bits of PC
2919 * appropriately depending on the new Thumb bit, so it must
2920 * be called after storing the new PC.
2922 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
2925 gen_helper_cpsr_write_eret(cpu_env
, cpsr
);
2926 tcg_temp_free_i32(cpsr
);
2927 /* Must exit loop to check un-masked IRQs */
2928 s
->base
.is_jmp
= DISAS_EXIT
;
2931 /* Generate an old-style exception return. Marks pc as dead. */
2932 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
2934 gen_rfe(s
, pc
, load_cpu_field(spsr
));
2937 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
2941 rd
= tcg_temp_new_i32();
2942 tmp
= tcg_temp_new_i32();
2944 tcg_gen_shli_i32(rd
, t0
, 8);
2945 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
2946 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
2947 tcg_gen_or_i32(rd
, rd
, tmp
);
2949 tcg_gen_shri_i32(t1
, t1
, 8);
2950 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
2951 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
2952 tcg_gen_or_i32(t1
, t1
, tmp
);
2953 tcg_gen_mov_i32(t0
, rd
);
2955 tcg_temp_free_i32(tmp
);
2956 tcg_temp_free_i32(rd
);
2959 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
2963 rd
= tcg_temp_new_i32();
2964 tmp
= tcg_temp_new_i32();
2966 tcg_gen_shli_i32(rd
, t0
, 16);
2967 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
2968 tcg_gen_or_i32(rd
, rd
, tmp
);
2969 tcg_gen_shri_i32(t1
, t1
, 16);
2970 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
2971 tcg_gen_or_i32(t1
, t1
, tmp
);
2972 tcg_gen_mov_i32(t0
, rd
);
2974 tcg_temp_free_i32(tmp
);
2975 tcg_temp_free_i32(rd
);
2978 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
2979 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
2982 #define NEON_2RM_VREV64 0
2983 #define NEON_2RM_VREV32 1
2984 #define NEON_2RM_VREV16 2
2985 #define NEON_2RM_VPADDL 4
2986 #define NEON_2RM_VPADDL_U 5
2987 #define NEON_2RM_AESE 6 /* Includes AESD */
2988 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
2989 #define NEON_2RM_VCLS 8
2990 #define NEON_2RM_VCLZ 9
2991 #define NEON_2RM_VCNT 10
2992 #define NEON_2RM_VMVN 11
2993 #define NEON_2RM_VPADAL 12
2994 #define NEON_2RM_VPADAL_U 13
2995 #define NEON_2RM_VQABS 14
2996 #define NEON_2RM_VQNEG 15
2997 #define NEON_2RM_VCGT0 16
2998 #define NEON_2RM_VCGE0 17
2999 #define NEON_2RM_VCEQ0 18
3000 #define NEON_2RM_VCLE0 19
3001 #define NEON_2RM_VCLT0 20
3002 #define NEON_2RM_SHA1H 21
3003 #define NEON_2RM_VABS 22
3004 #define NEON_2RM_VNEG 23
3005 #define NEON_2RM_VCGT0_F 24
3006 #define NEON_2RM_VCGE0_F 25
3007 #define NEON_2RM_VCEQ0_F 26
3008 #define NEON_2RM_VCLE0_F 27
3009 #define NEON_2RM_VCLT0_F 28
3010 #define NEON_2RM_VABS_F 30
3011 #define NEON_2RM_VNEG_F 31
3012 #define NEON_2RM_VSWP 32
3013 #define NEON_2RM_VTRN 33
3014 #define NEON_2RM_VUZP 34
3015 #define NEON_2RM_VZIP 35
3016 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
3017 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
3018 #define NEON_2RM_VSHLL 38
3019 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
3020 #define NEON_2RM_VRINTN 40
3021 #define NEON_2RM_VRINTX 41
3022 #define NEON_2RM_VRINTA 42
3023 #define NEON_2RM_VRINTZ 43
3024 #define NEON_2RM_VCVT_F16_F32 44
3025 #define NEON_2RM_VRINTM 45
3026 #define NEON_2RM_VCVT_F32_F16 46
3027 #define NEON_2RM_VRINTP 47
3028 #define NEON_2RM_VCVTAU 48
3029 #define NEON_2RM_VCVTAS 49
3030 #define NEON_2RM_VCVTNU 50
3031 #define NEON_2RM_VCVTNS 51
3032 #define NEON_2RM_VCVTPU 52
3033 #define NEON_2RM_VCVTPS 53
3034 #define NEON_2RM_VCVTMU 54
3035 #define NEON_2RM_VCVTMS 55
3036 #define NEON_2RM_VRECPE 56
3037 #define NEON_2RM_VRSQRTE 57
3038 #define NEON_2RM_VRECPE_F 58
3039 #define NEON_2RM_VRSQRTE_F 59
3040 #define NEON_2RM_VCVT_FS 60
3041 #define NEON_2RM_VCVT_FU 61
3042 #define NEON_2RM_VCVT_SF 62
3043 #define NEON_2RM_VCVT_UF 63
3045 static bool neon_2rm_is_v8_op(int op
)
3047 /* Return true if this neon 2reg-misc op is ARMv8 and up */
3049 case NEON_2RM_VRINTN
:
3050 case NEON_2RM_VRINTA
:
3051 case NEON_2RM_VRINTM
:
3052 case NEON_2RM_VRINTP
:
3053 case NEON_2RM_VRINTZ
:
3054 case NEON_2RM_VRINTX
:
3055 case NEON_2RM_VCVTAU
:
3056 case NEON_2RM_VCVTAS
:
3057 case NEON_2RM_VCVTNU
:
3058 case NEON_2RM_VCVTNS
:
3059 case NEON_2RM_VCVTPU
:
3060 case NEON_2RM_VCVTPS
:
3061 case NEON_2RM_VCVTMU
:
3062 case NEON_2RM_VCVTMS
:
3069 /* Each entry in this array has bit n set if the insn allows
3070 * size value n (otherwise it will UNDEF). Since unallocated
3071 * op values will have no bits set they always UNDEF.
3073 static const uint8_t neon_2rm_sizes
[] = {
3074 [NEON_2RM_VREV64
] = 0x7,
3075 [NEON_2RM_VREV32
] = 0x3,
3076 [NEON_2RM_VREV16
] = 0x1,
3077 [NEON_2RM_VPADDL
] = 0x7,
3078 [NEON_2RM_VPADDL_U
] = 0x7,
3079 [NEON_2RM_AESE
] = 0x1,
3080 [NEON_2RM_AESMC
] = 0x1,
3081 [NEON_2RM_VCLS
] = 0x7,
3082 [NEON_2RM_VCLZ
] = 0x7,
3083 [NEON_2RM_VCNT
] = 0x1,
3084 [NEON_2RM_VMVN
] = 0x1,
3085 [NEON_2RM_VPADAL
] = 0x7,
3086 [NEON_2RM_VPADAL_U
] = 0x7,
3087 [NEON_2RM_VQABS
] = 0x7,
3088 [NEON_2RM_VQNEG
] = 0x7,
3089 [NEON_2RM_VCGT0
] = 0x7,
3090 [NEON_2RM_VCGE0
] = 0x7,
3091 [NEON_2RM_VCEQ0
] = 0x7,
3092 [NEON_2RM_VCLE0
] = 0x7,
3093 [NEON_2RM_VCLT0
] = 0x7,
3094 [NEON_2RM_SHA1H
] = 0x4,
3095 [NEON_2RM_VABS
] = 0x7,
3096 [NEON_2RM_VNEG
] = 0x7,
3097 [NEON_2RM_VCGT0_F
] = 0x4,
3098 [NEON_2RM_VCGE0_F
] = 0x4,
3099 [NEON_2RM_VCEQ0_F
] = 0x4,
3100 [NEON_2RM_VCLE0_F
] = 0x4,
3101 [NEON_2RM_VCLT0_F
] = 0x4,
3102 [NEON_2RM_VABS_F
] = 0x4,
3103 [NEON_2RM_VNEG_F
] = 0x4,
3104 [NEON_2RM_VSWP
] = 0x1,
3105 [NEON_2RM_VTRN
] = 0x7,
3106 [NEON_2RM_VUZP
] = 0x7,
3107 [NEON_2RM_VZIP
] = 0x7,
3108 [NEON_2RM_VMOVN
] = 0x7,
3109 [NEON_2RM_VQMOVN
] = 0x7,
3110 [NEON_2RM_VSHLL
] = 0x7,
3111 [NEON_2RM_SHA1SU1
] = 0x4,
3112 [NEON_2RM_VRINTN
] = 0x4,
3113 [NEON_2RM_VRINTX
] = 0x4,
3114 [NEON_2RM_VRINTA
] = 0x4,
3115 [NEON_2RM_VRINTZ
] = 0x4,
3116 [NEON_2RM_VCVT_F16_F32
] = 0x2,
3117 [NEON_2RM_VRINTM
] = 0x4,
3118 [NEON_2RM_VCVT_F32_F16
] = 0x2,
3119 [NEON_2RM_VRINTP
] = 0x4,
3120 [NEON_2RM_VCVTAU
] = 0x4,
3121 [NEON_2RM_VCVTAS
] = 0x4,
3122 [NEON_2RM_VCVTNU
] = 0x4,
3123 [NEON_2RM_VCVTNS
] = 0x4,
3124 [NEON_2RM_VCVTPU
] = 0x4,
3125 [NEON_2RM_VCVTPS
] = 0x4,
3126 [NEON_2RM_VCVTMU
] = 0x4,
3127 [NEON_2RM_VCVTMS
] = 0x4,
3128 [NEON_2RM_VRECPE
] = 0x4,
3129 [NEON_2RM_VRSQRTE
] = 0x4,
3130 [NEON_2RM_VRECPE_F
] = 0x4,
3131 [NEON_2RM_VRSQRTE_F
] = 0x4,
3132 [NEON_2RM_VCVT_FS
] = 0x4,
3133 [NEON_2RM_VCVT_FU
] = 0x4,
3134 [NEON_2RM_VCVT_SF
] = 0x4,
3135 [NEON_2RM_VCVT_UF
] = 0x4,
3138 static void gen_gvec_fn3_qc(uint32_t rd_ofs
, uint32_t rn_ofs
, uint32_t rm_ofs
,
3139 uint32_t opr_sz
, uint32_t max_sz
,
3140 gen_helper_gvec_3_ptr
*fn
)
3142 TCGv_ptr qc_ptr
= tcg_temp_new_ptr();
3144 tcg_gen_addi_ptr(qc_ptr
, cpu_env
, offsetof(CPUARMState
, vfp
.qc
));
3145 tcg_gen_gvec_3_ptr(rd_ofs
, rn_ofs
, rm_ofs
, qc_ptr
,
3146 opr_sz
, max_sz
, 0, fn
);
3147 tcg_temp_free_ptr(qc_ptr
);
3150 void gen_gvec_sqrdmlah_qc(unsigned vece
, uint32_t rd_ofs
, uint32_t rn_ofs
,
3151 uint32_t rm_ofs
, uint32_t opr_sz
, uint32_t max_sz
)
3153 static gen_helper_gvec_3_ptr
* const fns
[2] = {
3154 gen_helper_gvec_qrdmlah_s16
, gen_helper_gvec_qrdmlah_s32
3156 tcg_debug_assert(vece
>= 1 && vece
<= 2);
3157 gen_gvec_fn3_qc(rd_ofs
, rn_ofs
, rm_ofs
, opr_sz
, max_sz
, fns
[vece
- 1]);
3160 void gen_gvec_sqrdmlsh_qc(unsigned vece
, uint32_t rd_ofs
, uint32_t rn_ofs
,
3161 uint32_t rm_ofs
, uint32_t opr_sz
, uint32_t max_sz
)
3163 static gen_helper_gvec_3_ptr
* const fns
[2] = {
3164 gen_helper_gvec_qrdmlsh_s16
, gen_helper_gvec_qrdmlsh_s32
3166 tcg_debug_assert(vece
>= 1 && vece
<= 2);
3167 gen_gvec_fn3_qc(rd_ofs
, rn_ofs
, rm_ofs
, opr_sz
, max_sz
, fns
[vece
- 1]);
3170 #define GEN_CMP0(NAME, COND) \
3171 static void gen_##NAME##0_i32(TCGv_i32 d, TCGv_i32 a) \
3173 tcg_gen_setcondi_i32(COND, d, a, 0); \
3174 tcg_gen_neg_i32(d, d); \
3176 static void gen_##NAME##0_i64(TCGv_i64 d, TCGv_i64 a) \
3178 tcg_gen_setcondi_i64(COND, d, a, 0); \
3179 tcg_gen_neg_i64(d, d); \
3181 static void gen_##NAME##0_vec(unsigned vece, TCGv_vec d, TCGv_vec a) \
3183 TCGv_vec zero = tcg_const_zeros_vec_matching(d); \
3184 tcg_gen_cmp_vec(COND, vece, d, a, zero); \
3185 tcg_temp_free_vec(zero); \
3187 void gen_gvec_##NAME##0(unsigned vece, uint32_t d, uint32_t m, \
3188 uint32_t opr_sz, uint32_t max_sz) \
3190 const GVecGen2 op[4] = { \
3191 { .fno = gen_helper_gvec_##NAME##0_b, \
3192 .fniv = gen_##NAME##0_vec, \
3193 .opt_opc = vecop_list_cmp, \
3195 { .fno = gen_helper_gvec_##NAME##0_h, \
3196 .fniv = gen_##NAME##0_vec, \
3197 .opt_opc = vecop_list_cmp, \
3199 { .fni4 = gen_##NAME##0_i32, \
3200 .fniv = gen_##NAME##0_vec, \
3201 .opt_opc = vecop_list_cmp, \
3203 { .fni8 = gen_##NAME##0_i64, \
3204 .fniv = gen_##NAME##0_vec, \
3205 .opt_opc = vecop_list_cmp, \
3206 .prefer_i64 = TCG_TARGET_REG_BITS == 64, \
3209 tcg_gen_gvec_2(d, m, opr_sz, max_sz, &op[vece]); \
3212 static const TCGOpcode vecop_list_cmp
[] = {
3216 GEN_CMP0(ceq
, TCG_COND_EQ
)
3217 GEN_CMP0(cle
, TCG_COND_LE
)
3218 GEN_CMP0(cge
, TCG_COND_GE
)
3219 GEN_CMP0(clt
, TCG_COND_LT
)
3220 GEN_CMP0(cgt
, TCG_COND_GT
)
3224 static void gen_ssra8_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
3226 tcg_gen_vec_sar8i_i64(a
, a
, shift
);
3227 tcg_gen_vec_add8_i64(d
, d
, a
);
3230 static void gen_ssra16_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
3232 tcg_gen_vec_sar16i_i64(a
, a
, shift
);
3233 tcg_gen_vec_add16_i64(d
, d
, a
);
3236 static void gen_ssra32_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t shift
)
3238 tcg_gen_sari_i32(a
, a
, shift
);
3239 tcg_gen_add_i32(d
, d
, a
);
3242 static void gen_ssra64_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
3244 tcg_gen_sari_i64(a
, a
, shift
);
3245 tcg_gen_add_i64(d
, d
, a
);
3248 static void gen_ssra_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
3250 tcg_gen_sari_vec(vece
, a
, a
, sh
);
3251 tcg_gen_add_vec(vece
, d
, d
, a
);
3254 void gen_gvec_ssra(unsigned vece
, uint32_t rd_ofs
, uint32_t rm_ofs
,
3255 int64_t shift
, uint32_t opr_sz
, uint32_t max_sz
)
3257 static const TCGOpcode vecop_list
[] = {
3258 INDEX_op_sari_vec
, INDEX_op_add_vec
, 0
3260 static const GVecGen2i ops
[4] = {
3261 { .fni8
= gen_ssra8_i64
,
3262 .fniv
= gen_ssra_vec
,
3263 .fno
= gen_helper_gvec_ssra_b
,
3265 .opt_opc
= vecop_list
,
3267 { .fni8
= gen_ssra16_i64
,
3268 .fniv
= gen_ssra_vec
,
3269 .fno
= gen_helper_gvec_ssra_h
,
3271 .opt_opc
= vecop_list
,
3273 { .fni4
= gen_ssra32_i32
,
3274 .fniv
= gen_ssra_vec
,
3275 .fno
= gen_helper_gvec_ssra_s
,
3277 .opt_opc
= vecop_list
,
3279 { .fni8
= gen_ssra64_i64
,
3280 .fniv
= gen_ssra_vec
,
3281 .fno
= gen_helper_gvec_ssra_b
,
3282 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
3283 .opt_opc
= vecop_list
,
3288 /* tszimm encoding produces immediates in the range [1..esize]. */
3289 tcg_debug_assert(shift
> 0);
3290 tcg_debug_assert(shift
<= (8 << vece
));
3293 * Shifts larger than the element size are architecturally valid.
3294 * Signed results in all sign bits.
3296 shift
= MIN(shift
, (8 << vece
) - 1);
3297 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, opr_sz
, max_sz
, shift
, &ops
[vece
]);
3300 static void gen_usra8_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
3302 tcg_gen_vec_shr8i_i64(a
, a
, shift
);
3303 tcg_gen_vec_add8_i64(d
, d
, a
);
3306 static void gen_usra16_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
3308 tcg_gen_vec_shr16i_i64(a
, a
, shift
);
3309 tcg_gen_vec_add16_i64(d
, d
, a
);
3312 static void gen_usra32_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t shift
)
3314 tcg_gen_shri_i32(a
, a
, shift
);
3315 tcg_gen_add_i32(d
, d
, a
);
3318 static void gen_usra64_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
3320 tcg_gen_shri_i64(a
, a
, shift
);
3321 tcg_gen_add_i64(d
, d
, a
);
3324 static void gen_usra_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
3326 tcg_gen_shri_vec(vece
, a
, a
, sh
);
3327 tcg_gen_add_vec(vece
, d
, d
, a
);
3330 void gen_gvec_usra(unsigned vece
, uint32_t rd_ofs
, uint32_t rm_ofs
,
3331 int64_t shift
, uint32_t opr_sz
, uint32_t max_sz
)
3333 static const TCGOpcode vecop_list
[] = {
3334 INDEX_op_shri_vec
, INDEX_op_add_vec
, 0
3336 static const GVecGen2i ops
[4] = {
3337 { .fni8
= gen_usra8_i64
,
3338 .fniv
= gen_usra_vec
,
3339 .fno
= gen_helper_gvec_usra_b
,
3341 .opt_opc
= vecop_list
,
3343 { .fni8
= gen_usra16_i64
,
3344 .fniv
= gen_usra_vec
,
3345 .fno
= gen_helper_gvec_usra_h
,
3347 .opt_opc
= vecop_list
,
3349 { .fni4
= gen_usra32_i32
,
3350 .fniv
= gen_usra_vec
,
3351 .fno
= gen_helper_gvec_usra_s
,
3353 .opt_opc
= vecop_list
,
3355 { .fni8
= gen_usra64_i64
,
3356 .fniv
= gen_usra_vec
,
3357 .fno
= gen_helper_gvec_usra_d
,
3358 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
3360 .opt_opc
= vecop_list
,
3364 /* tszimm encoding produces immediates in the range [1..esize]. */
3365 tcg_debug_assert(shift
> 0);
3366 tcg_debug_assert(shift
<= (8 << vece
));
3369 * Shifts larger than the element size are architecturally valid.
3370 * Unsigned results in all zeros as input to accumulate: nop.
3372 if (shift
< (8 << vece
)) {
3373 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, opr_sz
, max_sz
, shift
, &ops
[vece
]);
3375 /* Nop, but we do need to clear the tail. */
3376 tcg_gen_gvec_mov(vece
, rd_ofs
, rd_ofs
, opr_sz
, max_sz
);
3381 * Shift one less than the requested amount, and the low bit is
3382 * the rounding bit. For the 8 and 16-bit operations, because we
3383 * mask the low bit, we can perform a normal integer shift instead
3384 * of a vector shift.
3386 static void gen_srshr8_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t sh
)
3388 TCGv_i64 t
= tcg_temp_new_i64();
3390 tcg_gen_shri_i64(t
, a
, sh
- 1);
3391 tcg_gen_andi_i64(t
, t
, dup_const(MO_8
, 1));
3392 tcg_gen_vec_sar8i_i64(d
, a
, sh
);
3393 tcg_gen_vec_add8_i64(d
, d
, t
);
3394 tcg_temp_free_i64(t
);
3397 static void gen_srshr16_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t sh
)
3399 TCGv_i64 t
= tcg_temp_new_i64();
3401 tcg_gen_shri_i64(t
, a
, sh
- 1);
3402 tcg_gen_andi_i64(t
, t
, dup_const(MO_16
, 1));
3403 tcg_gen_vec_sar16i_i64(d
, a
, sh
);
3404 tcg_gen_vec_add16_i64(d
, d
, t
);
3405 tcg_temp_free_i64(t
);
3408 static void gen_srshr32_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t sh
)
3410 TCGv_i32 t
= tcg_temp_new_i32();
3412 tcg_gen_extract_i32(t
, a
, sh
- 1, 1);
3413 tcg_gen_sari_i32(d
, a
, sh
);
3414 tcg_gen_add_i32(d
, d
, t
);
3415 tcg_temp_free_i32(t
);
3418 static void gen_srshr64_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t sh
)
3420 TCGv_i64 t
= tcg_temp_new_i64();
3422 tcg_gen_extract_i64(t
, a
, sh
- 1, 1);
3423 tcg_gen_sari_i64(d
, a
, sh
);
3424 tcg_gen_add_i64(d
, d
, t
);
3425 tcg_temp_free_i64(t
);
3428 static void gen_srshr_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
3430 TCGv_vec t
= tcg_temp_new_vec_matching(d
);
3431 TCGv_vec ones
= tcg_temp_new_vec_matching(d
);
3433 tcg_gen_shri_vec(vece
, t
, a
, sh
- 1);
3434 tcg_gen_dupi_vec(vece
, ones
, 1);
3435 tcg_gen_and_vec(vece
, t
, t
, ones
);
3436 tcg_gen_sari_vec(vece
, d
, a
, sh
);
3437 tcg_gen_add_vec(vece
, d
, d
, t
);
3439 tcg_temp_free_vec(t
);
3440 tcg_temp_free_vec(ones
);
3443 void gen_gvec_srshr(unsigned vece
, uint32_t rd_ofs
, uint32_t rm_ofs
,
3444 int64_t shift
, uint32_t opr_sz
, uint32_t max_sz
)
3446 static const TCGOpcode vecop_list
[] = {
3447 INDEX_op_shri_vec
, INDEX_op_sari_vec
, INDEX_op_add_vec
, 0
3449 static const GVecGen2i ops
[4] = {
3450 { .fni8
= gen_srshr8_i64
,
3451 .fniv
= gen_srshr_vec
,
3452 .fno
= gen_helper_gvec_srshr_b
,
3453 .opt_opc
= vecop_list
,
3455 { .fni8
= gen_srshr16_i64
,
3456 .fniv
= gen_srshr_vec
,
3457 .fno
= gen_helper_gvec_srshr_h
,
3458 .opt_opc
= vecop_list
,
3460 { .fni4
= gen_srshr32_i32
,
3461 .fniv
= gen_srshr_vec
,
3462 .fno
= gen_helper_gvec_srshr_s
,
3463 .opt_opc
= vecop_list
,
3465 { .fni8
= gen_srshr64_i64
,
3466 .fniv
= gen_srshr_vec
,
3467 .fno
= gen_helper_gvec_srshr_d
,
3468 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
3469 .opt_opc
= vecop_list
,
3473 /* tszimm encoding produces immediates in the range [1..esize] */
3474 tcg_debug_assert(shift
> 0);
3475 tcg_debug_assert(shift
<= (8 << vece
));
3477 if (shift
== (8 << vece
)) {
3479 * Shifts larger than the element size are architecturally valid.
3480 * Signed results in all sign bits. With rounding, this produces
3481 * (-1 + 1) >> 1 == 0, or (0 + 1) >> 1 == 0.
3484 tcg_gen_gvec_dup_imm(vece
, rd_ofs
, opr_sz
, max_sz
, 0);
3486 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, opr_sz
, max_sz
, shift
, &ops
[vece
]);
3490 static void gen_srsra8_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t sh
)
3492 TCGv_i64 t
= tcg_temp_new_i64();
3494 gen_srshr8_i64(t
, a
, sh
);
3495 tcg_gen_vec_add8_i64(d
, d
, t
);
3496 tcg_temp_free_i64(t
);
3499 static void gen_srsra16_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t sh
)
3501 TCGv_i64 t
= tcg_temp_new_i64();
3503 gen_srshr16_i64(t
, a
, sh
);
3504 tcg_gen_vec_add16_i64(d
, d
, t
);
3505 tcg_temp_free_i64(t
);
3508 static void gen_srsra32_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t sh
)
3510 TCGv_i32 t
= tcg_temp_new_i32();
3512 gen_srshr32_i32(t
, a
, sh
);
3513 tcg_gen_add_i32(d
, d
, t
);
3514 tcg_temp_free_i32(t
);
3517 static void gen_srsra64_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t sh
)
3519 TCGv_i64 t
= tcg_temp_new_i64();
3521 gen_srshr64_i64(t
, a
, sh
);
3522 tcg_gen_add_i64(d
, d
, t
);
3523 tcg_temp_free_i64(t
);
3526 static void gen_srsra_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
3528 TCGv_vec t
= tcg_temp_new_vec_matching(d
);
3530 gen_srshr_vec(vece
, t
, a
, sh
);
3531 tcg_gen_add_vec(vece
, d
, d
, t
);
3532 tcg_temp_free_vec(t
);
3535 void gen_gvec_srsra(unsigned vece
, uint32_t rd_ofs
, uint32_t rm_ofs
,
3536 int64_t shift
, uint32_t opr_sz
, uint32_t max_sz
)
3538 static const TCGOpcode vecop_list
[] = {
3539 INDEX_op_shri_vec
, INDEX_op_sari_vec
, INDEX_op_add_vec
, 0
3541 static const GVecGen2i ops
[4] = {
3542 { .fni8
= gen_srsra8_i64
,
3543 .fniv
= gen_srsra_vec
,
3544 .fno
= gen_helper_gvec_srsra_b
,
3545 .opt_opc
= vecop_list
,
3548 { .fni8
= gen_srsra16_i64
,
3549 .fniv
= gen_srsra_vec
,
3550 .fno
= gen_helper_gvec_srsra_h
,
3551 .opt_opc
= vecop_list
,
3554 { .fni4
= gen_srsra32_i32
,
3555 .fniv
= gen_srsra_vec
,
3556 .fno
= gen_helper_gvec_srsra_s
,
3557 .opt_opc
= vecop_list
,
3560 { .fni8
= gen_srsra64_i64
,
3561 .fniv
= gen_srsra_vec
,
3562 .fno
= gen_helper_gvec_srsra_d
,
3563 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
3564 .opt_opc
= vecop_list
,
3569 /* tszimm encoding produces immediates in the range [1..esize] */
3570 tcg_debug_assert(shift
> 0);
3571 tcg_debug_assert(shift
<= (8 << vece
));
3574 * Shifts larger than the element size are architecturally valid.
3575 * Signed results in all sign bits. With rounding, this produces
3576 * (-1 + 1) >> 1 == 0, or (0 + 1) >> 1 == 0.
3577 * I.e. always zero. With accumulation, this leaves D unchanged.
3579 if (shift
== (8 << vece
)) {
3580 /* Nop, but we do need to clear the tail. */
3581 tcg_gen_gvec_mov(vece
, rd_ofs
, rd_ofs
, opr_sz
, max_sz
);
3583 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, opr_sz
, max_sz
, shift
, &ops
[vece
]);
3587 static void gen_urshr8_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t sh
)
3589 TCGv_i64 t
= tcg_temp_new_i64();
3591 tcg_gen_shri_i64(t
, a
, sh
- 1);
3592 tcg_gen_andi_i64(t
, t
, dup_const(MO_8
, 1));
3593 tcg_gen_vec_shr8i_i64(d
, a
, sh
);
3594 tcg_gen_vec_add8_i64(d
, d
, t
);
3595 tcg_temp_free_i64(t
);
3598 static void gen_urshr16_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t sh
)
3600 TCGv_i64 t
= tcg_temp_new_i64();
3602 tcg_gen_shri_i64(t
, a
, sh
- 1);
3603 tcg_gen_andi_i64(t
, t
, dup_const(MO_16
, 1));
3604 tcg_gen_vec_shr16i_i64(d
, a
, sh
);
3605 tcg_gen_vec_add16_i64(d
, d
, t
);
3606 tcg_temp_free_i64(t
);
3609 static void gen_urshr32_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t sh
)
3611 TCGv_i32 t
= tcg_temp_new_i32();
3613 tcg_gen_extract_i32(t
, a
, sh
- 1, 1);
3614 tcg_gen_shri_i32(d
, a
, sh
);
3615 tcg_gen_add_i32(d
, d
, t
);
3616 tcg_temp_free_i32(t
);
3619 static void gen_urshr64_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t sh
)
3621 TCGv_i64 t
= tcg_temp_new_i64();
3623 tcg_gen_extract_i64(t
, a
, sh
- 1, 1);
3624 tcg_gen_shri_i64(d
, a
, sh
);
3625 tcg_gen_add_i64(d
, d
, t
);
3626 tcg_temp_free_i64(t
);
3629 static void gen_urshr_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t shift
)
3631 TCGv_vec t
= tcg_temp_new_vec_matching(d
);
3632 TCGv_vec ones
= tcg_temp_new_vec_matching(d
);
3634 tcg_gen_shri_vec(vece
, t
, a
, shift
- 1);
3635 tcg_gen_dupi_vec(vece
, ones
, 1);
3636 tcg_gen_and_vec(vece
, t
, t
, ones
);
3637 tcg_gen_shri_vec(vece
, d
, a
, shift
);
3638 tcg_gen_add_vec(vece
, d
, d
, t
);
3640 tcg_temp_free_vec(t
);
3641 tcg_temp_free_vec(ones
);
3644 void gen_gvec_urshr(unsigned vece
, uint32_t rd_ofs
, uint32_t rm_ofs
,
3645 int64_t shift
, uint32_t opr_sz
, uint32_t max_sz
)
3647 static const TCGOpcode vecop_list
[] = {
3648 INDEX_op_shri_vec
, INDEX_op_add_vec
, 0
3650 static const GVecGen2i ops
[4] = {
3651 { .fni8
= gen_urshr8_i64
,
3652 .fniv
= gen_urshr_vec
,
3653 .fno
= gen_helper_gvec_urshr_b
,
3654 .opt_opc
= vecop_list
,
3656 { .fni8
= gen_urshr16_i64
,
3657 .fniv
= gen_urshr_vec
,
3658 .fno
= gen_helper_gvec_urshr_h
,
3659 .opt_opc
= vecop_list
,
3661 { .fni4
= gen_urshr32_i32
,
3662 .fniv
= gen_urshr_vec
,
3663 .fno
= gen_helper_gvec_urshr_s
,
3664 .opt_opc
= vecop_list
,
3666 { .fni8
= gen_urshr64_i64
,
3667 .fniv
= gen_urshr_vec
,
3668 .fno
= gen_helper_gvec_urshr_d
,
3669 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
3670 .opt_opc
= vecop_list
,
3674 /* tszimm encoding produces immediates in the range [1..esize] */
3675 tcg_debug_assert(shift
> 0);
3676 tcg_debug_assert(shift
<= (8 << vece
));
3678 if (shift
== (8 << vece
)) {
3680 * Shifts larger than the element size are architecturally valid.
3681 * Unsigned results in zero. With rounding, this produces a
3682 * copy of the most significant bit.
3684 tcg_gen_gvec_shri(vece
, rd_ofs
, rm_ofs
, shift
- 1, opr_sz
, max_sz
);
3686 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, opr_sz
, max_sz
, shift
, &ops
[vece
]);
3690 static void gen_ursra8_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t sh
)
3692 TCGv_i64 t
= tcg_temp_new_i64();
3695 tcg_gen_vec_shr8i_i64(t
, a
, 7);
3697 gen_urshr8_i64(t
, a
, sh
);
3699 tcg_gen_vec_add8_i64(d
, d
, t
);
3700 tcg_temp_free_i64(t
);
3703 static void gen_ursra16_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t sh
)
3705 TCGv_i64 t
= tcg_temp_new_i64();
3708 tcg_gen_vec_shr16i_i64(t
, a
, 15);
3710 gen_urshr16_i64(t
, a
, sh
);
3712 tcg_gen_vec_add16_i64(d
, d
, t
);
3713 tcg_temp_free_i64(t
);
3716 static void gen_ursra32_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t sh
)
3718 TCGv_i32 t
= tcg_temp_new_i32();
3721 tcg_gen_shri_i32(t
, a
, 31);
3723 gen_urshr32_i32(t
, a
, sh
);
3725 tcg_gen_add_i32(d
, d
, t
);
3726 tcg_temp_free_i32(t
);
3729 static void gen_ursra64_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t sh
)
3731 TCGv_i64 t
= tcg_temp_new_i64();
3734 tcg_gen_shri_i64(t
, a
, 63);
3736 gen_urshr64_i64(t
, a
, sh
);
3738 tcg_gen_add_i64(d
, d
, t
);
3739 tcg_temp_free_i64(t
);
3742 static void gen_ursra_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
3744 TCGv_vec t
= tcg_temp_new_vec_matching(d
);
3746 if (sh
== (8 << vece
)) {
3747 tcg_gen_shri_vec(vece
, t
, a
, sh
- 1);
3749 gen_urshr_vec(vece
, t
, a
, sh
);
3751 tcg_gen_add_vec(vece
, d
, d
, t
);
3752 tcg_temp_free_vec(t
);
3755 void gen_gvec_ursra(unsigned vece
, uint32_t rd_ofs
, uint32_t rm_ofs
,
3756 int64_t shift
, uint32_t opr_sz
, uint32_t max_sz
)
3758 static const TCGOpcode vecop_list
[] = {
3759 INDEX_op_shri_vec
, INDEX_op_add_vec
, 0
3761 static const GVecGen2i ops
[4] = {
3762 { .fni8
= gen_ursra8_i64
,
3763 .fniv
= gen_ursra_vec
,
3764 .fno
= gen_helper_gvec_ursra_b
,
3765 .opt_opc
= vecop_list
,
3768 { .fni8
= gen_ursra16_i64
,
3769 .fniv
= gen_ursra_vec
,
3770 .fno
= gen_helper_gvec_ursra_h
,
3771 .opt_opc
= vecop_list
,
3774 { .fni4
= gen_ursra32_i32
,
3775 .fniv
= gen_ursra_vec
,
3776 .fno
= gen_helper_gvec_ursra_s
,
3777 .opt_opc
= vecop_list
,
3780 { .fni8
= gen_ursra64_i64
,
3781 .fniv
= gen_ursra_vec
,
3782 .fno
= gen_helper_gvec_ursra_d
,
3783 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
3784 .opt_opc
= vecop_list
,
3789 /* tszimm encoding produces immediates in the range [1..esize] */
3790 tcg_debug_assert(shift
> 0);
3791 tcg_debug_assert(shift
<= (8 << vece
));
3793 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, opr_sz
, max_sz
, shift
, &ops
[vece
]);
3796 static void gen_shr8_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
3798 uint64_t mask
= dup_const(MO_8
, 0xff >> shift
);
3799 TCGv_i64 t
= tcg_temp_new_i64();
3801 tcg_gen_shri_i64(t
, a
, shift
);
3802 tcg_gen_andi_i64(t
, t
, mask
);
3803 tcg_gen_andi_i64(d
, d
, ~mask
);
3804 tcg_gen_or_i64(d
, d
, t
);
3805 tcg_temp_free_i64(t
);
3808 static void gen_shr16_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
3810 uint64_t mask
= dup_const(MO_16
, 0xffff >> shift
);
3811 TCGv_i64 t
= tcg_temp_new_i64();
3813 tcg_gen_shri_i64(t
, a
, shift
);
3814 tcg_gen_andi_i64(t
, t
, mask
);
3815 tcg_gen_andi_i64(d
, d
, ~mask
);
3816 tcg_gen_or_i64(d
, d
, t
);
3817 tcg_temp_free_i64(t
);
3820 static void gen_shr32_ins_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t shift
)
3822 tcg_gen_shri_i32(a
, a
, shift
);
3823 tcg_gen_deposit_i32(d
, d
, a
, 0, 32 - shift
);
3826 static void gen_shr64_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
3828 tcg_gen_shri_i64(a
, a
, shift
);
3829 tcg_gen_deposit_i64(d
, d
, a
, 0, 64 - shift
);
3832 static void gen_shr_ins_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
3834 TCGv_vec t
= tcg_temp_new_vec_matching(d
);
3835 TCGv_vec m
= tcg_temp_new_vec_matching(d
);
3837 tcg_gen_dupi_vec(vece
, m
, MAKE_64BIT_MASK((8 << vece
) - sh
, sh
));
3838 tcg_gen_shri_vec(vece
, t
, a
, sh
);
3839 tcg_gen_and_vec(vece
, d
, d
, m
);
3840 tcg_gen_or_vec(vece
, d
, d
, t
);
3842 tcg_temp_free_vec(t
);
3843 tcg_temp_free_vec(m
);
3846 void gen_gvec_sri(unsigned vece
, uint32_t rd_ofs
, uint32_t rm_ofs
,
3847 int64_t shift
, uint32_t opr_sz
, uint32_t max_sz
)
3849 static const TCGOpcode vecop_list
[] = { INDEX_op_shri_vec
, 0 };
3850 const GVecGen2i ops
[4] = {
3851 { .fni8
= gen_shr8_ins_i64
,
3852 .fniv
= gen_shr_ins_vec
,
3853 .fno
= gen_helper_gvec_sri_b
,
3855 .opt_opc
= vecop_list
,
3857 { .fni8
= gen_shr16_ins_i64
,
3858 .fniv
= gen_shr_ins_vec
,
3859 .fno
= gen_helper_gvec_sri_h
,
3861 .opt_opc
= vecop_list
,
3863 { .fni4
= gen_shr32_ins_i32
,
3864 .fniv
= gen_shr_ins_vec
,
3865 .fno
= gen_helper_gvec_sri_s
,
3867 .opt_opc
= vecop_list
,
3869 { .fni8
= gen_shr64_ins_i64
,
3870 .fniv
= gen_shr_ins_vec
,
3871 .fno
= gen_helper_gvec_sri_d
,
3872 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
3874 .opt_opc
= vecop_list
,
3878 /* tszimm encoding produces immediates in the range [1..esize]. */
3879 tcg_debug_assert(shift
> 0);
3880 tcg_debug_assert(shift
<= (8 << vece
));
3882 /* Shift of esize leaves destination unchanged. */
3883 if (shift
< (8 << vece
)) {
3884 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, opr_sz
, max_sz
, shift
, &ops
[vece
]);
3886 /* Nop, but we do need to clear the tail. */
3887 tcg_gen_gvec_mov(vece
, rd_ofs
, rd_ofs
, opr_sz
, max_sz
);
3891 static void gen_shl8_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
3893 uint64_t mask
= dup_const(MO_8
, 0xff << shift
);
3894 TCGv_i64 t
= tcg_temp_new_i64();
3896 tcg_gen_shli_i64(t
, a
, shift
);
3897 tcg_gen_andi_i64(t
, t
, mask
);
3898 tcg_gen_andi_i64(d
, d
, ~mask
);
3899 tcg_gen_or_i64(d
, d
, t
);
3900 tcg_temp_free_i64(t
);
3903 static void gen_shl16_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
3905 uint64_t mask
= dup_const(MO_16
, 0xffff << shift
);
3906 TCGv_i64 t
= tcg_temp_new_i64();
3908 tcg_gen_shli_i64(t
, a
, shift
);
3909 tcg_gen_andi_i64(t
, t
, mask
);
3910 tcg_gen_andi_i64(d
, d
, ~mask
);
3911 tcg_gen_or_i64(d
, d
, t
);
3912 tcg_temp_free_i64(t
);
3915 static void gen_shl32_ins_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t shift
)
3917 tcg_gen_deposit_i32(d
, d
, a
, shift
, 32 - shift
);
3920 static void gen_shl64_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
3922 tcg_gen_deposit_i64(d
, d
, a
, shift
, 64 - shift
);
3925 static void gen_shl_ins_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
3927 TCGv_vec t
= tcg_temp_new_vec_matching(d
);
3928 TCGv_vec m
= tcg_temp_new_vec_matching(d
);
3930 tcg_gen_shli_vec(vece
, t
, a
, sh
);
3931 tcg_gen_dupi_vec(vece
, m
, MAKE_64BIT_MASK(0, sh
));
3932 tcg_gen_and_vec(vece
, d
, d
, m
);
3933 tcg_gen_or_vec(vece
, d
, d
, t
);
3935 tcg_temp_free_vec(t
);
3936 tcg_temp_free_vec(m
);
3939 void gen_gvec_sli(unsigned vece
, uint32_t rd_ofs
, uint32_t rm_ofs
,
3940 int64_t shift
, uint32_t opr_sz
, uint32_t max_sz
)
3942 static const TCGOpcode vecop_list
[] = { INDEX_op_shli_vec
, 0 };
3943 const GVecGen2i ops
[4] = {
3944 { .fni8
= gen_shl8_ins_i64
,
3945 .fniv
= gen_shl_ins_vec
,
3946 .fno
= gen_helper_gvec_sli_b
,
3948 .opt_opc
= vecop_list
,
3950 { .fni8
= gen_shl16_ins_i64
,
3951 .fniv
= gen_shl_ins_vec
,
3952 .fno
= gen_helper_gvec_sli_h
,
3954 .opt_opc
= vecop_list
,
3956 { .fni4
= gen_shl32_ins_i32
,
3957 .fniv
= gen_shl_ins_vec
,
3958 .fno
= gen_helper_gvec_sli_s
,
3960 .opt_opc
= vecop_list
,
3962 { .fni8
= gen_shl64_ins_i64
,
3963 .fniv
= gen_shl_ins_vec
,
3964 .fno
= gen_helper_gvec_sli_d
,
3965 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
3967 .opt_opc
= vecop_list
,
3971 /* tszimm encoding produces immediates in the range [0..esize-1]. */
3972 tcg_debug_assert(shift
>= 0);
3973 tcg_debug_assert(shift
< (8 << vece
));
3976 tcg_gen_gvec_mov(vece
, rd_ofs
, rm_ofs
, opr_sz
, max_sz
);
3978 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, opr_sz
, max_sz
, shift
, &ops
[vece
]);
3982 static void gen_mla8_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
3984 gen_helper_neon_mul_u8(a
, a
, b
);
3985 gen_helper_neon_add_u8(d
, d
, a
);
3988 static void gen_mls8_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
3990 gen_helper_neon_mul_u8(a
, a
, b
);
3991 gen_helper_neon_sub_u8(d
, d
, a
);
3994 static void gen_mla16_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
3996 gen_helper_neon_mul_u16(a
, a
, b
);
3997 gen_helper_neon_add_u16(d
, d
, a
);
4000 static void gen_mls16_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
4002 gen_helper_neon_mul_u16(a
, a
, b
);
4003 gen_helper_neon_sub_u16(d
, d
, a
);
4006 static void gen_mla32_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
4008 tcg_gen_mul_i32(a
, a
, b
);
4009 tcg_gen_add_i32(d
, d
, a
);
4012 static void gen_mls32_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
4014 tcg_gen_mul_i32(a
, a
, b
);
4015 tcg_gen_sub_i32(d
, d
, a
);
4018 static void gen_mla64_i64(TCGv_i64 d
, TCGv_i64 a
, TCGv_i64 b
)
4020 tcg_gen_mul_i64(a
, a
, b
);
4021 tcg_gen_add_i64(d
, d
, a
);
4024 static void gen_mls64_i64(TCGv_i64 d
, TCGv_i64 a
, TCGv_i64 b
)
4026 tcg_gen_mul_i64(a
, a
, b
);
4027 tcg_gen_sub_i64(d
, d
, a
);
4030 static void gen_mla_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, TCGv_vec b
)
4032 tcg_gen_mul_vec(vece
, a
, a
, b
);
4033 tcg_gen_add_vec(vece
, d
, d
, a
);
4036 static void gen_mls_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, TCGv_vec b
)
4038 tcg_gen_mul_vec(vece
, a
, a
, b
);
4039 tcg_gen_sub_vec(vece
, d
, d
, a
);
4042 /* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
4043 * these tables are shared with AArch64 which does support them.
4045 void gen_gvec_mla(unsigned vece
, uint32_t rd_ofs
, uint32_t rn_ofs
,
4046 uint32_t rm_ofs
, uint32_t opr_sz
, uint32_t max_sz
)
4048 static const TCGOpcode vecop_list
[] = {
4049 INDEX_op_mul_vec
, INDEX_op_add_vec
, 0
4051 static const GVecGen3 ops
[4] = {
4052 { .fni4
= gen_mla8_i32
,
4053 .fniv
= gen_mla_vec
,
4055 .opt_opc
= vecop_list
,
4057 { .fni4
= gen_mla16_i32
,
4058 .fniv
= gen_mla_vec
,
4060 .opt_opc
= vecop_list
,
4062 { .fni4
= gen_mla32_i32
,
4063 .fniv
= gen_mla_vec
,
4065 .opt_opc
= vecop_list
,
4067 { .fni8
= gen_mla64_i64
,
4068 .fniv
= gen_mla_vec
,
4069 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
4071 .opt_opc
= vecop_list
,
4074 tcg_gen_gvec_3(rd_ofs
, rn_ofs
, rm_ofs
, opr_sz
, max_sz
, &ops
[vece
]);
4077 void gen_gvec_mls(unsigned vece
, uint32_t rd_ofs
, uint32_t rn_ofs
,
4078 uint32_t rm_ofs
, uint32_t opr_sz
, uint32_t max_sz
)
4080 static const TCGOpcode vecop_list
[] = {
4081 INDEX_op_mul_vec
, INDEX_op_sub_vec
, 0
4083 static const GVecGen3 ops
[4] = {
4084 { .fni4
= gen_mls8_i32
,
4085 .fniv
= gen_mls_vec
,
4087 .opt_opc
= vecop_list
,
4089 { .fni4
= gen_mls16_i32
,
4090 .fniv
= gen_mls_vec
,
4092 .opt_opc
= vecop_list
,
4094 { .fni4
= gen_mls32_i32
,
4095 .fniv
= gen_mls_vec
,
4097 .opt_opc
= vecop_list
,
4099 { .fni8
= gen_mls64_i64
,
4100 .fniv
= gen_mls_vec
,
4101 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
4103 .opt_opc
= vecop_list
,
4106 tcg_gen_gvec_3(rd_ofs
, rn_ofs
, rm_ofs
, opr_sz
, max_sz
, &ops
[vece
]);
4109 /* CMTST : test is "if (X & Y != 0)". */
4110 static void gen_cmtst_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
4112 tcg_gen_and_i32(d
, a
, b
);
4113 tcg_gen_setcondi_i32(TCG_COND_NE
, d
, d
, 0);
4114 tcg_gen_neg_i32(d
, d
);
4117 void gen_cmtst_i64(TCGv_i64 d
, TCGv_i64 a
, TCGv_i64 b
)
4119 tcg_gen_and_i64(d
, a
, b
);
4120 tcg_gen_setcondi_i64(TCG_COND_NE
, d
, d
, 0);
4121 tcg_gen_neg_i64(d
, d
);
4124 static void gen_cmtst_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, TCGv_vec b
)
4126 tcg_gen_and_vec(vece
, d
, a
, b
);
4127 tcg_gen_dupi_vec(vece
, a
, 0);
4128 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, d
, d
, a
);
4131 void gen_gvec_cmtst(unsigned vece
, uint32_t rd_ofs
, uint32_t rn_ofs
,
4132 uint32_t rm_ofs
, uint32_t opr_sz
, uint32_t max_sz
)
4134 static const TCGOpcode vecop_list
[] = { INDEX_op_cmp_vec
, 0 };
4135 static const GVecGen3 ops
[4] = {
4136 { .fni4
= gen_helper_neon_tst_u8
,
4137 .fniv
= gen_cmtst_vec
,
4138 .opt_opc
= vecop_list
,
4140 { .fni4
= gen_helper_neon_tst_u16
,
4141 .fniv
= gen_cmtst_vec
,
4142 .opt_opc
= vecop_list
,
4144 { .fni4
= gen_cmtst_i32
,
4145 .fniv
= gen_cmtst_vec
,
4146 .opt_opc
= vecop_list
,
4148 { .fni8
= gen_cmtst_i64
,
4149 .fniv
= gen_cmtst_vec
,
4150 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
4151 .opt_opc
= vecop_list
,
4154 tcg_gen_gvec_3(rd_ofs
, rn_ofs
, rm_ofs
, opr_sz
, max_sz
, &ops
[vece
]);
4157 void gen_ushl_i32(TCGv_i32 dst
, TCGv_i32 src
, TCGv_i32 shift
)
4159 TCGv_i32 lval
= tcg_temp_new_i32();
4160 TCGv_i32 rval
= tcg_temp_new_i32();
4161 TCGv_i32 lsh
= tcg_temp_new_i32();
4162 TCGv_i32 rsh
= tcg_temp_new_i32();
4163 TCGv_i32 zero
= tcg_const_i32(0);
4164 TCGv_i32 max
= tcg_const_i32(32);
4167 * Rely on the TCG guarantee that out of range shifts produce
4168 * unspecified results, not undefined behaviour (i.e. no trap).
4169 * Discard out-of-range results after the fact.
4171 tcg_gen_ext8s_i32(lsh
, shift
);
4172 tcg_gen_neg_i32(rsh
, lsh
);
4173 tcg_gen_shl_i32(lval
, src
, lsh
);
4174 tcg_gen_shr_i32(rval
, src
, rsh
);
4175 tcg_gen_movcond_i32(TCG_COND_LTU
, dst
, lsh
, max
, lval
, zero
);
4176 tcg_gen_movcond_i32(TCG_COND_LTU
, dst
, rsh
, max
, rval
, dst
);
4178 tcg_temp_free_i32(lval
);
4179 tcg_temp_free_i32(rval
);
4180 tcg_temp_free_i32(lsh
);
4181 tcg_temp_free_i32(rsh
);
4182 tcg_temp_free_i32(zero
);
4183 tcg_temp_free_i32(max
);
4186 void gen_ushl_i64(TCGv_i64 dst
, TCGv_i64 src
, TCGv_i64 shift
)
4188 TCGv_i64 lval
= tcg_temp_new_i64();
4189 TCGv_i64 rval
= tcg_temp_new_i64();
4190 TCGv_i64 lsh
= tcg_temp_new_i64();
4191 TCGv_i64 rsh
= tcg_temp_new_i64();
4192 TCGv_i64 zero
= tcg_const_i64(0);
4193 TCGv_i64 max
= tcg_const_i64(64);
4196 * Rely on the TCG guarantee that out of range shifts produce
4197 * unspecified results, not undefined behaviour (i.e. no trap).
4198 * Discard out-of-range results after the fact.
4200 tcg_gen_ext8s_i64(lsh
, shift
);
4201 tcg_gen_neg_i64(rsh
, lsh
);
4202 tcg_gen_shl_i64(lval
, src
, lsh
);
4203 tcg_gen_shr_i64(rval
, src
, rsh
);
4204 tcg_gen_movcond_i64(TCG_COND_LTU
, dst
, lsh
, max
, lval
, zero
);
4205 tcg_gen_movcond_i64(TCG_COND_LTU
, dst
, rsh
, max
, rval
, dst
);
4207 tcg_temp_free_i64(lval
);
4208 tcg_temp_free_i64(rval
);
4209 tcg_temp_free_i64(lsh
);
4210 tcg_temp_free_i64(rsh
);
4211 tcg_temp_free_i64(zero
);
4212 tcg_temp_free_i64(max
);
4215 static void gen_ushl_vec(unsigned vece
, TCGv_vec dst
,
4216 TCGv_vec src
, TCGv_vec shift
)
4218 TCGv_vec lval
= tcg_temp_new_vec_matching(dst
);
4219 TCGv_vec rval
= tcg_temp_new_vec_matching(dst
);
4220 TCGv_vec lsh
= tcg_temp_new_vec_matching(dst
);
4221 TCGv_vec rsh
= tcg_temp_new_vec_matching(dst
);
4224 tcg_gen_neg_vec(vece
, rsh
, shift
);
4226 tcg_gen_mov_vec(lsh
, shift
);
4228 msk
= tcg_temp_new_vec_matching(dst
);
4229 tcg_gen_dupi_vec(vece
, msk
, 0xff);
4230 tcg_gen_and_vec(vece
, lsh
, shift
, msk
);
4231 tcg_gen_and_vec(vece
, rsh
, rsh
, msk
);
4232 tcg_temp_free_vec(msk
);
4236 * Rely on the TCG guarantee that out of range shifts produce
4237 * unspecified results, not undefined behaviour (i.e. no trap).
4238 * Discard out-of-range results after the fact.
4240 tcg_gen_shlv_vec(vece
, lval
, src
, lsh
);
4241 tcg_gen_shrv_vec(vece
, rval
, src
, rsh
);
4243 max
= tcg_temp_new_vec_matching(dst
);
4244 tcg_gen_dupi_vec(vece
, max
, 8 << vece
);
4247 * The choice of LT (signed) and GEU (unsigned) are biased toward
4248 * the instructions of the x86_64 host. For MO_8, the whole byte
4249 * is significant so we must use an unsigned compare; otherwise we
4250 * have already masked to a byte and so a signed compare works.
4251 * Other tcg hosts have a full set of comparisons and do not care.
4254 tcg_gen_cmp_vec(TCG_COND_GEU
, vece
, lsh
, lsh
, max
);
4255 tcg_gen_cmp_vec(TCG_COND_GEU
, vece
, rsh
, rsh
, max
);
4256 tcg_gen_andc_vec(vece
, lval
, lval
, lsh
);
4257 tcg_gen_andc_vec(vece
, rval
, rval
, rsh
);
4259 tcg_gen_cmp_vec(TCG_COND_LT
, vece
, lsh
, lsh
, max
);
4260 tcg_gen_cmp_vec(TCG_COND_LT
, vece
, rsh
, rsh
, max
);
4261 tcg_gen_and_vec(vece
, lval
, lval
, lsh
);
4262 tcg_gen_and_vec(vece
, rval
, rval
, rsh
);
4264 tcg_gen_or_vec(vece
, dst
, lval
, rval
);
4266 tcg_temp_free_vec(max
);
4267 tcg_temp_free_vec(lval
);
4268 tcg_temp_free_vec(rval
);
4269 tcg_temp_free_vec(lsh
);
4270 tcg_temp_free_vec(rsh
);
4273 void gen_gvec_ushl(unsigned vece
, uint32_t rd_ofs
, uint32_t rn_ofs
,
4274 uint32_t rm_ofs
, uint32_t opr_sz
, uint32_t max_sz
)
4276 static const TCGOpcode vecop_list
[] = {
4277 INDEX_op_neg_vec
, INDEX_op_shlv_vec
,
4278 INDEX_op_shrv_vec
, INDEX_op_cmp_vec
, 0
4280 static const GVecGen3 ops
[4] = {
4281 { .fniv
= gen_ushl_vec
,
4282 .fno
= gen_helper_gvec_ushl_b
,
4283 .opt_opc
= vecop_list
,
4285 { .fniv
= gen_ushl_vec
,
4286 .fno
= gen_helper_gvec_ushl_h
,
4287 .opt_opc
= vecop_list
,
4289 { .fni4
= gen_ushl_i32
,
4290 .fniv
= gen_ushl_vec
,
4291 .opt_opc
= vecop_list
,
4293 { .fni8
= gen_ushl_i64
,
4294 .fniv
= gen_ushl_vec
,
4295 .opt_opc
= vecop_list
,
4298 tcg_gen_gvec_3(rd_ofs
, rn_ofs
, rm_ofs
, opr_sz
, max_sz
, &ops
[vece
]);
4301 void gen_sshl_i32(TCGv_i32 dst
, TCGv_i32 src
, TCGv_i32 shift
)
4303 TCGv_i32 lval
= tcg_temp_new_i32();
4304 TCGv_i32 rval
= tcg_temp_new_i32();
4305 TCGv_i32 lsh
= tcg_temp_new_i32();
4306 TCGv_i32 rsh
= tcg_temp_new_i32();
4307 TCGv_i32 zero
= tcg_const_i32(0);
4308 TCGv_i32 max
= tcg_const_i32(31);
4311 * Rely on the TCG guarantee that out of range shifts produce
4312 * unspecified results, not undefined behaviour (i.e. no trap).
4313 * Discard out-of-range results after the fact.
4315 tcg_gen_ext8s_i32(lsh
, shift
);
4316 tcg_gen_neg_i32(rsh
, lsh
);
4317 tcg_gen_shl_i32(lval
, src
, lsh
);
4318 tcg_gen_umin_i32(rsh
, rsh
, max
);
4319 tcg_gen_sar_i32(rval
, src
, rsh
);
4320 tcg_gen_movcond_i32(TCG_COND_LEU
, lval
, lsh
, max
, lval
, zero
);
4321 tcg_gen_movcond_i32(TCG_COND_LT
, dst
, lsh
, zero
, rval
, lval
);
4323 tcg_temp_free_i32(lval
);
4324 tcg_temp_free_i32(rval
);
4325 tcg_temp_free_i32(lsh
);
4326 tcg_temp_free_i32(rsh
);
4327 tcg_temp_free_i32(zero
);
4328 tcg_temp_free_i32(max
);
4331 void gen_sshl_i64(TCGv_i64 dst
, TCGv_i64 src
, TCGv_i64 shift
)
4333 TCGv_i64 lval
= tcg_temp_new_i64();
4334 TCGv_i64 rval
= tcg_temp_new_i64();
4335 TCGv_i64 lsh
= tcg_temp_new_i64();
4336 TCGv_i64 rsh
= tcg_temp_new_i64();
4337 TCGv_i64 zero
= tcg_const_i64(0);
4338 TCGv_i64 max
= tcg_const_i64(63);
4341 * Rely on the TCG guarantee that out of range shifts produce
4342 * unspecified results, not undefined behaviour (i.e. no trap).
4343 * Discard out-of-range results after the fact.
4345 tcg_gen_ext8s_i64(lsh
, shift
);
4346 tcg_gen_neg_i64(rsh
, lsh
);
4347 tcg_gen_shl_i64(lval
, src
, lsh
);
4348 tcg_gen_umin_i64(rsh
, rsh
, max
);
4349 tcg_gen_sar_i64(rval
, src
, rsh
);
4350 tcg_gen_movcond_i64(TCG_COND_LEU
, lval
, lsh
, max
, lval
, zero
);
4351 tcg_gen_movcond_i64(TCG_COND_LT
, dst
, lsh
, zero
, rval
, lval
);
4353 tcg_temp_free_i64(lval
);
4354 tcg_temp_free_i64(rval
);
4355 tcg_temp_free_i64(lsh
);
4356 tcg_temp_free_i64(rsh
);
4357 tcg_temp_free_i64(zero
);
4358 tcg_temp_free_i64(max
);
4361 static void gen_sshl_vec(unsigned vece
, TCGv_vec dst
,
4362 TCGv_vec src
, TCGv_vec shift
)
4364 TCGv_vec lval
= tcg_temp_new_vec_matching(dst
);
4365 TCGv_vec rval
= tcg_temp_new_vec_matching(dst
);
4366 TCGv_vec lsh
= tcg_temp_new_vec_matching(dst
);
4367 TCGv_vec rsh
= tcg_temp_new_vec_matching(dst
);
4368 TCGv_vec tmp
= tcg_temp_new_vec_matching(dst
);
4371 * Rely on the TCG guarantee that out of range shifts produce
4372 * unspecified results, not undefined behaviour (i.e. no trap).
4373 * Discard out-of-range results after the fact.
4375 tcg_gen_neg_vec(vece
, rsh
, shift
);
4377 tcg_gen_mov_vec(lsh
, shift
);
4379 tcg_gen_dupi_vec(vece
, tmp
, 0xff);
4380 tcg_gen_and_vec(vece
, lsh
, shift
, tmp
);
4381 tcg_gen_and_vec(vece
, rsh
, rsh
, tmp
);
4384 /* Bound rsh so out of bound right shift gets -1. */
4385 tcg_gen_dupi_vec(vece
, tmp
, (8 << vece
) - 1);
4386 tcg_gen_umin_vec(vece
, rsh
, rsh
, tmp
);
4387 tcg_gen_cmp_vec(TCG_COND_GT
, vece
, tmp
, lsh
, tmp
);
4389 tcg_gen_shlv_vec(vece
, lval
, src
, lsh
);
4390 tcg_gen_sarv_vec(vece
, rval
, src
, rsh
);
4392 /* Select in-bound left shift. */
4393 tcg_gen_andc_vec(vece
, lval
, lval
, tmp
);
4395 /* Select between left and right shift. */
4397 tcg_gen_dupi_vec(vece
, tmp
, 0);
4398 tcg_gen_cmpsel_vec(TCG_COND_LT
, vece
, dst
, lsh
, tmp
, rval
, lval
);
4400 tcg_gen_dupi_vec(vece
, tmp
, 0x80);
4401 tcg_gen_cmpsel_vec(TCG_COND_LT
, vece
, dst
, lsh
, tmp
, lval
, rval
);
4404 tcg_temp_free_vec(lval
);
4405 tcg_temp_free_vec(rval
);
4406 tcg_temp_free_vec(lsh
);
4407 tcg_temp_free_vec(rsh
);
4408 tcg_temp_free_vec(tmp
);
4411 void gen_gvec_sshl(unsigned vece
, uint32_t rd_ofs
, uint32_t rn_ofs
,
4412 uint32_t rm_ofs
, uint32_t opr_sz
, uint32_t max_sz
)
4414 static const TCGOpcode vecop_list
[] = {
4415 INDEX_op_neg_vec
, INDEX_op_umin_vec
, INDEX_op_shlv_vec
,
4416 INDEX_op_sarv_vec
, INDEX_op_cmp_vec
, INDEX_op_cmpsel_vec
, 0
4418 static const GVecGen3 ops
[4] = {
4419 { .fniv
= gen_sshl_vec
,
4420 .fno
= gen_helper_gvec_sshl_b
,
4421 .opt_opc
= vecop_list
,
4423 { .fniv
= gen_sshl_vec
,
4424 .fno
= gen_helper_gvec_sshl_h
,
4425 .opt_opc
= vecop_list
,
4427 { .fni4
= gen_sshl_i32
,
4428 .fniv
= gen_sshl_vec
,
4429 .opt_opc
= vecop_list
,
4431 { .fni8
= gen_sshl_i64
,
4432 .fniv
= gen_sshl_vec
,
4433 .opt_opc
= vecop_list
,
4436 tcg_gen_gvec_3(rd_ofs
, rn_ofs
, rm_ofs
, opr_sz
, max_sz
, &ops
[vece
]);
4439 static void gen_uqadd_vec(unsigned vece
, TCGv_vec t
, TCGv_vec sat
,
4440 TCGv_vec a
, TCGv_vec b
)
4442 TCGv_vec x
= tcg_temp_new_vec_matching(t
);
4443 tcg_gen_add_vec(vece
, x
, a
, b
);
4444 tcg_gen_usadd_vec(vece
, t
, a
, b
);
4445 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, x
, x
, t
);
4446 tcg_gen_or_vec(vece
, sat
, sat
, x
);
4447 tcg_temp_free_vec(x
);
4450 void gen_gvec_uqadd_qc(unsigned vece
, uint32_t rd_ofs
, uint32_t rn_ofs
,
4451 uint32_t rm_ofs
, uint32_t opr_sz
, uint32_t max_sz
)
4453 static const TCGOpcode vecop_list
[] = {
4454 INDEX_op_usadd_vec
, INDEX_op_cmp_vec
, INDEX_op_add_vec
, 0
4456 static const GVecGen4 ops
[4] = {
4457 { .fniv
= gen_uqadd_vec
,
4458 .fno
= gen_helper_gvec_uqadd_b
,
4460 .opt_opc
= vecop_list
,
4462 { .fniv
= gen_uqadd_vec
,
4463 .fno
= gen_helper_gvec_uqadd_h
,
4465 .opt_opc
= vecop_list
,
4467 { .fniv
= gen_uqadd_vec
,
4468 .fno
= gen_helper_gvec_uqadd_s
,
4470 .opt_opc
= vecop_list
,
4472 { .fniv
= gen_uqadd_vec
,
4473 .fno
= gen_helper_gvec_uqadd_d
,
4475 .opt_opc
= vecop_list
,
4478 tcg_gen_gvec_4(rd_ofs
, offsetof(CPUARMState
, vfp
.qc
),
4479 rn_ofs
, rm_ofs
, opr_sz
, max_sz
, &ops
[vece
]);
4482 static void gen_sqadd_vec(unsigned vece
, TCGv_vec t
, TCGv_vec sat
,
4483 TCGv_vec a
, TCGv_vec b
)
4485 TCGv_vec x
= tcg_temp_new_vec_matching(t
);
4486 tcg_gen_add_vec(vece
, x
, a
, b
);
4487 tcg_gen_ssadd_vec(vece
, t
, a
, b
);
4488 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, x
, x
, t
);
4489 tcg_gen_or_vec(vece
, sat
, sat
, x
);
4490 tcg_temp_free_vec(x
);
4493 void gen_gvec_sqadd_qc(unsigned vece
, uint32_t rd_ofs
, uint32_t rn_ofs
,
4494 uint32_t rm_ofs
, uint32_t opr_sz
, uint32_t max_sz
)
4496 static const TCGOpcode vecop_list
[] = {
4497 INDEX_op_ssadd_vec
, INDEX_op_cmp_vec
, INDEX_op_add_vec
, 0
4499 static const GVecGen4 ops
[4] = {
4500 { .fniv
= gen_sqadd_vec
,
4501 .fno
= gen_helper_gvec_sqadd_b
,
4502 .opt_opc
= vecop_list
,
4505 { .fniv
= gen_sqadd_vec
,
4506 .fno
= gen_helper_gvec_sqadd_h
,
4507 .opt_opc
= vecop_list
,
4510 { .fniv
= gen_sqadd_vec
,
4511 .fno
= gen_helper_gvec_sqadd_s
,
4512 .opt_opc
= vecop_list
,
4515 { .fniv
= gen_sqadd_vec
,
4516 .fno
= gen_helper_gvec_sqadd_d
,
4517 .opt_opc
= vecop_list
,
4521 tcg_gen_gvec_4(rd_ofs
, offsetof(CPUARMState
, vfp
.qc
),
4522 rn_ofs
, rm_ofs
, opr_sz
, max_sz
, &ops
[vece
]);
4525 static void gen_uqsub_vec(unsigned vece
, TCGv_vec t
, TCGv_vec sat
,
4526 TCGv_vec a
, TCGv_vec b
)
4528 TCGv_vec x
= tcg_temp_new_vec_matching(t
);
4529 tcg_gen_sub_vec(vece
, x
, a
, b
);
4530 tcg_gen_ussub_vec(vece
, t
, a
, b
);
4531 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, x
, x
, t
);
4532 tcg_gen_or_vec(vece
, sat
, sat
, x
);
4533 tcg_temp_free_vec(x
);
4536 void gen_gvec_uqsub_qc(unsigned vece
, uint32_t rd_ofs
, uint32_t rn_ofs
,
4537 uint32_t rm_ofs
, uint32_t opr_sz
, uint32_t max_sz
)
4539 static const TCGOpcode vecop_list
[] = {
4540 INDEX_op_ussub_vec
, INDEX_op_cmp_vec
, INDEX_op_sub_vec
, 0
4542 static const GVecGen4 ops
[4] = {
4543 { .fniv
= gen_uqsub_vec
,
4544 .fno
= gen_helper_gvec_uqsub_b
,
4545 .opt_opc
= vecop_list
,
4548 { .fniv
= gen_uqsub_vec
,
4549 .fno
= gen_helper_gvec_uqsub_h
,
4550 .opt_opc
= vecop_list
,
4553 { .fniv
= gen_uqsub_vec
,
4554 .fno
= gen_helper_gvec_uqsub_s
,
4555 .opt_opc
= vecop_list
,
4558 { .fniv
= gen_uqsub_vec
,
4559 .fno
= gen_helper_gvec_uqsub_d
,
4560 .opt_opc
= vecop_list
,
4564 tcg_gen_gvec_4(rd_ofs
, offsetof(CPUARMState
, vfp
.qc
),
4565 rn_ofs
, rm_ofs
, opr_sz
, max_sz
, &ops
[vece
]);
4568 static void gen_sqsub_vec(unsigned vece
, TCGv_vec t
, TCGv_vec sat
,
4569 TCGv_vec a
, TCGv_vec b
)
4571 TCGv_vec x
= tcg_temp_new_vec_matching(t
);
4572 tcg_gen_sub_vec(vece
, x
, a
, b
);
4573 tcg_gen_sssub_vec(vece
, t
, a
, b
);
4574 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, x
, x
, t
);
4575 tcg_gen_or_vec(vece
, sat
, sat
, x
);
4576 tcg_temp_free_vec(x
);
4579 void gen_gvec_sqsub_qc(unsigned vece
, uint32_t rd_ofs
, uint32_t rn_ofs
,
4580 uint32_t rm_ofs
, uint32_t opr_sz
, uint32_t max_sz
)
4582 static const TCGOpcode vecop_list
[] = {
4583 INDEX_op_sssub_vec
, INDEX_op_cmp_vec
, INDEX_op_sub_vec
, 0
4585 static const GVecGen4 ops
[4] = {
4586 { .fniv
= gen_sqsub_vec
,
4587 .fno
= gen_helper_gvec_sqsub_b
,
4588 .opt_opc
= vecop_list
,
4591 { .fniv
= gen_sqsub_vec
,
4592 .fno
= gen_helper_gvec_sqsub_h
,
4593 .opt_opc
= vecop_list
,
4596 { .fniv
= gen_sqsub_vec
,
4597 .fno
= gen_helper_gvec_sqsub_s
,
4598 .opt_opc
= vecop_list
,
4601 { .fniv
= gen_sqsub_vec
,
4602 .fno
= gen_helper_gvec_sqsub_d
,
4603 .opt_opc
= vecop_list
,
4607 tcg_gen_gvec_4(rd_ofs
, offsetof(CPUARMState
, vfp
.qc
),
4608 rn_ofs
, rm_ofs
, opr_sz
, max_sz
, &ops
[vece
]);
4611 static void gen_sabd_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
4613 TCGv_i32 t
= tcg_temp_new_i32();
4615 tcg_gen_sub_i32(t
, a
, b
);
4616 tcg_gen_sub_i32(d
, b
, a
);
4617 tcg_gen_movcond_i32(TCG_COND_LT
, d
, a
, b
, d
, t
);
4618 tcg_temp_free_i32(t
);
4621 static void gen_sabd_i64(TCGv_i64 d
, TCGv_i64 a
, TCGv_i64 b
)
4623 TCGv_i64 t
= tcg_temp_new_i64();
4625 tcg_gen_sub_i64(t
, a
, b
);
4626 tcg_gen_sub_i64(d
, b
, a
);
4627 tcg_gen_movcond_i64(TCG_COND_LT
, d
, a
, b
, d
, t
);
4628 tcg_temp_free_i64(t
);
4631 static void gen_sabd_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, TCGv_vec b
)
4633 TCGv_vec t
= tcg_temp_new_vec_matching(d
);
4635 tcg_gen_smin_vec(vece
, t
, a
, b
);
4636 tcg_gen_smax_vec(vece
, d
, a
, b
);
4637 tcg_gen_sub_vec(vece
, d
, d
, t
);
4638 tcg_temp_free_vec(t
);
4641 void gen_gvec_sabd(unsigned vece
, uint32_t rd_ofs
, uint32_t rn_ofs
,
4642 uint32_t rm_ofs
, uint32_t opr_sz
, uint32_t max_sz
)
4644 static const TCGOpcode vecop_list
[] = {
4645 INDEX_op_sub_vec
, INDEX_op_smin_vec
, INDEX_op_smax_vec
, 0
4647 static const GVecGen3 ops
[4] = {
4648 { .fniv
= gen_sabd_vec
,
4649 .fno
= gen_helper_gvec_sabd_b
,
4650 .opt_opc
= vecop_list
,
4652 { .fniv
= gen_sabd_vec
,
4653 .fno
= gen_helper_gvec_sabd_h
,
4654 .opt_opc
= vecop_list
,
4656 { .fni4
= gen_sabd_i32
,
4657 .fniv
= gen_sabd_vec
,
4658 .fno
= gen_helper_gvec_sabd_s
,
4659 .opt_opc
= vecop_list
,
4661 { .fni8
= gen_sabd_i64
,
4662 .fniv
= gen_sabd_vec
,
4663 .fno
= gen_helper_gvec_sabd_d
,
4664 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
4665 .opt_opc
= vecop_list
,
4668 tcg_gen_gvec_3(rd_ofs
, rn_ofs
, rm_ofs
, opr_sz
, max_sz
, &ops
[vece
]);
4671 static void gen_uabd_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
4673 TCGv_i32 t
= tcg_temp_new_i32();
4675 tcg_gen_sub_i32(t
, a
, b
);
4676 tcg_gen_sub_i32(d
, b
, a
);
4677 tcg_gen_movcond_i32(TCG_COND_LTU
, d
, a
, b
, d
, t
);
4678 tcg_temp_free_i32(t
);
4681 static void gen_uabd_i64(TCGv_i64 d
, TCGv_i64 a
, TCGv_i64 b
)
4683 TCGv_i64 t
= tcg_temp_new_i64();
4685 tcg_gen_sub_i64(t
, a
, b
);
4686 tcg_gen_sub_i64(d
, b
, a
);
4687 tcg_gen_movcond_i64(TCG_COND_LTU
, d
, a
, b
, d
, t
);
4688 tcg_temp_free_i64(t
);
4691 static void gen_uabd_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, TCGv_vec b
)
4693 TCGv_vec t
= tcg_temp_new_vec_matching(d
);
4695 tcg_gen_umin_vec(vece
, t
, a
, b
);
4696 tcg_gen_umax_vec(vece
, d
, a
, b
);
4697 tcg_gen_sub_vec(vece
, d
, d
, t
);
4698 tcg_temp_free_vec(t
);
4701 void gen_gvec_uabd(unsigned vece
, uint32_t rd_ofs
, uint32_t rn_ofs
,
4702 uint32_t rm_ofs
, uint32_t opr_sz
, uint32_t max_sz
)
4704 static const TCGOpcode vecop_list
[] = {
4705 INDEX_op_sub_vec
, INDEX_op_umin_vec
, INDEX_op_umax_vec
, 0
4707 static const GVecGen3 ops
[4] = {
4708 { .fniv
= gen_uabd_vec
,
4709 .fno
= gen_helper_gvec_uabd_b
,
4710 .opt_opc
= vecop_list
,
4712 { .fniv
= gen_uabd_vec
,
4713 .fno
= gen_helper_gvec_uabd_h
,
4714 .opt_opc
= vecop_list
,
4716 { .fni4
= gen_uabd_i32
,
4717 .fniv
= gen_uabd_vec
,
4718 .fno
= gen_helper_gvec_uabd_s
,
4719 .opt_opc
= vecop_list
,
4721 { .fni8
= gen_uabd_i64
,
4722 .fniv
= gen_uabd_vec
,
4723 .fno
= gen_helper_gvec_uabd_d
,
4724 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
4725 .opt_opc
= vecop_list
,
4728 tcg_gen_gvec_3(rd_ofs
, rn_ofs
, rm_ofs
, opr_sz
, max_sz
, &ops
[vece
]);
4731 static void gen_saba_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
4733 TCGv_i32 t
= tcg_temp_new_i32();
4734 gen_sabd_i32(t
, a
, b
);
4735 tcg_gen_add_i32(d
, d
, t
);
4736 tcg_temp_free_i32(t
);
4739 static void gen_saba_i64(TCGv_i64 d
, TCGv_i64 a
, TCGv_i64 b
)
4741 TCGv_i64 t
= tcg_temp_new_i64();
4742 gen_sabd_i64(t
, a
, b
);
4743 tcg_gen_add_i64(d
, d
, t
);
4744 tcg_temp_free_i64(t
);
4747 static void gen_saba_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, TCGv_vec b
)
4749 TCGv_vec t
= tcg_temp_new_vec_matching(d
);
4750 gen_sabd_vec(vece
, t
, a
, b
);
4751 tcg_gen_add_vec(vece
, d
, d
, t
);
4752 tcg_temp_free_vec(t
);
4755 void gen_gvec_saba(unsigned vece
, uint32_t rd_ofs
, uint32_t rn_ofs
,
4756 uint32_t rm_ofs
, uint32_t opr_sz
, uint32_t max_sz
)
4758 static const TCGOpcode vecop_list
[] = {
4759 INDEX_op_sub_vec
, INDEX_op_add_vec
,
4760 INDEX_op_smin_vec
, INDEX_op_smax_vec
, 0
4762 static const GVecGen3 ops
[4] = {
4763 { .fniv
= gen_saba_vec
,
4764 .fno
= gen_helper_gvec_saba_b
,
4765 .opt_opc
= vecop_list
,
4768 { .fniv
= gen_saba_vec
,
4769 .fno
= gen_helper_gvec_saba_h
,
4770 .opt_opc
= vecop_list
,
4773 { .fni4
= gen_saba_i32
,
4774 .fniv
= gen_saba_vec
,
4775 .fno
= gen_helper_gvec_saba_s
,
4776 .opt_opc
= vecop_list
,
4779 { .fni8
= gen_saba_i64
,
4780 .fniv
= gen_saba_vec
,
4781 .fno
= gen_helper_gvec_saba_d
,
4782 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
4783 .opt_opc
= vecop_list
,
4787 tcg_gen_gvec_3(rd_ofs
, rn_ofs
, rm_ofs
, opr_sz
, max_sz
, &ops
[vece
]);
4790 static void gen_uaba_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
4792 TCGv_i32 t
= tcg_temp_new_i32();
4793 gen_uabd_i32(t
, a
, b
);
4794 tcg_gen_add_i32(d
, d
, t
);
4795 tcg_temp_free_i32(t
);
4798 static void gen_uaba_i64(TCGv_i64 d
, TCGv_i64 a
, TCGv_i64 b
)
4800 TCGv_i64 t
= tcg_temp_new_i64();
4801 gen_uabd_i64(t
, a
, b
);
4802 tcg_gen_add_i64(d
, d
, t
);
4803 tcg_temp_free_i64(t
);
4806 static void gen_uaba_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, TCGv_vec b
)
4808 TCGv_vec t
= tcg_temp_new_vec_matching(d
);
4809 gen_uabd_vec(vece
, t
, a
, b
);
4810 tcg_gen_add_vec(vece
, d
, d
, t
);
4811 tcg_temp_free_vec(t
);
4814 void gen_gvec_uaba(unsigned vece
, uint32_t rd_ofs
, uint32_t rn_ofs
,
4815 uint32_t rm_ofs
, uint32_t opr_sz
, uint32_t max_sz
)
4817 static const TCGOpcode vecop_list
[] = {
4818 INDEX_op_sub_vec
, INDEX_op_add_vec
,
4819 INDEX_op_umin_vec
, INDEX_op_umax_vec
, 0
4821 static const GVecGen3 ops
[4] = {
4822 { .fniv
= gen_uaba_vec
,
4823 .fno
= gen_helper_gvec_uaba_b
,
4824 .opt_opc
= vecop_list
,
4827 { .fniv
= gen_uaba_vec
,
4828 .fno
= gen_helper_gvec_uaba_h
,
4829 .opt_opc
= vecop_list
,
4832 { .fni4
= gen_uaba_i32
,
4833 .fniv
= gen_uaba_vec
,
4834 .fno
= gen_helper_gvec_uaba_s
,
4835 .opt_opc
= vecop_list
,
4838 { .fni8
= gen_uaba_i64
,
4839 .fniv
= gen_uaba_vec
,
4840 .fno
= gen_helper_gvec_uaba_d
,
4841 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
4842 .opt_opc
= vecop_list
,
4846 tcg_gen_gvec_3(rd_ofs
, rn_ofs
, rm_ofs
, opr_sz
, max_sz
, &ops
[vece
]);
4849 /* Translate a NEON data processing instruction. Return nonzero if the
4850 instruction is invalid.
4851 We process data in a mixture of 32-bit and 64-bit chunks.
4852 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4854 static int disas_neon_data_insn(DisasContext
*s
, uint32_t insn
)
4858 int rd
, rm
, rd_ofs
, rm_ofs
;
4863 TCGv_i32 tmp
, tmp2
, tmp3
;
4865 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
4869 /* FIXME: this access check should not take precedence over UNDEF
4870 * for invalid encodings; we will generate incorrect syndrome information
4871 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4873 if (s
->fp_excp_el
) {
4874 gen_exception_insn(s
, s
->pc_curr
, EXCP_UDEF
,
4875 syn_simd_access_trap(1, 0xe, false), s
->fp_excp_el
);
4879 if (!s
->vfp_enabled
)
4881 q
= (insn
& (1 << 6)) != 0;
4882 u
= (insn
>> 24) & 1;
4883 VFP_DREG_D(rd
, insn
);
4884 VFP_DREG_M(rm
, insn
);
4885 size
= (insn
>> 20) & 3;
4886 vec_size
= q
? 16 : 8;
4887 rd_ofs
= neon_reg_offset(rd
, 0);
4888 rm_ofs
= neon_reg_offset(rm
, 0);
4890 if ((insn
& (1 << 23)) == 0) {
4891 /* Three register same length: handled by decodetree */
4893 } else if (insn
& (1 << 4)) {
4894 /* Two registers and shift or reg and imm: handled by decodetree */
4896 } else { /* (insn & 0x00800010 == 0x00800000) */
4899 * Three registers of different lengths, or two registers and
4900 * a scalar: handled by decodetree
4903 } else { /* size == 3 */
4905 /* Extract: handled by decodetree */
4907 } else if ((insn
& (1 << 11)) == 0) {
4908 /* Two register misc. */
4909 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
4910 size
= (insn
>> 18) & 3;
4911 /* UNDEF for unknown op values and bad op-size combinations */
4912 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
4915 if (neon_2rm_is_v8_op(op
) &&
4916 !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
4919 if (q
&& ((rm
| rd
) & 1)) {
4923 case NEON_2RM_VREV64
:
4924 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
4925 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
4928 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
4929 case NEON_2RM_VSHLL
:
4930 /* handled by decodetree */
4935 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
4936 tmp
= neon_load_reg(rm
, n
);
4937 tmp2
= neon_load_reg(rd
, n
+ 1);
4938 neon_store_reg(rm
, n
, tmp2
);
4939 neon_store_reg(rd
, n
+ 1, tmp
);
4945 case NEON_2RM_VCVT_F16_F32
:
4950 if (!dc_isar_feature(aa32_fp16_spconv
, s
) ||
4954 fpst
= get_fpstatus_ptr(true);
4955 ahp
= get_ahp_flag();
4956 tmp
= neon_load_reg(rm
, 0);
4957 gen_helper_vfp_fcvt_f32_to_f16(tmp
, tmp
, fpst
, ahp
);
4958 tmp2
= neon_load_reg(rm
, 1);
4959 gen_helper_vfp_fcvt_f32_to_f16(tmp2
, tmp2
, fpst
, ahp
);
4960 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
4961 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
4962 tcg_temp_free_i32(tmp
);
4963 tmp
= neon_load_reg(rm
, 2);
4964 gen_helper_vfp_fcvt_f32_to_f16(tmp
, tmp
, fpst
, ahp
);
4965 tmp3
= neon_load_reg(rm
, 3);
4966 neon_store_reg(rd
, 0, tmp2
);
4967 gen_helper_vfp_fcvt_f32_to_f16(tmp3
, tmp3
, fpst
, ahp
);
4968 tcg_gen_shli_i32(tmp3
, tmp3
, 16);
4969 tcg_gen_or_i32(tmp3
, tmp3
, tmp
);
4970 neon_store_reg(rd
, 1, tmp3
);
4971 tcg_temp_free_i32(tmp
);
4972 tcg_temp_free_i32(ahp
);
4973 tcg_temp_free_ptr(fpst
);
4976 case NEON_2RM_VCVT_F32_F16
:
4980 if (!dc_isar_feature(aa32_fp16_spconv
, s
) ||
4984 fpst
= get_fpstatus_ptr(true);
4985 ahp
= get_ahp_flag();
4986 tmp3
= tcg_temp_new_i32();
4987 tmp
= neon_load_reg(rm
, 0);
4988 tmp2
= neon_load_reg(rm
, 1);
4989 tcg_gen_ext16u_i32(tmp3
, tmp
);
4990 gen_helper_vfp_fcvt_f16_to_f32(tmp3
, tmp3
, fpst
, ahp
);
4991 neon_store_reg(rd
, 0, tmp3
);
4992 tcg_gen_shri_i32(tmp
, tmp
, 16);
4993 gen_helper_vfp_fcvt_f16_to_f32(tmp
, tmp
, fpst
, ahp
);
4994 neon_store_reg(rd
, 1, tmp
);
4995 tmp3
= tcg_temp_new_i32();
4996 tcg_gen_ext16u_i32(tmp3
, tmp2
);
4997 gen_helper_vfp_fcvt_f16_to_f32(tmp3
, tmp3
, fpst
, ahp
);
4998 neon_store_reg(rd
, 2, tmp3
);
4999 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
5000 gen_helper_vfp_fcvt_f16_to_f32(tmp2
, tmp2
, fpst
, ahp
);
5001 neon_store_reg(rd
, 3, tmp2
);
5002 tcg_temp_free_i32(ahp
);
5003 tcg_temp_free_ptr(fpst
);
5006 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
5007 if (!dc_isar_feature(aa32_aes
, s
) || ((rm
| rd
) & 1)) {
5011 * Bit 6 is the lowest opcode bit; it distinguishes
5012 * between encryption (AESE/AESMC) and decryption
5015 if (op
== NEON_2RM_AESE
) {
5016 tcg_gen_gvec_3_ool(vfp_reg_offset(true, rd
),
5017 vfp_reg_offset(true, rd
),
5018 vfp_reg_offset(true, rm
),
5019 16, 16, extract32(insn
, 6, 1),
5020 gen_helper_crypto_aese
);
5022 tcg_gen_gvec_2_ool(vfp_reg_offset(true, rd
),
5023 vfp_reg_offset(true, rm
),
5024 16, 16, extract32(insn
, 6, 1),
5025 gen_helper_crypto_aesmc
);
5028 case NEON_2RM_SHA1H
:
5029 if (!dc_isar_feature(aa32_sha1
, s
) || ((rm
| rd
) & 1)) {
5032 tcg_gen_gvec_2_ool(rd_ofs
, rm_ofs
, 16, 16, 0,
5033 gen_helper_crypto_sha1h
);
5035 case NEON_2RM_SHA1SU1
:
5036 if ((rm
| rd
) & 1) {
5039 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
5041 if (!dc_isar_feature(aa32_sha2
, s
)) {
5044 } else if (!dc_isar_feature(aa32_sha1
, s
)) {
5047 tcg_gen_gvec_2_ool(rd_ofs
, rm_ofs
, 16, 16, 0,
5048 q
? gen_helper_crypto_sha256su0
5049 : gen_helper_crypto_sha1su1
);
5052 tcg_gen_gvec_not(0, rd_ofs
, rm_ofs
, vec_size
, vec_size
);
5055 tcg_gen_gvec_neg(size
, rd_ofs
, rm_ofs
, vec_size
, vec_size
);
5058 tcg_gen_gvec_abs(size
, rd_ofs
, rm_ofs
, vec_size
, vec_size
);
5061 case NEON_2RM_VCEQ0
:
5062 gen_gvec_ceq0(size
, rd_ofs
, rm_ofs
, vec_size
, vec_size
);
5064 case NEON_2RM_VCGT0
:
5065 gen_gvec_cgt0(size
, rd_ofs
, rm_ofs
, vec_size
, vec_size
);
5067 case NEON_2RM_VCLE0
:
5068 gen_gvec_cle0(size
, rd_ofs
, rm_ofs
, vec_size
, vec_size
);
5070 case NEON_2RM_VCGE0
:
5071 gen_gvec_cge0(size
, rd_ofs
, rm_ofs
, vec_size
, vec_size
);
5073 case NEON_2RM_VCLT0
:
5074 gen_gvec_clt0(size
, rd_ofs
, rm_ofs
, vec_size
, vec_size
);
5079 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5080 tmp
= neon_load_reg(rm
, pass
);
5082 case NEON_2RM_VREV32
:
5084 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
5085 case 1: gen_swap_half(tmp
); break;
5089 case NEON_2RM_VREV16
:
5090 gen_rev16(tmp
, tmp
);
5094 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
5095 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
5096 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
5102 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
5103 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
5104 case 2: tcg_gen_clzi_i32(tmp
, tmp
, 32); break;
5109 gen_helper_neon_cnt_u8(tmp
, tmp
);
5111 case NEON_2RM_VQABS
:
5114 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
5117 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
5120 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
5125 case NEON_2RM_VQNEG
:
5128 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
5131 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
5134 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
5139 case NEON_2RM_VCGT0_F
:
5141 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5142 tmp2
= tcg_const_i32(0);
5143 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5144 tcg_temp_free_i32(tmp2
);
5145 tcg_temp_free_ptr(fpstatus
);
5148 case NEON_2RM_VCGE0_F
:
5150 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5151 tmp2
= tcg_const_i32(0);
5152 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5153 tcg_temp_free_i32(tmp2
);
5154 tcg_temp_free_ptr(fpstatus
);
5157 case NEON_2RM_VCEQ0_F
:
5159 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5160 tmp2
= tcg_const_i32(0);
5161 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
5162 tcg_temp_free_i32(tmp2
);
5163 tcg_temp_free_ptr(fpstatus
);
5166 case NEON_2RM_VCLE0_F
:
5168 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5169 tmp2
= tcg_const_i32(0);
5170 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
5171 tcg_temp_free_i32(tmp2
);
5172 tcg_temp_free_ptr(fpstatus
);
5175 case NEON_2RM_VCLT0_F
:
5177 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5178 tmp2
= tcg_const_i32(0);
5179 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
5180 tcg_temp_free_i32(tmp2
);
5181 tcg_temp_free_ptr(fpstatus
);
5184 case NEON_2RM_VABS_F
:
5185 gen_helper_vfp_abss(tmp
, tmp
);
5187 case NEON_2RM_VNEG_F
:
5188 gen_helper_vfp_negs(tmp
, tmp
);
5191 tmp2
= neon_load_reg(rd
, pass
);
5192 neon_store_reg(rm
, pass
, tmp2
);
5195 tmp2
= neon_load_reg(rd
, pass
);
5197 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
5198 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
5201 neon_store_reg(rm
, pass
, tmp2
);
5203 case NEON_2RM_VRINTN
:
5204 case NEON_2RM_VRINTA
:
5205 case NEON_2RM_VRINTM
:
5206 case NEON_2RM_VRINTP
:
5207 case NEON_2RM_VRINTZ
:
5210 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5213 if (op
== NEON_2RM_VRINTZ
) {
5214 rmode
= FPROUNDING_ZERO
;
5216 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
5219 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
5220 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
5222 gen_helper_rints(tmp
, tmp
, fpstatus
);
5223 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
5225 tcg_temp_free_ptr(fpstatus
);
5226 tcg_temp_free_i32(tcg_rmode
);
5229 case NEON_2RM_VRINTX
:
5231 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5232 gen_helper_rints_exact(tmp
, tmp
, fpstatus
);
5233 tcg_temp_free_ptr(fpstatus
);
5236 case NEON_2RM_VCVTAU
:
5237 case NEON_2RM_VCVTAS
:
5238 case NEON_2RM_VCVTNU
:
5239 case NEON_2RM_VCVTNS
:
5240 case NEON_2RM_VCVTPU
:
5241 case NEON_2RM_VCVTPS
:
5242 case NEON_2RM_VCVTMU
:
5243 case NEON_2RM_VCVTMS
:
5245 bool is_signed
= !extract32(insn
, 7, 1);
5246 TCGv_ptr fpst
= get_fpstatus_ptr(1);
5247 TCGv_i32 tcg_rmode
, tcg_shift
;
5248 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
5250 tcg_shift
= tcg_const_i32(0);
5251 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
5252 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
5256 gen_helper_vfp_tosls(tmp
, tmp
,
5259 gen_helper_vfp_touls(tmp
, tmp
,
5263 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
5265 tcg_temp_free_i32(tcg_rmode
);
5266 tcg_temp_free_i32(tcg_shift
);
5267 tcg_temp_free_ptr(fpst
);
5270 case NEON_2RM_VRECPE
:
5271 gen_helper_recpe_u32(tmp
, tmp
);
5273 case NEON_2RM_VRSQRTE
:
5274 gen_helper_rsqrte_u32(tmp
, tmp
);
5276 case NEON_2RM_VRECPE_F
:
5278 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5279 gen_helper_recpe_f32(tmp
, tmp
, fpstatus
);
5280 tcg_temp_free_ptr(fpstatus
);
5283 case NEON_2RM_VRSQRTE_F
:
5285 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5286 gen_helper_rsqrte_f32(tmp
, tmp
, fpstatus
);
5287 tcg_temp_free_ptr(fpstatus
);
5290 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
5292 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5293 gen_helper_vfp_sitos(tmp
, tmp
, fpstatus
);
5294 tcg_temp_free_ptr(fpstatus
);
5297 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
5299 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5300 gen_helper_vfp_uitos(tmp
, tmp
, fpstatus
);
5301 tcg_temp_free_ptr(fpstatus
);
5304 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
5306 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5307 gen_helper_vfp_tosizs(tmp
, tmp
, fpstatus
);
5308 tcg_temp_free_ptr(fpstatus
);
5311 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
5313 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5314 gen_helper_vfp_touizs(tmp
, tmp
, fpstatus
);
5315 tcg_temp_free_ptr(fpstatus
);
5319 /* Reserved op values were caught by the
5320 * neon_2rm_sizes[] check earlier.
5324 neon_store_reg(rd
, pass
, tmp
);
5329 /* VTBL, VTBX, VDUP: handled by decodetree */
5337 static int disas_coproc_insn(DisasContext
*s
, uint32_t insn
)
5339 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
5340 const ARMCPRegInfo
*ri
;
5342 cpnum
= (insn
>> 8) & 0xf;
5344 /* First check for coprocessor space used for XScale/iwMMXt insns */
5345 if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && (cpnum
< 2)) {
5346 if (extract32(s
->c15_cpar
, cpnum
, 1) == 0) {
5349 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
5350 return disas_iwmmxt_insn(s
, insn
);
5351 } else if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
)) {
5352 return disas_dsp_insn(s
, insn
);
5357 /* Otherwise treat as a generic register access */
5358 is64
= (insn
& (1 << 25)) == 0;
5359 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
5367 opc1
= (insn
>> 4) & 0xf;
5369 rt2
= (insn
>> 16) & 0xf;
5371 crn
= (insn
>> 16) & 0xf;
5372 opc1
= (insn
>> 21) & 7;
5373 opc2
= (insn
>> 5) & 7;
5376 isread
= (insn
>> 20) & 1;
5377 rt
= (insn
>> 12) & 0xf;
5379 ri
= get_arm_cp_reginfo(s
->cp_regs
,
5380 ENCODE_CP_REG(cpnum
, is64
, s
->ns
, crn
, crm
, opc1
, opc2
));
5384 /* Check access permissions */
5385 if (!cp_access_ok(s
->current_el
, ri
, isread
)) {
5389 if (s
->hstr_active
|| ri
->accessfn
||
5390 (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && cpnum
< 14)) {
5391 /* Emit code to perform further access permissions checks at
5392 * runtime; this may result in an exception.
5393 * Note that on XScale all cp0..c13 registers do an access check
5394 * call in order to handle c15_cpar.
5397 TCGv_i32 tcg_syn
, tcg_isread
;
5400 /* Note that since we are an implementation which takes an
5401 * exception on a trapped conditional instruction only if the
5402 * instruction passes its condition code check, we can take
5403 * advantage of the clause in the ARM ARM that allows us to set
5404 * the COND field in the instruction to 0xE in all cases.
5405 * We could fish the actual condition out of the insn (ARM)
5406 * or the condexec bits (Thumb) but it isn't necessary.
5411 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
5414 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
5420 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
5423 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
5428 /* ARMv8 defines that only coprocessors 14 and 15 exist,
5429 * so this can only happen if this is an ARMv7 or earlier CPU,
5430 * in which case the syndrome information won't actually be
5433 assert(!arm_dc_feature(s
, ARM_FEATURE_V8
));
5434 syndrome
= syn_uncategorized();
5438 gen_set_condexec(s
);
5439 gen_set_pc_im(s
, s
->pc_curr
);
5440 tmpptr
= tcg_const_ptr(ri
);
5441 tcg_syn
= tcg_const_i32(syndrome
);
5442 tcg_isread
= tcg_const_i32(isread
);
5443 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
,
5445 tcg_temp_free_ptr(tmpptr
);
5446 tcg_temp_free_i32(tcg_syn
);
5447 tcg_temp_free_i32(tcg_isread
);
5448 } else if (ri
->type
& ARM_CP_RAISES_EXC
) {
5450 * The readfn or writefn might raise an exception;
5451 * synchronize the CPU state in case it does.
5453 gen_set_condexec(s
);
5454 gen_set_pc_im(s
, s
->pc_curr
);
5457 /* Handle special cases first */
5458 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
5465 gen_set_pc_im(s
, s
->base
.pc_next
);
5466 s
->base
.is_jmp
= DISAS_WFI
;
5472 if ((tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
5481 if (ri
->type
& ARM_CP_CONST
) {
5482 tmp64
= tcg_const_i64(ri
->resetvalue
);
5483 } else if (ri
->readfn
) {
5485 tmp64
= tcg_temp_new_i64();
5486 tmpptr
= tcg_const_ptr(ri
);
5487 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
5488 tcg_temp_free_ptr(tmpptr
);
5490 tmp64
= tcg_temp_new_i64();
5491 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
5493 tmp
= tcg_temp_new_i32();
5494 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
5495 store_reg(s
, rt
, tmp
);
5496 tmp
= tcg_temp_new_i32();
5497 tcg_gen_extrh_i64_i32(tmp
, tmp64
);
5498 tcg_temp_free_i64(tmp64
);
5499 store_reg(s
, rt2
, tmp
);
5502 if (ri
->type
& ARM_CP_CONST
) {
5503 tmp
= tcg_const_i32(ri
->resetvalue
);
5504 } else if (ri
->readfn
) {
5506 tmp
= tcg_temp_new_i32();
5507 tmpptr
= tcg_const_ptr(ri
);
5508 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
5509 tcg_temp_free_ptr(tmpptr
);
5511 tmp
= load_cpu_offset(ri
->fieldoffset
);
5514 /* Destination register of r15 for 32 bit loads sets
5515 * the condition codes from the high 4 bits of the value
5518 tcg_temp_free_i32(tmp
);
5520 store_reg(s
, rt
, tmp
);
5525 if (ri
->type
& ARM_CP_CONST
) {
5526 /* If not forbidden by access permissions, treat as WI */
5531 TCGv_i32 tmplo
, tmphi
;
5532 TCGv_i64 tmp64
= tcg_temp_new_i64();
5533 tmplo
= load_reg(s
, rt
);
5534 tmphi
= load_reg(s
, rt2
);
5535 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
5536 tcg_temp_free_i32(tmplo
);
5537 tcg_temp_free_i32(tmphi
);
5539 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
5540 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
5541 tcg_temp_free_ptr(tmpptr
);
5543 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
5545 tcg_temp_free_i64(tmp64
);
5550 tmp
= load_reg(s
, rt
);
5551 tmpptr
= tcg_const_ptr(ri
);
5552 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
5553 tcg_temp_free_ptr(tmpptr
);
5554 tcg_temp_free_i32(tmp
);
5556 TCGv_i32 tmp
= load_reg(s
, rt
);
5557 store_cpu_offset(tmp
, ri
->fieldoffset
);
5562 /* I/O operations must end the TB here (whether read or write) */
5563 need_exit_tb
= ((tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) &&
5564 (ri
->type
& ARM_CP_IO
));
5566 if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
5568 * A write to any coprocessor register that ends a TB
5569 * must rebuild the hflags for the next TB.
5571 TCGv_i32 tcg_el
= tcg_const_i32(s
->current_el
);
5572 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
5573 gen_helper_rebuild_hflags_m32(cpu_env
, tcg_el
);
5575 if (ri
->type
& ARM_CP_NEWEL
) {
5576 gen_helper_rebuild_hflags_a32_newel(cpu_env
);
5578 gen_helper_rebuild_hflags_a32(cpu_env
, tcg_el
);
5581 tcg_temp_free_i32(tcg_el
);
5583 * We default to ending the TB on a coprocessor register write,
5584 * but allow this to be suppressed by the register definition
5585 * (usually only necessary to work around guest bugs).
5587 need_exit_tb
= true;
5596 /* Unknown register; this might be a guest error or a QEMU
5597 * unimplemented feature.
5600 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
5601 "64 bit system register cp:%d opc1: %d crm:%d "
5603 isread
? "read" : "write", cpnum
, opc1
, crm
,
5604 s
->ns
? "non-secure" : "secure");
5606 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
5607 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
5609 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
,
5610 s
->ns
? "non-secure" : "secure");
5617 /* Store a 64-bit value to a register pair. Clobbers val. */
5618 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
5621 tmp
= tcg_temp_new_i32();
5622 tcg_gen_extrl_i64_i32(tmp
, val
);
5623 store_reg(s
, rlow
, tmp
);
5624 tmp
= tcg_temp_new_i32();
5625 tcg_gen_extrh_i64_i32(tmp
, val
);
5626 store_reg(s
, rhigh
, tmp
);
5629 /* load and add a 64-bit value from a register pair. */
5630 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
5636 /* Load 64-bit value rd:rn. */
5637 tmpl
= load_reg(s
, rlow
);
5638 tmph
= load_reg(s
, rhigh
);
5639 tmp
= tcg_temp_new_i64();
5640 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
5641 tcg_temp_free_i32(tmpl
);
5642 tcg_temp_free_i32(tmph
);
5643 tcg_gen_add_i64(val
, val
, tmp
);
5644 tcg_temp_free_i64(tmp
);
5647 /* Set N and Z flags from hi|lo. */
5648 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
5650 tcg_gen_mov_i32(cpu_NF
, hi
);
5651 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
5654 /* Load/Store exclusive instructions are implemented by remembering
5655 the value/address loaded, and seeing if these are the same
5656 when the store is performed. This should be sufficient to implement
5657 the architecturally mandated semantics, and avoids having to monitor
5658 regular stores. The compare vs the remembered value is done during
5659 the cmpxchg operation, but we must compare the addresses manually. */
5660 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
5661 TCGv_i32 addr
, int size
)
5663 TCGv_i32 tmp
= tcg_temp_new_i32();
5664 MemOp opc
= size
| MO_ALIGN
| s
->be_data
;
5669 TCGv_i32 tmp2
= tcg_temp_new_i32();
5670 TCGv_i64 t64
= tcg_temp_new_i64();
5672 /* For AArch32, architecturally the 32-bit word at the lowest
5673 * address is always Rt and the one at addr+4 is Rt2, even if
5674 * the CPU is big-endian. That means we don't want to do a
5675 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
5676 * for an architecturally 64-bit access, but instead do a
5677 * 64-bit access using MO_BE if appropriate and then split
5679 * This only makes a difference for BE32 user-mode, where
5680 * frob64() must not flip the two halves of the 64-bit data
5681 * but this code must treat BE32 user-mode like BE32 system.
5683 TCGv taddr
= gen_aa32_addr(s
, addr
, opc
);
5685 tcg_gen_qemu_ld_i64(t64
, taddr
, get_mem_index(s
), opc
);
5686 tcg_temp_free(taddr
);
5687 tcg_gen_mov_i64(cpu_exclusive_val
, t64
);
5688 if (s
->be_data
== MO_BE
) {
5689 tcg_gen_extr_i64_i32(tmp2
, tmp
, t64
);
5691 tcg_gen_extr_i64_i32(tmp
, tmp2
, t64
);
5693 tcg_temp_free_i64(t64
);
5695 store_reg(s
, rt2
, tmp2
);
5697 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
), opc
);
5698 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
5701 store_reg(s
, rt
, tmp
);
5702 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
5705 static void gen_clrex(DisasContext
*s
)
5707 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
5710 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
5711 TCGv_i32 addr
, int size
)
5713 TCGv_i32 t0
, t1
, t2
;
5716 TCGLabel
*done_label
;
5717 TCGLabel
*fail_label
;
5718 MemOp opc
= size
| MO_ALIGN
| s
->be_data
;
5720 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
5726 fail_label
= gen_new_label();
5727 done_label
= gen_new_label();
5728 extaddr
= tcg_temp_new_i64();
5729 tcg_gen_extu_i32_i64(extaddr
, addr
);
5730 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
5731 tcg_temp_free_i64(extaddr
);
5733 taddr
= gen_aa32_addr(s
, addr
, opc
);
5734 t0
= tcg_temp_new_i32();
5735 t1
= load_reg(s
, rt
);
5737 TCGv_i64 o64
= tcg_temp_new_i64();
5738 TCGv_i64 n64
= tcg_temp_new_i64();
5740 t2
= load_reg(s
, rt2
);
5741 /* For AArch32, architecturally the 32-bit word at the lowest
5742 * address is always Rt and the one at addr+4 is Rt2, even if
5743 * the CPU is big-endian. Since we're going to treat this as a
5744 * single 64-bit BE store, we need to put the two halves in the
5745 * opposite order for BE to LE, so that they end up in the right
5747 * We don't want gen_aa32_frob64() because that does the wrong
5748 * thing for BE32 usermode.
5750 if (s
->be_data
== MO_BE
) {
5751 tcg_gen_concat_i32_i64(n64
, t2
, t1
);
5753 tcg_gen_concat_i32_i64(n64
, t1
, t2
);
5755 tcg_temp_free_i32(t2
);
5757 tcg_gen_atomic_cmpxchg_i64(o64
, taddr
, cpu_exclusive_val
, n64
,
5758 get_mem_index(s
), opc
);
5759 tcg_temp_free_i64(n64
);
5761 tcg_gen_setcond_i64(TCG_COND_NE
, o64
, o64
, cpu_exclusive_val
);
5762 tcg_gen_extrl_i64_i32(t0
, o64
);
5764 tcg_temp_free_i64(o64
);
5766 t2
= tcg_temp_new_i32();
5767 tcg_gen_extrl_i64_i32(t2
, cpu_exclusive_val
);
5768 tcg_gen_atomic_cmpxchg_i32(t0
, taddr
, t2
, t1
, get_mem_index(s
), opc
);
5769 tcg_gen_setcond_i32(TCG_COND_NE
, t0
, t0
, t2
);
5770 tcg_temp_free_i32(t2
);
5772 tcg_temp_free_i32(t1
);
5773 tcg_temp_free(taddr
);
5774 tcg_gen_mov_i32(cpu_R
[rd
], t0
);
5775 tcg_temp_free_i32(t0
);
5776 tcg_gen_br(done_label
);
5778 gen_set_label(fail_label
);
5779 tcg_gen_movi_i32(cpu_R
[rd
], 1);
5780 gen_set_label(done_label
);
5781 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
5787 * @mode: mode field from insn (which stack to store to)
5788 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
5789 * @writeback: true if writeback bit set
5791 * Generate code for the SRS (Store Return State) insn.
5793 static void gen_srs(DisasContext
*s
,
5794 uint32_t mode
, uint32_t amode
, bool writeback
)
5801 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
5802 * and specified mode is monitor mode
5803 * - UNDEFINED in Hyp mode
5804 * - UNPREDICTABLE in User or System mode
5805 * - UNPREDICTABLE if the specified mode is:
5806 * -- not implemented
5807 * -- not a valid mode number
5808 * -- a mode that's at a higher exception level
5809 * -- Monitor, if we are Non-secure
5810 * For the UNPREDICTABLE cases we choose to UNDEF.
5812 if (s
->current_el
== 1 && !s
->ns
&& mode
== ARM_CPU_MODE_MON
) {
5813 gen_exception_insn(s
, s
->pc_curr
, EXCP_UDEF
, syn_uncategorized(), 3);
5817 if (s
->current_el
== 0 || s
->current_el
== 2) {
5822 case ARM_CPU_MODE_USR
:
5823 case ARM_CPU_MODE_FIQ
:
5824 case ARM_CPU_MODE_IRQ
:
5825 case ARM_CPU_MODE_SVC
:
5826 case ARM_CPU_MODE_ABT
:
5827 case ARM_CPU_MODE_UND
:
5828 case ARM_CPU_MODE_SYS
:
5830 case ARM_CPU_MODE_HYP
:
5831 if (s
->current_el
== 1 || !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
5835 case ARM_CPU_MODE_MON
:
5836 /* No need to check specifically for "are we non-secure" because
5837 * we've already made EL0 UNDEF and handled the trap for S-EL1;
5838 * so if this isn't EL3 then we must be non-secure.
5840 if (s
->current_el
!= 3) {
5849 unallocated_encoding(s
);
5853 addr
= tcg_temp_new_i32();
5854 tmp
= tcg_const_i32(mode
);
5855 /* get_r13_banked() will raise an exception if called from System mode */
5856 gen_set_condexec(s
);
5857 gen_set_pc_im(s
, s
->pc_curr
);
5858 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
5859 tcg_temp_free_i32(tmp
);
5876 tcg_gen_addi_i32(addr
, addr
, offset
);
5877 tmp
= load_reg(s
, 14);
5878 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
5879 tcg_temp_free_i32(tmp
);
5880 tmp
= load_cpu_field(spsr
);
5881 tcg_gen_addi_i32(addr
, addr
, 4);
5882 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
5883 tcg_temp_free_i32(tmp
);
5901 tcg_gen_addi_i32(addr
, addr
, offset
);
5902 tmp
= tcg_const_i32(mode
);
5903 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
5904 tcg_temp_free_i32(tmp
);
5906 tcg_temp_free_i32(addr
);
5907 s
->base
.is_jmp
= DISAS_UPDATE
;
5910 /* Generate a label used for skipping this instruction */
5911 static void arm_gen_condlabel(DisasContext
*s
)
5914 s
->condlabel
= gen_new_label();
5919 /* Skip this instruction if the ARM condition is false */
5920 static void arm_skip_unless(DisasContext
*s
, uint32_t cond
)
5922 arm_gen_condlabel(s
);
5923 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
5928 * Constant expanders for the decoders.
5931 static int negate(DisasContext
*s
, int x
)
5936 static int plus_2(DisasContext
*s
, int x
)
5941 static int times_2(DisasContext
*s
, int x
)
5946 static int times_4(DisasContext
*s
, int x
)
5951 /* Return only the rotation part of T32ExpandImm. */
5952 static int t32_expandimm_rot(DisasContext
*s
, int x
)
5954 return x
& 0xc00 ? extract32(x
, 7, 5) : 0;
5957 /* Return the unrotated immediate from T32ExpandImm. */
5958 static int t32_expandimm_imm(DisasContext
*s
, int x
)
5960 int imm
= extract32(x
, 0, 8);
5962 switch (extract32(x
, 8, 4)) {
5964 /* Nothing to do. */
5966 case 1: /* 00XY00XY */
5969 case 2: /* XY00XY00 */
5972 case 3: /* XYXYXYXY */
5976 /* Rotated constant. */
5983 static int t32_branch24(DisasContext
*s
, int x
)
5985 /* Convert J1:J2 at x[22:21] to I2:I1, which involves I=J^~S. */
5986 x
^= !(x
< 0) * (3 << 21);
5987 /* Append the final zero. */
5991 static int t16_setflags(DisasContext
*s
)
5993 return s
->condexec_mask
== 0;
5996 static int t16_push_list(DisasContext
*s
, int x
)
5998 return (x
& 0xff) | (x
& 0x100) << (14 - 8);
6001 static int t16_pop_list(DisasContext
*s
, int x
)
6003 return (x
& 0xff) | (x
& 0x100) << (15 - 8);
6007 * Include the generated decoders.
6010 #include "decode-a32.inc.c"
6011 #include "decode-a32-uncond.inc.c"
6012 #include "decode-t32.inc.c"
6013 #include "decode-t16.inc.c"
6015 /* Helpers to swap operands for reverse-subtract. */
6016 static void gen_rsb(TCGv_i32 dst
, TCGv_i32 a
, TCGv_i32 b
)
6018 tcg_gen_sub_i32(dst
, b
, a
);
6021 static void gen_rsb_CC(TCGv_i32 dst
, TCGv_i32 a
, TCGv_i32 b
)
6023 gen_sub_CC(dst
, b
, a
);
6026 static void gen_rsc(TCGv_i32 dest
, TCGv_i32 a
, TCGv_i32 b
)
6028 gen_sub_carry(dest
, b
, a
);
6031 static void gen_rsc_CC(TCGv_i32 dest
, TCGv_i32 a
, TCGv_i32 b
)
6033 gen_sbc_CC(dest
, b
, a
);
6037 * Helpers for the data processing routines.
6039 * After the computation store the results back.
6040 * This may be suppressed altogether (STREG_NONE), require a runtime
6041 * check against the stack limits (STREG_SP_CHECK), or generate an
6042 * exception return. Oh, or store into a register.
6044 * Always return true, indicating success for a trans_* function.
6053 static bool store_reg_kind(DisasContext
*s
, int rd
,
6054 TCGv_i32 val
, StoreRegKind kind
)
6058 tcg_temp_free_i32(val
);
6061 /* See ALUWritePC: Interworking only from a32 mode. */
6063 store_reg(s
, rd
, val
);
6065 store_reg_bx(s
, rd
, val
);
6068 case STREG_SP_CHECK
:
6069 store_sp_checked(s
, val
);
6072 gen_exception_return(s
, val
);
6075 g_assert_not_reached();
6079 * Data Processing (register)
6081 * Operate, with set flags, one register source,
6082 * one immediate shifted register source, and a destination.
6084 static bool op_s_rrr_shi(DisasContext
*s
, arg_s_rrr_shi
*a
,
6085 void (*gen
)(TCGv_i32
, TCGv_i32
, TCGv_i32
),
6086 int logic_cc
, StoreRegKind kind
)
6088 TCGv_i32 tmp1
, tmp2
;
6090 tmp2
= load_reg(s
, a
->rm
);
6091 gen_arm_shift_im(tmp2
, a
->shty
, a
->shim
, logic_cc
);
6092 tmp1
= load_reg(s
, a
->rn
);
6094 gen(tmp1
, tmp1
, tmp2
);
6095 tcg_temp_free_i32(tmp2
);
6100 return store_reg_kind(s
, a
->rd
, tmp1
, kind
);
6103 static bool op_s_rxr_shi(DisasContext
*s
, arg_s_rrr_shi
*a
,
6104 void (*gen
)(TCGv_i32
, TCGv_i32
),
6105 int logic_cc
, StoreRegKind kind
)
6109 tmp
= load_reg(s
, a
->rm
);
6110 gen_arm_shift_im(tmp
, a
->shty
, a
->shim
, logic_cc
);
6116 return store_reg_kind(s
, a
->rd
, tmp
, kind
);
6120 * Data-processing (register-shifted register)
6122 * Operate, with set flags, one register source,
6123 * one register shifted register source, and a destination.
6125 static bool op_s_rrr_shr(DisasContext
*s
, arg_s_rrr_shr
*a
,
6126 void (*gen
)(TCGv_i32
, TCGv_i32
, TCGv_i32
),
6127 int logic_cc
, StoreRegKind kind
)
6129 TCGv_i32 tmp1
, tmp2
;
6131 tmp1
= load_reg(s
, a
->rs
);
6132 tmp2
= load_reg(s
, a
->rm
);
6133 gen_arm_shift_reg(tmp2
, a
->shty
, tmp1
, logic_cc
);
6134 tmp1
= load_reg(s
, a
->rn
);
6136 gen(tmp1
, tmp1
, tmp2
);
6137 tcg_temp_free_i32(tmp2
);
6142 return store_reg_kind(s
, a
->rd
, tmp1
, kind
);
6145 static bool op_s_rxr_shr(DisasContext
*s
, arg_s_rrr_shr
*a
,
6146 void (*gen
)(TCGv_i32
, TCGv_i32
),
6147 int logic_cc
, StoreRegKind kind
)
6149 TCGv_i32 tmp1
, tmp2
;
6151 tmp1
= load_reg(s
, a
->rs
);
6152 tmp2
= load_reg(s
, a
->rm
);
6153 gen_arm_shift_reg(tmp2
, a
->shty
, tmp1
, logic_cc
);
6159 return store_reg_kind(s
, a
->rd
, tmp2
, kind
);
6163 * Data-processing (immediate)
6165 * Operate, with set flags, one register source,
6166 * one rotated immediate, and a destination.
6168 * Note that logic_cc && a->rot setting CF based on the msb of the
6169 * immediate is the reason why we must pass in the unrotated form
6172 static bool op_s_rri_rot(DisasContext
*s
, arg_s_rri_rot
*a
,
6173 void (*gen
)(TCGv_i32
, TCGv_i32
, TCGv_i32
),
6174 int logic_cc
, StoreRegKind kind
)
6176 TCGv_i32 tmp1
, tmp2
;
6179 imm
= ror32(a
->imm
, a
->rot
);
6180 if (logic_cc
&& a
->rot
) {
6181 tcg_gen_movi_i32(cpu_CF
, imm
>> 31);
6183 tmp2
= tcg_const_i32(imm
);
6184 tmp1
= load_reg(s
, a
->rn
);
6186 gen(tmp1
, tmp1
, tmp2
);
6187 tcg_temp_free_i32(tmp2
);
6192 return store_reg_kind(s
, a
->rd
, tmp1
, kind
);
6195 static bool op_s_rxi_rot(DisasContext
*s
, arg_s_rri_rot
*a
,
6196 void (*gen
)(TCGv_i32
, TCGv_i32
),
6197 int logic_cc
, StoreRegKind kind
)
6202 imm
= ror32(a
->imm
, a
->rot
);
6203 if (logic_cc
&& a
->rot
) {
6204 tcg_gen_movi_i32(cpu_CF
, imm
>> 31);
6206 tmp
= tcg_const_i32(imm
);
6212 return store_reg_kind(s
, a
->rd
, tmp
, kind
);
6215 #define DO_ANY3(NAME, OP, L, K) \
6216 static bool trans_##NAME##_rrri(DisasContext *s, arg_s_rrr_shi *a) \
6217 { StoreRegKind k = (K); return op_s_rrr_shi(s, a, OP, L, k); } \
6218 static bool trans_##NAME##_rrrr(DisasContext *s, arg_s_rrr_shr *a) \
6219 { StoreRegKind k = (K); return op_s_rrr_shr(s, a, OP, L, k); } \
6220 static bool trans_##NAME##_rri(DisasContext *s, arg_s_rri_rot *a) \
6221 { StoreRegKind k = (K); return op_s_rri_rot(s, a, OP, L, k); }
6223 #define DO_ANY2(NAME, OP, L, K) \
6224 static bool trans_##NAME##_rxri(DisasContext *s, arg_s_rrr_shi *a) \
6225 { StoreRegKind k = (K); return op_s_rxr_shi(s, a, OP, L, k); } \
6226 static bool trans_##NAME##_rxrr(DisasContext *s, arg_s_rrr_shr *a) \
6227 { StoreRegKind k = (K); return op_s_rxr_shr(s, a, OP, L, k); } \
6228 static bool trans_##NAME##_rxi(DisasContext *s, arg_s_rri_rot *a) \
6229 { StoreRegKind k = (K); return op_s_rxi_rot(s, a, OP, L, k); }
6231 #define DO_CMP2(NAME, OP, L) \
6232 static bool trans_##NAME##_xrri(DisasContext *s, arg_s_rrr_shi *a) \
6233 { return op_s_rrr_shi(s, a, OP, L, STREG_NONE); } \
6234 static bool trans_##NAME##_xrrr(DisasContext *s, arg_s_rrr_shr *a) \
6235 { return op_s_rrr_shr(s, a, OP, L, STREG_NONE); } \
6236 static bool trans_##NAME##_xri(DisasContext *s, arg_s_rri_rot *a) \
6237 { return op_s_rri_rot(s, a, OP, L, STREG_NONE); }
6239 DO_ANY3(AND
, tcg_gen_and_i32
, a
->s
, STREG_NORMAL
)
6240 DO_ANY3(EOR
, tcg_gen_xor_i32
, a
->s
, STREG_NORMAL
)
6241 DO_ANY3(ORR
, tcg_gen_or_i32
, a
->s
, STREG_NORMAL
)
6242 DO_ANY3(BIC
, tcg_gen_andc_i32
, a
->s
, STREG_NORMAL
)
6244 DO_ANY3(RSB
, a
->s
? gen_rsb_CC
: gen_rsb
, false, STREG_NORMAL
)
6245 DO_ANY3(ADC
, a
->s
? gen_adc_CC
: gen_add_carry
, false, STREG_NORMAL
)
6246 DO_ANY3(SBC
, a
->s
? gen_sbc_CC
: gen_sub_carry
, false, STREG_NORMAL
)
6247 DO_ANY3(RSC
, a
->s
? gen_rsc_CC
: gen_rsc
, false, STREG_NORMAL
)
6249 DO_CMP2(TST
, tcg_gen_and_i32
, true)
6250 DO_CMP2(TEQ
, tcg_gen_xor_i32
, true)
6251 DO_CMP2(CMN
, gen_add_CC
, false)
6252 DO_CMP2(CMP
, gen_sub_CC
, false)
6254 DO_ANY3(ADD
, a
->s
? gen_add_CC
: tcg_gen_add_i32
, false,
6255 a
->rd
== 13 && a
->rn
== 13 ? STREG_SP_CHECK
: STREG_NORMAL
)
6258 * Note for the computation of StoreRegKind we return out of the
6259 * middle of the functions that are expanded by DO_ANY3, and that
6260 * we modify a->s via that parameter before it is used by OP.
6262 DO_ANY3(SUB
, a
->s
? gen_sub_CC
: tcg_gen_sub_i32
, false,
6264 StoreRegKind ret
= STREG_NORMAL
;
6265 if (a
->rd
== 15 && a
->s
) {
6267 * See ALUExceptionReturn:
6268 * In User mode, UNPREDICTABLE; we choose UNDEF.
6269 * In Hyp mode, UNDEFINED.
6271 if (IS_USER(s
) || s
->current_el
== 2) {
6272 unallocated_encoding(s
);
6275 /* There is no writeback of nzcv to PSTATE. */
6277 ret
= STREG_EXC_RET
;
6278 } else if (a
->rd
== 13 && a
->rn
== 13) {
6279 ret
= STREG_SP_CHECK
;
6284 DO_ANY2(MOV
, tcg_gen_mov_i32
, a
->s
,
6286 StoreRegKind ret
= STREG_NORMAL
;
6287 if (a
->rd
== 15 && a
->s
) {
6289 * See ALUExceptionReturn:
6290 * In User mode, UNPREDICTABLE; we choose UNDEF.
6291 * In Hyp mode, UNDEFINED.
6293 if (IS_USER(s
) || s
->current_el
== 2) {
6294 unallocated_encoding(s
);
6297 /* There is no writeback of nzcv to PSTATE. */
6299 ret
= STREG_EXC_RET
;
6300 } else if (a
->rd
== 13) {
6301 ret
= STREG_SP_CHECK
;
6306 DO_ANY2(MVN
, tcg_gen_not_i32
, a
->s
, STREG_NORMAL
)
6309 * ORN is only available with T32, so there is no register-shifted-register
6310 * form of the insn. Using the DO_ANY3 macro would create an unused function.
6312 static bool trans_ORN_rrri(DisasContext
*s
, arg_s_rrr_shi
*a
)
6314 return op_s_rrr_shi(s
, a
, tcg_gen_orc_i32
, a
->s
, STREG_NORMAL
);
6317 static bool trans_ORN_rri(DisasContext
*s
, arg_s_rri_rot
*a
)
6319 return op_s_rri_rot(s
, a
, tcg_gen_orc_i32
, a
->s
, STREG_NORMAL
);
6326 static bool trans_ADR(DisasContext
*s
, arg_ri
*a
)
6328 store_reg_bx(s
, a
->rd
, add_reg_for_lit(s
, 15, a
->imm
));
6332 static bool trans_MOVW(DisasContext
*s
, arg_MOVW
*a
)
6336 if (!ENABLE_ARCH_6T2
) {
6340 tmp
= tcg_const_i32(a
->imm
);
6341 store_reg(s
, a
->rd
, tmp
);
6345 static bool trans_MOVT(DisasContext
*s
, arg_MOVW
*a
)
6349 if (!ENABLE_ARCH_6T2
) {
6353 tmp
= load_reg(s
, a
->rd
);
6354 tcg_gen_ext16u_i32(tmp
, tmp
);
6355 tcg_gen_ori_i32(tmp
, tmp
, a
->imm
<< 16);
6356 store_reg(s
, a
->rd
, tmp
);
6361 * Multiply and multiply accumulate
6364 static bool op_mla(DisasContext
*s
, arg_s_rrrr
*a
, bool add
)
6368 t1
= load_reg(s
, a
->rn
);
6369 t2
= load_reg(s
, a
->rm
);
6370 tcg_gen_mul_i32(t1
, t1
, t2
);
6371 tcg_temp_free_i32(t2
);
6373 t2
= load_reg(s
, a
->ra
);
6374 tcg_gen_add_i32(t1
, t1
, t2
);
6375 tcg_temp_free_i32(t2
);
6380 store_reg(s
, a
->rd
, t1
);
6384 static bool trans_MUL(DisasContext
*s
, arg_MUL
*a
)
6386 return op_mla(s
, a
, false);
6389 static bool trans_MLA(DisasContext
*s
, arg_MLA
*a
)
6391 return op_mla(s
, a
, true);
6394 static bool trans_MLS(DisasContext
*s
, arg_MLS
*a
)
6398 if (!ENABLE_ARCH_6T2
) {
6401 t1
= load_reg(s
, a
->rn
);
6402 t2
= load_reg(s
, a
->rm
);
6403 tcg_gen_mul_i32(t1
, t1
, t2
);
6404 tcg_temp_free_i32(t2
);
6405 t2
= load_reg(s
, a
->ra
);
6406 tcg_gen_sub_i32(t1
, t2
, t1
);
6407 tcg_temp_free_i32(t2
);
6408 store_reg(s
, a
->rd
, t1
);
6412 static bool op_mlal(DisasContext
*s
, arg_s_rrrr
*a
, bool uns
, bool add
)
6414 TCGv_i32 t0
, t1
, t2
, t3
;
6416 t0
= load_reg(s
, a
->rm
);
6417 t1
= load_reg(s
, a
->rn
);
6419 tcg_gen_mulu2_i32(t0
, t1
, t0
, t1
);
6421 tcg_gen_muls2_i32(t0
, t1
, t0
, t1
);
6424 t2
= load_reg(s
, a
->ra
);
6425 t3
= load_reg(s
, a
->rd
);
6426 tcg_gen_add2_i32(t0
, t1
, t0
, t1
, t2
, t3
);
6427 tcg_temp_free_i32(t2
);
6428 tcg_temp_free_i32(t3
);
6431 gen_logicq_cc(t0
, t1
);
6433 store_reg(s
, a
->ra
, t0
);
6434 store_reg(s
, a
->rd
, t1
);
6438 static bool trans_UMULL(DisasContext
*s
, arg_UMULL
*a
)
6440 return op_mlal(s
, a
, true, false);
6443 static bool trans_SMULL(DisasContext
*s
, arg_SMULL
*a
)
6445 return op_mlal(s
, a
, false, false);
6448 static bool trans_UMLAL(DisasContext
*s
, arg_UMLAL
*a
)
6450 return op_mlal(s
, a
, true, true);
6453 static bool trans_SMLAL(DisasContext
*s
, arg_SMLAL
*a
)
6455 return op_mlal(s
, a
, false, true);
6458 static bool trans_UMAAL(DisasContext
*s
, arg_UMAAL
*a
)
6460 TCGv_i32 t0
, t1
, t2
, zero
;
6463 ? !arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)
6468 t0
= load_reg(s
, a
->rm
);
6469 t1
= load_reg(s
, a
->rn
);
6470 tcg_gen_mulu2_i32(t0
, t1
, t0
, t1
);
6471 zero
= tcg_const_i32(0);
6472 t2
= load_reg(s
, a
->ra
);
6473 tcg_gen_add2_i32(t0
, t1
, t0
, t1
, t2
, zero
);
6474 tcg_temp_free_i32(t2
);
6475 t2
= load_reg(s
, a
->rd
);
6476 tcg_gen_add2_i32(t0
, t1
, t0
, t1
, t2
, zero
);
6477 tcg_temp_free_i32(t2
);
6478 tcg_temp_free_i32(zero
);
6479 store_reg(s
, a
->ra
, t0
);
6480 store_reg(s
, a
->rd
, t1
);
6485 * Saturating addition and subtraction
6488 static bool op_qaddsub(DisasContext
*s
, arg_rrr
*a
, bool add
, bool doub
)
6493 ? !arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)
6494 : !ENABLE_ARCH_5TE
) {
6498 t0
= load_reg(s
, a
->rm
);
6499 t1
= load_reg(s
, a
->rn
);
6501 gen_helper_add_saturate(t1
, cpu_env
, t1
, t1
);
6504 gen_helper_add_saturate(t0
, cpu_env
, t0
, t1
);
6506 gen_helper_sub_saturate(t0
, cpu_env
, t0
, t1
);
6508 tcg_temp_free_i32(t1
);
6509 store_reg(s
, a
->rd
, t0
);
6513 #define DO_QADDSUB(NAME, ADD, DOUB) \
6514 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
6516 return op_qaddsub(s, a, ADD, DOUB); \
6519 DO_QADDSUB(QADD
, true, false)
6520 DO_QADDSUB(QSUB
, false, false)
6521 DO_QADDSUB(QDADD
, true, true)
6522 DO_QADDSUB(QDSUB
, false, true)
6527 * Halfword multiply and multiply accumulate
6530 static bool op_smlaxxx(DisasContext
*s
, arg_rrrr
*a
,
6531 int add_long
, bool nt
, bool mt
)
6533 TCGv_i32 t0
, t1
, tl
, th
;
6536 ? !arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)
6537 : !ENABLE_ARCH_5TE
) {
6541 t0
= load_reg(s
, a
->rn
);
6542 t1
= load_reg(s
, a
->rm
);
6543 gen_mulxy(t0
, t1
, nt
, mt
);
6544 tcg_temp_free_i32(t1
);
6548 store_reg(s
, a
->rd
, t0
);
6551 t1
= load_reg(s
, a
->ra
);
6552 gen_helper_add_setq(t0
, cpu_env
, t0
, t1
);
6553 tcg_temp_free_i32(t1
);
6554 store_reg(s
, a
->rd
, t0
);
6557 tl
= load_reg(s
, a
->ra
);
6558 th
= load_reg(s
, a
->rd
);
6559 /* Sign-extend the 32-bit product to 64 bits. */
6560 t1
= tcg_temp_new_i32();
6561 tcg_gen_sari_i32(t1
, t0
, 31);
6562 tcg_gen_add2_i32(tl
, th
, tl
, th
, t0
, t1
);
6563 tcg_temp_free_i32(t0
);
6564 tcg_temp_free_i32(t1
);
6565 store_reg(s
, a
->ra
, tl
);
6566 store_reg(s
, a
->rd
, th
);
6569 g_assert_not_reached();
6574 #define DO_SMLAX(NAME, add, nt, mt) \
6575 static bool trans_##NAME(DisasContext *s, arg_rrrr *a) \
6577 return op_smlaxxx(s, a, add, nt, mt); \
6580 DO_SMLAX(SMULBB
, 0, 0, 0)
6581 DO_SMLAX(SMULBT
, 0, 0, 1)
6582 DO_SMLAX(SMULTB
, 0, 1, 0)
6583 DO_SMLAX(SMULTT
, 0, 1, 1)
6585 DO_SMLAX(SMLABB
, 1, 0, 0)
6586 DO_SMLAX(SMLABT
, 1, 0, 1)
6587 DO_SMLAX(SMLATB
, 1, 1, 0)
6588 DO_SMLAX(SMLATT
, 1, 1, 1)
6590 DO_SMLAX(SMLALBB
, 2, 0, 0)
6591 DO_SMLAX(SMLALBT
, 2, 0, 1)
6592 DO_SMLAX(SMLALTB
, 2, 1, 0)
6593 DO_SMLAX(SMLALTT
, 2, 1, 1)
6597 static bool op_smlawx(DisasContext
*s
, arg_rrrr
*a
, bool add
, bool mt
)
6601 if (!ENABLE_ARCH_5TE
) {
6605 t0
= load_reg(s
, a
->rn
);
6606 t1
= load_reg(s
, a
->rm
);
6608 * Since the nominal result is product<47:16>, shift the 16-bit
6609 * input up by 16 bits, so that the result is at product<63:32>.
6612 tcg_gen_andi_i32(t1
, t1
, 0xffff0000);
6614 tcg_gen_shli_i32(t1
, t1
, 16);
6616 tcg_gen_muls2_i32(t0
, t1
, t0
, t1
);
6617 tcg_temp_free_i32(t0
);
6619 t0
= load_reg(s
, a
->ra
);
6620 gen_helper_add_setq(t1
, cpu_env
, t1
, t0
);
6621 tcg_temp_free_i32(t0
);
6623 store_reg(s
, a
->rd
, t1
);
6627 #define DO_SMLAWX(NAME, add, mt) \
6628 static bool trans_##NAME(DisasContext *s, arg_rrrr *a) \
6630 return op_smlawx(s, a, add, mt); \
6633 DO_SMLAWX(SMULWB
, 0, 0)
6634 DO_SMLAWX(SMULWT
, 0, 1)
6635 DO_SMLAWX(SMLAWB
, 1, 0)
6636 DO_SMLAWX(SMLAWT
, 1, 1)
6641 * MSR (immediate) and hints
6644 static bool trans_YIELD(DisasContext
*s
, arg_YIELD
*a
)
6647 * When running single-threaded TCG code, use the helper to ensure that
6648 * the next round-robin scheduled vCPU gets a crack. When running in
6649 * MTTCG we don't generate jumps to the helper as it won't affect the
6650 * scheduling of other vCPUs.
6652 if (!(tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
6653 gen_set_pc_im(s
, s
->base
.pc_next
);
6654 s
->base
.is_jmp
= DISAS_YIELD
;
6659 static bool trans_WFE(DisasContext
*s
, arg_WFE
*a
)
6662 * When running single-threaded TCG code, use the helper to ensure that
6663 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
6664 * just skip this instruction. Currently the SEV/SEVL instructions,
6665 * which are *one* of many ways to wake the CPU from WFE, are not
6666 * implemented so we can't sleep like WFI does.
6668 if (!(tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
6669 gen_set_pc_im(s
, s
->base
.pc_next
);
6670 s
->base
.is_jmp
= DISAS_WFE
;
6675 static bool trans_WFI(DisasContext
*s
, arg_WFI
*a
)
6677 /* For WFI, halt the vCPU until an IRQ. */
6678 gen_set_pc_im(s
, s
->base
.pc_next
);
6679 s
->base
.is_jmp
= DISAS_WFI
;
6683 static bool trans_NOP(DisasContext
*s
, arg_NOP
*a
)
6688 static bool trans_MSR_imm(DisasContext
*s
, arg_MSR_imm
*a
)
6690 uint32_t val
= ror32(a
->imm
, a
->rot
* 2);
6691 uint32_t mask
= msr_mask(s
, a
->mask
, a
->r
);
6693 if (gen_set_psr_im(s
, mask
, a
->r
, val
)) {
6694 unallocated_encoding(s
);
6700 * Cyclic Redundancy Check
6703 static bool op_crc32(DisasContext
*s
, arg_rrr
*a
, bool c
, MemOp sz
)
6705 TCGv_i32 t1
, t2
, t3
;
6707 if (!dc_isar_feature(aa32_crc32
, s
)) {
6711 t1
= load_reg(s
, a
->rn
);
6712 t2
= load_reg(s
, a
->rm
);
6723 g_assert_not_reached();
6725 t3
= tcg_const_i32(1 << sz
);
6727 gen_helper_crc32c(t1
, t1
, t2
, t3
);
6729 gen_helper_crc32(t1
, t1
, t2
, t3
);
6731 tcg_temp_free_i32(t2
);
6732 tcg_temp_free_i32(t3
);
6733 store_reg(s
, a
->rd
, t1
);
6737 #define DO_CRC32(NAME, c, sz) \
6738 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
6739 { return op_crc32(s, a, c, sz); }
6741 DO_CRC32(CRC32B
, false, MO_8
)
6742 DO_CRC32(CRC32H
, false, MO_16
)
6743 DO_CRC32(CRC32W
, false, MO_32
)
6744 DO_CRC32(CRC32CB
, true, MO_8
)
6745 DO_CRC32(CRC32CH
, true, MO_16
)
6746 DO_CRC32(CRC32CW
, true, MO_32
)
6751 * Miscellaneous instructions
6754 static bool trans_MRS_bank(DisasContext
*s
, arg_MRS_bank
*a
)
6756 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
6759 gen_mrs_banked(s
, a
->r
, a
->sysm
, a
->rd
);
6763 static bool trans_MSR_bank(DisasContext
*s
, arg_MSR_bank
*a
)
6765 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
6768 gen_msr_banked(s
, a
->r
, a
->sysm
, a
->rn
);
6772 static bool trans_MRS_reg(DisasContext
*s
, arg_MRS_reg
*a
)
6776 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
6781 unallocated_encoding(s
);
6784 tmp
= load_cpu_field(spsr
);
6786 tmp
= tcg_temp_new_i32();
6787 gen_helper_cpsr_read(tmp
, cpu_env
);
6789 store_reg(s
, a
->rd
, tmp
);
6793 static bool trans_MSR_reg(DisasContext
*s
, arg_MSR_reg
*a
)
6796 uint32_t mask
= msr_mask(s
, a
->mask
, a
->r
);
6798 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
6801 tmp
= load_reg(s
, a
->rn
);
6802 if (gen_set_psr(s
, mask
, a
->r
, tmp
)) {
6803 unallocated_encoding(s
);
6808 static bool trans_MRS_v7m(DisasContext
*s
, arg_MRS_v7m
*a
)
6812 if (!arm_dc_feature(s
, ARM_FEATURE_M
)) {
6815 tmp
= tcg_const_i32(a
->sysm
);
6816 gen_helper_v7m_mrs(tmp
, cpu_env
, tmp
);
6817 store_reg(s
, a
->rd
, tmp
);
6821 static bool trans_MSR_v7m(DisasContext
*s
, arg_MSR_v7m
*a
)
6825 if (!arm_dc_feature(s
, ARM_FEATURE_M
)) {
6828 addr
= tcg_const_i32((a
->mask
<< 10) | a
->sysm
);
6829 reg
= load_reg(s
, a
->rn
);
6830 gen_helper_v7m_msr(cpu_env
, addr
, reg
);
6831 tcg_temp_free_i32(addr
);
6832 tcg_temp_free_i32(reg
);
6833 /* If we wrote to CONTROL, the EL might have changed */
6834 gen_helper_rebuild_hflags_m32_newel(cpu_env
);
6839 static bool trans_BX(DisasContext
*s
, arg_BX
*a
)
6841 if (!ENABLE_ARCH_4T
) {
6844 gen_bx_excret(s
, load_reg(s
, a
->rm
));
6848 static bool trans_BXJ(DisasContext
*s
, arg_BXJ
*a
)
6850 if (!ENABLE_ARCH_5J
|| arm_dc_feature(s
, ARM_FEATURE_M
)) {
6853 /* Trivial implementation equivalent to bx. */
6854 gen_bx(s
, load_reg(s
, a
->rm
));
6858 static bool trans_BLX_r(DisasContext
*s
, arg_BLX_r
*a
)
6862 if (!ENABLE_ARCH_5
) {
6865 tmp
= load_reg(s
, a
->rm
);
6866 tcg_gen_movi_i32(cpu_R
[14], s
->base
.pc_next
| s
->thumb
);
6872 * BXNS/BLXNS: only exist for v8M with the security extensions,
6873 * and always UNDEF if NonSecure. We don't implement these in
6874 * the user-only mode either (in theory you can use them from
6875 * Secure User mode but they are too tied in to system emulation).
6877 static bool trans_BXNS(DisasContext
*s
, arg_BXNS
*a
)
6879 if (!s
->v8m_secure
|| IS_USER_ONLY
) {
6880 unallocated_encoding(s
);
6887 static bool trans_BLXNS(DisasContext
*s
, arg_BLXNS
*a
)
6889 if (!s
->v8m_secure
|| IS_USER_ONLY
) {
6890 unallocated_encoding(s
);
6892 gen_blxns(s
, a
->rm
);
6897 static bool trans_CLZ(DisasContext
*s
, arg_CLZ
*a
)
6901 if (!ENABLE_ARCH_5
) {
6904 tmp
= load_reg(s
, a
->rm
);
6905 tcg_gen_clzi_i32(tmp
, tmp
, 32);
6906 store_reg(s
, a
->rd
, tmp
);
6910 static bool trans_ERET(DisasContext
*s
, arg_ERET
*a
)
6914 if (!arm_dc_feature(s
, ARM_FEATURE_V7VE
)) {
6918 unallocated_encoding(s
);
6921 if (s
->current_el
== 2) {
6922 /* ERET from Hyp uses ELR_Hyp, not LR */
6923 tmp
= load_cpu_field(elr_el
[2]);
6925 tmp
= load_reg(s
, 14);
6927 gen_exception_return(s
, tmp
);
6931 static bool trans_HLT(DisasContext
*s
, arg_HLT
*a
)
6937 static bool trans_BKPT(DisasContext
*s
, arg_BKPT
*a
)
6939 if (!ENABLE_ARCH_5
) {
6942 if (arm_dc_feature(s
, ARM_FEATURE_M
) &&
6943 semihosting_enabled() &&
6944 #ifndef CONFIG_USER_ONLY
6948 gen_exception_internal_insn(s
, s
->pc_curr
, EXCP_SEMIHOST
);
6950 gen_exception_bkpt_insn(s
, syn_aa32_bkpt(a
->imm
, false));
6955 static bool trans_HVC(DisasContext
*s
, arg_HVC
*a
)
6957 if (!ENABLE_ARCH_7
|| arm_dc_feature(s
, ARM_FEATURE_M
)) {
6961 unallocated_encoding(s
);
6968 static bool trans_SMC(DisasContext
*s
, arg_SMC
*a
)
6970 if (!ENABLE_ARCH_6K
|| arm_dc_feature(s
, ARM_FEATURE_M
)) {
6974 unallocated_encoding(s
);
6981 static bool trans_SG(DisasContext
*s
, arg_SG
*a
)
6983 if (!arm_dc_feature(s
, ARM_FEATURE_M
) ||
6984 !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
6989 * The bulk of the behaviour for this instruction is implemented
6990 * in v7m_handle_execute_nsc(), which deals with the insn when
6991 * it is executed by a CPU in non-secure state from memory
6992 * which is Secure & NonSecure-Callable.
6993 * Here we only need to handle the remaining cases:
6994 * * in NS memory (including the "security extension not
6995 * implemented" case) : NOP
6996 * * in S memory but CPU already secure (clear IT bits)
6997 * We know that the attribute for the memory this insn is
6998 * in must match the current CPU state, because otherwise
6999 * get_phys_addr_pmsav8 would have generated an exception.
7001 if (s
->v8m_secure
) {
7002 /* Like the IT insn, we don't need to generate any code */
7003 s
->condexec_cond
= 0;
7004 s
->condexec_mask
= 0;
7009 static bool trans_TT(DisasContext
*s
, arg_TT
*a
)
7013 if (!arm_dc_feature(s
, ARM_FEATURE_M
) ||
7014 !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
7017 if (a
->rd
== 13 || a
->rd
== 15 || a
->rn
== 15) {
7018 /* We UNDEF for these UNPREDICTABLE cases */
7019 unallocated_encoding(s
);
7022 if (a
->A
&& !s
->v8m_secure
) {
7023 /* This case is UNDEFINED. */
7024 unallocated_encoding(s
);
7028 addr
= load_reg(s
, a
->rn
);
7029 tmp
= tcg_const_i32((a
->A
<< 1) | a
->T
);
7030 gen_helper_v7m_tt(tmp
, cpu_env
, addr
, tmp
);
7031 tcg_temp_free_i32(addr
);
7032 store_reg(s
, a
->rd
, tmp
);
7037 * Load/store register index
7040 static ISSInfo
make_issinfo(DisasContext
*s
, int rd
, bool p
, bool w
)
7044 /* ISS not valid if writeback */
7047 if (s
->base
.pc_next
- s
->pc_curr
== 2) {
7056 static TCGv_i32
op_addr_rr_pre(DisasContext
*s
, arg_ldst_rr
*a
)
7058 TCGv_i32 addr
= load_reg(s
, a
->rn
);
7060 if (s
->v8m_stackcheck
&& a
->rn
== 13 && a
->w
) {
7061 gen_helper_v8m_stackcheck(cpu_env
, addr
);
7065 TCGv_i32 ofs
= load_reg(s
, a
->rm
);
7066 gen_arm_shift_im(ofs
, a
->shtype
, a
->shimm
, 0);
7068 tcg_gen_add_i32(addr
, addr
, ofs
);
7070 tcg_gen_sub_i32(addr
, addr
, ofs
);
7072 tcg_temp_free_i32(ofs
);
7077 static void op_addr_rr_post(DisasContext
*s
, arg_ldst_rr
*a
,
7078 TCGv_i32 addr
, int address_offset
)
7081 TCGv_i32 ofs
= load_reg(s
, a
->rm
);
7082 gen_arm_shift_im(ofs
, a
->shtype
, a
->shimm
, 0);
7084 tcg_gen_add_i32(addr
, addr
, ofs
);
7086 tcg_gen_sub_i32(addr
, addr
, ofs
);
7088 tcg_temp_free_i32(ofs
);
7090 tcg_temp_free_i32(addr
);
7093 tcg_gen_addi_i32(addr
, addr
, address_offset
);
7094 store_reg(s
, a
->rn
, addr
);
7097 static bool op_load_rr(DisasContext
*s
, arg_ldst_rr
*a
,
7098 MemOp mop
, int mem_idx
)
7100 ISSInfo issinfo
= make_issinfo(s
, a
->rt
, a
->p
, a
->w
);
7103 addr
= op_addr_rr_pre(s
, a
);
7105 tmp
= tcg_temp_new_i32();
7106 gen_aa32_ld_i32(s
, tmp
, addr
, mem_idx
, mop
| s
->be_data
);
7107 disas_set_da_iss(s
, mop
, issinfo
);
7110 * Perform base writeback before the loaded value to
7111 * ensure correct behavior with overlapping index registers.
7113 op_addr_rr_post(s
, a
, addr
, 0);
7114 store_reg_from_load(s
, a
->rt
, tmp
);
7118 static bool op_store_rr(DisasContext
*s
, arg_ldst_rr
*a
,
7119 MemOp mop
, int mem_idx
)
7121 ISSInfo issinfo
= make_issinfo(s
, a
->rt
, a
->p
, a
->w
) | ISSIsWrite
;
7124 addr
= op_addr_rr_pre(s
, a
);
7126 tmp
= load_reg(s
, a
->rt
);
7127 gen_aa32_st_i32(s
, tmp
, addr
, mem_idx
, mop
| s
->be_data
);
7128 disas_set_da_iss(s
, mop
, issinfo
);
7129 tcg_temp_free_i32(tmp
);
7131 op_addr_rr_post(s
, a
, addr
, 0);
7135 static bool trans_LDRD_rr(DisasContext
*s
, arg_ldst_rr
*a
)
7137 int mem_idx
= get_mem_index(s
);
7140 if (!ENABLE_ARCH_5TE
) {
7144 unallocated_encoding(s
);
7147 addr
= op_addr_rr_pre(s
, a
);
7149 tmp
= tcg_temp_new_i32();
7150 gen_aa32_ld_i32(s
, tmp
, addr
, mem_idx
, MO_UL
| s
->be_data
);
7151 store_reg(s
, a
->rt
, tmp
);
7153 tcg_gen_addi_i32(addr
, addr
, 4);
7155 tmp
= tcg_temp_new_i32();
7156 gen_aa32_ld_i32(s
, tmp
, addr
, mem_idx
, MO_UL
| s
->be_data
);
7157 store_reg(s
, a
->rt
+ 1, tmp
);
7159 /* LDRD w/ base writeback is undefined if the registers overlap. */
7160 op_addr_rr_post(s
, a
, addr
, -4);
7164 static bool trans_STRD_rr(DisasContext
*s
, arg_ldst_rr
*a
)
7166 int mem_idx
= get_mem_index(s
);
7169 if (!ENABLE_ARCH_5TE
) {
7173 unallocated_encoding(s
);
7176 addr
= op_addr_rr_pre(s
, a
);
7178 tmp
= load_reg(s
, a
->rt
);
7179 gen_aa32_st_i32(s
, tmp
, addr
, mem_idx
, MO_UL
| s
->be_data
);
7180 tcg_temp_free_i32(tmp
);
7182 tcg_gen_addi_i32(addr
, addr
, 4);
7184 tmp
= load_reg(s
, a
->rt
+ 1);
7185 gen_aa32_st_i32(s
, tmp
, addr
, mem_idx
, MO_UL
| s
->be_data
);
7186 tcg_temp_free_i32(tmp
);
7188 op_addr_rr_post(s
, a
, addr
, -4);
7193 * Load/store immediate index
7196 static TCGv_i32
op_addr_ri_pre(DisasContext
*s
, arg_ldst_ri
*a
)
7204 if (s
->v8m_stackcheck
&& a
->rn
== 13 && a
->w
) {
7206 * Stackcheck. Here we know 'addr' is the current SP;
7207 * U is set if we're moving SP up, else down. It is
7208 * UNKNOWN whether the limit check triggers when SP starts
7209 * below the limit and ends up above it; we chose to do so.
7212 TCGv_i32 newsp
= tcg_temp_new_i32();
7213 tcg_gen_addi_i32(newsp
, cpu_R
[13], ofs
);
7214 gen_helper_v8m_stackcheck(cpu_env
, newsp
);
7215 tcg_temp_free_i32(newsp
);
7217 gen_helper_v8m_stackcheck(cpu_env
, cpu_R
[13]);
7221 return add_reg_for_lit(s
, a
->rn
, a
->p
? ofs
: 0);
7224 static void op_addr_ri_post(DisasContext
*s
, arg_ldst_ri
*a
,
7225 TCGv_i32 addr
, int address_offset
)
7229 address_offset
+= a
->imm
;
7231 address_offset
-= a
->imm
;
7234 tcg_temp_free_i32(addr
);
7237 tcg_gen_addi_i32(addr
, addr
, address_offset
);
7238 store_reg(s
, a
->rn
, addr
);
7241 static bool op_load_ri(DisasContext
*s
, arg_ldst_ri
*a
,
7242 MemOp mop
, int mem_idx
)
7244 ISSInfo issinfo
= make_issinfo(s
, a
->rt
, a
->p
, a
->w
);
7247 addr
= op_addr_ri_pre(s
, a
);
7249 tmp
= tcg_temp_new_i32();
7250 gen_aa32_ld_i32(s
, tmp
, addr
, mem_idx
, mop
| s
->be_data
);
7251 disas_set_da_iss(s
, mop
, issinfo
);
7254 * Perform base writeback before the loaded value to
7255 * ensure correct behavior with overlapping index registers.
7257 op_addr_ri_post(s
, a
, addr
, 0);
7258 store_reg_from_load(s
, a
->rt
, tmp
);
7262 static bool op_store_ri(DisasContext
*s
, arg_ldst_ri
*a
,
7263 MemOp mop
, int mem_idx
)
7265 ISSInfo issinfo
= make_issinfo(s
, a
->rt
, a
->p
, a
->w
) | ISSIsWrite
;
7268 addr
= op_addr_ri_pre(s
, a
);
7270 tmp
= load_reg(s
, a
->rt
);
7271 gen_aa32_st_i32(s
, tmp
, addr
, mem_idx
, mop
| s
->be_data
);
7272 disas_set_da_iss(s
, mop
, issinfo
);
7273 tcg_temp_free_i32(tmp
);
7275 op_addr_ri_post(s
, a
, addr
, 0);
7279 static bool op_ldrd_ri(DisasContext
*s
, arg_ldst_ri
*a
, int rt2
)
7281 int mem_idx
= get_mem_index(s
);
7284 addr
= op_addr_ri_pre(s
, a
);
7286 tmp
= tcg_temp_new_i32();
7287 gen_aa32_ld_i32(s
, tmp
, addr
, mem_idx
, MO_UL
| s
->be_data
);
7288 store_reg(s
, a
->rt
, tmp
);
7290 tcg_gen_addi_i32(addr
, addr
, 4);
7292 tmp
= tcg_temp_new_i32();
7293 gen_aa32_ld_i32(s
, tmp
, addr
, mem_idx
, MO_UL
| s
->be_data
);
7294 store_reg(s
, rt2
, tmp
);
7296 /* LDRD w/ base writeback is undefined if the registers overlap. */
7297 op_addr_ri_post(s
, a
, addr
, -4);
7301 static bool trans_LDRD_ri_a32(DisasContext
*s
, arg_ldst_ri
*a
)
7303 if (!ENABLE_ARCH_5TE
|| (a
->rt
& 1)) {
7306 return op_ldrd_ri(s
, a
, a
->rt
+ 1);
7309 static bool trans_LDRD_ri_t32(DisasContext
*s
, arg_ldst_ri2
*a
)
7312 .u
= a
->u
, .w
= a
->w
, .p
= a
->p
,
7313 .rn
= a
->rn
, .rt
= a
->rt
, .imm
= a
->imm
7315 return op_ldrd_ri(s
, &b
, a
->rt2
);
7318 static bool op_strd_ri(DisasContext
*s
, arg_ldst_ri
*a
, int rt2
)
7320 int mem_idx
= get_mem_index(s
);
7323 addr
= op_addr_ri_pre(s
, a
);
7325 tmp
= load_reg(s
, a
->rt
);
7326 gen_aa32_st_i32(s
, tmp
, addr
, mem_idx
, MO_UL
| s
->be_data
);
7327 tcg_temp_free_i32(tmp
);
7329 tcg_gen_addi_i32(addr
, addr
, 4);
7331 tmp
= load_reg(s
, rt2
);
7332 gen_aa32_st_i32(s
, tmp
, addr
, mem_idx
, MO_UL
| s
->be_data
);
7333 tcg_temp_free_i32(tmp
);
7335 op_addr_ri_post(s
, a
, addr
, -4);
7339 static bool trans_STRD_ri_a32(DisasContext
*s
, arg_ldst_ri
*a
)
7341 if (!ENABLE_ARCH_5TE
|| (a
->rt
& 1)) {
7344 return op_strd_ri(s
, a
, a
->rt
+ 1);
7347 static bool trans_STRD_ri_t32(DisasContext
*s
, arg_ldst_ri2
*a
)
7350 .u
= a
->u
, .w
= a
->w
, .p
= a
->p
,
7351 .rn
= a
->rn
, .rt
= a
->rt
, .imm
= a
->imm
7353 return op_strd_ri(s
, &b
, a
->rt2
);
7356 #define DO_LDST(NAME, WHICH, MEMOP) \
7357 static bool trans_##NAME##_ri(DisasContext *s, arg_ldst_ri *a) \
7359 return op_##WHICH##_ri(s, a, MEMOP, get_mem_index(s)); \
7361 static bool trans_##NAME##T_ri(DisasContext *s, arg_ldst_ri *a) \
7363 return op_##WHICH##_ri(s, a, MEMOP, get_a32_user_mem_index(s)); \
7365 static bool trans_##NAME##_rr(DisasContext *s, arg_ldst_rr *a) \
7367 return op_##WHICH##_rr(s, a, MEMOP, get_mem_index(s)); \
7369 static bool trans_##NAME##T_rr(DisasContext *s, arg_ldst_rr *a) \
7371 return op_##WHICH##_rr(s, a, MEMOP, get_a32_user_mem_index(s)); \
7374 DO_LDST(LDR
, load
, MO_UL
)
7375 DO_LDST(LDRB
, load
, MO_UB
)
7376 DO_LDST(LDRH
, load
, MO_UW
)
7377 DO_LDST(LDRSB
, load
, MO_SB
)
7378 DO_LDST(LDRSH
, load
, MO_SW
)
7380 DO_LDST(STR
, store
, MO_UL
)
7381 DO_LDST(STRB
, store
, MO_UB
)
7382 DO_LDST(STRH
, store
, MO_UW
)
7387 * Synchronization primitives
7390 static bool op_swp(DisasContext
*s
, arg_SWP
*a
, MemOp opc
)
7396 addr
= load_reg(s
, a
->rn
);
7397 taddr
= gen_aa32_addr(s
, addr
, opc
);
7398 tcg_temp_free_i32(addr
);
7400 tmp
= load_reg(s
, a
->rt2
);
7401 tcg_gen_atomic_xchg_i32(tmp
, taddr
, tmp
, get_mem_index(s
), opc
);
7402 tcg_temp_free(taddr
);
7404 store_reg(s
, a
->rt
, tmp
);
7408 static bool trans_SWP(DisasContext
*s
, arg_SWP
*a
)
7410 return op_swp(s
, a
, MO_UL
| MO_ALIGN
);
7413 static bool trans_SWPB(DisasContext
*s
, arg_SWP
*a
)
7415 return op_swp(s
, a
, MO_UB
);
7419 * Load/Store Exclusive and Load-Acquire/Store-Release
7422 static bool op_strex(DisasContext
*s
, arg_STREX
*a
, MemOp mop
, bool rel
)
7425 /* Some cases stopped being UNPREDICTABLE in v8A (but not v8M) */
7426 bool v8a
= ENABLE_ARCH_8
&& !arm_dc_feature(s
, ARM_FEATURE_M
);
7428 /* We UNDEF for these UNPREDICTABLE cases. */
7429 if (a
->rd
== 15 || a
->rn
== 15 || a
->rt
== 15
7430 || a
->rd
== a
->rn
|| a
->rd
== a
->rt
7431 || (!v8a
&& s
->thumb
&& (a
->rd
== 13 || a
->rt
== 13))
7435 || (!v8a
&& s
->thumb
&& a
->rt2
== 13)))) {
7436 unallocated_encoding(s
);
7441 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_STRL
);
7444 addr
= tcg_temp_local_new_i32();
7445 load_reg_var(s
, addr
, a
->rn
);
7446 tcg_gen_addi_i32(addr
, addr
, a
->imm
);
7448 gen_store_exclusive(s
, a
->rd
, a
->rt
, a
->rt2
, addr
, mop
);
7449 tcg_temp_free_i32(addr
);
7453 static bool trans_STREX(DisasContext
*s
, arg_STREX
*a
)
7455 if (!ENABLE_ARCH_6
) {
7458 return op_strex(s
, a
, MO_32
, false);
7461 static bool trans_STREXD_a32(DisasContext
*s
, arg_STREX
*a
)
7463 if (!ENABLE_ARCH_6K
) {
7466 /* We UNDEF for these UNPREDICTABLE cases. */
7468 unallocated_encoding(s
);
7472 return op_strex(s
, a
, MO_64
, false);
7475 static bool trans_STREXD_t32(DisasContext
*s
, arg_STREX
*a
)
7477 return op_strex(s
, a
, MO_64
, false);
7480 static bool trans_STREXB(DisasContext
*s
, arg_STREX
*a
)
7482 if (s
->thumb
? !ENABLE_ARCH_7
: !ENABLE_ARCH_6K
) {
7485 return op_strex(s
, a
, MO_8
, false);
7488 static bool trans_STREXH(DisasContext
*s
, arg_STREX
*a
)
7490 if (s
->thumb
? !ENABLE_ARCH_7
: !ENABLE_ARCH_6K
) {
7493 return op_strex(s
, a
, MO_16
, false);
7496 static bool trans_STLEX(DisasContext
*s
, arg_STREX
*a
)
7498 if (!ENABLE_ARCH_8
) {
7501 return op_strex(s
, a
, MO_32
, true);
7504 static bool trans_STLEXD_a32(DisasContext
*s
, arg_STREX
*a
)
7506 if (!ENABLE_ARCH_8
) {
7509 /* We UNDEF for these UNPREDICTABLE cases. */
7511 unallocated_encoding(s
);
7515 return op_strex(s
, a
, MO_64
, true);
7518 static bool trans_STLEXD_t32(DisasContext
*s
, arg_STREX
*a
)
7520 if (!ENABLE_ARCH_8
) {
7523 return op_strex(s
, a
, MO_64
, true);
7526 static bool trans_STLEXB(DisasContext
*s
, arg_STREX
*a
)
7528 if (!ENABLE_ARCH_8
) {
7531 return op_strex(s
, a
, MO_8
, true);
7534 static bool trans_STLEXH(DisasContext
*s
, arg_STREX
*a
)
7536 if (!ENABLE_ARCH_8
) {
7539 return op_strex(s
, a
, MO_16
, true);
7542 static bool op_stl(DisasContext
*s
, arg_STL
*a
, MemOp mop
)
7546 if (!ENABLE_ARCH_8
) {
7549 /* We UNDEF for these UNPREDICTABLE cases. */
7550 if (a
->rn
== 15 || a
->rt
== 15) {
7551 unallocated_encoding(s
);
7555 addr
= load_reg(s
, a
->rn
);
7556 tmp
= load_reg(s
, a
->rt
);
7557 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_STRL
);
7558 gen_aa32_st_i32(s
, tmp
, addr
, get_mem_index(s
), mop
| s
->be_data
);
7559 disas_set_da_iss(s
, mop
, a
->rt
| ISSIsAcqRel
| ISSIsWrite
);
7561 tcg_temp_free_i32(tmp
);
7562 tcg_temp_free_i32(addr
);
7566 static bool trans_STL(DisasContext
*s
, arg_STL
*a
)
7568 return op_stl(s
, a
, MO_UL
);
7571 static bool trans_STLB(DisasContext
*s
, arg_STL
*a
)
7573 return op_stl(s
, a
, MO_UB
);
7576 static bool trans_STLH(DisasContext
*s
, arg_STL
*a
)
7578 return op_stl(s
, a
, MO_UW
);
7581 static bool op_ldrex(DisasContext
*s
, arg_LDREX
*a
, MemOp mop
, bool acq
)
7584 /* Some cases stopped being UNPREDICTABLE in v8A (but not v8M) */
7585 bool v8a
= ENABLE_ARCH_8
&& !arm_dc_feature(s
, ARM_FEATURE_M
);
7587 /* We UNDEF for these UNPREDICTABLE cases. */
7588 if (a
->rn
== 15 || a
->rt
== 15
7589 || (!v8a
&& s
->thumb
&& a
->rt
== 13)
7591 && (a
->rt2
== 15 || a
->rt
== a
->rt2
7592 || (!v8a
&& s
->thumb
&& a
->rt2
== 13)))) {
7593 unallocated_encoding(s
);
7597 addr
= tcg_temp_local_new_i32();
7598 load_reg_var(s
, addr
, a
->rn
);
7599 tcg_gen_addi_i32(addr
, addr
, a
->imm
);
7601 gen_load_exclusive(s
, a
->rt
, a
->rt2
, addr
, mop
);
7602 tcg_temp_free_i32(addr
);
7605 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_LDAQ
);
7610 static bool trans_LDREX(DisasContext
*s
, arg_LDREX
*a
)
7612 if (!ENABLE_ARCH_6
) {
7615 return op_ldrex(s
, a
, MO_32
, false);
7618 static bool trans_LDREXD_a32(DisasContext
*s
, arg_LDREX
*a
)
7620 if (!ENABLE_ARCH_6K
) {
7623 /* We UNDEF for these UNPREDICTABLE cases. */
7625 unallocated_encoding(s
);
7629 return op_ldrex(s
, a
, MO_64
, false);
7632 static bool trans_LDREXD_t32(DisasContext
*s
, arg_LDREX
*a
)
7634 return op_ldrex(s
, a
, MO_64
, false);
7637 static bool trans_LDREXB(DisasContext
*s
, arg_LDREX
*a
)
7639 if (s
->thumb
? !ENABLE_ARCH_7
: !ENABLE_ARCH_6K
) {
7642 return op_ldrex(s
, a
, MO_8
, false);
7645 static bool trans_LDREXH(DisasContext
*s
, arg_LDREX
*a
)
7647 if (s
->thumb
? !ENABLE_ARCH_7
: !ENABLE_ARCH_6K
) {
7650 return op_ldrex(s
, a
, MO_16
, false);
7653 static bool trans_LDAEX(DisasContext
*s
, arg_LDREX
*a
)
7655 if (!ENABLE_ARCH_8
) {
7658 return op_ldrex(s
, a
, MO_32
, true);
7661 static bool trans_LDAEXD_a32(DisasContext
*s
, arg_LDREX
*a
)
7663 if (!ENABLE_ARCH_8
) {
7666 /* We UNDEF for these UNPREDICTABLE cases. */
7668 unallocated_encoding(s
);
7672 return op_ldrex(s
, a
, MO_64
, true);
7675 static bool trans_LDAEXD_t32(DisasContext
*s
, arg_LDREX
*a
)
7677 if (!ENABLE_ARCH_8
) {
7680 return op_ldrex(s
, a
, MO_64
, true);
7683 static bool trans_LDAEXB(DisasContext
*s
, arg_LDREX
*a
)
7685 if (!ENABLE_ARCH_8
) {
7688 return op_ldrex(s
, a
, MO_8
, true);
7691 static bool trans_LDAEXH(DisasContext
*s
, arg_LDREX
*a
)
7693 if (!ENABLE_ARCH_8
) {
7696 return op_ldrex(s
, a
, MO_16
, true);
7699 static bool op_lda(DisasContext
*s
, arg_LDA
*a
, MemOp mop
)
7703 if (!ENABLE_ARCH_8
) {
7706 /* We UNDEF for these UNPREDICTABLE cases. */
7707 if (a
->rn
== 15 || a
->rt
== 15) {
7708 unallocated_encoding(s
);
7712 addr
= load_reg(s
, a
->rn
);
7713 tmp
= tcg_temp_new_i32();
7714 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
), mop
| s
->be_data
);
7715 disas_set_da_iss(s
, mop
, a
->rt
| ISSIsAcqRel
);
7716 tcg_temp_free_i32(addr
);
7718 store_reg(s
, a
->rt
, tmp
);
7719 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_STRL
);
7723 static bool trans_LDA(DisasContext
*s
, arg_LDA
*a
)
7725 return op_lda(s
, a
, MO_UL
);
7728 static bool trans_LDAB(DisasContext
*s
, arg_LDA
*a
)
7730 return op_lda(s
, a
, MO_UB
);
7733 static bool trans_LDAH(DisasContext
*s
, arg_LDA
*a
)
7735 return op_lda(s
, a
, MO_UW
);
7739 * Media instructions
7742 static bool trans_USADA8(DisasContext
*s
, arg_USADA8
*a
)
7746 if (!ENABLE_ARCH_6
) {
7750 t1
= load_reg(s
, a
->rn
);
7751 t2
= load_reg(s
, a
->rm
);
7752 gen_helper_usad8(t1
, t1
, t2
);
7753 tcg_temp_free_i32(t2
);
7755 t2
= load_reg(s
, a
->ra
);
7756 tcg_gen_add_i32(t1
, t1
, t2
);
7757 tcg_temp_free_i32(t2
);
7759 store_reg(s
, a
->rd
, t1
);
7763 static bool op_bfx(DisasContext
*s
, arg_UBFX
*a
, bool u
)
7766 int width
= a
->widthm1
+ 1;
7769 if (!ENABLE_ARCH_6T2
) {
7772 if (shift
+ width
> 32) {
7773 /* UNPREDICTABLE; we choose to UNDEF */
7774 unallocated_encoding(s
);
7778 tmp
= load_reg(s
, a
->rn
);
7780 tcg_gen_extract_i32(tmp
, tmp
, shift
, width
);
7782 tcg_gen_sextract_i32(tmp
, tmp
, shift
, width
);
7784 store_reg(s
, a
->rd
, tmp
);
7788 static bool trans_SBFX(DisasContext
*s
, arg_SBFX
*a
)
7790 return op_bfx(s
, a
, false);
7793 static bool trans_UBFX(DisasContext
*s
, arg_UBFX
*a
)
7795 return op_bfx(s
, a
, true);
7798 static bool trans_BFCI(DisasContext
*s
, arg_BFCI
*a
)
7801 int msb
= a
->msb
, lsb
= a
->lsb
;
7804 if (!ENABLE_ARCH_6T2
) {
7808 /* UNPREDICTABLE; we choose to UNDEF */
7809 unallocated_encoding(s
);
7813 width
= msb
+ 1 - lsb
;
7816 tmp
= tcg_const_i32(0);
7819 tmp
= load_reg(s
, a
->rn
);
7822 TCGv_i32 tmp2
= load_reg(s
, a
->rd
);
7823 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, lsb
, width
);
7824 tcg_temp_free_i32(tmp2
);
7826 store_reg(s
, a
->rd
, tmp
);
7830 static bool trans_UDF(DisasContext
*s
, arg_UDF
*a
)
7832 unallocated_encoding(s
);
7837 * Parallel addition and subtraction
7840 static bool op_par_addsub(DisasContext
*s
, arg_rrr
*a
,
7841 void (*gen
)(TCGv_i32
, TCGv_i32
, TCGv_i32
))
7846 ? !arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)
7851 t0
= load_reg(s
, a
->rn
);
7852 t1
= load_reg(s
, a
->rm
);
7856 tcg_temp_free_i32(t1
);
7857 store_reg(s
, a
->rd
, t0
);
7861 static bool op_par_addsub_ge(DisasContext
*s
, arg_rrr
*a
,
7862 void (*gen
)(TCGv_i32
, TCGv_i32
,
7863 TCGv_i32
, TCGv_ptr
))
7869 ? !arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)
7874 t0
= load_reg(s
, a
->rn
);
7875 t1
= load_reg(s
, a
->rm
);
7877 ge
= tcg_temp_new_ptr();
7878 tcg_gen_addi_ptr(ge
, cpu_env
, offsetof(CPUARMState
, GE
));
7879 gen(t0
, t0
, t1
, ge
);
7881 tcg_temp_free_ptr(ge
);
7882 tcg_temp_free_i32(t1
);
7883 store_reg(s
, a
->rd
, t0
);
7887 #define DO_PAR_ADDSUB(NAME, helper) \
7888 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
7890 return op_par_addsub(s, a, helper); \
7893 #define DO_PAR_ADDSUB_GE(NAME, helper) \
7894 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
7896 return op_par_addsub_ge(s, a, helper); \
7899 DO_PAR_ADDSUB_GE(SADD16
, gen_helper_sadd16
)
7900 DO_PAR_ADDSUB_GE(SASX
, gen_helper_saddsubx
)
7901 DO_PAR_ADDSUB_GE(SSAX
, gen_helper_ssubaddx
)
7902 DO_PAR_ADDSUB_GE(SSUB16
, gen_helper_ssub16
)
7903 DO_PAR_ADDSUB_GE(SADD8
, gen_helper_sadd8
)
7904 DO_PAR_ADDSUB_GE(SSUB8
, gen_helper_ssub8
)
7906 DO_PAR_ADDSUB_GE(UADD16
, gen_helper_uadd16
)
7907 DO_PAR_ADDSUB_GE(UASX
, gen_helper_uaddsubx
)
7908 DO_PAR_ADDSUB_GE(USAX
, gen_helper_usubaddx
)
7909 DO_PAR_ADDSUB_GE(USUB16
, gen_helper_usub16
)
7910 DO_PAR_ADDSUB_GE(UADD8
, gen_helper_uadd8
)
7911 DO_PAR_ADDSUB_GE(USUB8
, gen_helper_usub8
)
7913 DO_PAR_ADDSUB(QADD16
, gen_helper_qadd16
)
7914 DO_PAR_ADDSUB(QASX
, gen_helper_qaddsubx
)
7915 DO_PAR_ADDSUB(QSAX
, gen_helper_qsubaddx
)
7916 DO_PAR_ADDSUB(QSUB16
, gen_helper_qsub16
)
7917 DO_PAR_ADDSUB(QADD8
, gen_helper_qadd8
)
7918 DO_PAR_ADDSUB(QSUB8
, gen_helper_qsub8
)
7920 DO_PAR_ADDSUB(UQADD16
, gen_helper_uqadd16
)
7921 DO_PAR_ADDSUB(UQASX
, gen_helper_uqaddsubx
)
7922 DO_PAR_ADDSUB(UQSAX
, gen_helper_uqsubaddx
)
7923 DO_PAR_ADDSUB(UQSUB16
, gen_helper_uqsub16
)
7924 DO_PAR_ADDSUB(UQADD8
, gen_helper_uqadd8
)
7925 DO_PAR_ADDSUB(UQSUB8
, gen_helper_uqsub8
)
7927 DO_PAR_ADDSUB(SHADD16
, gen_helper_shadd16
)
7928 DO_PAR_ADDSUB(SHASX
, gen_helper_shaddsubx
)
7929 DO_PAR_ADDSUB(SHSAX
, gen_helper_shsubaddx
)
7930 DO_PAR_ADDSUB(SHSUB16
, gen_helper_shsub16
)
7931 DO_PAR_ADDSUB(SHADD8
, gen_helper_shadd8
)
7932 DO_PAR_ADDSUB(SHSUB8
, gen_helper_shsub8
)
7934 DO_PAR_ADDSUB(UHADD16
, gen_helper_uhadd16
)
7935 DO_PAR_ADDSUB(UHASX
, gen_helper_uhaddsubx
)
7936 DO_PAR_ADDSUB(UHSAX
, gen_helper_uhsubaddx
)
7937 DO_PAR_ADDSUB(UHSUB16
, gen_helper_uhsub16
)
7938 DO_PAR_ADDSUB(UHADD8
, gen_helper_uhadd8
)
7939 DO_PAR_ADDSUB(UHSUB8
, gen_helper_uhsub8
)
7941 #undef DO_PAR_ADDSUB
7942 #undef DO_PAR_ADDSUB_GE
7945 * Packing, unpacking, saturation, and reversal
7948 static bool trans_PKH(DisasContext
*s
, arg_PKH
*a
)
7954 ? !arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)
7959 tn
= load_reg(s
, a
->rn
);
7960 tm
= load_reg(s
, a
->rm
);
7966 tcg_gen_sari_i32(tm
, tm
, shift
);
7967 tcg_gen_deposit_i32(tn
, tn
, tm
, 0, 16);
7970 tcg_gen_shli_i32(tm
, tm
, shift
);
7971 tcg_gen_deposit_i32(tn
, tm
, tn
, 0, 16);
7973 tcg_temp_free_i32(tm
);
7974 store_reg(s
, a
->rd
, tn
);
7978 static bool op_sat(DisasContext
*s
, arg_sat
*a
,
7979 void (*gen
)(TCGv_i32
, TCGv_env
, TCGv_i32
, TCGv_i32
))
7981 TCGv_i32 tmp
, satimm
;
7984 if (!ENABLE_ARCH_6
) {
7988 tmp
= load_reg(s
, a
->rn
);
7990 tcg_gen_sari_i32(tmp
, tmp
, shift
? shift
: 31);
7992 tcg_gen_shli_i32(tmp
, tmp
, shift
);
7995 satimm
= tcg_const_i32(a
->satimm
);
7996 gen(tmp
, cpu_env
, tmp
, satimm
);
7997 tcg_temp_free_i32(satimm
);
7999 store_reg(s
, a
->rd
, tmp
);
8003 static bool trans_SSAT(DisasContext
*s
, arg_sat
*a
)
8005 return op_sat(s
, a
, gen_helper_ssat
);
8008 static bool trans_USAT(DisasContext
*s
, arg_sat
*a
)
8010 return op_sat(s
, a
, gen_helper_usat
);
8013 static bool trans_SSAT16(DisasContext
*s
, arg_sat
*a
)
8015 if (s
->thumb
&& !arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
8018 return op_sat(s
, a
, gen_helper_ssat16
);
8021 static bool trans_USAT16(DisasContext
*s
, arg_sat
*a
)
8023 if (s
->thumb
&& !arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
8026 return op_sat(s
, a
, gen_helper_usat16
);
8029 static bool op_xta(DisasContext
*s
, arg_rrr_rot
*a
,
8030 void (*gen_extract
)(TCGv_i32
, TCGv_i32
),
8031 void (*gen_add
)(TCGv_i32
, TCGv_i32
, TCGv_i32
))
8035 if (!ENABLE_ARCH_6
) {
8039 tmp
= load_reg(s
, a
->rm
);
8041 * TODO: In many cases we could do a shift instead of a rotate.
8042 * Combined with a simple extend, that becomes an extract.
8044 tcg_gen_rotri_i32(tmp
, tmp
, a
->rot
* 8);
8045 gen_extract(tmp
, tmp
);
8048 TCGv_i32 tmp2
= load_reg(s
, a
->rn
);
8049 gen_add(tmp
, tmp
, tmp2
);
8050 tcg_temp_free_i32(tmp2
);
8052 store_reg(s
, a
->rd
, tmp
);
8056 static bool trans_SXTAB(DisasContext
*s
, arg_rrr_rot
*a
)
8058 return op_xta(s
, a
, tcg_gen_ext8s_i32
, tcg_gen_add_i32
);
8061 static bool trans_SXTAH(DisasContext
*s
, arg_rrr_rot
*a
)
8063 return op_xta(s
, a
, tcg_gen_ext16s_i32
, tcg_gen_add_i32
);
8066 static bool trans_SXTAB16(DisasContext
*s
, arg_rrr_rot
*a
)
8068 if (s
->thumb
&& !arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
8071 return op_xta(s
, a
, gen_helper_sxtb16
, gen_add16
);
8074 static bool trans_UXTAB(DisasContext
*s
, arg_rrr_rot
*a
)
8076 return op_xta(s
, a
, tcg_gen_ext8u_i32
, tcg_gen_add_i32
);
8079 static bool trans_UXTAH(DisasContext
*s
, arg_rrr_rot
*a
)
8081 return op_xta(s
, a
, tcg_gen_ext16u_i32
, tcg_gen_add_i32
);
8084 static bool trans_UXTAB16(DisasContext
*s
, arg_rrr_rot
*a
)
8086 if (s
->thumb
&& !arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
8089 return op_xta(s
, a
, gen_helper_uxtb16
, gen_add16
);
8092 static bool trans_SEL(DisasContext
*s
, arg_rrr
*a
)
8094 TCGv_i32 t1
, t2
, t3
;
8097 ? !arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)
8102 t1
= load_reg(s
, a
->rn
);
8103 t2
= load_reg(s
, a
->rm
);
8104 t3
= tcg_temp_new_i32();
8105 tcg_gen_ld_i32(t3
, cpu_env
, offsetof(CPUARMState
, GE
));
8106 gen_helper_sel_flags(t1
, t3
, t1
, t2
);
8107 tcg_temp_free_i32(t3
);
8108 tcg_temp_free_i32(t2
);
8109 store_reg(s
, a
->rd
, t1
);
8113 static bool op_rr(DisasContext
*s
, arg_rr
*a
,
8114 void (*gen
)(TCGv_i32
, TCGv_i32
))
8118 tmp
= load_reg(s
, a
->rm
);
8120 store_reg(s
, a
->rd
, tmp
);
8124 static bool trans_REV(DisasContext
*s
, arg_rr
*a
)
8126 if (!ENABLE_ARCH_6
) {
8129 return op_rr(s
, a
, tcg_gen_bswap32_i32
);
8132 static bool trans_REV16(DisasContext
*s
, arg_rr
*a
)
8134 if (!ENABLE_ARCH_6
) {
8137 return op_rr(s
, a
, gen_rev16
);
8140 static bool trans_REVSH(DisasContext
*s
, arg_rr
*a
)
8142 if (!ENABLE_ARCH_6
) {
8145 return op_rr(s
, a
, gen_revsh
);
8148 static bool trans_RBIT(DisasContext
*s
, arg_rr
*a
)
8150 if (!ENABLE_ARCH_6T2
) {
8153 return op_rr(s
, a
, gen_helper_rbit
);
8157 * Signed multiply, signed and unsigned divide
8160 static bool op_smlad(DisasContext
*s
, arg_rrrr
*a
, bool m_swap
, bool sub
)
8164 if (!ENABLE_ARCH_6
) {
8168 t1
= load_reg(s
, a
->rn
);
8169 t2
= load_reg(s
, a
->rm
);
8173 gen_smul_dual(t1
, t2
);
8176 /* This subtraction cannot overflow. */
8177 tcg_gen_sub_i32(t1
, t1
, t2
);
8180 * This addition cannot overflow 32 bits; however it may
8181 * overflow considered as a signed operation, in which case
8182 * we must set the Q flag.
8184 gen_helper_add_setq(t1
, cpu_env
, t1
, t2
);
8186 tcg_temp_free_i32(t2
);
8189 t2
= load_reg(s
, a
->ra
);
8190 gen_helper_add_setq(t1
, cpu_env
, t1
, t2
);
8191 tcg_temp_free_i32(t2
);
8193 store_reg(s
, a
->rd
, t1
);
8197 static bool trans_SMLAD(DisasContext
*s
, arg_rrrr
*a
)
8199 return op_smlad(s
, a
, false, false);
8202 static bool trans_SMLADX(DisasContext
*s
, arg_rrrr
*a
)
8204 return op_smlad(s
, a
, true, false);
8207 static bool trans_SMLSD(DisasContext
*s
, arg_rrrr
*a
)
8209 return op_smlad(s
, a
, false, true);
8212 static bool trans_SMLSDX(DisasContext
*s
, arg_rrrr
*a
)
8214 return op_smlad(s
, a
, true, true);
8217 static bool op_smlald(DisasContext
*s
, arg_rrrr
*a
, bool m_swap
, bool sub
)
8222 if (!ENABLE_ARCH_6
) {
8226 t1
= load_reg(s
, a
->rn
);
8227 t2
= load_reg(s
, a
->rm
);
8231 gen_smul_dual(t1
, t2
);
8233 l1
= tcg_temp_new_i64();
8234 l2
= tcg_temp_new_i64();
8235 tcg_gen_ext_i32_i64(l1
, t1
);
8236 tcg_gen_ext_i32_i64(l2
, t2
);
8237 tcg_temp_free_i32(t1
);
8238 tcg_temp_free_i32(t2
);
8241 tcg_gen_sub_i64(l1
, l1
, l2
);
8243 tcg_gen_add_i64(l1
, l1
, l2
);
8245 tcg_temp_free_i64(l2
);
8247 gen_addq(s
, l1
, a
->ra
, a
->rd
);
8248 gen_storeq_reg(s
, a
->ra
, a
->rd
, l1
);
8249 tcg_temp_free_i64(l1
);
8253 static bool trans_SMLALD(DisasContext
*s
, arg_rrrr
*a
)
8255 return op_smlald(s
, a
, false, false);
8258 static bool trans_SMLALDX(DisasContext
*s
, arg_rrrr
*a
)
8260 return op_smlald(s
, a
, true, false);
8263 static bool trans_SMLSLD(DisasContext
*s
, arg_rrrr
*a
)
8265 return op_smlald(s
, a
, false, true);
8268 static bool trans_SMLSLDX(DisasContext
*s
, arg_rrrr
*a
)
8270 return op_smlald(s
, a
, true, true);
8273 static bool op_smmla(DisasContext
*s
, arg_rrrr
*a
, bool round
, bool sub
)
8278 ? !arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)
8283 t1
= load_reg(s
, a
->rn
);
8284 t2
= load_reg(s
, a
->rm
);
8285 tcg_gen_muls2_i32(t2
, t1
, t1
, t2
);
8288 TCGv_i32 t3
= load_reg(s
, a
->ra
);
8291 * For SMMLS, we need a 64-bit subtract. Borrow caused by
8292 * a non-zero multiplicand lowpart, and the correct result
8293 * lowpart for rounding.
8295 TCGv_i32 zero
= tcg_const_i32(0);
8296 tcg_gen_sub2_i32(t2
, t1
, zero
, t3
, t2
, t1
);
8297 tcg_temp_free_i32(zero
);
8299 tcg_gen_add_i32(t1
, t1
, t3
);
8301 tcg_temp_free_i32(t3
);
8305 * Adding 0x80000000 to the 64-bit quantity means that we have
8306 * carry in to the high word when the low word has the msb set.
8308 tcg_gen_shri_i32(t2
, t2
, 31);
8309 tcg_gen_add_i32(t1
, t1
, t2
);
8311 tcg_temp_free_i32(t2
);
8312 store_reg(s
, a
->rd
, t1
);
8316 static bool trans_SMMLA(DisasContext
*s
, arg_rrrr
*a
)
8318 return op_smmla(s
, a
, false, false);
8321 static bool trans_SMMLAR(DisasContext
*s
, arg_rrrr
*a
)
8323 return op_smmla(s
, a
, true, false);
8326 static bool trans_SMMLS(DisasContext
*s
, arg_rrrr
*a
)
8328 return op_smmla(s
, a
, false, true);
8331 static bool trans_SMMLSR(DisasContext
*s
, arg_rrrr
*a
)
8333 return op_smmla(s
, a
, true, true);
8336 static bool op_div(DisasContext
*s
, arg_rrr
*a
, bool u
)
8341 ? !dc_isar_feature(aa32_thumb_div
, s
)
8342 : !dc_isar_feature(aa32_arm_div
, s
)) {
8346 t1
= load_reg(s
, a
->rn
);
8347 t2
= load_reg(s
, a
->rm
);
8349 gen_helper_udiv(t1
, t1
, t2
);
8351 gen_helper_sdiv(t1
, t1
, t2
);
8353 tcg_temp_free_i32(t2
);
8354 store_reg(s
, a
->rd
, t1
);
8358 static bool trans_SDIV(DisasContext
*s
, arg_rrr
*a
)
8360 return op_div(s
, a
, false);
8363 static bool trans_UDIV(DisasContext
*s
, arg_rrr
*a
)
8365 return op_div(s
, a
, true);
8369 * Block data transfer
8372 static TCGv_i32
op_addr_block_pre(DisasContext
*s
, arg_ldst_block
*a
, int n
)
8374 TCGv_i32 addr
= load_reg(s
, a
->rn
);
8379 tcg_gen_addi_i32(addr
, addr
, 4);
8382 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
8384 } else if (!a
->i
&& n
!= 1) {
8385 /* post decrement */
8386 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
8389 if (s
->v8m_stackcheck
&& a
->rn
== 13 && a
->w
) {
8391 * If the writeback is incrementing SP rather than
8392 * decrementing it, and the initial SP is below the
8393 * stack limit but the final written-back SP would
8394 * be above, then then we must not perform any memory
8395 * accesses, but it is IMPDEF whether we generate
8396 * an exception. We choose to do so in this case.
8397 * At this point 'addr' is the lowest address, so
8398 * either the original SP (if incrementing) or our
8399 * final SP (if decrementing), so that's what we check.
8401 gen_helper_v8m_stackcheck(cpu_env
, addr
);
8407 static void op_addr_block_post(DisasContext
*s
, arg_ldst_block
*a
,
8408 TCGv_i32 addr
, int n
)
8414 /* post increment */
8415 tcg_gen_addi_i32(addr
, addr
, 4);
8417 /* post decrement */
8418 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
8420 } else if (!a
->i
&& n
!= 1) {
8422 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
8424 store_reg(s
, a
->rn
, addr
);
8426 tcg_temp_free_i32(addr
);
8430 static bool op_stm(DisasContext
*s
, arg_ldst_block
*a
, int min_n
)
8432 int i
, j
, n
, list
, mem_idx
;
8434 TCGv_i32 addr
, tmp
, tmp2
;
8439 /* Only usable in supervisor mode. */
8440 unallocated_encoding(s
);
8447 if (n
< min_n
|| a
->rn
== 15) {
8448 unallocated_encoding(s
);
8452 addr
= op_addr_block_pre(s
, a
, n
);
8453 mem_idx
= get_mem_index(s
);
8455 for (i
= j
= 0; i
< 16; i
++) {
8456 if (!(list
& (1 << i
))) {
8460 if (user
&& i
!= 15) {
8461 tmp
= tcg_temp_new_i32();
8462 tmp2
= tcg_const_i32(i
);
8463 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
8464 tcg_temp_free_i32(tmp2
);
8466 tmp
= load_reg(s
, i
);
8468 gen_aa32_st32(s
, tmp
, addr
, mem_idx
);
8469 tcg_temp_free_i32(tmp
);
8471 /* No need to add after the last transfer. */
8473 tcg_gen_addi_i32(addr
, addr
, 4);
8477 op_addr_block_post(s
, a
, addr
, n
);
8481 static bool trans_STM(DisasContext
*s
, arg_ldst_block
*a
)
8483 /* BitCount(list) < 1 is UNPREDICTABLE */
8484 return op_stm(s
, a
, 1);
8487 static bool trans_STM_t32(DisasContext
*s
, arg_ldst_block
*a
)
8489 /* Writeback register in register list is UNPREDICTABLE for T32. */
8490 if (a
->w
&& (a
->list
& (1 << a
->rn
))) {
8491 unallocated_encoding(s
);
8494 /* BitCount(list) < 2 is UNPREDICTABLE */
8495 return op_stm(s
, a
, 2);
8498 static bool do_ldm(DisasContext
*s
, arg_ldst_block
*a
, int min_n
)
8500 int i
, j
, n
, list
, mem_idx
;
8503 bool exc_return
= false;
8504 TCGv_i32 addr
, tmp
, tmp2
, loaded_var
;
8507 /* LDM (user), LDM (exception return) */
8509 /* Only usable in supervisor mode. */
8510 unallocated_encoding(s
);
8513 if (extract32(a
->list
, 15, 1)) {
8517 /* LDM (user) does not allow writeback. */
8519 unallocated_encoding(s
);
8527 if (n
< min_n
|| a
->rn
== 15) {
8528 unallocated_encoding(s
);
8532 addr
= op_addr_block_pre(s
, a
, n
);
8533 mem_idx
= get_mem_index(s
);
8534 loaded_base
= false;
8537 for (i
= j
= 0; i
< 16; i
++) {
8538 if (!(list
& (1 << i
))) {
8542 tmp
= tcg_temp_new_i32();
8543 gen_aa32_ld32u(s
, tmp
, addr
, mem_idx
);
8545 tmp2
= tcg_const_i32(i
);
8546 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
8547 tcg_temp_free_i32(tmp2
);
8548 tcg_temp_free_i32(tmp
);
8549 } else if (i
== a
->rn
) {
8552 } else if (i
== 15 && exc_return
) {
8553 store_pc_exc_ret(s
, tmp
);
8555 store_reg_from_load(s
, i
, tmp
);
8558 /* No need to add after the last transfer. */
8560 tcg_gen_addi_i32(addr
, addr
, 4);
8564 op_addr_block_post(s
, a
, addr
, n
);
8567 /* Note that we reject base == pc above. */
8568 store_reg(s
, a
->rn
, loaded_var
);
8572 /* Restore CPSR from SPSR. */
8573 tmp
= load_cpu_field(spsr
);
8574 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
8577 gen_helper_cpsr_write_eret(cpu_env
, tmp
);
8578 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
8581 tcg_temp_free_i32(tmp
);
8582 /* Must exit loop to check un-masked IRQs */
8583 s
->base
.is_jmp
= DISAS_EXIT
;
8588 static bool trans_LDM_a32(DisasContext
*s
, arg_ldst_block
*a
)
8591 * Writeback register in register list is UNPREDICTABLE
8592 * for ArchVersion() >= 7. Prior to v7, A32 would write
8593 * an UNKNOWN value to the base register.
8595 if (ENABLE_ARCH_7
&& a
->w
&& (a
->list
& (1 << a
->rn
))) {
8596 unallocated_encoding(s
);
8599 /* BitCount(list) < 1 is UNPREDICTABLE */
8600 return do_ldm(s
, a
, 1);
8603 static bool trans_LDM_t32(DisasContext
*s
, arg_ldst_block
*a
)
8605 /* Writeback register in register list is UNPREDICTABLE for T32. */
8606 if (a
->w
&& (a
->list
& (1 << a
->rn
))) {
8607 unallocated_encoding(s
);
8610 /* BitCount(list) < 2 is UNPREDICTABLE */
8611 return do_ldm(s
, a
, 2);
8614 static bool trans_LDM_t16(DisasContext
*s
, arg_ldst_block
*a
)
8616 /* Writeback is conditional on the base register not being loaded. */
8617 a
->w
= !(a
->list
& (1 << a
->rn
));
8618 /* BitCount(list) < 1 is UNPREDICTABLE */
8619 return do_ldm(s
, a
, 1);
8623 * Branch, branch with link
8626 static bool trans_B(DisasContext
*s
, arg_i
*a
)
8628 gen_jmp(s
, read_pc(s
) + a
->imm
);
8632 static bool trans_B_cond_thumb(DisasContext
*s
, arg_ci
*a
)
8634 /* This has cond from encoding, required to be outside IT block. */
8635 if (a
->cond
>= 0xe) {
8638 if (s
->condexec_mask
) {
8639 unallocated_encoding(s
);
8642 arm_skip_unless(s
, a
->cond
);
8643 gen_jmp(s
, read_pc(s
) + a
->imm
);
8647 static bool trans_BL(DisasContext
*s
, arg_i
*a
)
8649 tcg_gen_movi_i32(cpu_R
[14], s
->base
.pc_next
| s
->thumb
);
8650 gen_jmp(s
, read_pc(s
) + a
->imm
);
8654 static bool trans_BLX_i(DisasContext
*s
, arg_BLX_i
*a
)
8658 /* For A32, ARCH(5) is checked near the start of the uncond block. */
8659 if (s
->thumb
&& (a
->imm
& 2)) {
8662 tcg_gen_movi_i32(cpu_R
[14], s
->base
.pc_next
| s
->thumb
);
8663 tmp
= tcg_const_i32(!s
->thumb
);
8664 store_cpu_field(tmp
, thumb
);
8665 gen_jmp(s
, (read_pc(s
) & ~3) + a
->imm
);
8669 static bool trans_BL_BLX_prefix(DisasContext
*s
, arg_BL_BLX_prefix
*a
)
8671 assert(!arm_dc_feature(s
, ARM_FEATURE_THUMB2
));
8672 tcg_gen_movi_i32(cpu_R
[14], read_pc(s
) + (a
->imm
<< 12));
8676 static bool trans_BL_suffix(DisasContext
*s
, arg_BL_suffix
*a
)
8678 TCGv_i32 tmp
= tcg_temp_new_i32();
8680 assert(!arm_dc_feature(s
, ARM_FEATURE_THUMB2
));
8681 tcg_gen_addi_i32(tmp
, cpu_R
[14], (a
->imm
<< 1) | 1);
8682 tcg_gen_movi_i32(cpu_R
[14], s
->base
.pc_next
| 1);
8687 static bool trans_BLX_suffix(DisasContext
*s
, arg_BLX_suffix
*a
)
8691 assert(!arm_dc_feature(s
, ARM_FEATURE_THUMB2
));
8692 if (!ENABLE_ARCH_5
) {
8695 tmp
= tcg_temp_new_i32();
8696 tcg_gen_addi_i32(tmp
, cpu_R
[14], a
->imm
<< 1);
8697 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
8698 tcg_gen_movi_i32(cpu_R
[14], s
->base
.pc_next
| 1);
8703 static bool op_tbranch(DisasContext
*s
, arg_tbranch
*a
, bool half
)
8707 tmp
= load_reg(s
, a
->rm
);
8709 tcg_gen_add_i32(tmp
, tmp
, tmp
);
8711 addr
= load_reg(s
, a
->rn
);
8712 tcg_gen_add_i32(addr
, addr
, tmp
);
8714 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
),
8715 half
? MO_UW
| s
->be_data
: MO_UB
);
8716 tcg_temp_free_i32(addr
);
8718 tcg_gen_add_i32(tmp
, tmp
, tmp
);
8719 tcg_gen_addi_i32(tmp
, tmp
, read_pc(s
));
8720 store_reg(s
, 15, tmp
);
8724 static bool trans_TBB(DisasContext
*s
, arg_tbranch
*a
)
8726 return op_tbranch(s
, a
, false);
8729 static bool trans_TBH(DisasContext
*s
, arg_tbranch
*a
)
8731 return op_tbranch(s
, a
, true);
8734 static bool trans_CBZ(DisasContext
*s
, arg_CBZ
*a
)
8736 TCGv_i32 tmp
= load_reg(s
, a
->rn
);
8738 arm_gen_condlabel(s
);
8739 tcg_gen_brcondi_i32(a
->nz
? TCG_COND_EQ
: TCG_COND_NE
,
8740 tmp
, 0, s
->condlabel
);
8741 tcg_temp_free_i32(tmp
);
8742 gen_jmp(s
, read_pc(s
) + a
->imm
);
8747 * Supervisor call - both T32 & A32 come here so we need to check
8748 * which mode we are in when checking for semihosting.
8751 static bool trans_SVC(DisasContext
*s
, arg_SVC
*a
)
8753 const uint32_t semihost_imm
= s
->thumb
? 0xab : 0x123456;
8755 if (!arm_dc_feature(s
, ARM_FEATURE_M
) && semihosting_enabled() &&
8756 #ifndef CONFIG_USER_ONLY
8759 (a
->imm
== semihost_imm
)) {
8760 gen_exception_internal_insn(s
, s
->pc_curr
, EXCP_SEMIHOST
);
8762 gen_set_pc_im(s
, s
->base
.pc_next
);
8763 s
->svc_imm
= a
->imm
;
8764 s
->base
.is_jmp
= DISAS_SWI
;
8770 * Unconditional system instructions
8773 static bool trans_RFE(DisasContext
*s
, arg_RFE
*a
)
8775 static const int8_t pre_offset
[4] = {
8776 /* DA */ -4, /* IA */ 0, /* DB */ -8, /* IB */ 4
8778 static const int8_t post_offset
[4] = {
8779 /* DA */ -8, /* IA */ 4, /* DB */ -4, /* IB */ 0
8781 TCGv_i32 addr
, t1
, t2
;
8783 if (!ENABLE_ARCH_6
|| arm_dc_feature(s
, ARM_FEATURE_M
)) {
8787 unallocated_encoding(s
);
8791 addr
= load_reg(s
, a
->rn
);
8792 tcg_gen_addi_i32(addr
, addr
, pre_offset
[a
->pu
]);
8794 /* Load PC into tmp and CPSR into tmp2. */
8795 t1
= tcg_temp_new_i32();
8796 gen_aa32_ld32u(s
, t1
, addr
, get_mem_index(s
));
8797 tcg_gen_addi_i32(addr
, addr
, 4);
8798 t2
= tcg_temp_new_i32();
8799 gen_aa32_ld32u(s
, t2
, addr
, get_mem_index(s
));
8802 /* Base writeback. */
8803 tcg_gen_addi_i32(addr
, addr
, post_offset
[a
->pu
]);
8804 store_reg(s
, a
->rn
, addr
);
8806 tcg_temp_free_i32(addr
);
8812 static bool trans_SRS(DisasContext
*s
, arg_SRS
*a
)
8814 if (!ENABLE_ARCH_6
|| arm_dc_feature(s
, ARM_FEATURE_M
)) {
8817 gen_srs(s
, a
->mode
, a
->pu
, a
->w
);
8821 static bool trans_CPS(DisasContext
*s
, arg_CPS
*a
)
8825 if (!ENABLE_ARCH_6
|| arm_dc_feature(s
, ARM_FEATURE_M
)) {
8829 /* Implemented as NOP in user mode. */
8832 /* TODO: There are quite a lot of UNPREDICTABLE argument combinations. */
8854 gen_set_psr_im(s
, mask
, 0, val
);
8859 static bool trans_CPS_v7m(DisasContext
*s
, arg_CPS_v7m
*a
)
8861 TCGv_i32 tmp
, addr
, el
;
8863 if (!arm_dc_feature(s
, ARM_FEATURE_M
)) {
8867 /* Implemented as NOP in user mode. */
8871 tmp
= tcg_const_i32(a
->im
);
8874 addr
= tcg_const_i32(19);
8875 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
8876 tcg_temp_free_i32(addr
);
8880 addr
= tcg_const_i32(16);
8881 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
8882 tcg_temp_free_i32(addr
);
8884 el
= tcg_const_i32(s
->current_el
);
8885 gen_helper_rebuild_hflags_m32(cpu_env
, el
);
8886 tcg_temp_free_i32(el
);
8887 tcg_temp_free_i32(tmp
);
8893 * Clear-Exclusive, Barriers
8896 static bool trans_CLREX(DisasContext
*s
, arg_CLREX
*a
)
8899 ? !ENABLE_ARCH_7
&& !arm_dc_feature(s
, ARM_FEATURE_M
)
8900 : !ENABLE_ARCH_6K
) {
8907 static bool trans_DSB(DisasContext
*s
, arg_DSB
*a
)
8909 if (!ENABLE_ARCH_7
&& !arm_dc_feature(s
, ARM_FEATURE_M
)) {
8912 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
8916 static bool trans_DMB(DisasContext
*s
, arg_DMB
*a
)
8918 return trans_DSB(s
, NULL
);
8921 static bool trans_ISB(DisasContext
*s
, arg_ISB
*a
)
8923 if (!ENABLE_ARCH_7
&& !arm_dc_feature(s
, ARM_FEATURE_M
)) {
8927 * We need to break the TB after this insn to execute
8928 * self-modifying code correctly and also to take
8929 * any pending interrupts immediately.
8931 gen_goto_tb(s
, 0, s
->base
.pc_next
);
8935 static bool trans_SB(DisasContext
*s
, arg_SB
*a
)
8937 if (!dc_isar_feature(aa32_sb
, s
)) {
8941 * TODO: There is no speculation barrier opcode
8942 * for TCG; MB and end the TB instead.
8944 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
8945 gen_goto_tb(s
, 0, s
->base
.pc_next
);
8949 static bool trans_SETEND(DisasContext
*s
, arg_SETEND
*a
)
8951 if (!ENABLE_ARCH_6
) {
8954 if (a
->E
!= (s
->be_data
== MO_BE
)) {
8955 gen_helper_setend(cpu_env
);
8956 s
->base
.is_jmp
= DISAS_UPDATE
;
8962 * Preload instructions
8963 * All are nops, contingent on the appropriate arch level.
8966 static bool trans_PLD(DisasContext
*s
, arg_PLD
*a
)
8968 return ENABLE_ARCH_5TE
;
8971 static bool trans_PLDW(DisasContext
*s
, arg_PLD
*a
)
8973 return arm_dc_feature(s
, ARM_FEATURE_V7MP
);
8976 static bool trans_PLI(DisasContext
*s
, arg_PLD
*a
)
8978 return ENABLE_ARCH_7
;
8985 static bool trans_IT(DisasContext
*s
, arg_IT
*a
)
8987 int cond_mask
= a
->cond_mask
;
8990 * No actual code generated for this insn, just setup state.
8992 * Combinations of firstcond and mask which set up an 0b1111
8993 * condition are UNPREDICTABLE; we take the CONSTRAINED
8994 * UNPREDICTABLE choice to treat 0b1111 the same as 0b1110,
8995 * i.e. both meaning "execute always".
8997 s
->condexec_cond
= (cond_mask
>> 4) & 0xe;
8998 s
->condexec_mask
= cond_mask
& 0x1f;
9006 static void disas_arm_insn(DisasContext
*s
, unsigned int insn
)
9008 unsigned int cond
= insn
>> 28;
9010 /* M variants do not implement ARM mode; this must raise the INVSTATE
9011 * UsageFault exception.
9013 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
9014 gen_exception_insn(s
, s
->pc_curr
, EXCP_INVSTATE
, syn_uncategorized(),
9015 default_exception_el(s
));
9020 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
9021 * choose to UNDEF. In ARMv5 and above the space is used
9022 * for miscellaneous unconditional instructions.
9026 /* Unconditional instructions. */
9027 /* TODO: Perhaps merge these into one decodetree output file. */
9028 if (disas_a32_uncond(s
, insn
) ||
9029 disas_vfp_uncond(s
, insn
) ||
9030 disas_neon_dp(s
, insn
) ||
9031 disas_neon_ls(s
, insn
) ||
9032 disas_neon_shared(s
, insn
)) {
9035 /* fall back to legacy decoder */
9037 if (((insn
>> 25) & 7) == 1) {
9038 /* NEON Data processing. */
9039 if (disas_neon_data_insn(s
, insn
)) {
9044 if ((insn
& 0x0e000f00) == 0x0c000100) {
9045 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
9046 /* iWMMXt register transfer. */
9047 if (extract32(s
->c15_cpar
, 1, 1)) {
9048 if (!disas_iwmmxt_insn(s
, insn
)) {
9057 /* if not always execute, we generate a conditional jump to
9059 arm_skip_unless(s
, cond
);
9062 /* TODO: Perhaps merge these into one decodetree output file. */
9063 if (disas_a32(s
, insn
) ||
9064 disas_vfp(s
, insn
)) {
9067 /* fall back to legacy decoder */
9069 switch ((insn
>> 24) & 0xf) {
9073 if (((insn
>> 8) & 0xe) == 10) {
9074 /* VFP, but failed disas_vfp. */
9077 if (disas_coproc_insn(s
, insn
)) {
9084 unallocated_encoding(s
);
9089 static bool thumb_insn_is_16bit(DisasContext
*s
, uint32_t pc
, uint32_t insn
)
9092 * Return true if this is a 16 bit instruction. We must be precise
9093 * about this (matching the decode).
9095 if ((insn
>> 11) < 0x1d) {
9096 /* Definitely a 16-bit instruction */
9100 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
9101 * first half of a 32-bit Thumb insn. Thumb-1 cores might
9102 * end up actually treating this as two 16-bit insns, though,
9103 * if it's half of a bl/blx pair that might span a page boundary.
9105 if (arm_dc_feature(s
, ARM_FEATURE_THUMB2
) ||
9106 arm_dc_feature(s
, ARM_FEATURE_M
)) {
9107 /* Thumb2 cores (including all M profile ones) always treat
9108 * 32-bit insns as 32-bit.
9113 if ((insn
>> 11) == 0x1e && pc
- s
->page_start
< TARGET_PAGE_SIZE
- 3) {
9114 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
9115 * is not on the next page; we merge this into a 32-bit
9120 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
9121 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
9122 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
9123 * -- handle as single 16 bit insn
9128 /* Translate a 32-bit thumb instruction. */
9129 static void disas_thumb2_insn(DisasContext
*s
, uint32_t insn
)
9132 * ARMv6-M supports a limited subset of Thumb2 instructions.
9133 * Other Thumb1 architectures allow only 32-bit
9134 * combined BL/BLX prefix and suffix.
9136 if (arm_dc_feature(s
, ARM_FEATURE_M
) &&
9137 !arm_dc_feature(s
, ARM_FEATURE_V7
)) {
9140 static const uint32_t armv6m_insn
[] = {0xf3808000 /* msr */,
9141 0xf3b08040 /* dsb */,
9142 0xf3b08050 /* dmb */,
9143 0xf3b08060 /* isb */,
9144 0xf3e08000 /* mrs */,
9145 0xf000d000 /* bl */};
9146 static const uint32_t armv6m_mask
[] = {0xffe0d000,
9153 for (i
= 0; i
< ARRAY_SIZE(armv6m_insn
); i
++) {
9154 if ((insn
& armv6m_mask
[i
]) == armv6m_insn
[i
]) {
9162 } else if ((insn
& 0xf800e800) != 0xf000e800) {
9166 if ((insn
& 0xef000000) == 0xef000000) {
9168 * T32 encodings 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
9170 * A32 encodings 0b1111_001p_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
9172 uint32_t a32_insn
= (insn
& 0xe2ffffff) |
9173 ((insn
& (1 << 28)) >> 4) | (1 << 28);
9175 if (disas_neon_dp(s
, a32_insn
)) {
9180 if ((insn
& 0xff100000) == 0xf9000000) {
9182 * T32 encodings 0b1111_1001_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
9184 * A32 encodings 0b1111_0100_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
9186 uint32_t a32_insn
= (insn
& 0x00ffffff) | 0xf4000000;
9188 if (disas_neon_ls(s
, a32_insn
)) {
9194 * TODO: Perhaps merge these into one decodetree output file.
9195 * Note disas_vfp is written for a32 with cond field in the
9196 * top nibble. The t32 encoding requires 0xe in the top nibble.
9198 if (disas_t32(s
, insn
) ||
9199 disas_vfp_uncond(s
, insn
) ||
9200 disas_neon_shared(s
, insn
) ||
9201 ((insn
>> 28) == 0xe && disas_vfp(s
, insn
))) {
9204 /* fall back to legacy decoder */
9206 switch ((insn
>> 25) & 0xf) {
9207 case 0: case 1: case 2: case 3:
9208 /* 16-bit instructions. Should never happen. */
9210 case 6: case 7: case 14: case 15:
9212 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
9213 /* 0b111x_11xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx */
9214 if (extract32(insn
, 24, 2) == 3) {
9215 goto illegal_op
; /* op0 = 0b11 : unallocated */
9218 if (((insn
>> 8) & 0xe) == 10 &&
9219 dc_isar_feature(aa32_fpsp_v2
, s
)) {
9220 /* FP, and the CPU supports it */
9223 /* All other insns: NOCP */
9224 gen_exception_insn(s
, s
->pc_curr
, EXCP_NOCP
,
9225 syn_uncategorized(),
9226 default_exception_el(s
));
9230 if (((insn
>> 24) & 3) == 3) {
9231 /* Translate into the equivalent ARM encoding. */
9232 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
9233 if (disas_neon_data_insn(s
, insn
)) {
9236 } else if (((insn
>> 8) & 0xe) == 10) {
9237 /* VFP, but failed disas_vfp. */
9240 if (insn
& (1 << 28))
9242 if (disas_coproc_insn(s
, insn
)) {
9251 unallocated_encoding(s
);
9255 static void disas_thumb_insn(DisasContext
*s
, uint32_t insn
)
9257 if (!disas_t16(s
, insn
)) {
9258 unallocated_encoding(s
);
9262 static bool insn_crosses_page(CPUARMState
*env
, DisasContext
*s
)
9264 /* Return true if the insn at dc->base.pc_next might cross a page boundary.
9265 * (False positives are OK, false negatives are not.)
9266 * We know this is a Thumb insn, and our caller ensures we are
9267 * only called if dc->base.pc_next is less than 4 bytes from the page
9268 * boundary, so we cross the page if the first 16 bits indicate
9269 * that this is a 32 bit insn.
9271 uint16_t insn
= arm_lduw_code(env
, s
->base
.pc_next
, s
->sctlr_b
);
9273 return !thumb_insn_is_16bit(s
, s
->base
.pc_next
, insn
);
9276 static void arm_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cs
)
9278 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
9279 CPUARMState
*env
= cs
->env_ptr
;
9280 ARMCPU
*cpu
= env_archcpu(env
);
9281 uint32_t tb_flags
= dc
->base
.tb
->flags
;
9282 uint32_t condexec
, core_mmu_idx
;
9284 dc
->isar
= &cpu
->isar
;
9288 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
9289 * there is no secure EL1, so we route exceptions to EL3.
9291 dc
->secure_routed_to_el3
= arm_feature(env
, ARM_FEATURE_EL3
) &&
9292 !arm_el_is_aa64(env
, 3);
9293 dc
->thumb
= FIELD_EX32(tb_flags
, TBFLAG_AM32
, THUMB
);
9294 dc
->be_data
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, BE_DATA
) ? MO_BE
: MO_LE
;
9295 condexec
= FIELD_EX32(tb_flags
, TBFLAG_AM32
, CONDEXEC
);
9296 dc
->condexec_mask
= (condexec
& 0xf) << 1;
9297 dc
->condexec_cond
= condexec
>> 4;
9299 core_mmu_idx
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, MMUIDX
);
9300 dc
->mmu_idx
= core_to_arm_mmu_idx(env
, core_mmu_idx
);
9301 dc
->current_el
= arm_mmu_idx_to_el(dc
->mmu_idx
);
9302 #if !defined(CONFIG_USER_ONLY)
9303 dc
->user
= (dc
->current_el
== 0);
9305 dc
->fp_excp_el
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, FPEXC_EL
);
9307 if (arm_feature(env
, ARM_FEATURE_M
)) {
9308 dc
->vfp_enabled
= 1;
9309 dc
->be_data
= MO_TE
;
9310 dc
->v7m_handler_mode
= FIELD_EX32(tb_flags
, TBFLAG_M32
, HANDLER
);
9311 dc
->v8m_secure
= arm_feature(env
, ARM_FEATURE_M_SECURITY
) &&
9312 regime_is_secure(env
, dc
->mmu_idx
);
9313 dc
->v8m_stackcheck
= FIELD_EX32(tb_flags
, TBFLAG_M32
, STACKCHECK
);
9314 dc
->v8m_fpccr_s_wrong
=
9315 FIELD_EX32(tb_flags
, TBFLAG_M32
, FPCCR_S_WRONG
);
9316 dc
->v7m_new_fp_ctxt_needed
=
9317 FIELD_EX32(tb_flags
, TBFLAG_M32
, NEW_FP_CTXT_NEEDED
);
9318 dc
->v7m_lspact
= FIELD_EX32(tb_flags
, TBFLAG_M32
, LSPACT
);
9321 FIELD_EX32(tb_flags
, TBFLAG_ANY
, BE_DATA
) ? MO_BE
: MO_LE
;
9322 dc
->debug_target_el
=
9323 FIELD_EX32(tb_flags
, TBFLAG_ANY
, DEBUG_TARGET_EL
);
9324 dc
->sctlr_b
= FIELD_EX32(tb_flags
, TBFLAG_A32
, SCTLR_B
);
9325 dc
->hstr_active
= FIELD_EX32(tb_flags
, TBFLAG_A32
, HSTR_ACTIVE
);
9326 dc
->ns
= FIELD_EX32(tb_flags
, TBFLAG_A32
, NS
);
9327 dc
->vfp_enabled
= FIELD_EX32(tb_flags
, TBFLAG_A32
, VFPEN
);
9328 if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
9329 dc
->c15_cpar
= FIELD_EX32(tb_flags
, TBFLAG_A32
, XSCALE_CPAR
);
9331 dc
->vec_len
= FIELD_EX32(tb_flags
, TBFLAG_A32
, VECLEN
);
9332 dc
->vec_stride
= FIELD_EX32(tb_flags
, TBFLAG_A32
, VECSTRIDE
);
9335 dc
->cp_regs
= cpu
->cp_regs
;
9336 dc
->features
= env
->features
;
9338 /* Single step state. The code-generation logic here is:
9340 * generate code with no special handling for single-stepping (except
9341 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
9342 * this happens anyway because those changes are all system register or
9344 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
9345 * emit code for one insn
9346 * emit code to clear PSTATE.SS
9347 * emit code to generate software step exception for completed step
9348 * end TB (as usual for having generated an exception)
9349 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
9350 * emit code to generate a software step exception
9353 dc
->ss_active
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, SS_ACTIVE
);
9354 dc
->pstate_ss
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, PSTATE_SS
);
9355 dc
->is_ldex
= false;
9357 dc
->page_start
= dc
->base
.pc_first
& TARGET_PAGE_MASK
;
9359 /* If architectural single step active, limit to 1. */
9360 if (is_singlestepping(dc
)) {
9361 dc
->base
.max_insns
= 1;
9364 /* ARM is a fixed-length ISA. Bound the number of insns to execute
9365 to those left on the page. */
9367 int bound
= -(dc
->base
.pc_first
| TARGET_PAGE_MASK
) / 4;
9368 dc
->base
.max_insns
= MIN(dc
->base
.max_insns
, bound
);
9371 cpu_V0
= tcg_temp_new_i64();
9372 cpu_V1
= tcg_temp_new_i64();
9373 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
9374 cpu_M0
= tcg_temp_new_i64();
9377 static void arm_tr_tb_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
9379 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
9381 /* A note on handling of the condexec (IT) bits:
9383 * We want to avoid the overhead of having to write the updated condexec
9384 * bits back to the CPUARMState for every instruction in an IT block. So:
9385 * (1) if the condexec bits are not already zero then we write
9386 * zero back into the CPUARMState now. This avoids complications trying
9387 * to do it at the end of the block. (For example if we don't do this
9388 * it's hard to identify whether we can safely skip writing condexec
9389 * at the end of the TB, which we definitely want to do for the case
9390 * where a TB doesn't do anything with the IT state at all.)
9391 * (2) if we are going to leave the TB then we call gen_set_condexec()
9392 * which will write the correct value into CPUARMState if zero is wrong.
9393 * This is done both for leaving the TB at the end, and for leaving
9394 * it because of an exception we know will happen, which is done in
9395 * gen_exception_insn(). The latter is necessary because we need to
9396 * leave the TB with the PC/IT state just prior to execution of the
9397 * instruction which caused the exception.
9398 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
9399 * then the CPUARMState will be wrong and we need to reset it.
9400 * This is handled in the same way as restoration of the
9401 * PC in these situations; we save the value of the condexec bits
9402 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
9403 * then uses this to restore them after an exception.
9405 * Note that there are no instructions which can read the condexec
9406 * bits, and none which can write non-static values to them, so
9407 * we don't need to care about whether CPUARMState is correct in the
9411 /* Reset the conditional execution bits immediately. This avoids
9412 complications trying to do it at the end of the block. */
9413 if (dc
->condexec_mask
|| dc
->condexec_cond
) {
9414 TCGv_i32 tmp
= tcg_temp_new_i32();
9415 tcg_gen_movi_i32(tmp
, 0);
9416 store_cpu_field(tmp
, condexec_bits
);
9420 static void arm_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
9422 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
9424 tcg_gen_insn_start(dc
->base
.pc_next
,
9425 (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1),
9427 dc
->insn_start
= tcg_last_op();
9430 static bool arm_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cpu
,
9431 const CPUBreakpoint
*bp
)
9433 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
9435 if (bp
->flags
& BP_CPU
) {
9436 gen_set_condexec(dc
);
9437 gen_set_pc_im(dc
, dc
->base
.pc_next
);
9438 gen_helper_check_breakpoints(cpu_env
);
9439 /* End the TB early; it's likely not going to be executed */
9440 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
9442 gen_exception_internal_insn(dc
, dc
->base
.pc_next
, EXCP_DEBUG
);
9443 /* The address covered by the breakpoint must be
9444 included in [tb->pc, tb->pc + tb->size) in order
9445 to for it to be properly cleared -- thus we
9446 increment the PC here so that the logic setting
9447 tb->size below does the right thing. */
9448 /* TODO: Advance PC by correct instruction length to
9449 * avoid disassembler error messages */
9450 dc
->base
.pc_next
+= 2;
9451 dc
->base
.is_jmp
= DISAS_NORETURN
;
9457 static bool arm_pre_translate_insn(DisasContext
*dc
)
9459 #ifdef CONFIG_USER_ONLY
9460 /* Intercept jump to the magic kernel page. */
9461 if (dc
->base
.pc_next
>= 0xffff0000) {
9462 /* We always get here via a jump, so know we are not in a
9463 conditional execution block. */
9464 gen_exception_internal(EXCP_KERNEL_TRAP
);
9465 dc
->base
.is_jmp
= DISAS_NORETURN
;
9470 if (dc
->ss_active
&& !dc
->pstate_ss
) {
9471 /* Singlestep state is Active-pending.
9472 * If we're in this state at the start of a TB then either
9473 * a) we just took an exception to an EL which is being debugged
9474 * and this is the first insn in the exception handler
9475 * b) debug exceptions were masked and we just unmasked them
9476 * without changing EL (eg by clearing PSTATE.D)
9477 * In either case we're going to take a swstep exception in the
9478 * "did not step an insn" case, and so the syndrome ISV and EX
9479 * bits should be zero.
9481 assert(dc
->base
.num_insns
== 1);
9482 gen_swstep_exception(dc
, 0, 0);
9483 dc
->base
.is_jmp
= DISAS_NORETURN
;
9490 static void arm_post_translate_insn(DisasContext
*dc
)
9492 if (dc
->condjmp
&& !dc
->base
.is_jmp
) {
9493 gen_set_label(dc
->condlabel
);
9496 translator_loop_temp_check(&dc
->base
);
9499 static void arm_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cpu
)
9501 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
9502 CPUARMState
*env
= cpu
->env_ptr
;
9505 if (arm_pre_translate_insn(dc
)) {
9509 dc
->pc_curr
= dc
->base
.pc_next
;
9510 insn
= arm_ldl_code(env
, dc
->base
.pc_next
, dc
->sctlr_b
);
9512 dc
->base
.pc_next
+= 4;
9513 disas_arm_insn(dc
, insn
);
9515 arm_post_translate_insn(dc
);
9517 /* ARM is a fixed-length ISA. We performed the cross-page check
9518 in init_disas_context by adjusting max_insns. */
9521 static bool thumb_insn_is_unconditional(DisasContext
*s
, uint32_t insn
)
9523 /* Return true if this Thumb insn is always unconditional,
9524 * even inside an IT block. This is true of only a very few
9525 * instructions: BKPT, HLT, and SG.
9527 * A larger class of instructions are UNPREDICTABLE if used
9528 * inside an IT block; we do not need to detect those here, because
9529 * what we do by default (perform the cc check and update the IT
9530 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
9531 * choice for those situations.
9533 * insn is either a 16-bit or a 32-bit instruction; the two are
9534 * distinguishable because for the 16-bit case the top 16 bits
9535 * are zeroes, and that isn't a valid 32-bit encoding.
9537 if ((insn
& 0xffffff00) == 0xbe00) {
9542 if ((insn
& 0xffffffc0) == 0xba80 && arm_dc_feature(s
, ARM_FEATURE_V8
) &&
9543 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
9544 /* HLT: v8A only. This is unconditional even when it is going to
9545 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
9546 * For v7 cores this was a plain old undefined encoding and so
9547 * honours its cc check. (We might be using the encoding as
9548 * a semihosting trap, but we don't change the cc check behaviour
9549 * on that account, because a debugger connected to a real v7A
9550 * core and emulating semihosting traps by catching the UNDEF
9551 * exception would also only see cases where the cc check passed.
9552 * No guest code should be trying to do a HLT semihosting trap
9553 * in an IT block anyway.
9558 if (insn
== 0xe97fe97f && arm_dc_feature(s
, ARM_FEATURE_V8
) &&
9559 arm_dc_feature(s
, ARM_FEATURE_M
)) {
9567 static void thumb_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cpu
)
9569 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
9570 CPUARMState
*env
= cpu
->env_ptr
;
9574 if (arm_pre_translate_insn(dc
)) {
9578 dc
->pc_curr
= dc
->base
.pc_next
;
9579 insn
= arm_lduw_code(env
, dc
->base
.pc_next
, dc
->sctlr_b
);
9580 is_16bit
= thumb_insn_is_16bit(dc
, dc
->base
.pc_next
, insn
);
9581 dc
->base
.pc_next
+= 2;
9583 uint32_t insn2
= arm_lduw_code(env
, dc
->base
.pc_next
, dc
->sctlr_b
);
9585 insn
= insn
<< 16 | insn2
;
9586 dc
->base
.pc_next
+= 2;
9590 if (dc
->condexec_mask
&& !thumb_insn_is_unconditional(dc
, insn
)) {
9591 uint32_t cond
= dc
->condexec_cond
;
9594 * Conditionally skip the insn. Note that both 0xe and 0xf mean
9595 * "always"; 0xf is not "never".
9598 arm_skip_unless(dc
, cond
);
9603 disas_thumb_insn(dc
, insn
);
9605 disas_thumb2_insn(dc
, insn
);
9608 /* Advance the Thumb condexec condition. */
9609 if (dc
->condexec_mask
) {
9610 dc
->condexec_cond
= ((dc
->condexec_cond
& 0xe) |
9611 ((dc
->condexec_mask
>> 4) & 1));
9612 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
9613 if (dc
->condexec_mask
== 0) {
9614 dc
->condexec_cond
= 0;
9618 arm_post_translate_insn(dc
);
9620 /* Thumb is a variable-length ISA. Stop translation when the next insn
9621 * will touch a new page. This ensures that prefetch aborts occur at
9624 * We want to stop the TB if the next insn starts in a new page,
9625 * or if it spans between this page and the next. This means that
9626 * if we're looking at the last halfword in the page we need to
9627 * see if it's a 16-bit Thumb insn (which will fit in this TB)
9628 * or a 32-bit Thumb insn (which won't).
9629 * This is to avoid generating a silly TB with a single 16-bit insn
9630 * in it at the end of this page (which would execute correctly
9631 * but isn't very efficient).
9633 if (dc
->base
.is_jmp
== DISAS_NEXT
9634 && (dc
->base
.pc_next
- dc
->page_start
>= TARGET_PAGE_SIZE
9635 || (dc
->base
.pc_next
- dc
->page_start
>= TARGET_PAGE_SIZE
- 3
9636 && insn_crosses_page(env
, dc
)))) {
9637 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
9641 static void arm_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cpu
)
9643 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
9645 if (tb_cflags(dc
->base
.tb
) & CF_LAST_IO
&& dc
->condjmp
) {
9646 /* FIXME: This can theoretically happen with self-modifying code. */
9647 cpu_abort(cpu
, "IO on conditional branch instruction");
9650 /* At this stage dc->condjmp will only be set when the skipped
9651 instruction was a conditional branch or trap, and the PC has
9652 already been written. */
9653 gen_set_condexec(dc
);
9654 if (dc
->base
.is_jmp
== DISAS_BX_EXCRET
) {
9655 /* Exception return branches need some special case code at the
9656 * end of the TB, which is complex enough that it has to
9657 * handle the single-step vs not and the condition-failed
9658 * insn codepath itself.
9660 gen_bx_excret_final_code(dc
);
9661 } else if (unlikely(is_singlestepping(dc
))) {
9662 /* Unconditional and "condition passed" instruction codepath. */
9663 switch (dc
->base
.is_jmp
) {
9666 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
9667 default_exception_el(dc
));
9671 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
9675 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
9678 case DISAS_TOO_MANY
:
9680 gen_set_pc_im(dc
, dc
->base
.pc_next
);
9683 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
9684 gen_singlestep_exception(dc
);
9686 case DISAS_NORETURN
:
9690 /* While branches must always occur at the end of an IT block,
9691 there are a few other things that can cause us to terminate
9692 the TB in the middle of an IT block:
9693 - Exception generating instructions (bkpt, swi, undefined).
9695 - Hardware watchpoints.
9696 Hardware breakpoints have already been handled and skip this code.
9698 switch(dc
->base
.is_jmp
) {
9700 case DISAS_TOO_MANY
:
9701 gen_goto_tb(dc
, 1, dc
->base
.pc_next
);
9707 gen_set_pc_im(dc
, dc
->base
.pc_next
);
9710 /* indicate that the hash table must be used to find the next TB */
9711 tcg_gen_exit_tb(NULL
, 0);
9713 case DISAS_NORETURN
:
9714 /* nothing more to generate */
9718 TCGv_i32 tmp
= tcg_const_i32((dc
->thumb
&&
9719 !(dc
->insn
& (1U << 31))) ? 2 : 4);
9721 gen_helper_wfi(cpu_env
, tmp
);
9722 tcg_temp_free_i32(tmp
);
9723 /* The helper doesn't necessarily throw an exception, but we
9724 * must go back to the main loop to check for interrupts anyway.
9726 tcg_gen_exit_tb(NULL
, 0);
9730 gen_helper_wfe(cpu_env
);
9733 gen_helper_yield(cpu_env
);
9736 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
9737 default_exception_el(dc
));
9740 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
9743 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
9749 /* "Condition failed" instruction codepath for the branch/trap insn */
9750 gen_set_label(dc
->condlabel
);
9751 gen_set_condexec(dc
);
9752 if (unlikely(is_singlestepping(dc
))) {
9753 gen_set_pc_im(dc
, dc
->base
.pc_next
);
9754 gen_singlestep_exception(dc
);
9756 gen_goto_tb(dc
, 1, dc
->base
.pc_next
);
9761 static void arm_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cpu
)
9763 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
9765 qemu_log("IN: %s\n", lookup_symbol(dc
->base
.pc_first
));
9766 log_target_disas(cpu
, dc
->base
.pc_first
, dc
->base
.tb
->size
);
9769 static const TranslatorOps arm_translator_ops
= {
9770 .init_disas_context
= arm_tr_init_disas_context
,
9771 .tb_start
= arm_tr_tb_start
,
9772 .insn_start
= arm_tr_insn_start
,
9773 .breakpoint_check
= arm_tr_breakpoint_check
,
9774 .translate_insn
= arm_tr_translate_insn
,
9775 .tb_stop
= arm_tr_tb_stop
,
9776 .disas_log
= arm_tr_disas_log
,
9779 static const TranslatorOps thumb_translator_ops
= {
9780 .init_disas_context
= arm_tr_init_disas_context
,
9781 .tb_start
= arm_tr_tb_start
,
9782 .insn_start
= arm_tr_insn_start
,
9783 .breakpoint_check
= arm_tr_breakpoint_check
,
9784 .translate_insn
= thumb_tr_translate_insn
,
9785 .tb_stop
= arm_tr_tb_stop
,
9786 .disas_log
= arm_tr_disas_log
,
9789 /* generate intermediate code for basic block 'tb'. */
9790 void gen_intermediate_code(CPUState
*cpu
, TranslationBlock
*tb
, int max_insns
)
9792 DisasContext dc
= { };
9793 const TranslatorOps
*ops
= &arm_translator_ops
;
9795 if (FIELD_EX32(tb
->flags
, TBFLAG_AM32
, THUMB
)) {
9796 ops
= &thumb_translator_ops
;
9798 #ifdef TARGET_AARCH64
9799 if (FIELD_EX32(tb
->flags
, TBFLAG_ANY
, AARCH64_STATE
)) {
9800 ops
= &aarch64_translator_ops
;
9804 translator_loop(ops
, &dc
.base
, cpu
, tb
, max_insns
);
9807 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
,
9812 env
->condexec_bits
= 0;
9813 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;
9815 env
->regs
[15] = data
[0];
9816 env
->condexec_bits
= data
[1];
9817 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;