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 dest
, TCGv_i32 var
)
383 tcg_gen_rotri_i32(dest
, 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 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1138 TCGv_i32 tmp
= tcg_temp_new_i32();
1139 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1143 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1145 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1146 tcg_temp_free_i32(var
);
1149 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1151 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1154 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1156 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1159 static inline void neon_load_reg32(TCGv_i32 var
, int reg
)
1161 tcg_gen_ld_i32(var
, cpu_env
, vfp_reg_offset(false, reg
));
1164 static inline void neon_store_reg32(TCGv_i32 var
, int reg
)
1166 tcg_gen_st_i32(var
, cpu_env
, vfp_reg_offset(false, reg
));
1169 static TCGv_ptr
vfp_reg_ptr(bool dp
, int reg
)
1171 TCGv_ptr ret
= tcg_temp_new_ptr();
1172 tcg_gen_addi_ptr(ret
, cpu_env
, vfp_reg_offset(dp
, reg
));
1176 #define ARM_CP_RW_BIT (1 << 20)
1178 /* Include the VFP and Neon decoders */
1179 #include "translate-vfp.c.inc"
1180 #include "translate-neon.c.inc"
1182 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1184 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1187 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1189 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1192 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1194 TCGv_i32 var
= tcg_temp_new_i32();
1195 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1199 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1201 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1202 tcg_temp_free_i32(var
);
1205 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1207 iwmmxt_store_reg(cpu_M0
, rn
);
1210 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1212 iwmmxt_load_reg(cpu_M0
, rn
);
1215 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1217 iwmmxt_load_reg(cpu_V1
, rn
);
1218 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1221 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1223 iwmmxt_load_reg(cpu_V1
, rn
);
1224 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1227 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1229 iwmmxt_load_reg(cpu_V1
, rn
);
1230 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1233 #define IWMMXT_OP(name) \
1234 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1236 iwmmxt_load_reg(cpu_V1, rn); \
1237 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1240 #define IWMMXT_OP_ENV(name) \
1241 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1243 iwmmxt_load_reg(cpu_V1, rn); \
1244 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1247 #define IWMMXT_OP_ENV_SIZE(name) \
1248 IWMMXT_OP_ENV(name##b) \
1249 IWMMXT_OP_ENV(name##w) \
1250 IWMMXT_OP_ENV(name##l)
1252 #define IWMMXT_OP_ENV1(name) \
1253 static inline void gen_op_iwmmxt_##name##_M0(void) \
1255 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1269 IWMMXT_OP_ENV_SIZE(unpackl
)
1270 IWMMXT_OP_ENV_SIZE(unpackh
)
1272 IWMMXT_OP_ENV1(unpacklub
)
1273 IWMMXT_OP_ENV1(unpackluw
)
1274 IWMMXT_OP_ENV1(unpacklul
)
1275 IWMMXT_OP_ENV1(unpackhub
)
1276 IWMMXT_OP_ENV1(unpackhuw
)
1277 IWMMXT_OP_ENV1(unpackhul
)
1278 IWMMXT_OP_ENV1(unpacklsb
)
1279 IWMMXT_OP_ENV1(unpacklsw
)
1280 IWMMXT_OP_ENV1(unpacklsl
)
1281 IWMMXT_OP_ENV1(unpackhsb
)
1282 IWMMXT_OP_ENV1(unpackhsw
)
1283 IWMMXT_OP_ENV1(unpackhsl
)
1285 IWMMXT_OP_ENV_SIZE(cmpeq
)
1286 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1287 IWMMXT_OP_ENV_SIZE(cmpgts
)
1289 IWMMXT_OP_ENV_SIZE(mins
)
1290 IWMMXT_OP_ENV_SIZE(minu
)
1291 IWMMXT_OP_ENV_SIZE(maxs
)
1292 IWMMXT_OP_ENV_SIZE(maxu
)
1294 IWMMXT_OP_ENV_SIZE(subn
)
1295 IWMMXT_OP_ENV_SIZE(addn
)
1296 IWMMXT_OP_ENV_SIZE(subu
)
1297 IWMMXT_OP_ENV_SIZE(addu
)
1298 IWMMXT_OP_ENV_SIZE(subs
)
1299 IWMMXT_OP_ENV_SIZE(adds
)
1301 IWMMXT_OP_ENV(avgb0
)
1302 IWMMXT_OP_ENV(avgb1
)
1303 IWMMXT_OP_ENV(avgw0
)
1304 IWMMXT_OP_ENV(avgw1
)
1306 IWMMXT_OP_ENV(packuw
)
1307 IWMMXT_OP_ENV(packul
)
1308 IWMMXT_OP_ENV(packuq
)
1309 IWMMXT_OP_ENV(packsw
)
1310 IWMMXT_OP_ENV(packsl
)
1311 IWMMXT_OP_ENV(packsq
)
1313 static void gen_op_iwmmxt_set_mup(void)
1316 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1317 tcg_gen_ori_i32(tmp
, tmp
, 2);
1318 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1321 static void gen_op_iwmmxt_set_cup(void)
1324 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1325 tcg_gen_ori_i32(tmp
, tmp
, 1);
1326 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1329 static void gen_op_iwmmxt_setpsr_nz(void)
1331 TCGv_i32 tmp
= tcg_temp_new_i32();
1332 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1333 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1336 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1338 iwmmxt_load_reg(cpu_V1
, rn
);
1339 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1340 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1343 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1350 rd
= (insn
>> 16) & 0xf;
1351 tmp
= load_reg(s
, rd
);
1353 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1354 if (insn
& (1 << 24)) {
1356 if (insn
& (1 << 23))
1357 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1359 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1360 tcg_gen_mov_i32(dest
, tmp
);
1361 if (insn
& (1 << 21))
1362 store_reg(s
, rd
, tmp
);
1364 tcg_temp_free_i32(tmp
);
1365 } else if (insn
& (1 << 21)) {
1367 tcg_gen_mov_i32(dest
, tmp
);
1368 if (insn
& (1 << 23))
1369 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1371 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1372 store_reg(s
, rd
, tmp
);
1373 } else if (!(insn
& (1 << 23)))
1378 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1380 int rd
= (insn
>> 0) & 0xf;
1383 if (insn
& (1 << 8)) {
1384 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1387 tmp
= iwmmxt_load_creg(rd
);
1390 tmp
= tcg_temp_new_i32();
1391 iwmmxt_load_reg(cpu_V0
, rd
);
1392 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
1394 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1395 tcg_gen_mov_i32(dest
, tmp
);
1396 tcg_temp_free_i32(tmp
);
1400 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1401 (ie. an undefined instruction). */
1402 static int disas_iwmmxt_insn(DisasContext
*s
, uint32_t insn
)
1405 int rdhi
, rdlo
, rd0
, rd1
, i
;
1407 TCGv_i32 tmp
, tmp2
, tmp3
;
1409 if ((insn
& 0x0e000e00) == 0x0c000000) {
1410 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1412 rdlo
= (insn
>> 12) & 0xf;
1413 rdhi
= (insn
>> 16) & 0xf;
1414 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1415 iwmmxt_load_reg(cpu_V0
, wrd
);
1416 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1417 tcg_gen_extrh_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1418 } else { /* TMCRR */
1419 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1420 iwmmxt_store_reg(cpu_V0
, wrd
);
1421 gen_op_iwmmxt_set_mup();
1426 wrd
= (insn
>> 12) & 0xf;
1427 addr
= tcg_temp_new_i32();
1428 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1429 tcg_temp_free_i32(addr
);
1432 if (insn
& ARM_CP_RW_BIT
) {
1433 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1434 tmp
= tcg_temp_new_i32();
1435 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1436 iwmmxt_store_creg(wrd
, tmp
);
1439 if (insn
& (1 << 8)) {
1440 if (insn
& (1 << 22)) { /* WLDRD */
1441 gen_aa32_ld64(s
, cpu_M0
, addr
, get_mem_index(s
));
1443 } else { /* WLDRW wRd */
1444 tmp
= tcg_temp_new_i32();
1445 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1448 tmp
= tcg_temp_new_i32();
1449 if (insn
& (1 << 22)) { /* WLDRH */
1450 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
1451 } else { /* WLDRB */
1452 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
1456 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1457 tcg_temp_free_i32(tmp
);
1459 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1462 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1463 tmp
= iwmmxt_load_creg(wrd
);
1464 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1466 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1467 tmp
= tcg_temp_new_i32();
1468 if (insn
& (1 << 8)) {
1469 if (insn
& (1 << 22)) { /* WSTRD */
1470 gen_aa32_st64(s
, cpu_M0
, addr
, get_mem_index(s
));
1471 } else { /* WSTRW wRd */
1472 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1473 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1476 if (insn
& (1 << 22)) { /* WSTRH */
1477 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1478 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
1479 } else { /* WSTRB */
1480 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1481 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
1485 tcg_temp_free_i32(tmp
);
1487 tcg_temp_free_i32(addr
);
1491 if ((insn
& 0x0f000000) != 0x0e000000)
1494 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1495 case 0x000: /* WOR */
1496 wrd
= (insn
>> 12) & 0xf;
1497 rd0
= (insn
>> 0) & 0xf;
1498 rd1
= (insn
>> 16) & 0xf;
1499 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1500 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1501 gen_op_iwmmxt_setpsr_nz();
1502 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1503 gen_op_iwmmxt_set_mup();
1504 gen_op_iwmmxt_set_cup();
1506 case 0x011: /* TMCR */
1509 rd
= (insn
>> 12) & 0xf;
1510 wrd
= (insn
>> 16) & 0xf;
1512 case ARM_IWMMXT_wCID
:
1513 case ARM_IWMMXT_wCASF
:
1515 case ARM_IWMMXT_wCon
:
1516 gen_op_iwmmxt_set_cup();
1518 case ARM_IWMMXT_wCSSF
:
1519 tmp
= iwmmxt_load_creg(wrd
);
1520 tmp2
= load_reg(s
, rd
);
1521 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1522 tcg_temp_free_i32(tmp2
);
1523 iwmmxt_store_creg(wrd
, tmp
);
1525 case ARM_IWMMXT_wCGR0
:
1526 case ARM_IWMMXT_wCGR1
:
1527 case ARM_IWMMXT_wCGR2
:
1528 case ARM_IWMMXT_wCGR3
:
1529 gen_op_iwmmxt_set_cup();
1530 tmp
= load_reg(s
, rd
);
1531 iwmmxt_store_creg(wrd
, tmp
);
1537 case 0x100: /* WXOR */
1538 wrd
= (insn
>> 12) & 0xf;
1539 rd0
= (insn
>> 0) & 0xf;
1540 rd1
= (insn
>> 16) & 0xf;
1541 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1542 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1543 gen_op_iwmmxt_setpsr_nz();
1544 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1545 gen_op_iwmmxt_set_mup();
1546 gen_op_iwmmxt_set_cup();
1548 case 0x111: /* TMRC */
1551 rd
= (insn
>> 12) & 0xf;
1552 wrd
= (insn
>> 16) & 0xf;
1553 tmp
= iwmmxt_load_creg(wrd
);
1554 store_reg(s
, rd
, tmp
);
1556 case 0x300: /* WANDN */
1557 wrd
= (insn
>> 12) & 0xf;
1558 rd0
= (insn
>> 0) & 0xf;
1559 rd1
= (insn
>> 16) & 0xf;
1560 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1561 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1562 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1563 gen_op_iwmmxt_setpsr_nz();
1564 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1565 gen_op_iwmmxt_set_mup();
1566 gen_op_iwmmxt_set_cup();
1568 case 0x200: /* WAND */
1569 wrd
= (insn
>> 12) & 0xf;
1570 rd0
= (insn
>> 0) & 0xf;
1571 rd1
= (insn
>> 16) & 0xf;
1572 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1573 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1574 gen_op_iwmmxt_setpsr_nz();
1575 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1576 gen_op_iwmmxt_set_mup();
1577 gen_op_iwmmxt_set_cup();
1579 case 0x810: case 0xa10: /* WMADD */
1580 wrd
= (insn
>> 12) & 0xf;
1581 rd0
= (insn
>> 0) & 0xf;
1582 rd1
= (insn
>> 16) & 0xf;
1583 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1584 if (insn
& (1 << 21))
1585 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1587 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1588 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1589 gen_op_iwmmxt_set_mup();
1591 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1592 wrd
= (insn
>> 12) & 0xf;
1593 rd0
= (insn
>> 16) & 0xf;
1594 rd1
= (insn
>> 0) & 0xf;
1595 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1596 switch ((insn
>> 22) & 3) {
1598 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1601 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1604 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1609 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1610 gen_op_iwmmxt_set_mup();
1611 gen_op_iwmmxt_set_cup();
1613 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1614 wrd
= (insn
>> 12) & 0xf;
1615 rd0
= (insn
>> 16) & 0xf;
1616 rd1
= (insn
>> 0) & 0xf;
1617 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1618 switch ((insn
>> 22) & 3) {
1620 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1623 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1626 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1631 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1632 gen_op_iwmmxt_set_mup();
1633 gen_op_iwmmxt_set_cup();
1635 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1636 wrd
= (insn
>> 12) & 0xf;
1637 rd0
= (insn
>> 16) & 0xf;
1638 rd1
= (insn
>> 0) & 0xf;
1639 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1640 if (insn
& (1 << 22))
1641 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1643 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1644 if (!(insn
& (1 << 20)))
1645 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1646 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1647 gen_op_iwmmxt_set_mup();
1649 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1650 wrd
= (insn
>> 12) & 0xf;
1651 rd0
= (insn
>> 16) & 0xf;
1652 rd1
= (insn
>> 0) & 0xf;
1653 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1654 if (insn
& (1 << 21)) {
1655 if (insn
& (1 << 20))
1656 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1658 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1660 if (insn
& (1 << 20))
1661 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1663 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1665 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1666 gen_op_iwmmxt_set_mup();
1668 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1669 wrd
= (insn
>> 12) & 0xf;
1670 rd0
= (insn
>> 16) & 0xf;
1671 rd1
= (insn
>> 0) & 0xf;
1672 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1673 if (insn
& (1 << 21))
1674 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1676 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1677 if (!(insn
& (1 << 20))) {
1678 iwmmxt_load_reg(cpu_V1
, wrd
);
1679 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1681 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1682 gen_op_iwmmxt_set_mup();
1684 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1685 wrd
= (insn
>> 12) & 0xf;
1686 rd0
= (insn
>> 16) & 0xf;
1687 rd1
= (insn
>> 0) & 0xf;
1688 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1689 switch ((insn
>> 22) & 3) {
1691 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
1694 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1697 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
1702 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1703 gen_op_iwmmxt_set_mup();
1704 gen_op_iwmmxt_set_cup();
1706 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1707 wrd
= (insn
>> 12) & 0xf;
1708 rd0
= (insn
>> 16) & 0xf;
1709 rd1
= (insn
>> 0) & 0xf;
1710 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1711 if (insn
& (1 << 22)) {
1712 if (insn
& (1 << 20))
1713 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1715 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1717 if (insn
& (1 << 20))
1718 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1720 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
1722 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1723 gen_op_iwmmxt_set_mup();
1724 gen_op_iwmmxt_set_cup();
1726 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1727 wrd
= (insn
>> 12) & 0xf;
1728 rd0
= (insn
>> 16) & 0xf;
1729 rd1
= (insn
>> 0) & 0xf;
1730 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1731 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
1732 tcg_gen_andi_i32(tmp
, tmp
, 7);
1733 iwmmxt_load_reg(cpu_V1
, rd1
);
1734 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
1735 tcg_temp_free_i32(tmp
);
1736 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1737 gen_op_iwmmxt_set_mup();
1739 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1740 if (((insn
>> 6) & 3) == 3)
1742 rd
= (insn
>> 12) & 0xf;
1743 wrd
= (insn
>> 16) & 0xf;
1744 tmp
= load_reg(s
, rd
);
1745 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1746 switch ((insn
>> 6) & 3) {
1748 tmp2
= tcg_const_i32(0xff);
1749 tmp3
= tcg_const_i32((insn
& 7) << 3);
1752 tmp2
= tcg_const_i32(0xffff);
1753 tmp3
= tcg_const_i32((insn
& 3) << 4);
1756 tmp2
= tcg_const_i32(0xffffffff);
1757 tmp3
= tcg_const_i32((insn
& 1) << 5);
1763 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
1764 tcg_temp_free_i32(tmp3
);
1765 tcg_temp_free_i32(tmp2
);
1766 tcg_temp_free_i32(tmp
);
1767 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1768 gen_op_iwmmxt_set_mup();
1770 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1771 rd
= (insn
>> 12) & 0xf;
1772 wrd
= (insn
>> 16) & 0xf;
1773 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
1775 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1776 tmp
= tcg_temp_new_i32();
1777 switch ((insn
>> 22) & 3) {
1779 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
1780 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1782 tcg_gen_ext8s_i32(tmp
, tmp
);
1784 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
1788 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
1789 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1791 tcg_gen_ext16s_i32(tmp
, tmp
);
1793 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
1797 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
1798 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1801 store_reg(s
, rd
, tmp
);
1803 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1804 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1806 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1807 switch ((insn
>> 22) & 3) {
1809 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
1812 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
1815 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
1818 tcg_gen_shli_i32(tmp
, tmp
, 28);
1820 tcg_temp_free_i32(tmp
);
1822 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1823 if (((insn
>> 6) & 3) == 3)
1825 rd
= (insn
>> 12) & 0xf;
1826 wrd
= (insn
>> 16) & 0xf;
1827 tmp
= load_reg(s
, rd
);
1828 switch ((insn
>> 6) & 3) {
1830 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
1833 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
1836 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
1839 tcg_temp_free_i32(tmp
);
1840 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1841 gen_op_iwmmxt_set_mup();
1843 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1844 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1846 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1847 tmp2
= tcg_temp_new_i32();
1848 tcg_gen_mov_i32(tmp2
, tmp
);
1849 switch ((insn
>> 22) & 3) {
1851 for (i
= 0; i
< 7; i
++) {
1852 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1853 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1857 for (i
= 0; i
< 3; i
++) {
1858 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1859 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1863 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1864 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1868 tcg_temp_free_i32(tmp2
);
1869 tcg_temp_free_i32(tmp
);
1871 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1872 wrd
= (insn
>> 12) & 0xf;
1873 rd0
= (insn
>> 16) & 0xf;
1874 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1875 switch ((insn
>> 22) & 3) {
1877 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
1880 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
1883 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
1888 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1889 gen_op_iwmmxt_set_mup();
1891 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1892 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1894 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1895 tmp2
= tcg_temp_new_i32();
1896 tcg_gen_mov_i32(tmp2
, tmp
);
1897 switch ((insn
>> 22) & 3) {
1899 for (i
= 0; i
< 7; i
++) {
1900 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1901 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1905 for (i
= 0; i
< 3; i
++) {
1906 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1907 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1911 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1912 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1916 tcg_temp_free_i32(tmp2
);
1917 tcg_temp_free_i32(tmp
);
1919 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1920 rd
= (insn
>> 12) & 0xf;
1921 rd0
= (insn
>> 16) & 0xf;
1922 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
1924 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1925 tmp
= tcg_temp_new_i32();
1926 switch ((insn
>> 22) & 3) {
1928 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
1931 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
1934 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
1937 store_reg(s
, rd
, tmp
);
1939 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
1940 case 0x906: case 0xb06: case 0xd06: case 0xf06:
1941 wrd
= (insn
>> 12) & 0xf;
1942 rd0
= (insn
>> 16) & 0xf;
1943 rd1
= (insn
>> 0) & 0xf;
1944 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1945 switch ((insn
>> 22) & 3) {
1947 if (insn
& (1 << 21))
1948 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
1950 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
1953 if (insn
& (1 << 21))
1954 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
1956 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
1959 if (insn
& (1 << 21))
1960 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
1962 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
1967 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1968 gen_op_iwmmxt_set_mup();
1969 gen_op_iwmmxt_set_cup();
1971 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
1972 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
1973 wrd
= (insn
>> 12) & 0xf;
1974 rd0
= (insn
>> 16) & 0xf;
1975 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1976 switch ((insn
>> 22) & 3) {
1978 if (insn
& (1 << 21))
1979 gen_op_iwmmxt_unpacklsb_M0();
1981 gen_op_iwmmxt_unpacklub_M0();
1984 if (insn
& (1 << 21))
1985 gen_op_iwmmxt_unpacklsw_M0();
1987 gen_op_iwmmxt_unpackluw_M0();
1990 if (insn
& (1 << 21))
1991 gen_op_iwmmxt_unpacklsl_M0();
1993 gen_op_iwmmxt_unpacklul_M0();
1998 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1999 gen_op_iwmmxt_set_mup();
2000 gen_op_iwmmxt_set_cup();
2002 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2003 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2004 wrd
= (insn
>> 12) & 0xf;
2005 rd0
= (insn
>> 16) & 0xf;
2006 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2007 switch ((insn
>> 22) & 3) {
2009 if (insn
& (1 << 21))
2010 gen_op_iwmmxt_unpackhsb_M0();
2012 gen_op_iwmmxt_unpackhub_M0();
2015 if (insn
& (1 << 21))
2016 gen_op_iwmmxt_unpackhsw_M0();
2018 gen_op_iwmmxt_unpackhuw_M0();
2021 if (insn
& (1 << 21))
2022 gen_op_iwmmxt_unpackhsl_M0();
2024 gen_op_iwmmxt_unpackhul_M0();
2029 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2030 gen_op_iwmmxt_set_mup();
2031 gen_op_iwmmxt_set_cup();
2033 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2034 case 0x214: case 0x614: case 0xa14: case 0xe14:
2035 if (((insn
>> 22) & 3) == 0)
2037 wrd
= (insn
>> 12) & 0xf;
2038 rd0
= (insn
>> 16) & 0xf;
2039 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2040 tmp
= tcg_temp_new_i32();
2041 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2042 tcg_temp_free_i32(tmp
);
2045 switch ((insn
>> 22) & 3) {
2047 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2050 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2053 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2056 tcg_temp_free_i32(tmp
);
2057 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2058 gen_op_iwmmxt_set_mup();
2059 gen_op_iwmmxt_set_cup();
2061 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2062 case 0x014: case 0x414: case 0x814: case 0xc14:
2063 if (((insn
>> 22) & 3) == 0)
2065 wrd
= (insn
>> 12) & 0xf;
2066 rd0
= (insn
>> 16) & 0xf;
2067 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2068 tmp
= tcg_temp_new_i32();
2069 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2070 tcg_temp_free_i32(tmp
);
2073 switch ((insn
>> 22) & 3) {
2075 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2078 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2081 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2084 tcg_temp_free_i32(tmp
);
2085 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2086 gen_op_iwmmxt_set_mup();
2087 gen_op_iwmmxt_set_cup();
2089 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2090 case 0x114: case 0x514: case 0x914: case 0xd14:
2091 if (((insn
>> 22) & 3) == 0)
2093 wrd
= (insn
>> 12) & 0xf;
2094 rd0
= (insn
>> 16) & 0xf;
2095 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2096 tmp
= tcg_temp_new_i32();
2097 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2098 tcg_temp_free_i32(tmp
);
2101 switch ((insn
>> 22) & 3) {
2103 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2106 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2109 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2112 tcg_temp_free_i32(tmp
);
2113 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2114 gen_op_iwmmxt_set_mup();
2115 gen_op_iwmmxt_set_cup();
2117 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2118 case 0x314: case 0x714: case 0xb14: case 0xf14:
2119 if (((insn
>> 22) & 3) == 0)
2121 wrd
= (insn
>> 12) & 0xf;
2122 rd0
= (insn
>> 16) & 0xf;
2123 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2124 tmp
= tcg_temp_new_i32();
2125 switch ((insn
>> 22) & 3) {
2127 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2128 tcg_temp_free_i32(tmp
);
2131 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2134 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2135 tcg_temp_free_i32(tmp
);
2138 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2141 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2142 tcg_temp_free_i32(tmp
);
2145 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2148 tcg_temp_free_i32(tmp
);
2149 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2150 gen_op_iwmmxt_set_mup();
2151 gen_op_iwmmxt_set_cup();
2153 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2154 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2155 wrd
= (insn
>> 12) & 0xf;
2156 rd0
= (insn
>> 16) & 0xf;
2157 rd1
= (insn
>> 0) & 0xf;
2158 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2159 switch ((insn
>> 22) & 3) {
2161 if (insn
& (1 << 21))
2162 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2164 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2167 if (insn
& (1 << 21))
2168 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2170 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2173 if (insn
& (1 << 21))
2174 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2176 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2181 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2182 gen_op_iwmmxt_set_mup();
2184 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2185 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2186 wrd
= (insn
>> 12) & 0xf;
2187 rd0
= (insn
>> 16) & 0xf;
2188 rd1
= (insn
>> 0) & 0xf;
2189 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2190 switch ((insn
>> 22) & 3) {
2192 if (insn
& (1 << 21))
2193 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2195 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2198 if (insn
& (1 << 21))
2199 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2201 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2204 if (insn
& (1 << 21))
2205 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2207 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2212 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2213 gen_op_iwmmxt_set_mup();
2215 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2216 case 0x402: case 0x502: case 0x602: case 0x702:
2217 wrd
= (insn
>> 12) & 0xf;
2218 rd0
= (insn
>> 16) & 0xf;
2219 rd1
= (insn
>> 0) & 0xf;
2220 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2221 tmp
= tcg_const_i32((insn
>> 20) & 3);
2222 iwmmxt_load_reg(cpu_V1
, rd1
);
2223 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2224 tcg_temp_free_i32(tmp
);
2225 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2226 gen_op_iwmmxt_set_mup();
2228 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2229 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2230 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2231 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2232 wrd
= (insn
>> 12) & 0xf;
2233 rd0
= (insn
>> 16) & 0xf;
2234 rd1
= (insn
>> 0) & 0xf;
2235 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2236 switch ((insn
>> 20) & 0xf) {
2238 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2241 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2244 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2247 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2250 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2253 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2256 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2259 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2262 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2267 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2268 gen_op_iwmmxt_set_mup();
2269 gen_op_iwmmxt_set_cup();
2271 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2272 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2273 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2274 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2275 wrd
= (insn
>> 12) & 0xf;
2276 rd0
= (insn
>> 16) & 0xf;
2277 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2278 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2279 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2280 tcg_temp_free_i32(tmp
);
2281 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2282 gen_op_iwmmxt_set_mup();
2283 gen_op_iwmmxt_set_cup();
2285 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2286 case 0x418: case 0x518: case 0x618: case 0x718:
2287 case 0x818: case 0x918: case 0xa18: case 0xb18:
2288 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2289 wrd
= (insn
>> 12) & 0xf;
2290 rd0
= (insn
>> 16) & 0xf;
2291 rd1
= (insn
>> 0) & 0xf;
2292 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2293 switch ((insn
>> 20) & 0xf) {
2295 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2298 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2301 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2304 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2307 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2310 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2313 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2316 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2319 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2324 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2325 gen_op_iwmmxt_set_mup();
2326 gen_op_iwmmxt_set_cup();
2328 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2329 case 0x408: case 0x508: case 0x608: case 0x708:
2330 case 0x808: case 0x908: case 0xa08: case 0xb08:
2331 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2332 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2334 wrd
= (insn
>> 12) & 0xf;
2335 rd0
= (insn
>> 16) & 0xf;
2336 rd1
= (insn
>> 0) & 0xf;
2337 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2338 switch ((insn
>> 22) & 3) {
2340 if (insn
& (1 << 21))
2341 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2343 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2346 if (insn
& (1 << 21))
2347 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2349 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2352 if (insn
& (1 << 21))
2353 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2355 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2358 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2359 gen_op_iwmmxt_set_mup();
2360 gen_op_iwmmxt_set_cup();
2362 case 0x201: case 0x203: case 0x205: case 0x207:
2363 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2364 case 0x211: case 0x213: case 0x215: case 0x217:
2365 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2366 wrd
= (insn
>> 5) & 0xf;
2367 rd0
= (insn
>> 12) & 0xf;
2368 rd1
= (insn
>> 0) & 0xf;
2369 if (rd0
== 0xf || rd1
== 0xf)
2371 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2372 tmp
= load_reg(s
, rd0
);
2373 tmp2
= load_reg(s
, rd1
);
2374 switch ((insn
>> 16) & 0xf) {
2375 case 0x0: /* TMIA */
2376 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2378 case 0x8: /* TMIAPH */
2379 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2381 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2382 if (insn
& (1 << 16))
2383 tcg_gen_shri_i32(tmp
, tmp
, 16);
2384 if (insn
& (1 << 17))
2385 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2386 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2389 tcg_temp_free_i32(tmp2
);
2390 tcg_temp_free_i32(tmp
);
2393 tcg_temp_free_i32(tmp2
);
2394 tcg_temp_free_i32(tmp
);
2395 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2396 gen_op_iwmmxt_set_mup();
2405 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2406 (ie. an undefined instruction). */
2407 static int disas_dsp_insn(DisasContext
*s
, uint32_t insn
)
2409 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2412 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2413 /* Multiply with Internal Accumulate Format */
2414 rd0
= (insn
>> 12) & 0xf;
2416 acc
= (insn
>> 5) & 7;
2421 tmp
= load_reg(s
, rd0
);
2422 tmp2
= load_reg(s
, rd1
);
2423 switch ((insn
>> 16) & 0xf) {
2425 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2427 case 0x8: /* MIAPH */
2428 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2430 case 0xc: /* MIABB */
2431 case 0xd: /* MIABT */
2432 case 0xe: /* MIATB */
2433 case 0xf: /* MIATT */
2434 if (insn
& (1 << 16))
2435 tcg_gen_shri_i32(tmp
, tmp
, 16);
2436 if (insn
& (1 << 17))
2437 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2438 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2443 tcg_temp_free_i32(tmp2
);
2444 tcg_temp_free_i32(tmp
);
2446 gen_op_iwmmxt_movq_wRn_M0(acc
);
2450 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2451 /* Internal Accumulator Access Format */
2452 rdhi
= (insn
>> 16) & 0xf;
2453 rdlo
= (insn
>> 12) & 0xf;
2459 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2460 iwmmxt_load_reg(cpu_V0
, acc
);
2461 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2462 tcg_gen_extrh_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2463 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2465 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2466 iwmmxt_store_reg(cpu_V0
, acc
);
2474 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2475 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2476 if (dc_isar_feature(aa32_simd_r32, s)) { \
2477 reg = (((insn) >> (bigbit)) & 0x0f) \
2478 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2480 if (insn & (1 << (smallbit))) \
2482 reg = ((insn) >> (bigbit)) & 0x0f; \
2485 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2486 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2487 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2489 static inline bool use_goto_tb(DisasContext
*s
, target_ulong dest
)
2491 #ifndef CONFIG_USER_ONLY
2492 return (s
->base
.tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) ||
2493 ((s
->base
.pc_next
- 1) & TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
2499 static void gen_goto_ptr(void)
2501 tcg_gen_lookup_and_goto_ptr();
2504 /* This will end the TB but doesn't guarantee we'll return to
2505 * cpu_loop_exec. Any live exit_requests will be processed as we
2506 * enter the next TB.
2508 static void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
2510 if (use_goto_tb(s
, dest
)) {
2512 gen_set_pc_im(s
, dest
);
2513 tcg_gen_exit_tb(s
->base
.tb
, n
);
2515 gen_set_pc_im(s
, dest
);
2518 s
->base
.is_jmp
= DISAS_NORETURN
;
2521 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
2523 if (unlikely(is_singlestepping(s
))) {
2524 /* An indirect jump so that we still trigger the debug exception. */
2525 gen_set_pc_im(s
, dest
);
2526 s
->base
.is_jmp
= DISAS_JUMP
;
2528 gen_goto_tb(s
, 0, dest
);
2532 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
2535 tcg_gen_sari_i32(t0
, t0
, 16);
2539 tcg_gen_sari_i32(t1
, t1
, 16);
2542 tcg_gen_mul_i32(t0
, t0
, t1
);
2545 /* Return the mask of PSR bits set by a MSR instruction. */
2546 static uint32_t msr_mask(DisasContext
*s
, int flags
, int spsr
)
2550 if (flags
& (1 << 0)) {
2553 if (flags
& (1 << 1)) {
2556 if (flags
& (1 << 2)) {
2559 if (flags
& (1 << 3)) {
2563 /* Mask out undefined and reserved bits. */
2564 mask
&= aarch32_cpsr_valid_mask(s
->features
, s
->isar
);
2566 /* Mask out execution state. */
2571 /* Mask out privileged bits. */
2578 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
2579 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
2583 /* ??? This is also undefined in system mode. */
2587 tmp
= load_cpu_field(spsr
);
2588 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
2589 tcg_gen_andi_i32(t0
, t0
, mask
);
2590 tcg_gen_or_i32(tmp
, tmp
, t0
);
2591 store_cpu_field(tmp
, spsr
);
2593 gen_set_cpsr(t0
, mask
);
2595 tcg_temp_free_i32(t0
);
2600 /* Returns nonzero if access to the PSR is not permitted. */
2601 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
2604 tmp
= tcg_temp_new_i32();
2605 tcg_gen_movi_i32(tmp
, val
);
2606 return gen_set_psr(s
, mask
, spsr
, tmp
);
2609 static bool msr_banked_access_decode(DisasContext
*s
, int r
, int sysm
, int rn
,
2610 int *tgtmode
, int *regno
)
2612 /* Decode the r and sysm fields of MSR/MRS banked accesses into
2613 * the target mode and register number, and identify the various
2614 * unpredictable cases.
2615 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
2616 * + executed in user mode
2617 * + using R15 as the src/dest register
2618 * + accessing an unimplemented register
2619 * + accessing a register that's inaccessible at current PL/security state*
2620 * + accessing a register that you could access with a different insn
2621 * We choose to UNDEF in all these cases.
2622 * Since we don't know which of the various AArch32 modes we are in
2623 * we have to defer some checks to runtime.
2624 * Accesses to Monitor mode registers from Secure EL1 (which implies
2625 * that EL3 is AArch64) must trap to EL3.
2627 * If the access checks fail this function will emit code to take
2628 * an exception and return false. Otherwise it will return true,
2629 * and set *tgtmode and *regno appropriately.
2631 int exc_target
= default_exception_el(s
);
2633 /* These instructions are present only in ARMv8, or in ARMv7 with the
2634 * Virtualization Extensions.
2636 if (!arm_dc_feature(s
, ARM_FEATURE_V8
) &&
2637 !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
2641 if (IS_USER(s
) || rn
== 15) {
2645 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
2646 * of registers into (r, sysm).
2649 /* SPSRs for other modes */
2651 case 0xe: /* SPSR_fiq */
2652 *tgtmode
= ARM_CPU_MODE_FIQ
;
2654 case 0x10: /* SPSR_irq */
2655 *tgtmode
= ARM_CPU_MODE_IRQ
;
2657 case 0x12: /* SPSR_svc */
2658 *tgtmode
= ARM_CPU_MODE_SVC
;
2660 case 0x14: /* SPSR_abt */
2661 *tgtmode
= ARM_CPU_MODE_ABT
;
2663 case 0x16: /* SPSR_und */
2664 *tgtmode
= ARM_CPU_MODE_UND
;
2666 case 0x1c: /* SPSR_mon */
2667 *tgtmode
= ARM_CPU_MODE_MON
;
2669 case 0x1e: /* SPSR_hyp */
2670 *tgtmode
= ARM_CPU_MODE_HYP
;
2672 default: /* unallocated */
2675 /* We arbitrarily assign SPSR a register number of 16. */
2678 /* general purpose registers for other modes */
2680 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
2681 *tgtmode
= ARM_CPU_MODE_USR
;
2684 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
2685 *tgtmode
= ARM_CPU_MODE_FIQ
;
2688 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
2689 *tgtmode
= ARM_CPU_MODE_IRQ
;
2690 *regno
= sysm
& 1 ? 13 : 14;
2692 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
2693 *tgtmode
= ARM_CPU_MODE_SVC
;
2694 *regno
= sysm
& 1 ? 13 : 14;
2696 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
2697 *tgtmode
= ARM_CPU_MODE_ABT
;
2698 *regno
= sysm
& 1 ? 13 : 14;
2700 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
2701 *tgtmode
= ARM_CPU_MODE_UND
;
2702 *regno
= sysm
& 1 ? 13 : 14;
2704 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
2705 *tgtmode
= ARM_CPU_MODE_MON
;
2706 *regno
= sysm
& 1 ? 13 : 14;
2708 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
2709 *tgtmode
= ARM_CPU_MODE_HYP
;
2710 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
2711 *regno
= sysm
& 1 ? 13 : 17;
2713 default: /* unallocated */
2718 /* Catch the 'accessing inaccessible register' cases we can detect
2719 * at translate time.
2722 case ARM_CPU_MODE_MON
:
2723 if (!arm_dc_feature(s
, ARM_FEATURE_EL3
) || s
->ns
) {
2726 if (s
->current_el
== 1) {
2727 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
2728 * then accesses to Mon registers trap to EL3
2734 case ARM_CPU_MODE_HYP
:
2736 * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
2737 * (and so we can forbid accesses from EL2 or below). elr_hyp
2738 * can be accessed also from Hyp mode, so forbid accesses from
2741 if (!arm_dc_feature(s
, ARM_FEATURE_EL2
) || s
->current_el
< 2 ||
2742 (s
->current_el
< 3 && *regno
!= 17)) {
2753 /* If we get here then some access check did not pass */
2754 gen_exception_insn(s
, s
->pc_curr
, EXCP_UDEF
,
2755 syn_uncategorized(), exc_target
);
2759 static void gen_msr_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
2761 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
2762 int tgtmode
= 0, regno
= 0;
2764 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
2768 /* Sync state because msr_banked() can raise exceptions */
2769 gen_set_condexec(s
);
2770 gen_set_pc_im(s
, s
->pc_curr
);
2771 tcg_reg
= load_reg(s
, rn
);
2772 tcg_tgtmode
= tcg_const_i32(tgtmode
);
2773 tcg_regno
= tcg_const_i32(regno
);
2774 gen_helper_msr_banked(cpu_env
, tcg_reg
, tcg_tgtmode
, tcg_regno
);
2775 tcg_temp_free_i32(tcg_tgtmode
);
2776 tcg_temp_free_i32(tcg_regno
);
2777 tcg_temp_free_i32(tcg_reg
);
2778 s
->base
.is_jmp
= DISAS_UPDATE_EXIT
;
2781 static void gen_mrs_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
2783 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
2784 int tgtmode
= 0, regno
= 0;
2786 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
2790 /* Sync state because mrs_banked() can raise exceptions */
2791 gen_set_condexec(s
);
2792 gen_set_pc_im(s
, s
->pc_curr
);
2793 tcg_reg
= tcg_temp_new_i32();
2794 tcg_tgtmode
= tcg_const_i32(tgtmode
);
2795 tcg_regno
= tcg_const_i32(regno
);
2796 gen_helper_mrs_banked(tcg_reg
, cpu_env
, tcg_tgtmode
, tcg_regno
);
2797 tcg_temp_free_i32(tcg_tgtmode
);
2798 tcg_temp_free_i32(tcg_regno
);
2799 store_reg(s
, rn
, tcg_reg
);
2800 s
->base
.is_jmp
= DISAS_UPDATE_EXIT
;
2803 /* Store value to PC as for an exception return (ie don't
2804 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
2805 * will do the masking based on the new value of the Thumb bit.
2807 static void store_pc_exc_ret(DisasContext
*s
, TCGv_i32 pc
)
2809 tcg_gen_mov_i32(cpu_R
[15], pc
);
2810 tcg_temp_free_i32(pc
);
2813 /* Generate a v6 exception return. Marks both values as dead. */
2814 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
2816 store_pc_exc_ret(s
, pc
);
2817 /* The cpsr_write_eret helper will mask the low bits of PC
2818 * appropriately depending on the new Thumb bit, so it must
2819 * be called after storing the new PC.
2821 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
2824 gen_helper_cpsr_write_eret(cpu_env
, cpsr
);
2825 tcg_temp_free_i32(cpsr
);
2826 /* Must exit loop to check un-masked IRQs */
2827 s
->base
.is_jmp
= DISAS_EXIT
;
2830 /* Generate an old-style exception return. Marks pc as dead. */
2831 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
2833 gen_rfe(s
, pc
, load_cpu_field(spsr
));
2836 static void gen_gvec_fn3_qc(uint32_t rd_ofs
, uint32_t rn_ofs
, uint32_t rm_ofs
,
2837 uint32_t opr_sz
, uint32_t max_sz
,
2838 gen_helper_gvec_3_ptr
*fn
)
2840 TCGv_ptr qc_ptr
= tcg_temp_new_ptr();
2842 tcg_gen_addi_ptr(qc_ptr
, cpu_env
, offsetof(CPUARMState
, vfp
.qc
));
2843 tcg_gen_gvec_3_ptr(rd_ofs
, rn_ofs
, rm_ofs
, qc_ptr
,
2844 opr_sz
, max_sz
, 0, fn
);
2845 tcg_temp_free_ptr(qc_ptr
);
2848 void gen_gvec_sqrdmlah_qc(unsigned vece
, uint32_t rd_ofs
, uint32_t rn_ofs
,
2849 uint32_t rm_ofs
, uint32_t opr_sz
, uint32_t max_sz
)
2851 static gen_helper_gvec_3_ptr
* const fns
[2] = {
2852 gen_helper_gvec_qrdmlah_s16
, gen_helper_gvec_qrdmlah_s32
2854 tcg_debug_assert(vece
>= 1 && vece
<= 2);
2855 gen_gvec_fn3_qc(rd_ofs
, rn_ofs
, rm_ofs
, opr_sz
, max_sz
, fns
[vece
- 1]);
2858 void gen_gvec_sqrdmlsh_qc(unsigned vece
, uint32_t rd_ofs
, uint32_t rn_ofs
,
2859 uint32_t rm_ofs
, uint32_t opr_sz
, uint32_t max_sz
)
2861 static gen_helper_gvec_3_ptr
* const fns
[2] = {
2862 gen_helper_gvec_qrdmlsh_s16
, gen_helper_gvec_qrdmlsh_s32
2864 tcg_debug_assert(vece
>= 1 && vece
<= 2);
2865 gen_gvec_fn3_qc(rd_ofs
, rn_ofs
, rm_ofs
, opr_sz
, max_sz
, fns
[vece
- 1]);
2868 #define GEN_CMP0(NAME, COND) \
2869 static void gen_##NAME##0_i32(TCGv_i32 d, TCGv_i32 a) \
2871 tcg_gen_setcondi_i32(COND, d, a, 0); \
2872 tcg_gen_neg_i32(d, d); \
2874 static void gen_##NAME##0_i64(TCGv_i64 d, TCGv_i64 a) \
2876 tcg_gen_setcondi_i64(COND, d, a, 0); \
2877 tcg_gen_neg_i64(d, d); \
2879 static void gen_##NAME##0_vec(unsigned vece, TCGv_vec d, TCGv_vec a) \
2881 TCGv_vec zero = tcg_const_zeros_vec_matching(d); \
2882 tcg_gen_cmp_vec(COND, vece, d, a, zero); \
2883 tcg_temp_free_vec(zero); \
2885 void gen_gvec_##NAME##0(unsigned vece, uint32_t d, uint32_t m, \
2886 uint32_t opr_sz, uint32_t max_sz) \
2888 const GVecGen2 op[4] = { \
2889 { .fno = gen_helper_gvec_##NAME##0_b, \
2890 .fniv = gen_##NAME##0_vec, \
2891 .opt_opc = vecop_list_cmp, \
2893 { .fno = gen_helper_gvec_##NAME##0_h, \
2894 .fniv = gen_##NAME##0_vec, \
2895 .opt_opc = vecop_list_cmp, \
2897 { .fni4 = gen_##NAME##0_i32, \
2898 .fniv = gen_##NAME##0_vec, \
2899 .opt_opc = vecop_list_cmp, \
2901 { .fni8 = gen_##NAME##0_i64, \
2902 .fniv = gen_##NAME##0_vec, \
2903 .opt_opc = vecop_list_cmp, \
2904 .prefer_i64 = TCG_TARGET_REG_BITS == 64, \
2907 tcg_gen_gvec_2(d, m, opr_sz, max_sz, &op[vece]); \
2910 static const TCGOpcode vecop_list_cmp
[] = {
2914 GEN_CMP0(ceq
, TCG_COND_EQ
)
2915 GEN_CMP0(cle
, TCG_COND_LE
)
2916 GEN_CMP0(cge
, TCG_COND_GE
)
2917 GEN_CMP0(clt
, TCG_COND_LT
)
2918 GEN_CMP0(cgt
, TCG_COND_GT
)
2922 static void gen_ssra8_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
2924 tcg_gen_vec_sar8i_i64(a
, a
, shift
);
2925 tcg_gen_vec_add8_i64(d
, d
, a
);
2928 static void gen_ssra16_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
2930 tcg_gen_vec_sar16i_i64(a
, a
, shift
);
2931 tcg_gen_vec_add16_i64(d
, d
, a
);
2934 static void gen_ssra32_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t shift
)
2936 tcg_gen_sari_i32(a
, a
, shift
);
2937 tcg_gen_add_i32(d
, d
, a
);
2940 static void gen_ssra64_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
2942 tcg_gen_sari_i64(a
, a
, shift
);
2943 tcg_gen_add_i64(d
, d
, a
);
2946 static void gen_ssra_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
2948 tcg_gen_sari_vec(vece
, a
, a
, sh
);
2949 tcg_gen_add_vec(vece
, d
, d
, a
);
2952 void gen_gvec_ssra(unsigned vece
, uint32_t rd_ofs
, uint32_t rm_ofs
,
2953 int64_t shift
, uint32_t opr_sz
, uint32_t max_sz
)
2955 static const TCGOpcode vecop_list
[] = {
2956 INDEX_op_sari_vec
, INDEX_op_add_vec
, 0
2958 static const GVecGen2i ops
[4] = {
2959 { .fni8
= gen_ssra8_i64
,
2960 .fniv
= gen_ssra_vec
,
2961 .fno
= gen_helper_gvec_ssra_b
,
2963 .opt_opc
= vecop_list
,
2965 { .fni8
= gen_ssra16_i64
,
2966 .fniv
= gen_ssra_vec
,
2967 .fno
= gen_helper_gvec_ssra_h
,
2969 .opt_opc
= vecop_list
,
2971 { .fni4
= gen_ssra32_i32
,
2972 .fniv
= gen_ssra_vec
,
2973 .fno
= gen_helper_gvec_ssra_s
,
2975 .opt_opc
= vecop_list
,
2977 { .fni8
= gen_ssra64_i64
,
2978 .fniv
= gen_ssra_vec
,
2979 .fno
= gen_helper_gvec_ssra_b
,
2980 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
2981 .opt_opc
= vecop_list
,
2986 /* tszimm encoding produces immediates in the range [1..esize]. */
2987 tcg_debug_assert(shift
> 0);
2988 tcg_debug_assert(shift
<= (8 << vece
));
2991 * Shifts larger than the element size are architecturally valid.
2992 * Signed results in all sign bits.
2994 shift
= MIN(shift
, (8 << vece
) - 1);
2995 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, opr_sz
, max_sz
, shift
, &ops
[vece
]);
2998 static void gen_usra8_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
3000 tcg_gen_vec_shr8i_i64(a
, a
, shift
);
3001 tcg_gen_vec_add8_i64(d
, d
, a
);
3004 static void gen_usra16_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
3006 tcg_gen_vec_shr16i_i64(a
, a
, shift
);
3007 tcg_gen_vec_add16_i64(d
, d
, a
);
3010 static void gen_usra32_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t shift
)
3012 tcg_gen_shri_i32(a
, a
, shift
);
3013 tcg_gen_add_i32(d
, d
, a
);
3016 static void gen_usra64_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
3018 tcg_gen_shri_i64(a
, a
, shift
);
3019 tcg_gen_add_i64(d
, d
, a
);
3022 static void gen_usra_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
3024 tcg_gen_shri_vec(vece
, a
, a
, sh
);
3025 tcg_gen_add_vec(vece
, d
, d
, a
);
3028 void gen_gvec_usra(unsigned vece
, uint32_t rd_ofs
, uint32_t rm_ofs
,
3029 int64_t shift
, uint32_t opr_sz
, uint32_t max_sz
)
3031 static const TCGOpcode vecop_list
[] = {
3032 INDEX_op_shri_vec
, INDEX_op_add_vec
, 0
3034 static const GVecGen2i ops
[4] = {
3035 { .fni8
= gen_usra8_i64
,
3036 .fniv
= gen_usra_vec
,
3037 .fno
= gen_helper_gvec_usra_b
,
3039 .opt_opc
= vecop_list
,
3041 { .fni8
= gen_usra16_i64
,
3042 .fniv
= gen_usra_vec
,
3043 .fno
= gen_helper_gvec_usra_h
,
3045 .opt_opc
= vecop_list
,
3047 { .fni4
= gen_usra32_i32
,
3048 .fniv
= gen_usra_vec
,
3049 .fno
= gen_helper_gvec_usra_s
,
3051 .opt_opc
= vecop_list
,
3053 { .fni8
= gen_usra64_i64
,
3054 .fniv
= gen_usra_vec
,
3055 .fno
= gen_helper_gvec_usra_d
,
3056 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
3058 .opt_opc
= vecop_list
,
3062 /* tszimm encoding produces immediates in the range [1..esize]. */
3063 tcg_debug_assert(shift
> 0);
3064 tcg_debug_assert(shift
<= (8 << vece
));
3067 * Shifts larger than the element size are architecturally valid.
3068 * Unsigned results in all zeros as input to accumulate: nop.
3070 if (shift
< (8 << vece
)) {
3071 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, opr_sz
, max_sz
, shift
, &ops
[vece
]);
3073 /* Nop, but we do need to clear the tail. */
3074 tcg_gen_gvec_mov(vece
, rd_ofs
, rd_ofs
, opr_sz
, max_sz
);
3079 * Shift one less than the requested amount, and the low bit is
3080 * the rounding bit. For the 8 and 16-bit operations, because we
3081 * mask the low bit, we can perform a normal integer shift instead
3082 * of a vector shift.
3084 static void gen_srshr8_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t sh
)
3086 TCGv_i64 t
= tcg_temp_new_i64();
3088 tcg_gen_shri_i64(t
, a
, sh
- 1);
3089 tcg_gen_andi_i64(t
, t
, dup_const(MO_8
, 1));
3090 tcg_gen_vec_sar8i_i64(d
, a
, sh
);
3091 tcg_gen_vec_add8_i64(d
, d
, t
);
3092 tcg_temp_free_i64(t
);
3095 static void gen_srshr16_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t sh
)
3097 TCGv_i64 t
= tcg_temp_new_i64();
3099 tcg_gen_shri_i64(t
, a
, sh
- 1);
3100 tcg_gen_andi_i64(t
, t
, dup_const(MO_16
, 1));
3101 tcg_gen_vec_sar16i_i64(d
, a
, sh
);
3102 tcg_gen_vec_add16_i64(d
, d
, t
);
3103 tcg_temp_free_i64(t
);
3106 static void gen_srshr32_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t sh
)
3108 TCGv_i32 t
= tcg_temp_new_i32();
3110 tcg_gen_extract_i32(t
, a
, sh
- 1, 1);
3111 tcg_gen_sari_i32(d
, a
, sh
);
3112 tcg_gen_add_i32(d
, d
, t
);
3113 tcg_temp_free_i32(t
);
3116 static void gen_srshr64_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t sh
)
3118 TCGv_i64 t
= tcg_temp_new_i64();
3120 tcg_gen_extract_i64(t
, a
, sh
- 1, 1);
3121 tcg_gen_sari_i64(d
, a
, sh
);
3122 tcg_gen_add_i64(d
, d
, t
);
3123 tcg_temp_free_i64(t
);
3126 static void gen_srshr_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
3128 TCGv_vec t
= tcg_temp_new_vec_matching(d
);
3129 TCGv_vec ones
= tcg_temp_new_vec_matching(d
);
3131 tcg_gen_shri_vec(vece
, t
, a
, sh
- 1);
3132 tcg_gen_dupi_vec(vece
, ones
, 1);
3133 tcg_gen_and_vec(vece
, t
, t
, ones
);
3134 tcg_gen_sari_vec(vece
, d
, a
, sh
);
3135 tcg_gen_add_vec(vece
, d
, d
, t
);
3137 tcg_temp_free_vec(t
);
3138 tcg_temp_free_vec(ones
);
3141 void gen_gvec_srshr(unsigned vece
, uint32_t rd_ofs
, uint32_t rm_ofs
,
3142 int64_t shift
, uint32_t opr_sz
, uint32_t max_sz
)
3144 static const TCGOpcode vecop_list
[] = {
3145 INDEX_op_shri_vec
, INDEX_op_sari_vec
, INDEX_op_add_vec
, 0
3147 static const GVecGen2i ops
[4] = {
3148 { .fni8
= gen_srshr8_i64
,
3149 .fniv
= gen_srshr_vec
,
3150 .fno
= gen_helper_gvec_srshr_b
,
3151 .opt_opc
= vecop_list
,
3153 { .fni8
= gen_srshr16_i64
,
3154 .fniv
= gen_srshr_vec
,
3155 .fno
= gen_helper_gvec_srshr_h
,
3156 .opt_opc
= vecop_list
,
3158 { .fni4
= gen_srshr32_i32
,
3159 .fniv
= gen_srshr_vec
,
3160 .fno
= gen_helper_gvec_srshr_s
,
3161 .opt_opc
= vecop_list
,
3163 { .fni8
= gen_srshr64_i64
,
3164 .fniv
= gen_srshr_vec
,
3165 .fno
= gen_helper_gvec_srshr_d
,
3166 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
3167 .opt_opc
= vecop_list
,
3171 /* tszimm encoding produces immediates in the range [1..esize] */
3172 tcg_debug_assert(shift
> 0);
3173 tcg_debug_assert(shift
<= (8 << vece
));
3175 if (shift
== (8 << vece
)) {
3177 * Shifts larger than the element size are architecturally valid.
3178 * Signed results in all sign bits. With rounding, this produces
3179 * (-1 + 1) >> 1 == 0, or (0 + 1) >> 1 == 0.
3182 tcg_gen_gvec_dup_imm(vece
, rd_ofs
, opr_sz
, max_sz
, 0);
3184 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, opr_sz
, max_sz
, shift
, &ops
[vece
]);
3188 static void gen_srsra8_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t sh
)
3190 TCGv_i64 t
= tcg_temp_new_i64();
3192 gen_srshr8_i64(t
, a
, sh
);
3193 tcg_gen_vec_add8_i64(d
, d
, t
);
3194 tcg_temp_free_i64(t
);
3197 static void gen_srsra16_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t sh
)
3199 TCGv_i64 t
= tcg_temp_new_i64();
3201 gen_srshr16_i64(t
, a
, sh
);
3202 tcg_gen_vec_add16_i64(d
, d
, t
);
3203 tcg_temp_free_i64(t
);
3206 static void gen_srsra32_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t sh
)
3208 TCGv_i32 t
= tcg_temp_new_i32();
3210 gen_srshr32_i32(t
, a
, sh
);
3211 tcg_gen_add_i32(d
, d
, t
);
3212 tcg_temp_free_i32(t
);
3215 static void gen_srsra64_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t sh
)
3217 TCGv_i64 t
= tcg_temp_new_i64();
3219 gen_srshr64_i64(t
, a
, sh
);
3220 tcg_gen_add_i64(d
, d
, t
);
3221 tcg_temp_free_i64(t
);
3224 static void gen_srsra_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
3226 TCGv_vec t
= tcg_temp_new_vec_matching(d
);
3228 gen_srshr_vec(vece
, t
, a
, sh
);
3229 tcg_gen_add_vec(vece
, d
, d
, t
);
3230 tcg_temp_free_vec(t
);
3233 void gen_gvec_srsra(unsigned vece
, uint32_t rd_ofs
, uint32_t rm_ofs
,
3234 int64_t shift
, uint32_t opr_sz
, uint32_t max_sz
)
3236 static const TCGOpcode vecop_list
[] = {
3237 INDEX_op_shri_vec
, INDEX_op_sari_vec
, INDEX_op_add_vec
, 0
3239 static const GVecGen2i ops
[4] = {
3240 { .fni8
= gen_srsra8_i64
,
3241 .fniv
= gen_srsra_vec
,
3242 .fno
= gen_helper_gvec_srsra_b
,
3243 .opt_opc
= vecop_list
,
3246 { .fni8
= gen_srsra16_i64
,
3247 .fniv
= gen_srsra_vec
,
3248 .fno
= gen_helper_gvec_srsra_h
,
3249 .opt_opc
= vecop_list
,
3252 { .fni4
= gen_srsra32_i32
,
3253 .fniv
= gen_srsra_vec
,
3254 .fno
= gen_helper_gvec_srsra_s
,
3255 .opt_opc
= vecop_list
,
3258 { .fni8
= gen_srsra64_i64
,
3259 .fniv
= gen_srsra_vec
,
3260 .fno
= gen_helper_gvec_srsra_d
,
3261 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
3262 .opt_opc
= vecop_list
,
3267 /* tszimm encoding produces immediates in the range [1..esize] */
3268 tcg_debug_assert(shift
> 0);
3269 tcg_debug_assert(shift
<= (8 << vece
));
3272 * Shifts larger than the element size are architecturally valid.
3273 * Signed results in all sign bits. With rounding, this produces
3274 * (-1 + 1) >> 1 == 0, or (0 + 1) >> 1 == 0.
3275 * I.e. always zero. With accumulation, this leaves D unchanged.
3277 if (shift
== (8 << vece
)) {
3278 /* Nop, but we do need to clear the tail. */
3279 tcg_gen_gvec_mov(vece
, rd_ofs
, rd_ofs
, opr_sz
, max_sz
);
3281 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, opr_sz
, max_sz
, shift
, &ops
[vece
]);
3285 static void gen_urshr8_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t sh
)
3287 TCGv_i64 t
= tcg_temp_new_i64();
3289 tcg_gen_shri_i64(t
, a
, sh
- 1);
3290 tcg_gen_andi_i64(t
, t
, dup_const(MO_8
, 1));
3291 tcg_gen_vec_shr8i_i64(d
, a
, sh
);
3292 tcg_gen_vec_add8_i64(d
, d
, t
);
3293 tcg_temp_free_i64(t
);
3296 static void gen_urshr16_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t sh
)
3298 TCGv_i64 t
= tcg_temp_new_i64();
3300 tcg_gen_shri_i64(t
, a
, sh
- 1);
3301 tcg_gen_andi_i64(t
, t
, dup_const(MO_16
, 1));
3302 tcg_gen_vec_shr16i_i64(d
, a
, sh
);
3303 tcg_gen_vec_add16_i64(d
, d
, t
);
3304 tcg_temp_free_i64(t
);
3307 static void gen_urshr32_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t sh
)
3309 TCGv_i32 t
= tcg_temp_new_i32();
3311 tcg_gen_extract_i32(t
, a
, sh
- 1, 1);
3312 tcg_gen_shri_i32(d
, a
, sh
);
3313 tcg_gen_add_i32(d
, d
, t
);
3314 tcg_temp_free_i32(t
);
3317 static void gen_urshr64_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t sh
)
3319 TCGv_i64 t
= tcg_temp_new_i64();
3321 tcg_gen_extract_i64(t
, a
, sh
- 1, 1);
3322 tcg_gen_shri_i64(d
, a
, sh
);
3323 tcg_gen_add_i64(d
, d
, t
);
3324 tcg_temp_free_i64(t
);
3327 static void gen_urshr_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t shift
)
3329 TCGv_vec t
= tcg_temp_new_vec_matching(d
);
3330 TCGv_vec ones
= tcg_temp_new_vec_matching(d
);
3332 tcg_gen_shri_vec(vece
, t
, a
, shift
- 1);
3333 tcg_gen_dupi_vec(vece
, ones
, 1);
3334 tcg_gen_and_vec(vece
, t
, t
, ones
);
3335 tcg_gen_shri_vec(vece
, d
, a
, shift
);
3336 tcg_gen_add_vec(vece
, d
, d
, t
);
3338 tcg_temp_free_vec(t
);
3339 tcg_temp_free_vec(ones
);
3342 void gen_gvec_urshr(unsigned vece
, uint32_t rd_ofs
, uint32_t rm_ofs
,
3343 int64_t shift
, uint32_t opr_sz
, uint32_t max_sz
)
3345 static const TCGOpcode vecop_list
[] = {
3346 INDEX_op_shri_vec
, INDEX_op_add_vec
, 0
3348 static const GVecGen2i ops
[4] = {
3349 { .fni8
= gen_urshr8_i64
,
3350 .fniv
= gen_urshr_vec
,
3351 .fno
= gen_helper_gvec_urshr_b
,
3352 .opt_opc
= vecop_list
,
3354 { .fni8
= gen_urshr16_i64
,
3355 .fniv
= gen_urshr_vec
,
3356 .fno
= gen_helper_gvec_urshr_h
,
3357 .opt_opc
= vecop_list
,
3359 { .fni4
= gen_urshr32_i32
,
3360 .fniv
= gen_urshr_vec
,
3361 .fno
= gen_helper_gvec_urshr_s
,
3362 .opt_opc
= vecop_list
,
3364 { .fni8
= gen_urshr64_i64
,
3365 .fniv
= gen_urshr_vec
,
3366 .fno
= gen_helper_gvec_urshr_d
,
3367 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
3368 .opt_opc
= vecop_list
,
3372 /* tszimm encoding produces immediates in the range [1..esize] */
3373 tcg_debug_assert(shift
> 0);
3374 tcg_debug_assert(shift
<= (8 << vece
));
3376 if (shift
== (8 << vece
)) {
3378 * Shifts larger than the element size are architecturally valid.
3379 * Unsigned results in zero. With rounding, this produces a
3380 * copy of the most significant bit.
3382 tcg_gen_gvec_shri(vece
, rd_ofs
, rm_ofs
, shift
- 1, opr_sz
, max_sz
);
3384 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, opr_sz
, max_sz
, shift
, &ops
[vece
]);
3388 static void gen_ursra8_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t sh
)
3390 TCGv_i64 t
= tcg_temp_new_i64();
3393 tcg_gen_vec_shr8i_i64(t
, a
, 7);
3395 gen_urshr8_i64(t
, a
, sh
);
3397 tcg_gen_vec_add8_i64(d
, d
, t
);
3398 tcg_temp_free_i64(t
);
3401 static void gen_ursra16_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t sh
)
3403 TCGv_i64 t
= tcg_temp_new_i64();
3406 tcg_gen_vec_shr16i_i64(t
, a
, 15);
3408 gen_urshr16_i64(t
, a
, sh
);
3410 tcg_gen_vec_add16_i64(d
, d
, t
);
3411 tcg_temp_free_i64(t
);
3414 static void gen_ursra32_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t sh
)
3416 TCGv_i32 t
= tcg_temp_new_i32();
3419 tcg_gen_shri_i32(t
, a
, 31);
3421 gen_urshr32_i32(t
, a
, sh
);
3423 tcg_gen_add_i32(d
, d
, t
);
3424 tcg_temp_free_i32(t
);
3427 static void gen_ursra64_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t sh
)
3429 TCGv_i64 t
= tcg_temp_new_i64();
3432 tcg_gen_shri_i64(t
, a
, 63);
3434 gen_urshr64_i64(t
, a
, sh
);
3436 tcg_gen_add_i64(d
, d
, t
);
3437 tcg_temp_free_i64(t
);
3440 static void gen_ursra_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
3442 TCGv_vec t
= tcg_temp_new_vec_matching(d
);
3444 if (sh
== (8 << vece
)) {
3445 tcg_gen_shri_vec(vece
, t
, a
, sh
- 1);
3447 gen_urshr_vec(vece
, t
, a
, sh
);
3449 tcg_gen_add_vec(vece
, d
, d
, t
);
3450 tcg_temp_free_vec(t
);
3453 void gen_gvec_ursra(unsigned vece
, uint32_t rd_ofs
, uint32_t rm_ofs
,
3454 int64_t shift
, uint32_t opr_sz
, uint32_t max_sz
)
3456 static const TCGOpcode vecop_list
[] = {
3457 INDEX_op_shri_vec
, INDEX_op_add_vec
, 0
3459 static const GVecGen2i ops
[4] = {
3460 { .fni8
= gen_ursra8_i64
,
3461 .fniv
= gen_ursra_vec
,
3462 .fno
= gen_helper_gvec_ursra_b
,
3463 .opt_opc
= vecop_list
,
3466 { .fni8
= gen_ursra16_i64
,
3467 .fniv
= gen_ursra_vec
,
3468 .fno
= gen_helper_gvec_ursra_h
,
3469 .opt_opc
= vecop_list
,
3472 { .fni4
= gen_ursra32_i32
,
3473 .fniv
= gen_ursra_vec
,
3474 .fno
= gen_helper_gvec_ursra_s
,
3475 .opt_opc
= vecop_list
,
3478 { .fni8
= gen_ursra64_i64
,
3479 .fniv
= gen_ursra_vec
,
3480 .fno
= gen_helper_gvec_ursra_d
,
3481 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
3482 .opt_opc
= vecop_list
,
3487 /* tszimm encoding produces immediates in the range [1..esize] */
3488 tcg_debug_assert(shift
> 0);
3489 tcg_debug_assert(shift
<= (8 << vece
));
3491 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, opr_sz
, max_sz
, shift
, &ops
[vece
]);
3494 static void gen_shr8_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
3496 uint64_t mask
= dup_const(MO_8
, 0xff >> shift
);
3497 TCGv_i64 t
= tcg_temp_new_i64();
3499 tcg_gen_shri_i64(t
, a
, shift
);
3500 tcg_gen_andi_i64(t
, t
, mask
);
3501 tcg_gen_andi_i64(d
, d
, ~mask
);
3502 tcg_gen_or_i64(d
, d
, t
);
3503 tcg_temp_free_i64(t
);
3506 static void gen_shr16_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
3508 uint64_t mask
= dup_const(MO_16
, 0xffff >> shift
);
3509 TCGv_i64 t
= tcg_temp_new_i64();
3511 tcg_gen_shri_i64(t
, a
, shift
);
3512 tcg_gen_andi_i64(t
, t
, mask
);
3513 tcg_gen_andi_i64(d
, d
, ~mask
);
3514 tcg_gen_or_i64(d
, d
, t
);
3515 tcg_temp_free_i64(t
);
3518 static void gen_shr32_ins_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t shift
)
3520 tcg_gen_shri_i32(a
, a
, shift
);
3521 tcg_gen_deposit_i32(d
, d
, a
, 0, 32 - shift
);
3524 static void gen_shr64_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
3526 tcg_gen_shri_i64(a
, a
, shift
);
3527 tcg_gen_deposit_i64(d
, d
, a
, 0, 64 - shift
);
3530 static void gen_shr_ins_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
3532 TCGv_vec t
= tcg_temp_new_vec_matching(d
);
3533 TCGv_vec m
= tcg_temp_new_vec_matching(d
);
3535 tcg_gen_dupi_vec(vece
, m
, MAKE_64BIT_MASK((8 << vece
) - sh
, sh
));
3536 tcg_gen_shri_vec(vece
, t
, a
, sh
);
3537 tcg_gen_and_vec(vece
, d
, d
, m
);
3538 tcg_gen_or_vec(vece
, d
, d
, t
);
3540 tcg_temp_free_vec(t
);
3541 tcg_temp_free_vec(m
);
3544 void gen_gvec_sri(unsigned vece
, uint32_t rd_ofs
, uint32_t rm_ofs
,
3545 int64_t shift
, uint32_t opr_sz
, uint32_t max_sz
)
3547 static const TCGOpcode vecop_list
[] = { INDEX_op_shri_vec
, 0 };
3548 const GVecGen2i ops
[4] = {
3549 { .fni8
= gen_shr8_ins_i64
,
3550 .fniv
= gen_shr_ins_vec
,
3551 .fno
= gen_helper_gvec_sri_b
,
3553 .opt_opc
= vecop_list
,
3555 { .fni8
= gen_shr16_ins_i64
,
3556 .fniv
= gen_shr_ins_vec
,
3557 .fno
= gen_helper_gvec_sri_h
,
3559 .opt_opc
= vecop_list
,
3561 { .fni4
= gen_shr32_ins_i32
,
3562 .fniv
= gen_shr_ins_vec
,
3563 .fno
= gen_helper_gvec_sri_s
,
3565 .opt_opc
= vecop_list
,
3567 { .fni8
= gen_shr64_ins_i64
,
3568 .fniv
= gen_shr_ins_vec
,
3569 .fno
= gen_helper_gvec_sri_d
,
3570 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
3572 .opt_opc
= vecop_list
,
3576 /* tszimm encoding produces immediates in the range [1..esize]. */
3577 tcg_debug_assert(shift
> 0);
3578 tcg_debug_assert(shift
<= (8 << vece
));
3580 /* Shift of esize leaves destination unchanged. */
3581 if (shift
< (8 << vece
)) {
3582 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, opr_sz
, max_sz
, shift
, &ops
[vece
]);
3584 /* Nop, but we do need to clear the tail. */
3585 tcg_gen_gvec_mov(vece
, rd_ofs
, rd_ofs
, opr_sz
, max_sz
);
3589 static void gen_shl8_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
3591 uint64_t mask
= dup_const(MO_8
, 0xff << shift
);
3592 TCGv_i64 t
= tcg_temp_new_i64();
3594 tcg_gen_shli_i64(t
, a
, shift
);
3595 tcg_gen_andi_i64(t
, t
, mask
);
3596 tcg_gen_andi_i64(d
, d
, ~mask
);
3597 tcg_gen_or_i64(d
, d
, t
);
3598 tcg_temp_free_i64(t
);
3601 static void gen_shl16_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
3603 uint64_t mask
= dup_const(MO_16
, 0xffff << shift
);
3604 TCGv_i64 t
= tcg_temp_new_i64();
3606 tcg_gen_shli_i64(t
, a
, shift
);
3607 tcg_gen_andi_i64(t
, t
, mask
);
3608 tcg_gen_andi_i64(d
, d
, ~mask
);
3609 tcg_gen_or_i64(d
, d
, t
);
3610 tcg_temp_free_i64(t
);
3613 static void gen_shl32_ins_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t shift
)
3615 tcg_gen_deposit_i32(d
, d
, a
, shift
, 32 - shift
);
3618 static void gen_shl64_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
3620 tcg_gen_deposit_i64(d
, d
, a
, shift
, 64 - shift
);
3623 static void gen_shl_ins_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
3625 TCGv_vec t
= tcg_temp_new_vec_matching(d
);
3626 TCGv_vec m
= tcg_temp_new_vec_matching(d
);
3628 tcg_gen_shli_vec(vece
, t
, a
, sh
);
3629 tcg_gen_dupi_vec(vece
, m
, MAKE_64BIT_MASK(0, sh
));
3630 tcg_gen_and_vec(vece
, d
, d
, m
);
3631 tcg_gen_or_vec(vece
, d
, d
, t
);
3633 tcg_temp_free_vec(t
);
3634 tcg_temp_free_vec(m
);
3637 void gen_gvec_sli(unsigned vece
, uint32_t rd_ofs
, uint32_t rm_ofs
,
3638 int64_t shift
, uint32_t opr_sz
, uint32_t max_sz
)
3640 static const TCGOpcode vecop_list
[] = { INDEX_op_shli_vec
, 0 };
3641 const GVecGen2i ops
[4] = {
3642 { .fni8
= gen_shl8_ins_i64
,
3643 .fniv
= gen_shl_ins_vec
,
3644 .fno
= gen_helper_gvec_sli_b
,
3646 .opt_opc
= vecop_list
,
3648 { .fni8
= gen_shl16_ins_i64
,
3649 .fniv
= gen_shl_ins_vec
,
3650 .fno
= gen_helper_gvec_sli_h
,
3652 .opt_opc
= vecop_list
,
3654 { .fni4
= gen_shl32_ins_i32
,
3655 .fniv
= gen_shl_ins_vec
,
3656 .fno
= gen_helper_gvec_sli_s
,
3658 .opt_opc
= vecop_list
,
3660 { .fni8
= gen_shl64_ins_i64
,
3661 .fniv
= gen_shl_ins_vec
,
3662 .fno
= gen_helper_gvec_sli_d
,
3663 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
3665 .opt_opc
= vecop_list
,
3669 /* tszimm encoding produces immediates in the range [0..esize-1]. */
3670 tcg_debug_assert(shift
>= 0);
3671 tcg_debug_assert(shift
< (8 << vece
));
3674 tcg_gen_gvec_mov(vece
, rd_ofs
, rm_ofs
, opr_sz
, max_sz
);
3676 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, opr_sz
, max_sz
, shift
, &ops
[vece
]);
3680 static void gen_mla8_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
3682 gen_helper_neon_mul_u8(a
, a
, b
);
3683 gen_helper_neon_add_u8(d
, d
, a
);
3686 static void gen_mls8_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
3688 gen_helper_neon_mul_u8(a
, a
, b
);
3689 gen_helper_neon_sub_u8(d
, d
, a
);
3692 static void gen_mla16_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
3694 gen_helper_neon_mul_u16(a
, a
, b
);
3695 gen_helper_neon_add_u16(d
, d
, a
);
3698 static void gen_mls16_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
3700 gen_helper_neon_mul_u16(a
, a
, b
);
3701 gen_helper_neon_sub_u16(d
, d
, a
);
3704 static void gen_mla32_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
3706 tcg_gen_mul_i32(a
, a
, b
);
3707 tcg_gen_add_i32(d
, d
, a
);
3710 static void gen_mls32_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
3712 tcg_gen_mul_i32(a
, a
, b
);
3713 tcg_gen_sub_i32(d
, d
, a
);
3716 static void gen_mla64_i64(TCGv_i64 d
, TCGv_i64 a
, TCGv_i64 b
)
3718 tcg_gen_mul_i64(a
, a
, b
);
3719 tcg_gen_add_i64(d
, d
, a
);
3722 static void gen_mls64_i64(TCGv_i64 d
, TCGv_i64 a
, TCGv_i64 b
)
3724 tcg_gen_mul_i64(a
, a
, b
);
3725 tcg_gen_sub_i64(d
, d
, a
);
3728 static void gen_mla_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, TCGv_vec b
)
3730 tcg_gen_mul_vec(vece
, a
, a
, b
);
3731 tcg_gen_add_vec(vece
, d
, d
, a
);
3734 static void gen_mls_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, TCGv_vec b
)
3736 tcg_gen_mul_vec(vece
, a
, a
, b
);
3737 tcg_gen_sub_vec(vece
, d
, d
, a
);
3740 /* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
3741 * these tables are shared with AArch64 which does support them.
3743 void gen_gvec_mla(unsigned vece
, uint32_t rd_ofs
, uint32_t rn_ofs
,
3744 uint32_t rm_ofs
, uint32_t opr_sz
, uint32_t max_sz
)
3746 static const TCGOpcode vecop_list
[] = {
3747 INDEX_op_mul_vec
, INDEX_op_add_vec
, 0
3749 static const GVecGen3 ops
[4] = {
3750 { .fni4
= gen_mla8_i32
,
3751 .fniv
= gen_mla_vec
,
3753 .opt_opc
= vecop_list
,
3755 { .fni4
= gen_mla16_i32
,
3756 .fniv
= gen_mla_vec
,
3758 .opt_opc
= vecop_list
,
3760 { .fni4
= gen_mla32_i32
,
3761 .fniv
= gen_mla_vec
,
3763 .opt_opc
= vecop_list
,
3765 { .fni8
= gen_mla64_i64
,
3766 .fniv
= gen_mla_vec
,
3767 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
3769 .opt_opc
= vecop_list
,
3772 tcg_gen_gvec_3(rd_ofs
, rn_ofs
, rm_ofs
, opr_sz
, max_sz
, &ops
[vece
]);
3775 void gen_gvec_mls(unsigned vece
, uint32_t rd_ofs
, uint32_t rn_ofs
,
3776 uint32_t rm_ofs
, uint32_t opr_sz
, uint32_t max_sz
)
3778 static const TCGOpcode vecop_list
[] = {
3779 INDEX_op_mul_vec
, INDEX_op_sub_vec
, 0
3781 static const GVecGen3 ops
[4] = {
3782 { .fni4
= gen_mls8_i32
,
3783 .fniv
= gen_mls_vec
,
3785 .opt_opc
= vecop_list
,
3787 { .fni4
= gen_mls16_i32
,
3788 .fniv
= gen_mls_vec
,
3790 .opt_opc
= vecop_list
,
3792 { .fni4
= gen_mls32_i32
,
3793 .fniv
= gen_mls_vec
,
3795 .opt_opc
= vecop_list
,
3797 { .fni8
= gen_mls64_i64
,
3798 .fniv
= gen_mls_vec
,
3799 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
3801 .opt_opc
= vecop_list
,
3804 tcg_gen_gvec_3(rd_ofs
, rn_ofs
, rm_ofs
, opr_sz
, max_sz
, &ops
[vece
]);
3807 /* CMTST : test is "if (X & Y != 0)". */
3808 static void gen_cmtst_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
3810 tcg_gen_and_i32(d
, a
, b
);
3811 tcg_gen_setcondi_i32(TCG_COND_NE
, d
, d
, 0);
3812 tcg_gen_neg_i32(d
, d
);
3815 void gen_cmtst_i64(TCGv_i64 d
, TCGv_i64 a
, TCGv_i64 b
)
3817 tcg_gen_and_i64(d
, a
, b
);
3818 tcg_gen_setcondi_i64(TCG_COND_NE
, d
, d
, 0);
3819 tcg_gen_neg_i64(d
, d
);
3822 static void gen_cmtst_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, TCGv_vec b
)
3824 tcg_gen_and_vec(vece
, d
, a
, b
);
3825 tcg_gen_dupi_vec(vece
, a
, 0);
3826 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, d
, d
, a
);
3829 void gen_gvec_cmtst(unsigned vece
, uint32_t rd_ofs
, uint32_t rn_ofs
,
3830 uint32_t rm_ofs
, uint32_t opr_sz
, uint32_t max_sz
)
3832 static const TCGOpcode vecop_list
[] = { INDEX_op_cmp_vec
, 0 };
3833 static const GVecGen3 ops
[4] = {
3834 { .fni4
= gen_helper_neon_tst_u8
,
3835 .fniv
= gen_cmtst_vec
,
3836 .opt_opc
= vecop_list
,
3838 { .fni4
= gen_helper_neon_tst_u16
,
3839 .fniv
= gen_cmtst_vec
,
3840 .opt_opc
= vecop_list
,
3842 { .fni4
= gen_cmtst_i32
,
3843 .fniv
= gen_cmtst_vec
,
3844 .opt_opc
= vecop_list
,
3846 { .fni8
= gen_cmtst_i64
,
3847 .fniv
= gen_cmtst_vec
,
3848 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
3849 .opt_opc
= vecop_list
,
3852 tcg_gen_gvec_3(rd_ofs
, rn_ofs
, rm_ofs
, opr_sz
, max_sz
, &ops
[vece
]);
3855 void gen_ushl_i32(TCGv_i32 dst
, TCGv_i32 src
, TCGv_i32 shift
)
3857 TCGv_i32 lval
= tcg_temp_new_i32();
3858 TCGv_i32 rval
= tcg_temp_new_i32();
3859 TCGv_i32 lsh
= tcg_temp_new_i32();
3860 TCGv_i32 rsh
= tcg_temp_new_i32();
3861 TCGv_i32 zero
= tcg_const_i32(0);
3862 TCGv_i32 max
= tcg_const_i32(32);
3865 * Rely on the TCG guarantee that out of range shifts produce
3866 * unspecified results, not undefined behaviour (i.e. no trap).
3867 * Discard out-of-range results after the fact.
3869 tcg_gen_ext8s_i32(lsh
, shift
);
3870 tcg_gen_neg_i32(rsh
, lsh
);
3871 tcg_gen_shl_i32(lval
, src
, lsh
);
3872 tcg_gen_shr_i32(rval
, src
, rsh
);
3873 tcg_gen_movcond_i32(TCG_COND_LTU
, dst
, lsh
, max
, lval
, zero
);
3874 tcg_gen_movcond_i32(TCG_COND_LTU
, dst
, rsh
, max
, rval
, dst
);
3876 tcg_temp_free_i32(lval
);
3877 tcg_temp_free_i32(rval
);
3878 tcg_temp_free_i32(lsh
);
3879 tcg_temp_free_i32(rsh
);
3880 tcg_temp_free_i32(zero
);
3881 tcg_temp_free_i32(max
);
3884 void gen_ushl_i64(TCGv_i64 dst
, TCGv_i64 src
, TCGv_i64 shift
)
3886 TCGv_i64 lval
= tcg_temp_new_i64();
3887 TCGv_i64 rval
= tcg_temp_new_i64();
3888 TCGv_i64 lsh
= tcg_temp_new_i64();
3889 TCGv_i64 rsh
= tcg_temp_new_i64();
3890 TCGv_i64 zero
= tcg_const_i64(0);
3891 TCGv_i64 max
= tcg_const_i64(64);
3894 * Rely on the TCG guarantee that out of range shifts produce
3895 * unspecified results, not undefined behaviour (i.e. no trap).
3896 * Discard out-of-range results after the fact.
3898 tcg_gen_ext8s_i64(lsh
, shift
);
3899 tcg_gen_neg_i64(rsh
, lsh
);
3900 tcg_gen_shl_i64(lval
, src
, lsh
);
3901 tcg_gen_shr_i64(rval
, src
, rsh
);
3902 tcg_gen_movcond_i64(TCG_COND_LTU
, dst
, lsh
, max
, lval
, zero
);
3903 tcg_gen_movcond_i64(TCG_COND_LTU
, dst
, rsh
, max
, rval
, dst
);
3905 tcg_temp_free_i64(lval
);
3906 tcg_temp_free_i64(rval
);
3907 tcg_temp_free_i64(lsh
);
3908 tcg_temp_free_i64(rsh
);
3909 tcg_temp_free_i64(zero
);
3910 tcg_temp_free_i64(max
);
3913 static void gen_ushl_vec(unsigned vece
, TCGv_vec dst
,
3914 TCGv_vec src
, TCGv_vec shift
)
3916 TCGv_vec lval
= tcg_temp_new_vec_matching(dst
);
3917 TCGv_vec rval
= tcg_temp_new_vec_matching(dst
);
3918 TCGv_vec lsh
= tcg_temp_new_vec_matching(dst
);
3919 TCGv_vec rsh
= tcg_temp_new_vec_matching(dst
);
3922 tcg_gen_neg_vec(vece
, rsh
, shift
);
3924 tcg_gen_mov_vec(lsh
, shift
);
3926 msk
= tcg_temp_new_vec_matching(dst
);
3927 tcg_gen_dupi_vec(vece
, msk
, 0xff);
3928 tcg_gen_and_vec(vece
, lsh
, shift
, msk
);
3929 tcg_gen_and_vec(vece
, rsh
, rsh
, msk
);
3930 tcg_temp_free_vec(msk
);
3934 * Rely on the TCG guarantee that out of range shifts produce
3935 * unspecified results, not undefined behaviour (i.e. no trap).
3936 * Discard out-of-range results after the fact.
3938 tcg_gen_shlv_vec(vece
, lval
, src
, lsh
);
3939 tcg_gen_shrv_vec(vece
, rval
, src
, rsh
);
3941 max
= tcg_temp_new_vec_matching(dst
);
3942 tcg_gen_dupi_vec(vece
, max
, 8 << vece
);
3945 * The choice of LT (signed) and GEU (unsigned) are biased toward
3946 * the instructions of the x86_64 host. For MO_8, the whole byte
3947 * is significant so we must use an unsigned compare; otherwise we
3948 * have already masked to a byte and so a signed compare works.
3949 * Other tcg hosts have a full set of comparisons and do not care.
3952 tcg_gen_cmp_vec(TCG_COND_GEU
, vece
, lsh
, lsh
, max
);
3953 tcg_gen_cmp_vec(TCG_COND_GEU
, vece
, rsh
, rsh
, max
);
3954 tcg_gen_andc_vec(vece
, lval
, lval
, lsh
);
3955 tcg_gen_andc_vec(vece
, rval
, rval
, rsh
);
3957 tcg_gen_cmp_vec(TCG_COND_LT
, vece
, lsh
, lsh
, max
);
3958 tcg_gen_cmp_vec(TCG_COND_LT
, vece
, rsh
, rsh
, max
);
3959 tcg_gen_and_vec(vece
, lval
, lval
, lsh
);
3960 tcg_gen_and_vec(vece
, rval
, rval
, rsh
);
3962 tcg_gen_or_vec(vece
, dst
, lval
, rval
);
3964 tcg_temp_free_vec(max
);
3965 tcg_temp_free_vec(lval
);
3966 tcg_temp_free_vec(rval
);
3967 tcg_temp_free_vec(lsh
);
3968 tcg_temp_free_vec(rsh
);
3971 void gen_gvec_ushl(unsigned vece
, uint32_t rd_ofs
, uint32_t rn_ofs
,
3972 uint32_t rm_ofs
, uint32_t opr_sz
, uint32_t max_sz
)
3974 static const TCGOpcode vecop_list
[] = {
3975 INDEX_op_neg_vec
, INDEX_op_shlv_vec
,
3976 INDEX_op_shrv_vec
, INDEX_op_cmp_vec
, 0
3978 static const GVecGen3 ops
[4] = {
3979 { .fniv
= gen_ushl_vec
,
3980 .fno
= gen_helper_gvec_ushl_b
,
3981 .opt_opc
= vecop_list
,
3983 { .fniv
= gen_ushl_vec
,
3984 .fno
= gen_helper_gvec_ushl_h
,
3985 .opt_opc
= vecop_list
,
3987 { .fni4
= gen_ushl_i32
,
3988 .fniv
= gen_ushl_vec
,
3989 .opt_opc
= vecop_list
,
3991 { .fni8
= gen_ushl_i64
,
3992 .fniv
= gen_ushl_vec
,
3993 .opt_opc
= vecop_list
,
3996 tcg_gen_gvec_3(rd_ofs
, rn_ofs
, rm_ofs
, opr_sz
, max_sz
, &ops
[vece
]);
3999 void gen_sshl_i32(TCGv_i32 dst
, TCGv_i32 src
, TCGv_i32 shift
)
4001 TCGv_i32 lval
= tcg_temp_new_i32();
4002 TCGv_i32 rval
= tcg_temp_new_i32();
4003 TCGv_i32 lsh
= tcg_temp_new_i32();
4004 TCGv_i32 rsh
= tcg_temp_new_i32();
4005 TCGv_i32 zero
= tcg_const_i32(0);
4006 TCGv_i32 max
= tcg_const_i32(31);
4009 * Rely on the TCG guarantee that out of range shifts produce
4010 * unspecified results, not undefined behaviour (i.e. no trap).
4011 * Discard out-of-range results after the fact.
4013 tcg_gen_ext8s_i32(lsh
, shift
);
4014 tcg_gen_neg_i32(rsh
, lsh
);
4015 tcg_gen_shl_i32(lval
, src
, lsh
);
4016 tcg_gen_umin_i32(rsh
, rsh
, max
);
4017 tcg_gen_sar_i32(rval
, src
, rsh
);
4018 tcg_gen_movcond_i32(TCG_COND_LEU
, lval
, lsh
, max
, lval
, zero
);
4019 tcg_gen_movcond_i32(TCG_COND_LT
, dst
, lsh
, zero
, rval
, lval
);
4021 tcg_temp_free_i32(lval
);
4022 tcg_temp_free_i32(rval
);
4023 tcg_temp_free_i32(lsh
);
4024 tcg_temp_free_i32(rsh
);
4025 tcg_temp_free_i32(zero
);
4026 tcg_temp_free_i32(max
);
4029 void gen_sshl_i64(TCGv_i64 dst
, TCGv_i64 src
, TCGv_i64 shift
)
4031 TCGv_i64 lval
= tcg_temp_new_i64();
4032 TCGv_i64 rval
= tcg_temp_new_i64();
4033 TCGv_i64 lsh
= tcg_temp_new_i64();
4034 TCGv_i64 rsh
= tcg_temp_new_i64();
4035 TCGv_i64 zero
= tcg_const_i64(0);
4036 TCGv_i64 max
= tcg_const_i64(63);
4039 * Rely on the TCG guarantee that out of range shifts produce
4040 * unspecified results, not undefined behaviour (i.e. no trap).
4041 * Discard out-of-range results after the fact.
4043 tcg_gen_ext8s_i64(lsh
, shift
);
4044 tcg_gen_neg_i64(rsh
, lsh
);
4045 tcg_gen_shl_i64(lval
, src
, lsh
);
4046 tcg_gen_umin_i64(rsh
, rsh
, max
);
4047 tcg_gen_sar_i64(rval
, src
, rsh
);
4048 tcg_gen_movcond_i64(TCG_COND_LEU
, lval
, lsh
, max
, lval
, zero
);
4049 tcg_gen_movcond_i64(TCG_COND_LT
, dst
, lsh
, zero
, rval
, lval
);
4051 tcg_temp_free_i64(lval
);
4052 tcg_temp_free_i64(rval
);
4053 tcg_temp_free_i64(lsh
);
4054 tcg_temp_free_i64(rsh
);
4055 tcg_temp_free_i64(zero
);
4056 tcg_temp_free_i64(max
);
4059 static void gen_sshl_vec(unsigned vece
, TCGv_vec dst
,
4060 TCGv_vec src
, TCGv_vec shift
)
4062 TCGv_vec lval
= tcg_temp_new_vec_matching(dst
);
4063 TCGv_vec rval
= tcg_temp_new_vec_matching(dst
);
4064 TCGv_vec lsh
= tcg_temp_new_vec_matching(dst
);
4065 TCGv_vec rsh
= tcg_temp_new_vec_matching(dst
);
4066 TCGv_vec tmp
= tcg_temp_new_vec_matching(dst
);
4069 * Rely on the TCG guarantee that out of range shifts produce
4070 * unspecified results, not undefined behaviour (i.e. no trap).
4071 * Discard out-of-range results after the fact.
4073 tcg_gen_neg_vec(vece
, rsh
, shift
);
4075 tcg_gen_mov_vec(lsh
, shift
);
4077 tcg_gen_dupi_vec(vece
, tmp
, 0xff);
4078 tcg_gen_and_vec(vece
, lsh
, shift
, tmp
);
4079 tcg_gen_and_vec(vece
, rsh
, rsh
, tmp
);
4082 /* Bound rsh so out of bound right shift gets -1. */
4083 tcg_gen_dupi_vec(vece
, tmp
, (8 << vece
) - 1);
4084 tcg_gen_umin_vec(vece
, rsh
, rsh
, tmp
);
4085 tcg_gen_cmp_vec(TCG_COND_GT
, vece
, tmp
, lsh
, tmp
);
4087 tcg_gen_shlv_vec(vece
, lval
, src
, lsh
);
4088 tcg_gen_sarv_vec(vece
, rval
, src
, rsh
);
4090 /* Select in-bound left shift. */
4091 tcg_gen_andc_vec(vece
, lval
, lval
, tmp
);
4093 /* Select between left and right shift. */
4095 tcg_gen_dupi_vec(vece
, tmp
, 0);
4096 tcg_gen_cmpsel_vec(TCG_COND_LT
, vece
, dst
, lsh
, tmp
, rval
, lval
);
4098 tcg_gen_dupi_vec(vece
, tmp
, 0x80);
4099 tcg_gen_cmpsel_vec(TCG_COND_LT
, vece
, dst
, lsh
, tmp
, lval
, rval
);
4102 tcg_temp_free_vec(lval
);
4103 tcg_temp_free_vec(rval
);
4104 tcg_temp_free_vec(lsh
);
4105 tcg_temp_free_vec(rsh
);
4106 tcg_temp_free_vec(tmp
);
4109 void gen_gvec_sshl(unsigned vece
, uint32_t rd_ofs
, uint32_t rn_ofs
,
4110 uint32_t rm_ofs
, uint32_t opr_sz
, uint32_t max_sz
)
4112 static const TCGOpcode vecop_list
[] = {
4113 INDEX_op_neg_vec
, INDEX_op_umin_vec
, INDEX_op_shlv_vec
,
4114 INDEX_op_sarv_vec
, INDEX_op_cmp_vec
, INDEX_op_cmpsel_vec
, 0
4116 static const GVecGen3 ops
[4] = {
4117 { .fniv
= gen_sshl_vec
,
4118 .fno
= gen_helper_gvec_sshl_b
,
4119 .opt_opc
= vecop_list
,
4121 { .fniv
= gen_sshl_vec
,
4122 .fno
= gen_helper_gvec_sshl_h
,
4123 .opt_opc
= vecop_list
,
4125 { .fni4
= gen_sshl_i32
,
4126 .fniv
= gen_sshl_vec
,
4127 .opt_opc
= vecop_list
,
4129 { .fni8
= gen_sshl_i64
,
4130 .fniv
= gen_sshl_vec
,
4131 .opt_opc
= vecop_list
,
4134 tcg_gen_gvec_3(rd_ofs
, rn_ofs
, rm_ofs
, opr_sz
, max_sz
, &ops
[vece
]);
4137 static void gen_uqadd_vec(unsigned vece
, TCGv_vec t
, TCGv_vec sat
,
4138 TCGv_vec a
, TCGv_vec b
)
4140 TCGv_vec x
= tcg_temp_new_vec_matching(t
);
4141 tcg_gen_add_vec(vece
, x
, a
, b
);
4142 tcg_gen_usadd_vec(vece
, t
, a
, b
);
4143 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, x
, x
, t
);
4144 tcg_gen_or_vec(vece
, sat
, sat
, x
);
4145 tcg_temp_free_vec(x
);
4148 void gen_gvec_uqadd_qc(unsigned vece
, uint32_t rd_ofs
, uint32_t rn_ofs
,
4149 uint32_t rm_ofs
, uint32_t opr_sz
, uint32_t max_sz
)
4151 static const TCGOpcode vecop_list
[] = {
4152 INDEX_op_usadd_vec
, INDEX_op_cmp_vec
, INDEX_op_add_vec
, 0
4154 static const GVecGen4 ops
[4] = {
4155 { .fniv
= gen_uqadd_vec
,
4156 .fno
= gen_helper_gvec_uqadd_b
,
4158 .opt_opc
= vecop_list
,
4160 { .fniv
= gen_uqadd_vec
,
4161 .fno
= gen_helper_gvec_uqadd_h
,
4163 .opt_opc
= vecop_list
,
4165 { .fniv
= gen_uqadd_vec
,
4166 .fno
= gen_helper_gvec_uqadd_s
,
4168 .opt_opc
= vecop_list
,
4170 { .fniv
= gen_uqadd_vec
,
4171 .fno
= gen_helper_gvec_uqadd_d
,
4173 .opt_opc
= vecop_list
,
4176 tcg_gen_gvec_4(rd_ofs
, offsetof(CPUARMState
, vfp
.qc
),
4177 rn_ofs
, rm_ofs
, opr_sz
, max_sz
, &ops
[vece
]);
4180 static void gen_sqadd_vec(unsigned vece
, TCGv_vec t
, TCGv_vec sat
,
4181 TCGv_vec a
, TCGv_vec b
)
4183 TCGv_vec x
= tcg_temp_new_vec_matching(t
);
4184 tcg_gen_add_vec(vece
, x
, a
, b
);
4185 tcg_gen_ssadd_vec(vece
, t
, a
, b
);
4186 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, x
, x
, t
);
4187 tcg_gen_or_vec(vece
, sat
, sat
, x
);
4188 tcg_temp_free_vec(x
);
4191 void gen_gvec_sqadd_qc(unsigned vece
, uint32_t rd_ofs
, uint32_t rn_ofs
,
4192 uint32_t rm_ofs
, uint32_t opr_sz
, uint32_t max_sz
)
4194 static const TCGOpcode vecop_list
[] = {
4195 INDEX_op_ssadd_vec
, INDEX_op_cmp_vec
, INDEX_op_add_vec
, 0
4197 static const GVecGen4 ops
[4] = {
4198 { .fniv
= gen_sqadd_vec
,
4199 .fno
= gen_helper_gvec_sqadd_b
,
4200 .opt_opc
= vecop_list
,
4203 { .fniv
= gen_sqadd_vec
,
4204 .fno
= gen_helper_gvec_sqadd_h
,
4205 .opt_opc
= vecop_list
,
4208 { .fniv
= gen_sqadd_vec
,
4209 .fno
= gen_helper_gvec_sqadd_s
,
4210 .opt_opc
= vecop_list
,
4213 { .fniv
= gen_sqadd_vec
,
4214 .fno
= gen_helper_gvec_sqadd_d
,
4215 .opt_opc
= vecop_list
,
4219 tcg_gen_gvec_4(rd_ofs
, offsetof(CPUARMState
, vfp
.qc
),
4220 rn_ofs
, rm_ofs
, opr_sz
, max_sz
, &ops
[vece
]);
4223 static void gen_uqsub_vec(unsigned vece
, TCGv_vec t
, TCGv_vec sat
,
4224 TCGv_vec a
, TCGv_vec b
)
4226 TCGv_vec x
= tcg_temp_new_vec_matching(t
);
4227 tcg_gen_sub_vec(vece
, x
, a
, b
);
4228 tcg_gen_ussub_vec(vece
, t
, a
, b
);
4229 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, x
, x
, t
);
4230 tcg_gen_or_vec(vece
, sat
, sat
, x
);
4231 tcg_temp_free_vec(x
);
4234 void gen_gvec_uqsub_qc(unsigned vece
, uint32_t rd_ofs
, uint32_t rn_ofs
,
4235 uint32_t rm_ofs
, uint32_t opr_sz
, uint32_t max_sz
)
4237 static const TCGOpcode vecop_list
[] = {
4238 INDEX_op_ussub_vec
, INDEX_op_cmp_vec
, INDEX_op_sub_vec
, 0
4240 static const GVecGen4 ops
[4] = {
4241 { .fniv
= gen_uqsub_vec
,
4242 .fno
= gen_helper_gvec_uqsub_b
,
4243 .opt_opc
= vecop_list
,
4246 { .fniv
= gen_uqsub_vec
,
4247 .fno
= gen_helper_gvec_uqsub_h
,
4248 .opt_opc
= vecop_list
,
4251 { .fniv
= gen_uqsub_vec
,
4252 .fno
= gen_helper_gvec_uqsub_s
,
4253 .opt_opc
= vecop_list
,
4256 { .fniv
= gen_uqsub_vec
,
4257 .fno
= gen_helper_gvec_uqsub_d
,
4258 .opt_opc
= vecop_list
,
4262 tcg_gen_gvec_4(rd_ofs
, offsetof(CPUARMState
, vfp
.qc
),
4263 rn_ofs
, rm_ofs
, opr_sz
, max_sz
, &ops
[vece
]);
4266 static void gen_sqsub_vec(unsigned vece
, TCGv_vec t
, TCGv_vec sat
,
4267 TCGv_vec a
, TCGv_vec b
)
4269 TCGv_vec x
= tcg_temp_new_vec_matching(t
);
4270 tcg_gen_sub_vec(vece
, x
, a
, b
);
4271 tcg_gen_sssub_vec(vece
, t
, a
, b
);
4272 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, x
, x
, t
);
4273 tcg_gen_or_vec(vece
, sat
, sat
, x
);
4274 tcg_temp_free_vec(x
);
4277 void gen_gvec_sqsub_qc(unsigned vece
, uint32_t rd_ofs
, uint32_t rn_ofs
,
4278 uint32_t rm_ofs
, uint32_t opr_sz
, uint32_t max_sz
)
4280 static const TCGOpcode vecop_list
[] = {
4281 INDEX_op_sssub_vec
, INDEX_op_cmp_vec
, INDEX_op_sub_vec
, 0
4283 static const GVecGen4 ops
[4] = {
4284 { .fniv
= gen_sqsub_vec
,
4285 .fno
= gen_helper_gvec_sqsub_b
,
4286 .opt_opc
= vecop_list
,
4289 { .fniv
= gen_sqsub_vec
,
4290 .fno
= gen_helper_gvec_sqsub_h
,
4291 .opt_opc
= vecop_list
,
4294 { .fniv
= gen_sqsub_vec
,
4295 .fno
= gen_helper_gvec_sqsub_s
,
4296 .opt_opc
= vecop_list
,
4299 { .fniv
= gen_sqsub_vec
,
4300 .fno
= gen_helper_gvec_sqsub_d
,
4301 .opt_opc
= vecop_list
,
4305 tcg_gen_gvec_4(rd_ofs
, offsetof(CPUARMState
, vfp
.qc
),
4306 rn_ofs
, rm_ofs
, opr_sz
, max_sz
, &ops
[vece
]);
4309 static void gen_sabd_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
4311 TCGv_i32 t
= tcg_temp_new_i32();
4313 tcg_gen_sub_i32(t
, a
, b
);
4314 tcg_gen_sub_i32(d
, b
, a
);
4315 tcg_gen_movcond_i32(TCG_COND_LT
, d
, a
, b
, d
, t
);
4316 tcg_temp_free_i32(t
);
4319 static void gen_sabd_i64(TCGv_i64 d
, TCGv_i64 a
, TCGv_i64 b
)
4321 TCGv_i64 t
= tcg_temp_new_i64();
4323 tcg_gen_sub_i64(t
, a
, b
);
4324 tcg_gen_sub_i64(d
, b
, a
);
4325 tcg_gen_movcond_i64(TCG_COND_LT
, d
, a
, b
, d
, t
);
4326 tcg_temp_free_i64(t
);
4329 static void gen_sabd_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, TCGv_vec b
)
4331 TCGv_vec t
= tcg_temp_new_vec_matching(d
);
4333 tcg_gen_smin_vec(vece
, t
, a
, b
);
4334 tcg_gen_smax_vec(vece
, d
, a
, b
);
4335 tcg_gen_sub_vec(vece
, d
, d
, t
);
4336 tcg_temp_free_vec(t
);
4339 void gen_gvec_sabd(unsigned vece
, uint32_t rd_ofs
, uint32_t rn_ofs
,
4340 uint32_t rm_ofs
, uint32_t opr_sz
, uint32_t max_sz
)
4342 static const TCGOpcode vecop_list
[] = {
4343 INDEX_op_sub_vec
, INDEX_op_smin_vec
, INDEX_op_smax_vec
, 0
4345 static const GVecGen3 ops
[4] = {
4346 { .fniv
= gen_sabd_vec
,
4347 .fno
= gen_helper_gvec_sabd_b
,
4348 .opt_opc
= vecop_list
,
4350 { .fniv
= gen_sabd_vec
,
4351 .fno
= gen_helper_gvec_sabd_h
,
4352 .opt_opc
= vecop_list
,
4354 { .fni4
= gen_sabd_i32
,
4355 .fniv
= gen_sabd_vec
,
4356 .fno
= gen_helper_gvec_sabd_s
,
4357 .opt_opc
= vecop_list
,
4359 { .fni8
= gen_sabd_i64
,
4360 .fniv
= gen_sabd_vec
,
4361 .fno
= gen_helper_gvec_sabd_d
,
4362 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
4363 .opt_opc
= vecop_list
,
4366 tcg_gen_gvec_3(rd_ofs
, rn_ofs
, rm_ofs
, opr_sz
, max_sz
, &ops
[vece
]);
4369 static void gen_uabd_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
4371 TCGv_i32 t
= tcg_temp_new_i32();
4373 tcg_gen_sub_i32(t
, a
, b
);
4374 tcg_gen_sub_i32(d
, b
, a
);
4375 tcg_gen_movcond_i32(TCG_COND_LTU
, d
, a
, b
, d
, t
);
4376 tcg_temp_free_i32(t
);
4379 static void gen_uabd_i64(TCGv_i64 d
, TCGv_i64 a
, TCGv_i64 b
)
4381 TCGv_i64 t
= tcg_temp_new_i64();
4383 tcg_gen_sub_i64(t
, a
, b
);
4384 tcg_gen_sub_i64(d
, b
, a
);
4385 tcg_gen_movcond_i64(TCG_COND_LTU
, d
, a
, b
, d
, t
);
4386 tcg_temp_free_i64(t
);
4389 static void gen_uabd_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, TCGv_vec b
)
4391 TCGv_vec t
= tcg_temp_new_vec_matching(d
);
4393 tcg_gen_umin_vec(vece
, t
, a
, b
);
4394 tcg_gen_umax_vec(vece
, d
, a
, b
);
4395 tcg_gen_sub_vec(vece
, d
, d
, t
);
4396 tcg_temp_free_vec(t
);
4399 void gen_gvec_uabd(unsigned vece
, uint32_t rd_ofs
, uint32_t rn_ofs
,
4400 uint32_t rm_ofs
, uint32_t opr_sz
, uint32_t max_sz
)
4402 static const TCGOpcode vecop_list
[] = {
4403 INDEX_op_sub_vec
, INDEX_op_umin_vec
, INDEX_op_umax_vec
, 0
4405 static const GVecGen3 ops
[4] = {
4406 { .fniv
= gen_uabd_vec
,
4407 .fno
= gen_helper_gvec_uabd_b
,
4408 .opt_opc
= vecop_list
,
4410 { .fniv
= gen_uabd_vec
,
4411 .fno
= gen_helper_gvec_uabd_h
,
4412 .opt_opc
= vecop_list
,
4414 { .fni4
= gen_uabd_i32
,
4415 .fniv
= gen_uabd_vec
,
4416 .fno
= gen_helper_gvec_uabd_s
,
4417 .opt_opc
= vecop_list
,
4419 { .fni8
= gen_uabd_i64
,
4420 .fniv
= gen_uabd_vec
,
4421 .fno
= gen_helper_gvec_uabd_d
,
4422 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
4423 .opt_opc
= vecop_list
,
4426 tcg_gen_gvec_3(rd_ofs
, rn_ofs
, rm_ofs
, opr_sz
, max_sz
, &ops
[vece
]);
4429 static void gen_saba_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
4431 TCGv_i32 t
= tcg_temp_new_i32();
4432 gen_sabd_i32(t
, a
, b
);
4433 tcg_gen_add_i32(d
, d
, t
);
4434 tcg_temp_free_i32(t
);
4437 static void gen_saba_i64(TCGv_i64 d
, TCGv_i64 a
, TCGv_i64 b
)
4439 TCGv_i64 t
= tcg_temp_new_i64();
4440 gen_sabd_i64(t
, a
, b
);
4441 tcg_gen_add_i64(d
, d
, t
);
4442 tcg_temp_free_i64(t
);
4445 static void gen_saba_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, TCGv_vec b
)
4447 TCGv_vec t
= tcg_temp_new_vec_matching(d
);
4448 gen_sabd_vec(vece
, t
, a
, b
);
4449 tcg_gen_add_vec(vece
, d
, d
, t
);
4450 tcg_temp_free_vec(t
);
4453 void gen_gvec_saba(unsigned vece
, uint32_t rd_ofs
, uint32_t rn_ofs
,
4454 uint32_t rm_ofs
, uint32_t opr_sz
, uint32_t max_sz
)
4456 static const TCGOpcode vecop_list
[] = {
4457 INDEX_op_sub_vec
, INDEX_op_add_vec
,
4458 INDEX_op_smin_vec
, INDEX_op_smax_vec
, 0
4460 static const GVecGen3 ops
[4] = {
4461 { .fniv
= gen_saba_vec
,
4462 .fno
= gen_helper_gvec_saba_b
,
4463 .opt_opc
= vecop_list
,
4466 { .fniv
= gen_saba_vec
,
4467 .fno
= gen_helper_gvec_saba_h
,
4468 .opt_opc
= vecop_list
,
4471 { .fni4
= gen_saba_i32
,
4472 .fniv
= gen_saba_vec
,
4473 .fno
= gen_helper_gvec_saba_s
,
4474 .opt_opc
= vecop_list
,
4477 { .fni8
= gen_saba_i64
,
4478 .fniv
= gen_saba_vec
,
4479 .fno
= gen_helper_gvec_saba_d
,
4480 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
4481 .opt_opc
= vecop_list
,
4485 tcg_gen_gvec_3(rd_ofs
, rn_ofs
, rm_ofs
, opr_sz
, max_sz
, &ops
[vece
]);
4488 static void gen_uaba_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
4490 TCGv_i32 t
= tcg_temp_new_i32();
4491 gen_uabd_i32(t
, a
, b
);
4492 tcg_gen_add_i32(d
, d
, t
);
4493 tcg_temp_free_i32(t
);
4496 static void gen_uaba_i64(TCGv_i64 d
, TCGv_i64 a
, TCGv_i64 b
)
4498 TCGv_i64 t
= tcg_temp_new_i64();
4499 gen_uabd_i64(t
, a
, b
);
4500 tcg_gen_add_i64(d
, d
, t
);
4501 tcg_temp_free_i64(t
);
4504 static void gen_uaba_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, TCGv_vec b
)
4506 TCGv_vec t
= tcg_temp_new_vec_matching(d
);
4507 gen_uabd_vec(vece
, t
, a
, b
);
4508 tcg_gen_add_vec(vece
, d
, d
, t
);
4509 tcg_temp_free_vec(t
);
4512 void gen_gvec_uaba(unsigned vece
, uint32_t rd_ofs
, uint32_t rn_ofs
,
4513 uint32_t rm_ofs
, uint32_t opr_sz
, uint32_t max_sz
)
4515 static const TCGOpcode vecop_list
[] = {
4516 INDEX_op_sub_vec
, INDEX_op_add_vec
,
4517 INDEX_op_umin_vec
, INDEX_op_umax_vec
, 0
4519 static const GVecGen3 ops
[4] = {
4520 { .fniv
= gen_uaba_vec
,
4521 .fno
= gen_helper_gvec_uaba_b
,
4522 .opt_opc
= vecop_list
,
4525 { .fniv
= gen_uaba_vec
,
4526 .fno
= gen_helper_gvec_uaba_h
,
4527 .opt_opc
= vecop_list
,
4530 { .fni4
= gen_uaba_i32
,
4531 .fniv
= gen_uaba_vec
,
4532 .fno
= gen_helper_gvec_uaba_s
,
4533 .opt_opc
= vecop_list
,
4536 { .fni8
= gen_uaba_i64
,
4537 .fniv
= gen_uaba_vec
,
4538 .fno
= gen_helper_gvec_uaba_d
,
4539 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
4540 .opt_opc
= vecop_list
,
4544 tcg_gen_gvec_3(rd_ofs
, rn_ofs
, rm_ofs
, opr_sz
, max_sz
, &ops
[vece
]);
4547 static void do_coproc_insn(DisasContext
*s
, int cpnum
, int is64
,
4548 int opc1
, int crn
, int crm
, int opc2
,
4549 bool isread
, int rt
, int rt2
)
4551 const ARMCPRegInfo
*ri
;
4553 ri
= get_arm_cp_reginfo(s
->cp_regs
,
4554 ENCODE_CP_REG(cpnum
, is64
, s
->ns
, crn
, crm
, opc1
, opc2
));
4558 /* Check access permissions */
4559 if (!cp_access_ok(s
->current_el
, ri
, isread
)) {
4560 unallocated_encoding(s
);
4564 if (s
->hstr_active
|| ri
->accessfn
||
4565 (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && cpnum
< 14)) {
4566 /* Emit code to perform further access permissions checks at
4567 * runtime; this may result in an exception.
4568 * Note that on XScale all cp0..c13 registers do an access check
4569 * call in order to handle c15_cpar.
4572 TCGv_i32 tcg_syn
, tcg_isread
;
4575 /* Note that since we are an implementation which takes an
4576 * exception on a trapped conditional instruction only if the
4577 * instruction passes its condition code check, we can take
4578 * advantage of the clause in the ARM ARM that allows us to set
4579 * the COND field in the instruction to 0xE in all cases.
4580 * We could fish the actual condition out of the insn (ARM)
4581 * or the condexec bits (Thumb) but it isn't necessary.
4586 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
4589 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
4595 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
4598 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
4603 /* ARMv8 defines that only coprocessors 14 and 15 exist,
4604 * so this can only happen if this is an ARMv7 or earlier CPU,
4605 * in which case the syndrome information won't actually be
4608 assert(!arm_dc_feature(s
, ARM_FEATURE_V8
));
4609 syndrome
= syn_uncategorized();
4613 gen_set_condexec(s
);
4614 gen_set_pc_im(s
, s
->pc_curr
);
4615 tmpptr
= tcg_const_ptr(ri
);
4616 tcg_syn
= tcg_const_i32(syndrome
);
4617 tcg_isread
= tcg_const_i32(isread
);
4618 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
,
4620 tcg_temp_free_ptr(tmpptr
);
4621 tcg_temp_free_i32(tcg_syn
);
4622 tcg_temp_free_i32(tcg_isread
);
4623 } else if (ri
->type
& ARM_CP_RAISES_EXC
) {
4625 * The readfn or writefn might raise an exception;
4626 * synchronize the CPU state in case it does.
4628 gen_set_condexec(s
);
4629 gen_set_pc_im(s
, s
->pc_curr
);
4632 /* Handle special cases first */
4633 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
4638 unallocated_encoding(s
);
4641 gen_set_pc_im(s
, s
->base
.pc_next
);
4642 s
->base
.is_jmp
= DISAS_WFI
;
4648 if ((tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
4657 if (ri
->type
& ARM_CP_CONST
) {
4658 tmp64
= tcg_const_i64(ri
->resetvalue
);
4659 } else if (ri
->readfn
) {
4661 tmp64
= tcg_temp_new_i64();
4662 tmpptr
= tcg_const_ptr(ri
);
4663 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
4664 tcg_temp_free_ptr(tmpptr
);
4666 tmp64
= tcg_temp_new_i64();
4667 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
4669 tmp
= tcg_temp_new_i32();
4670 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
4671 store_reg(s
, rt
, tmp
);
4672 tmp
= tcg_temp_new_i32();
4673 tcg_gen_extrh_i64_i32(tmp
, tmp64
);
4674 tcg_temp_free_i64(tmp64
);
4675 store_reg(s
, rt2
, tmp
);
4678 if (ri
->type
& ARM_CP_CONST
) {
4679 tmp
= tcg_const_i32(ri
->resetvalue
);
4680 } else if (ri
->readfn
) {
4682 tmp
= tcg_temp_new_i32();
4683 tmpptr
= tcg_const_ptr(ri
);
4684 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
4685 tcg_temp_free_ptr(tmpptr
);
4687 tmp
= load_cpu_offset(ri
->fieldoffset
);
4690 /* Destination register of r15 for 32 bit loads sets
4691 * the condition codes from the high 4 bits of the value
4694 tcg_temp_free_i32(tmp
);
4696 store_reg(s
, rt
, tmp
);
4701 if (ri
->type
& ARM_CP_CONST
) {
4702 /* If not forbidden by access permissions, treat as WI */
4707 TCGv_i32 tmplo
, tmphi
;
4708 TCGv_i64 tmp64
= tcg_temp_new_i64();
4709 tmplo
= load_reg(s
, rt
);
4710 tmphi
= load_reg(s
, rt2
);
4711 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
4712 tcg_temp_free_i32(tmplo
);
4713 tcg_temp_free_i32(tmphi
);
4715 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
4716 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
4717 tcg_temp_free_ptr(tmpptr
);
4719 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
4721 tcg_temp_free_i64(tmp64
);
4726 tmp
= load_reg(s
, rt
);
4727 tmpptr
= tcg_const_ptr(ri
);
4728 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
4729 tcg_temp_free_ptr(tmpptr
);
4730 tcg_temp_free_i32(tmp
);
4732 TCGv_i32 tmp
= load_reg(s
, rt
);
4733 store_cpu_offset(tmp
, ri
->fieldoffset
);
4738 /* I/O operations must end the TB here (whether read or write) */
4739 need_exit_tb
= ((tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) &&
4740 (ri
->type
& ARM_CP_IO
));
4742 if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
4744 * A write to any coprocessor register that ends a TB
4745 * must rebuild the hflags for the next TB.
4747 TCGv_i32 tcg_el
= tcg_const_i32(s
->current_el
);
4748 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
4749 gen_helper_rebuild_hflags_m32(cpu_env
, tcg_el
);
4751 if (ri
->type
& ARM_CP_NEWEL
) {
4752 gen_helper_rebuild_hflags_a32_newel(cpu_env
);
4754 gen_helper_rebuild_hflags_a32(cpu_env
, tcg_el
);
4757 tcg_temp_free_i32(tcg_el
);
4759 * We default to ending the TB on a coprocessor register write,
4760 * but allow this to be suppressed by the register definition
4761 * (usually only necessary to work around guest bugs).
4763 need_exit_tb
= true;
4772 /* Unknown register; this might be a guest error or a QEMU
4773 * unimplemented feature.
4776 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
4777 "64 bit system register cp:%d opc1: %d crm:%d "
4779 isread
? "read" : "write", cpnum
, opc1
, crm
,
4780 s
->ns
? "non-secure" : "secure");
4782 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
4783 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
4785 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
,
4786 s
->ns
? "non-secure" : "secure");
4789 unallocated_encoding(s
);
4793 static int disas_coproc_insn(DisasContext
*s
, uint32_t insn
)
4795 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
4797 cpnum
= (insn
>> 8) & 0xf;
4799 is64
= (insn
& (1 << 25)) == 0;
4800 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
4808 opc1
= (insn
>> 4) & 0xf;
4810 rt2
= (insn
>> 16) & 0xf;
4812 crn
= (insn
>> 16) & 0xf;
4813 opc1
= (insn
>> 21) & 7;
4814 opc2
= (insn
>> 5) & 7;
4817 isread
= (insn
>> 20) & 1;
4818 rt
= (insn
>> 12) & 0xf;
4820 do_coproc_insn(s
, cpnum
, is64
, opc1
, crn
, crm
, opc2
, isread
, rt
, rt2
);
4824 /* Decode XScale DSP or iWMMXt insn (in the copro space, cp=0 or 1) */
4825 static void disas_xscale_insn(DisasContext
*s
, uint32_t insn
)
4827 int cpnum
= (insn
>> 8) & 0xf;
4829 if (extract32(s
->c15_cpar
, cpnum
, 1) == 0) {
4830 unallocated_encoding(s
);
4831 } else if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
4832 if (disas_iwmmxt_insn(s
, insn
)) {
4833 unallocated_encoding(s
);
4835 } else if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
)) {
4836 if (disas_dsp_insn(s
, insn
)) {
4837 unallocated_encoding(s
);
4842 /* Store a 64-bit value to a register pair. Clobbers val. */
4843 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
4846 tmp
= tcg_temp_new_i32();
4847 tcg_gen_extrl_i64_i32(tmp
, val
);
4848 store_reg(s
, rlow
, tmp
);
4849 tmp
= tcg_temp_new_i32();
4850 tcg_gen_extrh_i64_i32(tmp
, val
);
4851 store_reg(s
, rhigh
, tmp
);
4854 /* load and add a 64-bit value from a register pair. */
4855 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
4861 /* Load 64-bit value rd:rn. */
4862 tmpl
= load_reg(s
, rlow
);
4863 tmph
= load_reg(s
, rhigh
);
4864 tmp
= tcg_temp_new_i64();
4865 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
4866 tcg_temp_free_i32(tmpl
);
4867 tcg_temp_free_i32(tmph
);
4868 tcg_gen_add_i64(val
, val
, tmp
);
4869 tcg_temp_free_i64(tmp
);
4872 /* Set N and Z flags from hi|lo. */
4873 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
4875 tcg_gen_mov_i32(cpu_NF
, hi
);
4876 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
4879 /* Load/Store exclusive instructions are implemented by remembering
4880 the value/address loaded, and seeing if these are the same
4881 when the store is performed. This should be sufficient to implement
4882 the architecturally mandated semantics, and avoids having to monitor
4883 regular stores. The compare vs the remembered value is done during
4884 the cmpxchg operation, but we must compare the addresses manually. */
4885 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
4886 TCGv_i32 addr
, int size
)
4888 TCGv_i32 tmp
= tcg_temp_new_i32();
4889 MemOp opc
= size
| MO_ALIGN
| s
->be_data
;
4894 TCGv_i32 tmp2
= tcg_temp_new_i32();
4895 TCGv_i64 t64
= tcg_temp_new_i64();
4897 /* For AArch32, architecturally the 32-bit word at the lowest
4898 * address is always Rt and the one at addr+4 is Rt2, even if
4899 * the CPU is big-endian. That means we don't want to do a
4900 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
4901 * for an architecturally 64-bit access, but instead do a
4902 * 64-bit access using MO_BE if appropriate and then split
4904 * This only makes a difference for BE32 user-mode, where
4905 * frob64() must not flip the two halves of the 64-bit data
4906 * but this code must treat BE32 user-mode like BE32 system.
4908 TCGv taddr
= gen_aa32_addr(s
, addr
, opc
);
4910 tcg_gen_qemu_ld_i64(t64
, taddr
, get_mem_index(s
), opc
);
4911 tcg_temp_free(taddr
);
4912 tcg_gen_mov_i64(cpu_exclusive_val
, t64
);
4913 if (s
->be_data
== MO_BE
) {
4914 tcg_gen_extr_i64_i32(tmp2
, tmp
, t64
);
4916 tcg_gen_extr_i64_i32(tmp
, tmp2
, t64
);
4918 tcg_temp_free_i64(t64
);
4920 store_reg(s
, rt2
, tmp2
);
4922 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
), opc
);
4923 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
4926 store_reg(s
, rt
, tmp
);
4927 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
4930 static void gen_clrex(DisasContext
*s
)
4932 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
4935 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
4936 TCGv_i32 addr
, int size
)
4938 TCGv_i32 t0
, t1
, t2
;
4941 TCGLabel
*done_label
;
4942 TCGLabel
*fail_label
;
4943 MemOp opc
= size
| MO_ALIGN
| s
->be_data
;
4945 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
4951 fail_label
= gen_new_label();
4952 done_label
= gen_new_label();
4953 extaddr
= tcg_temp_new_i64();
4954 tcg_gen_extu_i32_i64(extaddr
, addr
);
4955 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
4956 tcg_temp_free_i64(extaddr
);
4958 taddr
= gen_aa32_addr(s
, addr
, opc
);
4959 t0
= tcg_temp_new_i32();
4960 t1
= load_reg(s
, rt
);
4962 TCGv_i64 o64
= tcg_temp_new_i64();
4963 TCGv_i64 n64
= tcg_temp_new_i64();
4965 t2
= load_reg(s
, rt2
);
4966 /* For AArch32, architecturally the 32-bit word at the lowest
4967 * address is always Rt and the one at addr+4 is Rt2, even if
4968 * the CPU is big-endian. Since we're going to treat this as a
4969 * single 64-bit BE store, we need to put the two halves in the
4970 * opposite order for BE to LE, so that they end up in the right
4972 * We don't want gen_aa32_frob64() because that does the wrong
4973 * thing for BE32 usermode.
4975 if (s
->be_data
== MO_BE
) {
4976 tcg_gen_concat_i32_i64(n64
, t2
, t1
);
4978 tcg_gen_concat_i32_i64(n64
, t1
, t2
);
4980 tcg_temp_free_i32(t2
);
4982 tcg_gen_atomic_cmpxchg_i64(o64
, taddr
, cpu_exclusive_val
, n64
,
4983 get_mem_index(s
), opc
);
4984 tcg_temp_free_i64(n64
);
4986 tcg_gen_setcond_i64(TCG_COND_NE
, o64
, o64
, cpu_exclusive_val
);
4987 tcg_gen_extrl_i64_i32(t0
, o64
);
4989 tcg_temp_free_i64(o64
);
4991 t2
= tcg_temp_new_i32();
4992 tcg_gen_extrl_i64_i32(t2
, cpu_exclusive_val
);
4993 tcg_gen_atomic_cmpxchg_i32(t0
, taddr
, t2
, t1
, get_mem_index(s
), opc
);
4994 tcg_gen_setcond_i32(TCG_COND_NE
, t0
, t0
, t2
);
4995 tcg_temp_free_i32(t2
);
4997 tcg_temp_free_i32(t1
);
4998 tcg_temp_free(taddr
);
4999 tcg_gen_mov_i32(cpu_R
[rd
], t0
);
5000 tcg_temp_free_i32(t0
);
5001 tcg_gen_br(done_label
);
5003 gen_set_label(fail_label
);
5004 tcg_gen_movi_i32(cpu_R
[rd
], 1);
5005 gen_set_label(done_label
);
5006 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
5012 * @mode: mode field from insn (which stack to store to)
5013 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
5014 * @writeback: true if writeback bit set
5016 * Generate code for the SRS (Store Return State) insn.
5018 static void gen_srs(DisasContext
*s
,
5019 uint32_t mode
, uint32_t amode
, bool writeback
)
5026 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
5027 * and specified mode is monitor mode
5028 * - UNDEFINED in Hyp mode
5029 * - UNPREDICTABLE in User or System mode
5030 * - UNPREDICTABLE if the specified mode is:
5031 * -- not implemented
5032 * -- not a valid mode number
5033 * -- a mode that's at a higher exception level
5034 * -- Monitor, if we are Non-secure
5035 * For the UNPREDICTABLE cases we choose to UNDEF.
5037 if (s
->current_el
== 1 && !s
->ns
&& mode
== ARM_CPU_MODE_MON
) {
5038 gen_exception_insn(s
, s
->pc_curr
, EXCP_UDEF
, syn_uncategorized(), 3);
5042 if (s
->current_el
== 0 || s
->current_el
== 2) {
5047 case ARM_CPU_MODE_USR
:
5048 case ARM_CPU_MODE_FIQ
:
5049 case ARM_CPU_MODE_IRQ
:
5050 case ARM_CPU_MODE_SVC
:
5051 case ARM_CPU_MODE_ABT
:
5052 case ARM_CPU_MODE_UND
:
5053 case ARM_CPU_MODE_SYS
:
5055 case ARM_CPU_MODE_HYP
:
5056 if (s
->current_el
== 1 || !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
5060 case ARM_CPU_MODE_MON
:
5061 /* No need to check specifically for "are we non-secure" because
5062 * we've already made EL0 UNDEF and handled the trap for S-EL1;
5063 * so if this isn't EL3 then we must be non-secure.
5065 if (s
->current_el
!= 3) {
5074 unallocated_encoding(s
);
5078 addr
= tcg_temp_new_i32();
5079 tmp
= tcg_const_i32(mode
);
5080 /* get_r13_banked() will raise an exception if called from System mode */
5081 gen_set_condexec(s
);
5082 gen_set_pc_im(s
, s
->pc_curr
);
5083 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
5084 tcg_temp_free_i32(tmp
);
5101 tcg_gen_addi_i32(addr
, addr
, offset
);
5102 tmp
= load_reg(s
, 14);
5103 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
5104 tcg_temp_free_i32(tmp
);
5105 tmp
= load_cpu_field(spsr
);
5106 tcg_gen_addi_i32(addr
, addr
, 4);
5107 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
5108 tcg_temp_free_i32(tmp
);
5126 tcg_gen_addi_i32(addr
, addr
, offset
);
5127 tmp
= tcg_const_i32(mode
);
5128 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
5129 tcg_temp_free_i32(tmp
);
5131 tcg_temp_free_i32(addr
);
5132 s
->base
.is_jmp
= DISAS_UPDATE_EXIT
;
5135 /* Generate a label used for skipping this instruction */
5136 static void arm_gen_condlabel(DisasContext
*s
)
5139 s
->condlabel
= gen_new_label();
5144 /* Skip this instruction if the ARM condition is false */
5145 static void arm_skip_unless(DisasContext
*s
, uint32_t cond
)
5147 arm_gen_condlabel(s
);
5148 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
5153 * Constant expanders for the decoders.
5156 static int negate(DisasContext
*s
, int x
)
5161 static int plus_2(DisasContext
*s
, int x
)
5166 static int times_2(DisasContext
*s
, int x
)
5171 static int times_4(DisasContext
*s
, int x
)
5176 /* Return only the rotation part of T32ExpandImm. */
5177 static int t32_expandimm_rot(DisasContext
*s
, int x
)
5179 return x
& 0xc00 ? extract32(x
, 7, 5) : 0;
5182 /* Return the unrotated immediate from T32ExpandImm. */
5183 static int t32_expandimm_imm(DisasContext
*s
, int x
)
5185 int imm
= extract32(x
, 0, 8);
5187 switch (extract32(x
, 8, 4)) {
5189 /* Nothing to do. */
5191 case 1: /* 00XY00XY */
5194 case 2: /* XY00XY00 */
5197 case 3: /* XYXYXYXY */
5201 /* Rotated constant. */
5208 static int t32_branch24(DisasContext
*s
, int x
)
5210 /* Convert J1:J2 at x[22:21] to I2:I1, which involves I=J^~S. */
5211 x
^= !(x
< 0) * (3 << 21);
5212 /* Append the final zero. */
5216 static int t16_setflags(DisasContext
*s
)
5218 return s
->condexec_mask
== 0;
5221 static int t16_push_list(DisasContext
*s
, int x
)
5223 return (x
& 0xff) | (x
& 0x100) << (14 - 8);
5226 static int t16_pop_list(DisasContext
*s
, int x
)
5228 return (x
& 0xff) | (x
& 0x100) << (15 - 8);
5232 * Include the generated decoders.
5235 #include "decode-a32.c.inc"
5236 #include "decode-a32-uncond.c.inc"
5237 #include "decode-t32.c.inc"
5238 #include "decode-t16.c.inc"
5240 static bool valid_cp(DisasContext
*s
, int cp
)
5243 * Return true if this coprocessor field indicates something
5244 * that's really a possible coprocessor.
5245 * For v7 and earlier, coprocessors 8..15 were reserved for Arm use,
5246 * and of those only cp14 and cp15 were used for registers.
5247 * cp10 and cp11 were used for VFP and Neon, whose decode is
5248 * dealt with elsewhere. With the advent of fp16, cp9 is also
5250 * For v8A and later, the encoding has been tightened so that
5251 * only cp14 and cp15 are valid, and other values aren't considered
5252 * to be in the coprocessor-instruction space at all. v8M still
5253 * permits coprocessors 0..7.
5255 if (arm_dc_feature(s
, ARM_FEATURE_V8
) &&
5256 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
5259 return cp
< 8 || cp
>= 14;
5262 static bool trans_MCR(DisasContext
*s
, arg_MCR
*a
)
5264 if (!valid_cp(s
, a
->cp
)) {
5267 do_coproc_insn(s
, a
->cp
, false, a
->opc1
, a
->crn
, a
->crm
, a
->opc2
,
5272 static bool trans_MRC(DisasContext
*s
, arg_MRC
*a
)
5274 if (!valid_cp(s
, a
->cp
)) {
5277 do_coproc_insn(s
, a
->cp
, false, a
->opc1
, a
->crn
, a
->crm
, a
->opc2
,
5282 static bool trans_MCRR(DisasContext
*s
, arg_MCRR
*a
)
5284 if (!valid_cp(s
, a
->cp
)) {
5287 do_coproc_insn(s
, a
->cp
, true, a
->opc1
, 0, a
->crm
, 0,
5288 false, a
->rt
, a
->rt2
);
5292 static bool trans_MRRC(DisasContext
*s
, arg_MRRC
*a
)
5294 if (!valid_cp(s
, a
->cp
)) {
5297 do_coproc_insn(s
, a
->cp
, true, a
->opc1
, 0, a
->crm
, 0,
5298 true, a
->rt
, a
->rt2
);
5302 /* Helpers to swap operands for reverse-subtract. */
5303 static void gen_rsb(TCGv_i32 dst
, TCGv_i32 a
, TCGv_i32 b
)
5305 tcg_gen_sub_i32(dst
, b
, a
);
5308 static void gen_rsb_CC(TCGv_i32 dst
, TCGv_i32 a
, TCGv_i32 b
)
5310 gen_sub_CC(dst
, b
, a
);
5313 static void gen_rsc(TCGv_i32 dest
, TCGv_i32 a
, TCGv_i32 b
)
5315 gen_sub_carry(dest
, b
, a
);
5318 static void gen_rsc_CC(TCGv_i32 dest
, TCGv_i32 a
, TCGv_i32 b
)
5320 gen_sbc_CC(dest
, b
, a
);
5324 * Helpers for the data processing routines.
5326 * After the computation store the results back.
5327 * This may be suppressed altogether (STREG_NONE), require a runtime
5328 * check against the stack limits (STREG_SP_CHECK), or generate an
5329 * exception return. Oh, or store into a register.
5331 * Always return true, indicating success for a trans_* function.
5340 static bool store_reg_kind(DisasContext
*s
, int rd
,
5341 TCGv_i32 val
, StoreRegKind kind
)
5345 tcg_temp_free_i32(val
);
5348 /* See ALUWritePC: Interworking only from a32 mode. */
5350 store_reg(s
, rd
, val
);
5352 store_reg_bx(s
, rd
, val
);
5355 case STREG_SP_CHECK
:
5356 store_sp_checked(s
, val
);
5359 gen_exception_return(s
, val
);
5362 g_assert_not_reached();
5366 * Data Processing (register)
5368 * Operate, with set flags, one register source,
5369 * one immediate shifted register source, and a destination.
5371 static bool op_s_rrr_shi(DisasContext
*s
, arg_s_rrr_shi
*a
,
5372 void (*gen
)(TCGv_i32
, TCGv_i32
, TCGv_i32
),
5373 int logic_cc
, StoreRegKind kind
)
5375 TCGv_i32 tmp1
, tmp2
;
5377 tmp2
= load_reg(s
, a
->rm
);
5378 gen_arm_shift_im(tmp2
, a
->shty
, a
->shim
, logic_cc
);
5379 tmp1
= load_reg(s
, a
->rn
);
5381 gen(tmp1
, tmp1
, tmp2
);
5382 tcg_temp_free_i32(tmp2
);
5387 return store_reg_kind(s
, a
->rd
, tmp1
, kind
);
5390 static bool op_s_rxr_shi(DisasContext
*s
, arg_s_rrr_shi
*a
,
5391 void (*gen
)(TCGv_i32
, TCGv_i32
),
5392 int logic_cc
, StoreRegKind kind
)
5396 tmp
= load_reg(s
, a
->rm
);
5397 gen_arm_shift_im(tmp
, a
->shty
, a
->shim
, logic_cc
);
5403 return store_reg_kind(s
, a
->rd
, tmp
, kind
);
5407 * Data-processing (register-shifted register)
5409 * Operate, with set flags, one register source,
5410 * one register shifted register source, and a destination.
5412 static bool op_s_rrr_shr(DisasContext
*s
, arg_s_rrr_shr
*a
,
5413 void (*gen
)(TCGv_i32
, TCGv_i32
, TCGv_i32
),
5414 int logic_cc
, StoreRegKind kind
)
5416 TCGv_i32 tmp1
, tmp2
;
5418 tmp1
= load_reg(s
, a
->rs
);
5419 tmp2
= load_reg(s
, a
->rm
);
5420 gen_arm_shift_reg(tmp2
, a
->shty
, tmp1
, logic_cc
);
5421 tmp1
= load_reg(s
, a
->rn
);
5423 gen(tmp1
, tmp1
, tmp2
);
5424 tcg_temp_free_i32(tmp2
);
5429 return store_reg_kind(s
, a
->rd
, tmp1
, kind
);
5432 static bool op_s_rxr_shr(DisasContext
*s
, arg_s_rrr_shr
*a
,
5433 void (*gen
)(TCGv_i32
, TCGv_i32
),
5434 int logic_cc
, StoreRegKind kind
)
5436 TCGv_i32 tmp1
, tmp2
;
5438 tmp1
= load_reg(s
, a
->rs
);
5439 tmp2
= load_reg(s
, a
->rm
);
5440 gen_arm_shift_reg(tmp2
, a
->shty
, tmp1
, logic_cc
);
5446 return store_reg_kind(s
, a
->rd
, tmp2
, kind
);
5450 * Data-processing (immediate)
5452 * Operate, with set flags, one register source,
5453 * one rotated immediate, and a destination.
5455 * Note that logic_cc && a->rot setting CF based on the msb of the
5456 * immediate is the reason why we must pass in the unrotated form
5459 static bool op_s_rri_rot(DisasContext
*s
, arg_s_rri_rot
*a
,
5460 void (*gen
)(TCGv_i32
, TCGv_i32
, TCGv_i32
),
5461 int logic_cc
, StoreRegKind kind
)
5463 TCGv_i32 tmp1
, tmp2
;
5466 imm
= ror32(a
->imm
, a
->rot
);
5467 if (logic_cc
&& a
->rot
) {
5468 tcg_gen_movi_i32(cpu_CF
, imm
>> 31);
5470 tmp2
= tcg_const_i32(imm
);
5471 tmp1
= load_reg(s
, a
->rn
);
5473 gen(tmp1
, tmp1
, tmp2
);
5474 tcg_temp_free_i32(tmp2
);
5479 return store_reg_kind(s
, a
->rd
, tmp1
, kind
);
5482 static bool op_s_rxi_rot(DisasContext
*s
, arg_s_rri_rot
*a
,
5483 void (*gen
)(TCGv_i32
, TCGv_i32
),
5484 int logic_cc
, StoreRegKind kind
)
5489 imm
= ror32(a
->imm
, a
->rot
);
5490 if (logic_cc
&& a
->rot
) {
5491 tcg_gen_movi_i32(cpu_CF
, imm
>> 31);
5493 tmp
= tcg_const_i32(imm
);
5499 return store_reg_kind(s
, a
->rd
, tmp
, kind
);
5502 #define DO_ANY3(NAME, OP, L, K) \
5503 static bool trans_##NAME##_rrri(DisasContext *s, arg_s_rrr_shi *a) \
5504 { StoreRegKind k = (K); return op_s_rrr_shi(s, a, OP, L, k); } \
5505 static bool trans_##NAME##_rrrr(DisasContext *s, arg_s_rrr_shr *a) \
5506 { StoreRegKind k = (K); return op_s_rrr_shr(s, a, OP, L, k); } \
5507 static bool trans_##NAME##_rri(DisasContext *s, arg_s_rri_rot *a) \
5508 { StoreRegKind k = (K); return op_s_rri_rot(s, a, OP, L, k); }
5510 #define DO_ANY2(NAME, OP, L, K) \
5511 static bool trans_##NAME##_rxri(DisasContext *s, arg_s_rrr_shi *a) \
5512 { StoreRegKind k = (K); return op_s_rxr_shi(s, a, OP, L, k); } \
5513 static bool trans_##NAME##_rxrr(DisasContext *s, arg_s_rrr_shr *a) \
5514 { StoreRegKind k = (K); return op_s_rxr_shr(s, a, OP, L, k); } \
5515 static bool trans_##NAME##_rxi(DisasContext *s, arg_s_rri_rot *a) \
5516 { StoreRegKind k = (K); return op_s_rxi_rot(s, a, OP, L, k); }
5518 #define DO_CMP2(NAME, OP, L) \
5519 static bool trans_##NAME##_xrri(DisasContext *s, arg_s_rrr_shi *a) \
5520 { return op_s_rrr_shi(s, a, OP, L, STREG_NONE); } \
5521 static bool trans_##NAME##_xrrr(DisasContext *s, arg_s_rrr_shr *a) \
5522 { return op_s_rrr_shr(s, a, OP, L, STREG_NONE); } \
5523 static bool trans_##NAME##_xri(DisasContext *s, arg_s_rri_rot *a) \
5524 { return op_s_rri_rot(s, a, OP, L, STREG_NONE); }
5526 DO_ANY3(AND
, tcg_gen_and_i32
, a
->s
, STREG_NORMAL
)
5527 DO_ANY3(EOR
, tcg_gen_xor_i32
, a
->s
, STREG_NORMAL
)
5528 DO_ANY3(ORR
, tcg_gen_or_i32
, a
->s
, STREG_NORMAL
)
5529 DO_ANY3(BIC
, tcg_gen_andc_i32
, a
->s
, STREG_NORMAL
)
5531 DO_ANY3(RSB
, a
->s
? gen_rsb_CC
: gen_rsb
, false, STREG_NORMAL
)
5532 DO_ANY3(ADC
, a
->s
? gen_adc_CC
: gen_add_carry
, false, STREG_NORMAL
)
5533 DO_ANY3(SBC
, a
->s
? gen_sbc_CC
: gen_sub_carry
, false, STREG_NORMAL
)
5534 DO_ANY3(RSC
, a
->s
? gen_rsc_CC
: gen_rsc
, false, STREG_NORMAL
)
5536 DO_CMP2(TST
, tcg_gen_and_i32
, true)
5537 DO_CMP2(TEQ
, tcg_gen_xor_i32
, true)
5538 DO_CMP2(CMN
, gen_add_CC
, false)
5539 DO_CMP2(CMP
, gen_sub_CC
, false)
5541 DO_ANY3(ADD
, a
->s
? gen_add_CC
: tcg_gen_add_i32
, false,
5542 a
->rd
== 13 && a
->rn
== 13 ? STREG_SP_CHECK
: STREG_NORMAL
)
5545 * Note for the computation of StoreRegKind we return out of the
5546 * middle of the functions that are expanded by DO_ANY3, and that
5547 * we modify a->s via that parameter before it is used by OP.
5549 DO_ANY3(SUB
, a
->s
? gen_sub_CC
: tcg_gen_sub_i32
, false,
5551 StoreRegKind ret
= STREG_NORMAL
;
5552 if (a
->rd
== 15 && a
->s
) {
5554 * See ALUExceptionReturn:
5555 * In User mode, UNPREDICTABLE; we choose UNDEF.
5556 * In Hyp mode, UNDEFINED.
5558 if (IS_USER(s
) || s
->current_el
== 2) {
5559 unallocated_encoding(s
);
5562 /* There is no writeback of nzcv to PSTATE. */
5564 ret
= STREG_EXC_RET
;
5565 } else if (a
->rd
== 13 && a
->rn
== 13) {
5566 ret
= STREG_SP_CHECK
;
5571 DO_ANY2(MOV
, tcg_gen_mov_i32
, a
->s
,
5573 StoreRegKind ret
= STREG_NORMAL
;
5574 if (a
->rd
== 15 && a
->s
) {
5576 * See ALUExceptionReturn:
5577 * In User mode, UNPREDICTABLE; we choose UNDEF.
5578 * In Hyp mode, UNDEFINED.
5580 if (IS_USER(s
) || s
->current_el
== 2) {
5581 unallocated_encoding(s
);
5584 /* There is no writeback of nzcv to PSTATE. */
5586 ret
= STREG_EXC_RET
;
5587 } else if (a
->rd
== 13) {
5588 ret
= STREG_SP_CHECK
;
5593 DO_ANY2(MVN
, tcg_gen_not_i32
, a
->s
, STREG_NORMAL
)
5596 * ORN is only available with T32, so there is no register-shifted-register
5597 * form of the insn. Using the DO_ANY3 macro would create an unused function.
5599 static bool trans_ORN_rrri(DisasContext
*s
, arg_s_rrr_shi
*a
)
5601 return op_s_rrr_shi(s
, a
, tcg_gen_orc_i32
, a
->s
, STREG_NORMAL
);
5604 static bool trans_ORN_rri(DisasContext
*s
, arg_s_rri_rot
*a
)
5606 return op_s_rri_rot(s
, a
, tcg_gen_orc_i32
, a
->s
, STREG_NORMAL
);
5613 static bool trans_ADR(DisasContext
*s
, arg_ri
*a
)
5615 store_reg_bx(s
, a
->rd
, add_reg_for_lit(s
, 15, a
->imm
));
5619 static bool trans_MOVW(DisasContext
*s
, arg_MOVW
*a
)
5623 if (!ENABLE_ARCH_6T2
) {
5627 tmp
= tcg_const_i32(a
->imm
);
5628 store_reg(s
, a
->rd
, tmp
);
5632 static bool trans_MOVT(DisasContext
*s
, arg_MOVW
*a
)
5636 if (!ENABLE_ARCH_6T2
) {
5640 tmp
= load_reg(s
, a
->rd
);
5641 tcg_gen_ext16u_i32(tmp
, tmp
);
5642 tcg_gen_ori_i32(tmp
, tmp
, a
->imm
<< 16);
5643 store_reg(s
, a
->rd
, tmp
);
5648 * Multiply and multiply accumulate
5651 static bool op_mla(DisasContext
*s
, arg_s_rrrr
*a
, bool add
)
5655 t1
= load_reg(s
, a
->rn
);
5656 t2
= load_reg(s
, a
->rm
);
5657 tcg_gen_mul_i32(t1
, t1
, t2
);
5658 tcg_temp_free_i32(t2
);
5660 t2
= load_reg(s
, a
->ra
);
5661 tcg_gen_add_i32(t1
, t1
, t2
);
5662 tcg_temp_free_i32(t2
);
5667 store_reg(s
, a
->rd
, t1
);
5671 static bool trans_MUL(DisasContext
*s
, arg_MUL
*a
)
5673 return op_mla(s
, a
, false);
5676 static bool trans_MLA(DisasContext
*s
, arg_MLA
*a
)
5678 return op_mla(s
, a
, true);
5681 static bool trans_MLS(DisasContext
*s
, arg_MLS
*a
)
5685 if (!ENABLE_ARCH_6T2
) {
5688 t1
= load_reg(s
, a
->rn
);
5689 t2
= load_reg(s
, a
->rm
);
5690 tcg_gen_mul_i32(t1
, t1
, t2
);
5691 tcg_temp_free_i32(t2
);
5692 t2
= load_reg(s
, a
->ra
);
5693 tcg_gen_sub_i32(t1
, t2
, t1
);
5694 tcg_temp_free_i32(t2
);
5695 store_reg(s
, a
->rd
, t1
);
5699 static bool op_mlal(DisasContext
*s
, arg_s_rrrr
*a
, bool uns
, bool add
)
5701 TCGv_i32 t0
, t1
, t2
, t3
;
5703 t0
= load_reg(s
, a
->rm
);
5704 t1
= load_reg(s
, a
->rn
);
5706 tcg_gen_mulu2_i32(t0
, t1
, t0
, t1
);
5708 tcg_gen_muls2_i32(t0
, t1
, t0
, t1
);
5711 t2
= load_reg(s
, a
->ra
);
5712 t3
= load_reg(s
, a
->rd
);
5713 tcg_gen_add2_i32(t0
, t1
, t0
, t1
, t2
, t3
);
5714 tcg_temp_free_i32(t2
);
5715 tcg_temp_free_i32(t3
);
5718 gen_logicq_cc(t0
, t1
);
5720 store_reg(s
, a
->ra
, t0
);
5721 store_reg(s
, a
->rd
, t1
);
5725 static bool trans_UMULL(DisasContext
*s
, arg_UMULL
*a
)
5727 return op_mlal(s
, a
, true, false);
5730 static bool trans_SMULL(DisasContext
*s
, arg_SMULL
*a
)
5732 return op_mlal(s
, a
, false, false);
5735 static bool trans_UMLAL(DisasContext
*s
, arg_UMLAL
*a
)
5737 return op_mlal(s
, a
, true, true);
5740 static bool trans_SMLAL(DisasContext
*s
, arg_SMLAL
*a
)
5742 return op_mlal(s
, a
, false, true);
5745 static bool trans_UMAAL(DisasContext
*s
, arg_UMAAL
*a
)
5747 TCGv_i32 t0
, t1
, t2
, zero
;
5750 ? !arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)
5755 t0
= load_reg(s
, a
->rm
);
5756 t1
= load_reg(s
, a
->rn
);
5757 tcg_gen_mulu2_i32(t0
, t1
, t0
, t1
);
5758 zero
= tcg_const_i32(0);
5759 t2
= load_reg(s
, a
->ra
);
5760 tcg_gen_add2_i32(t0
, t1
, t0
, t1
, t2
, zero
);
5761 tcg_temp_free_i32(t2
);
5762 t2
= load_reg(s
, a
->rd
);
5763 tcg_gen_add2_i32(t0
, t1
, t0
, t1
, t2
, zero
);
5764 tcg_temp_free_i32(t2
);
5765 tcg_temp_free_i32(zero
);
5766 store_reg(s
, a
->ra
, t0
);
5767 store_reg(s
, a
->rd
, t1
);
5772 * Saturating addition and subtraction
5775 static bool op_qaddsub(DisasContext
*s
, arg_rrr
*a
, bool add
, bool doub
)
5780 ? !arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)
5781 : !ENABLE_ARCH_5TE
) {
5785 t0
= load_reg(s
, a
->rm
);
5786 t1
= load_reg(s
, a
->rn
);
5788 gen_helper_add_saturate(t1
, cpu_env
, t1
, t1
);
5791 gen_helper_add_saturate(t0
, cpu_env
, t0
, t1
);
5793 gen_helper_sub_saturate(t0
, cpu_env
, t0
, t1
);
5795 tcg_temp_free_i32(t1
);
5796 store_reg(s
, a
->rd
, t0
);
5800 #define DO_QADDSUB(NAME, ADD, DOUB) \
5801 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
5803 return op_qaddsub(s, a, ADD, DOUB); \
5806 DO_QADDSUB(QADD
, true, false)
5807 DO_QADDSUB(QSUB
, false, false)
5808 DO_QADDSUB(QDADD
, true, true)
5809 DO_QADDSUB(QDSUB
, false, true)
5814 * Halfword multiply and multiply accumulate
5817 static bool op_smlaxxx(DisasContext
*s
, arg_rrrr
*a
,
5818 int add_long
, bool nt
, bool mt
)
5820 TCGv_i32 t0
, t1
, tl
, th
;
5823 ? !arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)
5824 : !ENABLE_ARCH_5TE
) {
5828 t0
= load_reg(s
, a
->rn
);
5829 t1
= load_reg(s
, a
->rm
);
5830 gen_mulxy(t0
, t1
, nt
, mt
);
5831 tcg_temp_free_i32(t1
);
5835 store_reg(s
, a
->rd
, t0
);
5838 t1
= load_reg(s
, a
->ra
);
5839 gen_helper_add_setq(t0
, cpu_env
, t0
, t1
);
5840 tcg_temp_free_i32(t1
);
5841 store_reg(s
, a
->rd
, t0
);
5844 tl
= load_reg(s
, a
->ra
);
5845 th
= load_reg(s
, a
->rd
);
5846 /* Sign-extend the 32-bit product to 64 bits. */
5847 t1
= tcg_temp_new_i32();
5848 tcg_gen_sari_i32(t1
, t0
, 31);
5849 tcg_gen_add2_i32(tl
, th
, tl
, th
, t0
, t1
);
5850 tcg_temp_free_i32(t0
);
5851 tcg_temp_free_i32(t1
);
5852 store_reg(s
, a
->ra
, tl
);
5853 store_reg(s
, a
->rd
, th
);
5856 g_assert_not_reached();
5861 #define DO_SMLAX(NAME, add, nt, mt) \
5862 static bool trans_##NAME(DisasContext *s, arg_rrrr *a) \
5864 return op_smlaxxx(s, a, add, nt, mt); \
5867 DO_SMLAX(SMULBB
, 0, 0, 0)
5868 DO_SMLAX(SMULBT
, 0, 0, 1)
5869 DO_SMLAX(SMULTB
, 0, 1, 0)
5870 DO_SMLAX(SMULTT
, 0, 1, 1)
5872 DO_SMLAX(SMLABB
, 1, 0, 0)
5873 DO_SMLAX(SMLABT
, 1, 0, 1)
5874 DO_SMLAX(SMLATB
, 1, 1, 0)
5875 DO_SMLAX(SMLATT
, 1, 1, 1)
5877 DO_SMLAX(SMLALBB
, 2, 0, 0)
5878 DO_SMLAX(SMLALBT
, 2, 0, 1)
5879 DO_SMLAX(SMLALTB
, 2, 1, 0)
5880 DO_SMLAX(SMLALTT
, 2, 1, 1)
5884 static bool op_smlawx(DisasContext
*s
, arg_rrrr
*a
, bool add
, bool mt
)
5888 if (!ENABLE_ARCH_5TE
) {
5892 t0
= load_reg(s
, a
->rn
);
5893 t1
= load_reg(s
, a
->rm
);
5895 * Since the nominal result is product<47:16>, shift the 16-bit
5896 * input up by 16 bits, so that the result is at product<63:32>.
5899 tcg_gen_andi_i32(t1
, t1
, 0xffff0000);
5901 tcg_gen_shli_i32(t1
, t1
, 16);
5903 tcg_gen_muls2_i32(t0
, t1
, t0
, t1
);
5904 tcg_temp_free_i32(t0
);
5906 t0
= load_reg(s
, a
->ra
);
5907 gen_helper_add_setq(t1
, cpu_env
, t1
, t0
);
5908 tcg_temp_free_i32(t0
);
5910 store_reg(s
, a
->rd
, t1
);
5914 #define DO_SMLAWX(NAME, add, mt) \
5915 static bool trans_##NAME(DisasContext *s, arg_rrrr *a) \
5917 return op_smlawx(s, a, add, mt); \
5920 DO_SMLAWX(SMULWB
, 0, 0)
5921 DO_SMLAWX(SMULWT
, 0, 1)
5922 DO_SMLAWX(SMLAWB
, 1, 0)
5923 DO_SMLAWX(SMLAWT
, 1, 1)
5928 * MSR (immediate) and hints
5931 static bool trans_YIELD(DisasContext
*s
, arg_YIELD
*a
)
5934 * When running single-threaded TCG code, use the helper to ensure that
5935 * the next round-robin scheduled vCPU gets a crack. When running in
5936 * MTTCG we don't generate jumps to the helper as it won't affect the
5937 * scheduling of other vCPUs.
5939 if (!(tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
5940 gen_set_pc_im(s
, s
->base
.pc_next
);
5941 s
->base
.is_jmp
= DISAS_YIELD
;
5946 static bool trans_WFE(DisasContext
*s
, arg_WFE
*a
)
5949 * When running single-threaded TCG code, use the helper to ensure that
5950 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
5951 * just skip this instruction. Currently the SEV/SEVL instructions,
5952 * which are *one* of many ways to wake the CPU from WFE, are not
5953 * implemented so we can't sleep like WFI does.
5955 if (!(tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
5956 gen_set_pc_im(s
, s
->base
.pc_next
);
5957 s
->base
.is_jmp
= DISAS_WFE
;
5962 static bool trans_WFI(DisasContext
*s
, arg_WFI
*a
)
5964 /* For WFI, halt the vCPU until an IRQ. */
5965 gen_set_pc_im(s
, s
->base
.pc_next
);
5966 s
->base
.is_jmp
= DISAS_WFI
;
5970 static bool trans_NOP(DisasContext
*s
, arg_NOP
*a
)
5975 static bool trans_MSR_imm(DisasContext
*s
, arg_MSR_imm
*a
)
5977 uint32_t val
= ror32(a
->imm
, a
->rot
* 2);
5978 uint32_t mask
= msr_mask(s
, a
->mask
, a
->r
);
5980 if (gen_set_psr_im(s
, mask
, a
->r
, val
)) {
5981 unallocated_encoding(s
);
5987 * Cyclic Redundancy Check
5990 static bool op_crc32(DisasContext
*s
, arg_rrr
*a
, bool c
, MemOp sz
)
5992 TCGv_i32 t1
, t2
, t3
;
5994 if (!dc_isar_feature(aa32_crc32
, s
)) {
5998 t1
= load_reg(s
, a
->rn
);
5999 t2
= load_reg(s
, a
->rm
);
6010 g_assert_not_reached();
6012 t3
= tcg_const_i32(1 << sz
);
6014 gen_helper_crc32c(t1
, t1
, t2
, t3
);
6016 gen_helper_crc32(t1
, t1
, t2
, t3
);
6018 tcg_temp_free_i32(t2
);
6019 tcg_temp_free_i32(t3
);
6020 store_reg(s
, a
->rd
, t1
);
6024 #define DO_CRC32(NAME, c, sz) \
6025 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
6026 { return op_crc32(s, a, c, sz); }
6028 DO_CRC32(CRC32B
, false, MO_8
)
6029 DO_CRC32(CRC32H
, false, MO_16
)
6030 DO_CRC32(CRC32W
, false, MO_32
)
6031 DO_CRC32(CRC32CB
, true, MO_8
)
6032 DO_CRC32(CRC32CH
, true, MO_16
)
6033 DO_CRC32(CRC32CW
, true, MO_32
)
6038 * Miscellaneous instructions
6041 static bool trans_MRS_bank(DisasContext
*s
, arg_MRS_bank
*a
)
6043 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
6046 gen_mrs_banked(s
, a
->r
, a
->sysm
, a
->rd
);
6050 static bool trans_MSR_bank(DisasContext
*s
, arg_MSR_bank
*a
)
6052 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
6055 gen_msr_banked(s
, a
->r
, a
->sysm
, a
->rn
);
6059 static bool trans_MRS_reg(DisasContext
*s
, arg_MRS_reg
*a
)
6063 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
6068 unallocated_encoding(s
);
6071 tmp
= load_cpu_field(spsr
);
6073 tmp
= tcg_temp_new_i32();
6074 gen_helper_cpsr_read(tmp
, cpu_env
);
6076 store_reg(s
, a
->rd
, tmp
);
6080 static bool trans_MSR_reg(DisasContext
*s
, arg_MSR_reg
*a
)
6083 uint32_t mask
= msr_mask(s
, a
->mask
, a
->r
);
6085 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
6088 tmp
= load_reg(s
, a
->rn
);
6089 if (gen_set_psr(s
, mask
, a
->r
, tmp
)) {
6090 unallocated_encoding(s
);
6095 static bool trans_MRS_v7m(DisasContext
*s
, arg_MRS_v7m
*a
)
6099 if (!arm_dc_feature(s
, ARM_FEATURE_M
)) {
6102 tmp
= tcg_const_i32(a
->sysm
);
6103 gen_helper_v7m_mrs(tmp
, cpu_env
, tmp
);
6104 store_reg(s
, a
->rd
, tmp
);
6108 static bool trans_MSR_v7m(DisasContext
*s
, arg_MSR_v7m
*a
)
6112 if (!arm_dc_feature(s
, ARM_FEATURE_M
)) {
6115 addr
= tcg_const_i32((a
->mask
<< 10) | a
->sysm
);
6116 reg
= load_reg(s
, a
->rn
);
6117 gen_helper_v7m_msr(cpu_env
, addr
, reg
);
6118 tcg_temp_free_i32(addr
);
6119 tcg_temp_free_i32(reg
);
6120 /* If we wrote to CONTROL, the EL might have changed */
6121 gen_helper_rebuild_hflags_m32_newel(cpu_env
);
6126 static bool trans_BX(DisasContext
*s
, arg_BX
*a
)
6128 if (!ENABLE_ARCH_4T
) {
6131 gen_bx_excret(s
, load_reg(s
, a
->rm
));
6135 static bool trans_BXJ(DisasContext
*s
, arg_BXJ
*a
)
6137 if (!ENABLE_ARCH_5J
|| arm_dc_feature(s
, ARM_FEATURE_M
)) {
6140 /* Trivial implementation equivalent to bx. */
6141 gen_bx(s
, load_reg(s
, a
->rm
));
6145 static bool trans_BLX_r(DisasContext
*s
, arg_BLX_r
*a
)
6149 if (!ENABLE_ARCH_5
) {
6152 tmp
= load_reg(s
, a
->rm
);
6153 tcg_gen_movi_i32(cpu_R
[14], s
->base
.pc_next
| s
->thumb
);
6159 * BXNS/BLXNS: only exist for v8M with the security extensions,
6160 * and always UNDEF if NonSecure. We don't implement these in
6161 * the user-only mode either (in theory you can use them from
6162 * Secure User mode but they are too tied in to system emulation).
6164 static bool trans_BXNS(DisasContext
*s
, arg_BXNS
*a
)
6166 if (!s
->v8m_secure
|| IS_USER_ONLY
) {
6167 unallocated_encoding(s
);
6174 static bool trans_BLXNS(DisasContext
*s
, arg_BLXNS
*a
)
6176 if (!s
->v8m_secure
|| IS_USER_ONLY
) {
6177 unallocated_encoding(s
);
6179 gen_blxns(s
, a
->rm
);
6184 static bool trans_CLZ(DisasContext
*s
, arg_CLZ
*a
)
6188 if (!ENABLE_ARCH_5
) {
6191 tmp
= load_reg(s
, a
->rm
);
6192 tcg_gen_clzi_i32(tmp
, tmp
, 32);
6193 store_reg(s
, a
->rd
, tmp
);
6197 static bool trans_ERET(DisasContext
*s
, arg_ERET
*a
)
6201 if (!arm_dc_feature(s
, ARM_FEATURE_V7VE
)) {
6205 unallocated_encoding(s
);
6208 if (s
->current_el
== 2) {
6209 /* ERET from Hyp uses ELR_Hyp, not LR */
6210 tmp
= load_cpu_field(elr_el
[2]);
6212 tmp
= load_reg(s
, 14);
6214 gen_exception_return(s
, tmp
);
6218 static bool trans_HLT(DisasContext
*s
, arg_HLT
*a
)
6224 static bool trans_BKPT(DisasContext
*s
, arg_BKPT
*a
)
6226 if (!ENABLE_ARCH_5
) {
6229 if (arm_dc_feature(s
, ARM_FEATURE_M
) &&
6230 semihosting_enabled() &&
6231 #ifndef CONFIG_USER_ONLY
6235 gen_exception_internal_insn(s
, s
->pc_curr
, EXCP_SEMIHOST
);
6237 gen_exception_bkpt_insn(s
, syn_aa32_bkpt(a
->imm
, false));
6242 static bool trans_HVC(DisasContext
*s
, arg_HVC
*a
)
6244 if (!ENABLE_ARCH_7
|| arm_dc_feature(s
, ARM_FEATURE_M
)) {
6248 unallocated_encoding(s
);
6255 static bool trans_SMC(DisasContext
*s
, arg_SMC
*a
)
6257 if (!ENABLE_ARCH_6K
|| arm_dc_feature(s
, ARM_FEATURE_M
)) {
6261 unallocated_encoding(s
);
6268 static bool trans_SG(DisasContext
*s
, arg_SG
*a
)
6270 if (!arm_dc_feature(s
, ARM_FEATURE_M
) ||
6271 !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
6276 * The bulk of the behaviour for this instruction is implemented
6277 * in v7m_handle_execute_nsc(), which deals with the insn when
6278 * it is executed by a CPU in non-secure state from memory
6279 * which is Secure & NonSecure-Callable.
6280 * Here we only need to handle the remaining cases:
6281 * * in NS memory (including the "security extension not
6282 * implemented" case) : NOP
6283 * * in S memory but CPU already secure (clear IT bits)
6284 * We know that the attribute for the memory this insn is
6285 * in must match the current CPU state, because otherwise
6286 * get_phys_addr_pmsav8 would have generated an exception.
6288 if (s
->v8m_secure
) {
6289 /* Like the IT insn, we don't need to generate any code */
6290 s
->condexec_cond
= 0;
6291 s
->condexec_mask
= 0;
6296 static bool trans_TT(DisasContext
*s
, arg_TT
*a
)
6300 if (!arm_dc_feature(s
, ARM_FEATURE_M
) ||
6301 !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
6304 if (a
->rd
== 13 || a
->rd
== 15 || a
->rn
== 15) {
6305 /* We UNDEF for these UNPREDICTABLE cases */
6306 unallocated_encoding(s
);
6309 if (a
->A
&& !s
->v8m_secure
) {
6310 /* This case is UNDEFINED. */
6311 unallocated_encoding(s
);
6315 addr
= load_reg(s
, a
->rn
);
6316 tmp
= tcg_const_i32((a
->A
<< 1) | a
->T
);
6317 gen_helper_v7m_tt(tmp
, cpu_env
, addr
, tmp
);
6318 tcg_temp_free_i32(addr
);
6319 store_reg(s
, a
->rd
, tmp
);
6324 * Load/store register index
6327 static ISSInfo
make_issinfo(DisasContext
*s
, int rd
, bool p
, bool w
)
6331 /* ISS not valid if writeback */
6334 if (s
->base
.pc_next
- s
->pc_curr
== 2) {
6343 static TCGv_i32
op_addr_rr_pre(DisasContext
*s
, arg_ldst_rr
*a
)
6345 TCGv_i32 addr
= load_reg(s
, a
->rn
);
6347 if (s
->v8m_stackcheck
&& a
->rn
== 13 && a
->w
) {
6348 gen_helper_v8m_stackcheck(cpu_env
, addr
);
6352 TCGv_i32 ofs
= load_reg(s
, a
->rm
);
6353 gen_arm_shift_im(ofs
, a
->shtype
, a
->shimm
, 0);
6355 tcg_gen_add_i32(addr
, addr
, ofs
);
6357 tcg_gen_sub_i32(addr
, addr
, ofs
);
6359 tcg_temp_free_i32(ofs
);
6364 static void op_addr_rr_post(DisasContext
*s
, arg_ldst_rr
*a
,
6365 TCGv_i32 addr
, int address_offset
)
6368 TCGv_i32 ofs
= load_reg(s
, a
->rm
);
6369 gen_arm_shift_im(ofs
, a
->shtype
, a
->shimm
, 0);
6371 tcg_gen_add_i32(addr
, addr
, ofs
);
6373 tcg_gen_sub_i32(addr
, addr
, ofs
);
6375 tcg_temp_free_i32(ofs
);
6377 tcg_temp_free_i32(addr
);
6380 tcg_gen_addi_i32(addr
, addr
, address_offset
);
6381 store_reg(s
, a
->rn
, addr
);
6384 static bool op_load_rr(DisasContext
*s
, arg_ldst_rr
*a
,
6385 MemOp mop
, int mem_idx
)
6387 ISSInfo issinfo
= make_issinfo(s
, a
->rt
, a
->p
, a
->w
);
6390 addr
= op_addr_rr_pre(s
, a
);
6392 tmp
= tcg_temp_new_i32();
6393 gen_aa32_ld_i32(s
, tmp
, addr
, mem_idx
, mop
| s
->be_data
);
6394 disas_set_da_iss(s
, mop
, issinfo
);
6397 * Perform base writeback before the loaded value to
6398 * ensure correct behavior with overlapping index registers.
6400 op_addr_rr_post(s
, a
, addr
, 0);
6401 store_reg_from_load(s
, a
->rt
, tmp
);
6405 static bool op_store_rr(DisasContext
*s
, arg_ldst_rr
*a
,
6406 MemOp mop
, int mem_idx
)
6408 ISSInfo issinfo
= make_issinfo(s
, a
->rt
, a
->p
, a
->w
) | ISSIsWrite
;
6411 addr
= op_addr_rr_pre(s
, a
);
6413 tmp
= load_reg(s
, a
->rt
);
6414 gen_aa32_st_i32(s
, tmp
, addr
, mem_idx
, mop
| s
->be_data
);
6415 disas_set_da_iss(s
, mop
, issinfo
);
6416 tcg_temp_free_i32(tmp
);
6418 op_addr_rr_post(s
, a
, addr
, 0);
6422 static bool trans_LDRD_rr(DisasContext
*s
, arg_ldst_rr
*a
)
6424 int mem_idx
= get_mem_index(s
);
6427 if (!ENABLE_ARCH_5TE
) {
6431 unallocated_encoding(s
);
6434 addr
= op_addr_rr_pre(s
, a
);
6436 tmp
= tcg_temp_new_i32();
6437 gen_aa32_ld_i32(s
, tmp
, addr
, mem_idx
, MO_UL
| s
->be_data
);
6438 store_reg(s
, a
->rt
, tmp
);
6440 tcg_gen_addi_i32(addr
, addr
, 4);
6442 tmp
= tcg_temp_new_i32();
6443 gen_aa32_ld_i32(s
, tmp
, addr
, mem_idx
, MO_UL
| s
->be_data
);
6444 store_reg(s
, a
->rt
+ 1, tmp
);
6446 /* LDRD w/ base writeback is undefined if the registers overlap. */
6447 op_addr_rr_post(s
, a
, addr
, -4);
6451 static bool trans_STRD_rr(DisasContext
*s
, arg_ldst_rr
*a
)
6453 int mem_idx
= get_mem_index(s
);
6456 if (!ENABLE_ARCH_5TE
) {
6460 unallocated_encoding(s
);
6463 addr
= op_addr_rr_pre(s
, a
);
6465 tmp
= load_reg(s
, a
->rt
);
6466 gen_aa32_st_i32(s
, tmp
, addr
, mem_idx
, MO_UL
| s
->be_data
);
6467 tcg_temp_free_i32(tmp
);
6469 tcg_gen_addi_i32(addr
, addr
, 4);
6471 tmp
= load_reg(s
, a
->rt
+ 1);
6472 gen_aa32_st_i32(s
, tmp
, addr
, mem_idx
, MO_UL
| s
->be_data
);
6473 tcg_temp_free_i32(tmp
);
6475 op_addr_rr_post(s
, a
, addr
, -4);
6480 * Load/store immediate index
6483 static TCGv_i32
op_addr_ri_pre(DisasContext
*s
, arg_ldst_ri
*a
)
6491 if (s
->v8m_stackcheck
&& a
->rn
== 13 && a
->w
) {
6493 * Stackcheck. Here we know 'addr' is the current SP;
6494 * U is set if we're moving SP up, else down. It is
6495 * UNKNOWN whether the limit check triggers when SP starts
6496 * below the limit and ends up above it; we chose to do so.
6499 TCGv_i32 newsp
= tcg_temp_new_i32();
6500 tcg_gen_addi_i32(newsp
, cpu_R
[13], ofs
);
6501 gen_helper_v8m_stackcheck(cpu_env
, newsp
);
6502 tcg_temp_free_i32(newsp
);
6504 gen_helper_v8m_stackcheck(cpu_env
, cpu_R
[13]);
6508 return add_reg_for_lit(s
, a
->rn
, a
->p
? ofs
: 0);
6511 static void op_addr_ri_post(DisasContext
*s
, arg_ldst_ri
*a
,
6512 TCGv_i32 addr
, int address_offset
)
6516 address_offset
+= a
->imm
;
6518 address_offset
-= a
->imm
;
6521 tcg_temp_free_i32(addr
);
6524 tcg_gen_addi_i32(addr
, addr
, address_offset
);
6525 store_reg(s
, a
->rn
, addr
);
6528 static bool op_load_ri(DisasContext
*s
, arg_ldst_ri
*a
,
6529 MemOp mop
, int mem_idx
)
6531 ISSInfo issinfo
= make_issinfo(s
, a
->rt
, a
->p
, a
->w
);
6534 addr
= op_addr_ri_pre(s
, a
);
6536 tmp
= tcg_temp_new_i32();
6537 gen_aa32_ld_i32(s
, tmp
, addr
, mem_idx
, mop
| s
->be_data
);
6538 disas_set_da_iss(s
, mop
, issinfo
);
6541 * Perform base writeback before the loaded value to
6542 * ensure correct behavior with overlapping index registers.
6544 op_addr_ri_post(s
, a
, addr
, 0);
6545 store_reg_from_load(s
, a
->rt
, tmp
);
6549 static bool op_store_ri(DisasContext
*s
, arg_ldst_ri
*a
,
6550 MemOp mop
, int mem_idx
)
6552 ISSInfo issinfo
= make_issinfo(s
, a
->rt
, a
->p
, a
->w
) | ISSIsWrite
;
6555 addr
= op_addr_ri_pre(s
, a
);
6557 tmp
= load_reg(s
, a
->rt
);
6558 gen_aa32_st_i32(s
, tmp
, addr
, mem_idx
, mop
| s
->be_data
);
6559 disas_set_da_iss(s
, mop
, issinfo
);
6560 tcg_temp_free_i32(tmp
);
6562 op_addr_ri_post(s
, a
, addr
, 0);
6566 static bool op_ldrd_ri(DisasContext
*s
, arg_ldst_ri
*a
, int rt2
)
6568 int mem_idx
= get_mem_index(s
);
6571 addr
= op_addr_ri_pre(s
, a
);
6573 tmp
= tcg_temp_new_i32();
6574 gen_aa32_ld_i32(s
, tmp
, addr
, mem_idx
, MO_UL
| s
->be_data
);
6575 store_reg(s
, a
->rt
, tmp
);
6577 tcg_gen_addi_i32(addr
, addr
, 4);
6579 tmp
= tcg_temp_new_i32();
6580 gen_aa32_ld_i32(s
, tmp
, addr
, mem_idx
, MO_UL
| s
->be_data
);
6581 store_reg(s
, rt2
, tmp
);
6583 /* LDRD w/ base writeback is undefined if the registers overlap. */
6584 op_addr_ri_post(s
, a
, addr
, -4);
6588 static bool trans_LDRD_ri_a32(DisasContext
*s
, arg_ldst_ri
*a
)
6590 if (!ENABLE_ARCH_5TE
|| (a
->rt
& 1)) {
6593 return op_ldrd_ri(s
, a
, a
->rt
+ 1);
6596 static bool trans_LDRD_ri_t32(DisasContext
*s
, arg_ldst_ri2
*a
)
6599 .u
= a
->u
, .w
= a
->w
, .p
= a
->p
,
6600 .rn
= a
->rn
, .rt
= a
->rt
, .imm
= a
->imm
6602 return op_ldrd_ri(s
, &b
, a
->rt2
);
6605 static bool op_strd_ri(DisasContext
*s
, arg_ldst_ri
*a
, int rt2
)
6607 int mem_idx
= get_mem_index(s
);
6610 addr
= op_addr_ri_pre(s
, a
);
6612 tmp
= load_reg(s
, a
->rt
);
6613 gen_aa32_st_i32(s
, tmp
, addr
, mem_idx
, MO_UL
| s
->be_data
);
6614 tcg_temp_free_i32(tmp
);
6616 tcg_gen_addi_i32(addr
, addr
, 4);
6618 tmp
= load_reg(s
, rt2
);
6619 gen_aa32_st_i32(s
, tmp
, addr
, mem_idx
, MO_UL
| s
->be_data
);
6620 tcg_temp_free_i32(tmp
);
6622 op_addr_ri_post(s
, a
, addr
, -4);
6626 static bool trans_STRD_ri_a32(DisasContext
*s
, arg_ldst_ri
*a
)
6628 if (!ENABLE_ARCH_5TE
|| (a
->rt
& 1)) {
6631 return op_strd_ri(s
, a
, a
->rt
+ 1);
6634 static bool trans_STRD_ri_t32(DisasContext
*s
, arg_ldst_ri2
*a
)
6637 .u
= a
->u
, .w
= a
->w
, .p
= a
->p
,
6638 .rn
= a
->rn
, .rt
= a
->rt
, .imm
= a
->imm
6640 return op_strd_ri(s
, &b
, a
->rt2
);
6643 #define DO_LDST(NAME, WHICH, MEMOP) \
6644 static bool trans_##NAME##_ri(DisasContext *s, arg_ldst_ri *a) \
6646 return op_##WHICH##_ri(s, a, MEMOP, get_mem_index(s)); \
6648 static bool trans_##NAME##T_ri(DisasContext *s, arg_ldst_ri *a) \
6650 return op_##WHICH##_ri(s, a, MEMOP, get_a32_user_mem_index(s)); \
6652 static bool trans_##NAME##_rr(DisasContext *s, arg_ldst_rr *a) \
6654 return op_##WHICH##_rr(s, a, MEMOP, get_mem_index(s)); \
6656 static bool trans_##NAME##T_rr(DisasContext *s, arg_ldst_rr *a) \
6658 return op_##WHICH##_rr(s, a, MEMOP, get_a32_user_mem_index(s)); \
6661 DO_LDST(LDR
, load
, MO_UL
)
6662 DO_LDST(LDRB
, load
, MO_UB
)
6663 DO_LDST(LDRH
, load
, MO_UW
)
6664 DO_LDST(LDRSB
, load
, MO_SB
)
6665 DO_LDST(LDRSH
, load
, MO_SW
)
6667 DO_LDST(STR
, store
, MO_UL
)
6668 DO_LDST(STRB
, store
, MO_UB
)
6669 DO_LDST(STRH
, store
, MO_UW
)
6674 * Synchronization primitives
6677 static bool op_swp(DisasContext
*s
, arg_SWP
*a
, MemOp opc
)
6683 addr
= load_reg(s
, a
->rn
);
6684 taddr
= gen_aa32_addr(s
, addr
, opc
);
6685 tcg_temp_free_i32(addr
);
6687 tmp
= load_reg(s
, a
->rt2
);
6688 tcg_gen_atomic_xchg_i32(tmp
, taddr
, tmp
, get_mem_index(s
), opc
);
6689 tcg_temp_free(taddr
);
6691 store_reg(s
, a
->rt
, tmp
);
6695 static bool trans_SWP(DisasContext
*s
, arg_SWP
*a
)
6697 return op_swp(s
, a
, MO_UL
| MO_ALIGN
);
6700 static bool trans_SWPB(DisasContext
*s
, arg_SWP
*a
)
6702 return op_swp(s
, a
, MO_UB
);
6706 * Load/Store Exclusive and Load-Acquire/Store-Release
6709 static bool op_strex(DisasContext
*s
, arg_STREX
*a
, MemOp mop
, bool rel
)
6712 /* Some cases stopped being UNPREDICTABLE in v8A (but not v8M) */
6713 bool v8a
= ENABLE_ARCH_8
&& !arm_dc_feature(s
, ARM_FEATURE_M
);
6715 /* We UNDEF for these UNPREDICTABLE cases. */
6716 if (a
->rd
== 15 || a
->rn
== 15 || a
->rt
== 15
6717 || a
->rd
== a
->rn
|| a
->rd
== a
->rt
6718 || (!v8a
&& s
->thumb
&& (a
->rd
== 13 || a
->rt
== 13))
6722 || (!v8a
&& s
->thumb
&& a
->rt2
== 13)))) {
6723 unallocated_encoding(s
);
6728 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_STRL
);
6731 addr
= tcg_temp_local_new_i32();
6732 load_reg_var(s
, addr
, a
->rn
);
6733 tcg_gen_addi_i32(addr
, addr
, a
->imm
);
6735 gen_store_exclusive(s
, a
->rd
, a
->rt
, a
->rt2
, addr
, mop
);
6736 tcg_temp_free_i32(addr
);
6740 static bool trans_STREX(DisasContext
*s
, arg_STREX
*a
)
6742 if (!ENABLE_ARCH_6
) {
6745 return op_strex(s
, a
, MO_32
, false);
6748 static bool trans_STREXD_a32(DisasContext
*s
, arg_STREX
*a
)
6750 if (!ENABLE_ARCH_6K
) {
6753 /* We UNDEF for these UNPREDICTABLE cases. */
6755 unallocated_encoding(s
);
6759 return op_strex(s
, a
, MO_64
, false);
6762 static bool trans_STREXD_t32(DisasContext
*s
, arg_STREX
*a
)
6764 return op_strex(s
, a
, MO_64
, false);
6767 static bool trans_STREXB(DisasContext
*s
, arg_STREX
*a
)
6769 if (s
->thumb
? !ENABLE_ARCH_7
: !ENABLE_ARCH_6K
) {
6772 return op_strex(s
, a
, MO_8
, false);
6775 static bool trans_STREXH(DisasContext
*s
, arg_STREX
*a
)
6777 if (s
->thumb
? !ENABLE_ARCH_7
: !ENABLE_ARCH_6K
) {
6780 return op_strex(s
, a
, MO_16
, false);
6783 static bool trans_STLEX(DisasContext
*s
, arg_STREX
*a
)
6785 if (!ENABLE_ARCH_8
) {
6788 return op_strex(s
, a
, MO_32
, true);
6791 static bool trans_STLEXD_a32(DisasContext
*s
, arg_STREX
*a
)
6793 if (!ENABLE_ARCH_8
) {
6796 /* We UNDEF for these UNPREDICTABLE cases. */
6798 unallocated_encoding(s
);
6802 return op_strex(s
, a
, MO_64
, true);
6805 static bool trans_STLEXD_t32(DisasContext
*s
, arg_STREX
*a
)
6807 if (!ENABLE_ARCH_8
) {
6810 return op_strex(s
, a
, MO_64
, true);
6813 static bool trans_STLEXB(DisasContext
*s
, arg_STREX
*a
)
6815 if (!ENABLE_ARCH_8
) {
6818 return op_strex(s
, a
, MO_8
, true);
6821 static bool trans_STLEXH(DisasContext
*s
, arg_STREX
*a
)
6823 if (!ENABLE_ARCH_8
) {
6826 return op_strex(s
, a
, MO_16
, true);
6829 static bool op_stl(DisasContext
*s
, arg_STL
*a
, MemOp mop
)
6833 if (!ENABLE_ARCH_8
) {
6836 /* We UNDEF for these UNPREDICTABLE cases. */
6837 if (a
->rn
== 15 || a
->rt
== 15) {
6838 unallocated_encoding(s
);
6842 addr
= load_reg(s
, a
->rn
);
6843 tmp
= load_reg(s
, a
->rt
);
6844 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_STRL
);
6845 gen_aa32_st_i32(s
, tmp
, addr
, get_mem_index(s
), mop
| s
->be_data
);
6846 disas_set_da_iss(s
, mop
, a
->rt
| ISSIsAcqRel
| ISSIsWrite
);
6848 tcg_temp_free_i32(tmp
);
6849 tcg_temp_free_i32(addr
);
6853 static bool trans_STL(DisasContext
*s
, arg_STL
*a
)
6855 return op_stl(s
, a
, MO_UL
);
6858 static bool trans_STLB(DisasContext
*s
, arg_STL
*a
)
6860 return op_stl(s
, a
, MO_UB
);
6863 static bool trans_STLH(DisasContext
*s
, arg_STL
*a
)
6865 return op_stl(s
, a
, MO_UW
);
6868 static bool op_ldrex(DisasContext
*s
, arg_LDREX
*a
, MemOp mop
, bool acq
)
6871 /* Some cases stopped being UNPREDICTABLE in v8A (but not v8M) */
6872 bool v8a
= ENABLE_ARCH_8
&& !arm_dc_feature(s
, ARM_FEATURE_M
);
6874 /* We UNDEF for these UNPREDICTABLE cases. */
6875 if (a
->rn
== 15 || a
->rt
== 15
6876 || (!v8a
&& s
->thumb
&& a
->rt
== 13)
6878 && (a
->rt2
== 15 || a
->rt
== a
->rt2
6879 || (!v8a
&& s
->thumb
&& a
->rt2
== 13)))) {
6880 unallocated_encoding(s
);
6884 addr
= tcg_temp_local_new_i32();
6885 load_reg_var(s
, addr
, a
->rn
);
6886 tcg_gen_addi_i32(addr
, addr
, a
->imm
);
6888 gen_load_exclusive(s
, a
->rt
, a
->rt2
, addr
, mop
);
6889 tcg_temp_free_i32(addr
);
6892 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_LDAQ
);
6897 static bool trans_LDREX(DisasContext
*s
, arg_LDREX
*a
)
6899 if (!ENABLE_ARCH_6
) {
6902 return op_ldrex(s
, a
, MO_32
, false);
6905 static bool trans_LDREXD_a32(DisasContext
*s
, arg_LDREX
*a
)
6907 if (!ENABLE_ARCH_6K
) {
6910 /* We UNDEF for these UNPREDICTABLE cases. */
6912 unallocated_encoding(s
);
6916 return op_ldrex(s
, a
, MO_64
, false);
6919 static bool trans_LDREXD_t32(DisasContext
*s
, arg_LDREX
*a
)
6921 return op_ldrex(s
, a
, MO_64
, false);
6924 static bool trans_LDREXB(DisasContext
*s
, arg_LDREX
*a
)
6926 if (s
->thumb
? !ENABLE_ARCH_7
: !ENABLE_ARCH_6K
) {
6929 return op_ldrex(s
, a
, MO_8
, false);
6932 static bool trans_LDREXH(DisasContext
*s
, arg_LDREX
*a
)
6934 if (s
->thumb
? !ENABLE_ARCH_7
: !ENABLE_ARCH_6K
) {
6937 return op_ldrex(s
, a
, MO_16
, false);
6940 static bool trans_LDAEX(DisasContext
*s
, arg_LDREX
*a
)
6942 if (!ENABLE_ARCH_8
) {
6945 return op_ldrex(s
, a
, MO_32
, true);
6948 static bool trans_LDAEXD_a32(DisasContext
*s
, arg_LDREX
*a
)
6950 if (!ENABLE_ARCH_8
) {
6953 /* We UNDEF for these UNPREDICTABLE cases. */
6955 unallocated_encoding(s
);
6959 return op_ldrex(s
, a
, MO_64
, true);
6962 static bool trans_LDAEXD_t32(DisasContext
*s
, arg_LDREX
*a
)
6964 if (!ENABLE_ARCH_8
) {
6967 return op_ldrex(s
, a
, MO_64
, true);
6970 static bool trans_LDAEXB(DisasContext
*s
, arg_LDREX
*a
)
6972 if (!ENABLE_ARCH_8
) {
6975 return op_ldrex(s
, a
, MO_8
, true);
6978 static bool trans_LDAEXH(DisasContext
*s
, arg_LDREX
*a
)
6980 if (!ENABLE_ARCH_8
) {
6983 return op_ldrex(s
, a
, MO_16
, true);
6986 static bool op_lda(DisasContext
*s
, arg_LDA
*a
, MemOp mop
)
6990 if (!ENABLE_ARCH_8
) {
6993 /* We UNDEF for these UNPREDICTABLE cases. */
6994 if (a
->rn
== 15 || a
->rt
== 15) {
6995 unallocated_encoding(s
);
6999 addr
= load_reg(s
, a
->rn
);
7000 tmp
= tcg_temp_new_i32();
7001 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
), mop
| s
->be_data
);
7002 disas_set_da_iss(s
, mop
, a
->rt
| ISSIsAcqRel
);
7003 tcg_temp_free_i32(addr
);
7005 store_reg(s
, a
->rt
, tmp
);
7006 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_STRL
);
7010 static bool trans_LDA(DisasContext
*s
, arg_LDA
*a
)
7012 return op_lda(s
, a
, MO_UL
);
7015 static bool trans_LDAB(DisasContext
*s
, arg_LDA
*a
)
7017 return op_lda(s
, a
, MO_UB
);
7020 static bool trans_LDAH(DisasContext
*s
, arg_LDA
*a
)
7022 return op_lda(s
, a
, MO_UW
);
7026 * Media instructions
7029 static bool trans_USADA8(DisasContext
*s
, arg_USADA8
*a
)
7033 if (!ENABLE_ARCH_6
) {
7037 t1
= load_reg(s
, a
->rn
);
7038 t2
= load_reg(s
, a
->rm
);
7039 gen_helper_usad8(t1
, t1
, t2
);
7040 tcg_temp_free_i32(t2
);
7042 t2
= load_reg(s
, a
->ra
);
7043 tcg_gen_add_i32(t1
, t1
, t2
);
7044 tcg_temp_free_i32(t2
);
7046 store_reg(s
, a
->rd
, t1
);
7050 static bool op_bfx(DisasContext
*s
, arg_UBFX
*a
, bool u
)
7053 int width
= a
->widthm1
+ 1;
7056 if (!ENABLE_ARCH_6T2
) {
7059 if (shift
+ width
> 32) {
7060 /* UNPREDICTABLE; we choose to UNDEF */
7061 unallocated_encoding(s
);
7065 tmp
= load_reg(s
, a
->rn
);
7067 tcg_gen_extract_i32(tmp
, tmp
, shift
, width
);
7069 tcg_gen_sextract_i32(tmp
, tmp
, shift
, width
);
7071 store_reg(s
, a
->rd
, tmp
);
7075 static bool trans_SBFX(DisasContext
*s
, arg_SBFX
*a
)
7077 return op_bfx(s
, a
, false);
7080 static bool trans_UBFX(DisasContext
*s
, arg_UBFX
*a
)
7082 return op_bfx(s
, a
, true);
7085 static bool trans_BFCI(DisasContext
*s
, arg_BFCI
*a
)
7088 int msb
= a
->msb
, lsb
= a
->lsb
;
7091 if (!ENABLE_ARCH_6T2
) {
7095 /* UNPREDICTABLE; we choose to UNDEF */
7096 unallocated_encoding(s
);
7100 width
= msb
+ 1 - lsb
;
7103 tmp
= tcg_const_i32(0);
7106 tmp
= load_reg(s
, a
->rn
);
7109 TCGv_i32 tmp2
= load_reg(s
, a
->rd
);
7110 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, lsb
, width
);
7111 tcg_temp_free_i32(tmp2
);
7113 store_reg(s
, a
->rd
, tmp
);
7117 static bool trans_UDF(DisasContext
*s
, arg_UDF
*a
)
7119 unallocated_encoding(s
);
7124 * Parallel addition and subtraction
7127 static bool op_par_addsub(DisasContext
*s
, arg_rrr
*a
,
7128 void (*gen
)(TCGv_i32
, TCGv_i32
, TCGv_i32
))
7133 ? !arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)
7138 t0
= load_reg(s
, a
->rn
);
7139 t1
= load_reg(s
, a
->rm
);
7143 tcg_temp_free_i32(t1
);
7144 store_reg(s
, a
->rd
, t0
);
7148 static bool op_par_addsub_ge(DisasContext
*s
, arg_rrr
*a
,
7149 void (*gen
)(TCGv_i32
, TCGv_i32
,
7150 TCGv_i32
, TCGv_ptr
))
7156 ? !arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)
7161 t0
= load_reg(s
, a
->rn
);
7162 t1
= load_reg(s
, a
->rm
);
7164 ge
= tcg_temp_new_ptr();
7165 tcg_gen_addi_ptr(ge
, cpu_env
, offsetof(CPUARMState
, GE
));
7166 gen(t0
, t0
, t1
, ge
);
7168 tcg_temp_free_ptr(ge
);
7169 tcg_temp_free_i32(t1
);
7170 store_reg(s
, a
->rd
, t0
);
7174 #define DO_PAR_ADDSUB(NAME, helper) \
7175 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
7177 return op_par_addsub(s, a, helper); \
7180 #define DO_PAR_ADDSUB_GE(NAME, helper) \
7181 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
7183 return op_par_addsub_ge(s, a, helper); \
7186 DO_PAR_ADDSUB_GE(SADD16
, gen_helper_sadd16
)
7187 DO_PAR_ADDSUB_GE(SASX
, gen_helper_saddsubx
)
7188 DO_PAR_ADDSUB_GE(SSAX
, gen_helper_ssubaddx
)
7189 DO_PAR_ADDSUB_GE(SSUB16
, gen_helper_ssub16
)
7190 DO_PAR_ADDSUB_GE(SADD8
, gen_helper_sadd8
)
7191 DO_PAR_ADDSUB_GE(SSUB8
, gen_helper_ssub8
)
7193 DO_PAR_ADDSUB_GE(UADD16
, gen_helper_uadd16
)
7194 DO_PAR_ADDSUB_GE(UASX
, gen_helper_uaddsubx
)
7195 DO_PAR_ADDSUB_GE(USAX
, gen_helper_usubaddx
)
7196 DO_PAR_ADDSUB_GE(USUB16
, gen_helper_usub16
)
7197 DO_PAR_ADDSUB_GE(UADD8
, gen_helper_uadd8
)
7198 DO_PAR_ADDSUB_GE(USUB8
, gen_helper_usub8
)
7200 DO_PAR_ADDSUB(QADD16
, gen_helper_qadd16
)
7201 DO_PAR_ADDSUB(QASX
, gen_helper_qaddsubx
)
7202 DO_PAR_ADDSUB(QSAX
, gen_helper_qsubaddx
)
7203 DO_PAR_ADDSUB(QSUB16
, gen_helper_qsub16
)
7204 DO_PAR_ADDSUB(QADD8
, gen_helper_qadd8
)
7205 DO_PAR_ADDSUB(QSUB8
, gen_helper_qsub8
)
7207 DO_PAR_ADDSUB(UQADD16
, gen_helper_uqadd16
)
7208 DO_PAR_ADDSUB(UQASX
, gen_helper_uqaddsubx
)
7209 DO_PAR_ADDSUB(UQSAX
, gen_helper_uqsubaddx
)
7210 DO_PAR_ADDSUB(UQSUB16
, gen_helper_uqsub16
)
7211 DO_PAR_ADDSUB(UQADD8
, gen_helper_uqadd8
)
7212 DO_PAR_ADDSUB(UQSUB8
, gen_helper_uqsub8
)
7214 DO_PAR_ADDSUB(SHADD16
, gen_helper_shadd16
)
7215 DO_PAR_ADDSUB(SHASX
, gen_helper_shaddsubx
)
7216 DO_PAR_ADDSUB(SHSAX
, gen_helper_shsubaddx
)
7217 DO_PAR_ADDSUB(SHSUB16
, gen_helper_shsub16
)
7218 DO_PAR_ADDSUB(SHADD8
, gen_helper_shadd8
)
7219 DO_PAR_ADDSUB(SHSUB8
, gen_helper_shsub8
)
7221 DO_PAR_ADDSUB(UHADD16
, gen_helper_uhadd16
)
7222 DO_PAR_ADDSUB(UHASX
, gen_helper_uhaddsubx
)
7223 DO_PAR_ADDSUB(UHSAX
, gen_helper_uhsubaddx
)
7224 DO_PAR_ADDSUB(UHSUB16
, gen_helper_uhsub16
)
7225 DO_PAR_ADDSUB(UHADD8
, gen_helper_uhadd8
)
7226 DO_PAR_ADDSUB(UHSUB8
, gen_helper_uhsub8
)
7228 #undef DO_PAR_ADDSUB
7229 #undef DO_PAR_ADDSUB_GE
7232 * Packing, unpacking, saturation, and reversal
7235 static bool trans_PKH(DisasContext
*s
, arg_PKH
*a
)
7241 ? !arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)
7246 tn
= load_reg(s
, a
->rn
);
7247 tm
= load_reg(s
, a
->rm
);
7253 tcg_gen_sari_i32(tm
, tm
, shift
);
7254 tcg_gen_deposit_i32(tn
, tn
, tm
, 0, 16);
7257 tcg_gen_shli_i32(tm
, tm
, shift
);
7258 tcg_gen_deposit_i32(tn
, tm
, tn
, 0, 16);
7260 tcg_temp_free_i32(tm
);
7261 store_reg(s
, a
->rd
, tn
);
7265 static bool op_sat(DisasContext
*s
, arg_sat
*a
,
7266 void (*gen
)(TCGv_i32
, TCGv_env
, TCGv_i32
, TCGv_i32
))
7268 TCGv_i32 tmp
, satimm
;
7271 if (!ENABLE_ARCH_6
) {
7275 tmp
= load_reg(s
, a
->rn
);
7277 tcg_gen_sari_i32(tmp
, tmp
, shift
? shift
: 31);
7279 tcg_gen_shli_i32(tmp
, tmp
, shift
);
7282 satimm
= tcg_const_i32(a
->satimm
);
7283 gen(tmp
, cpu_env
, tmp
, satimm
);
7284 tcg_temp_free_i32(satimm
);
7286 store_reg(s
, a
->rd
, tmp
);
7290 static bool trans_SSAT(DisasContext
*s
, arg_sat
*a
)
7292 return op_sat(s
, a
, gen_helper_ssat
);
7295 static bool trans_USAT(DisasContext
*s
, arg_sat
*a
)
7297 return op_sat(s
, a
, gen_helper_usat
);
7300 static bool trans_SSAT16(DisasContext
*s
, arg_sat
*a
)
7302 if (s
->thumb
&& !arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
7305 return op_sat(s
, a
, gen_helper_ssat16
);
7308 static bool trans_USAT16(DisasContext
*s
, arg_sat
*a
)
7310 if (s
->thumb
&& !arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
7313 return op_sat(s
, a
, gen_helper_usat16
);
7316 static bool op_xta(DisasContext
*s
, arg_rrr_rot
*a
,
7317 void (*gen_extract
)(TCGv_i32
, TCGv_i32
),
7318 void (*gen_add
)(TCGv_i32
, TCGv_i32
, TCGv_i32
))
7322 if (!ENABLE_ARCH_6
) {
7326 tmp
= load_reg(s
, a
->rm
);
7328 * TODO: In many cases we could do a shift instead of a rotate.
7329 * Combined with a simple extend, that becomes an extract.
7331 tcg_gen_rotri_i32(tmp
, tmp
, a
->rot
* 8);
7332 gen_extract(tmp
, tmp
);
7335 TCGv_i32 tmp2
= load_reg(s
, a
->rn
);
7336 gen_add(tmp
, tmp
, tmp2
);
7337 tcg_temp_free_i32(tmp2
);
7339 store_reg(s
, a
->rd
, tmp
);
7343 static bool trans_SXTAB(DisasContext
*s
, arg_rrr_rot
*a
)
7345 return op_xta(s
, a
, tcg_gen_ext8s_i32
, tcg_gen_add_i32
);
7348 static bool trans_SXTAH(DisasContext
*s
, arg_rrr_rot
*a
)
7350 return op_xta(s
, a
, tcg_gen_ext16s_i32
, tcg_gen_add_i32
);
7353 static bool trans_SXTAB16(DisasContext
*s
, arg_rrr_rot
*a
)
7355 if (s
->thumb
&& !arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
7358 return op_xta(s
, a
, gen_helper_sxtb16
, gen_add16
);
7361 static bool trans_UXTAB(DisasContext
*s
, arg_rrr_rot
*a
)
7363 return op_xta(s
, a
, tcg_gen_ext8u_i32
, tcg_gen_add_i32
);
7366 static bool trans_UXTAH(DisasContext
*s
, arg_rrr_rot
*a
)
7368 return op_xta(s
, a
, tcg_gen_ext16u_i32
, tcg_gen_add_i32
);
7371 static bool trans_UXTAB16(DisasContext
*s
, arg_rrr_rot
*a
)
7373 if (s
->thumb
&& !arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
7376 return op_xta(s
, a
, gen_helper_uxtb16
, gen_add16
);
7379 static bool trans_SEL(DisasContext
*s
, arg_rrr
*a
)
7381 TCGv_i32 t1
, t2
, t3
;
7384 ? !arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)
7389 t1
= load_reg(s
, a
->rn
);
7390 t2
= load_reg(s
, a
->rm
);
7391 t3
= tcg_temp_new_i32();
7392 tcg_gen_ld_i32(t3
, cpu_env
, offsetof(CPUARMState
, GE
));
7393 gen_helper_sel_flags(t1
, t3
, t1
, t2
);
7394 tcg_temp_free_i32(t3
);
7395 tcg_temp_free_i32(t2
);
7396 store_reg(s
, a
->rd
, t1
);
7400 static bool op_rr(DisasContext
*s
, arg_rr
*a
,
7401 void (*gen
)(TCGv_i32
, TCGv_i32
))
7405 tmp
= load_reg(s
, a
->rm
);
7407 store_reg(s
, a
->rd
, tmp
);
7411 static bool trans_REV(DisasContext
*s
, arg_rr
*a
)
7413 if (!ENABLE_ARCH_6
) {
7416 return op_rr(s
, a
, tcg_gen_bswap32_i32
);
7419 static bool trans_REV16(DisasContext
*s
, arg_rr
*a
)
7421 if (!ENABLE_ARCH_6
) {
7424 return op_rr(s
, a
, gen_rev16
);
7427 static bool trans_REVSH(DisasContext
*s
, arg_rr
*a
)
7429 if (!ENABLE_ARCH_6
) {
7432 return op_rr(s
, a
, gen_revsh
);
7435 static bool trans_RBIT(DisasContext
*s
, arg_rr
*a
)
7437 if (!ENABLE_ARCH_6T2
) {
7440 return op_rr(s
, a
, gen_helper_rbit
);
7444 * Signed multiply, signed and unsigned divide
7447 static bool op_smlad(DisasContext
*s
, arg_rrrr
*a
, bool m_swap
, bool sub
)
7451 if (!ENABLE_ARCH_6
) {
7455 t1
= load_reg(s
, a
->rn
);
7456 t2
= load_reg(s
, a
->rm
);
7458 gen_swap_half(t2
, t2
);
7460 gen_smul_dual(t1
, t2
);
7463 /* This subtraction cannot overflow. */
7464 tcg_gen_sub_i32(t1
, t1
, t2
);
7467 * This addition cannot overflow 32 bits; however it may
7468 * overflow considered as a signed operation, in which case
7469 * we must set the Q flag.
7471 gen_helper_add_setq(t1
, cpu_env
, t1
, t2
);
7473 tcg_temp_free_i32(t2
);
7476 t2
= load_reg(s
, a
->ra
);
7477 gen_helper_add_setq(t1
, cpu_env
, t1
, t2
);
7478 tcg_temp_free_i32(t2
);
7480 store_reg(s
, a
->rd
, t1
);
7484 static bool trans_SMLAD(DisasContext
*s
, arg_rrrr
*a
)
7486 return op_smlad(s
, a
, false, false);
7489 static bool trans_SMLADX(DisasContext
*s
, arg_rrrr
*a
)
7491 return op_smlad(s
, a
, true, false);
7494 static bool trans_SMLSD(DisasContext
*s
, arg_rrrr
*a
)
7496 return op_smlad(s
, a
, false, true);
7499 static bool trans_SMLSDX(DisasContext
*s
, arg_rrrr
*a
)
7501 return op_smlad(s
, a
, true, true);
7504 static bool op_smlald(DisasContext
*s
, arg_rrrr
*a
, bool m_swap
, bool sub
)
7509 if (!ENABLE_ARCH_6
) {
7513 t1
= load_reg(s
, a
->rn
);
7514 t2
= load_reg(s
, a
->rm
);
7516 gen_swap_half(t2
, t2
);
7518 gen_smul_dual(t1
, t2
);
7520 l1
= tcg_temp_new_i64();
7521 l2
= tcg_temp_new_i64();
7522 tcg_gen_ext_i32_i64(l1
, t1
);
7523 tcg_gen_ext_i32_i64(l2
, t2
);
7524 tcg_temp_free_i32(t1
);
7525 tcg_temp_free_i32(t2
);
7528 tcg_gen_sub_i64(l1
, l1
, l2
);
7530 tcg_gen_add_i64(l1
, l1
, l2
);
7532 tcg_temp_free_i64(l2
);
7534 gen_addq(s
, l1
, a
->ra
, a
->rd
);
7535 gen_storeq_reg(s
, a
->ra
, a
->rd
, l1
);
7536 tcg_temp_free_i64(l1
);
7540 static bool trans_SMLALD(DisasContext
*s
, arg_rrrr
*a
)
7542 return op_smlald(s
, a
, false, false);
7545 static bool trans_SMLALDX(DisasContext
*s
, arg_rrrr
*a
)
7547 return op_smlald(s
, a
, true, false);
7550 static bool trans_SMLSLD(DisasContext
*s
, arg_rrrr
*a
)
7552 return op_smlald(s
, a
, false, true);
7555 static bool trans_SMLSLDX(DisasContext
*s
, arg_rrrr
*a
)
7557 return op_smlald(s
, a
, true, true);
7560 static bool op_smmla(DisasContext
*s
, arg_rrrr
*a
, bool round
, bool sub
)
7565 ? !arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)
7570 t1
= load_reg(s
, a
->rn
);
7571 t2
= load_reg(s
, a
->rm
);
7572 tcg_gen_muls2_i32(t2
, t1
, t1
, t2
);
7575 TCGv_i32 t3
= load_reg(s
, a
->ra
);
7578 * For SMMLS, we need a 64-bit subtract. Borrow caused by
7579 * a non-zero multiplicand lowpart, and the correct result
7580 * lowpart for rounding.
7582 TCGv_i32 zero
= tcg_const_i32(0);
7583 tcg_gen_sub2_i32(t2
, t1
, zero
, t3
, t2
, t1
);
7584 tcg_temp_free_i32(zero
);
7586 tcg_gen_add_i32(t1
, t1
, t3
);
7588 tcg_temp_free_i32(t3
);
7592 * Adding 0x80000000 to the 64-bit quantity means that we have
7593 * carry in to the high word when the low word has the msb set.
7595 tcg_gen_shri_i32(t2
, t2
, 31);
7596 tcg_gen_add_i32(t1
, t1
, t2
);
7598 tcg_temp_free_i32(t2
);
7599 store_reg(s
, a
->rd
, t1
);
7603 static bool trans_SMMLA(DisasContext
*s
, arg_rrrr
*a
)
7605 return op_smmla(s
, a
, false, false);
7608 static bool trans_SMMLAR(DisasContext
*s
, arg_rrrr
*a
)
7610 return op_smmla(s
, a
, true, false);
7613 static bool trans_SMMLS(DisasContext
*s
, arg_rrrr
*a
)
7615 return op_smmla(s
, a
, false, true);
7618 static bool trans_SMMLSR(DisasContext
*s
, arg_rrrr
*a
)
7620 return op_smmla(s
, a
, true, true);
7623 static bool op_div(DisasContext
*s
, arg_rrr
*a
, bool u
)
7628 ? !dc_isar_feature(aa32_thumb_div
, s
)
7629 : !dc_isar_feature(aa32_arm_div
, s
)) {
7633 t1
= load_reg(s
, a
->rn
);
7634 t2
= load_reg(s
, a
->rm
);
7636 gen_helper_udiv(t1
, t1
, t2
);
7638 gen_helper_sdiv(t1
, t1
, t2
);
7640 tcg_temp_free_i32(t2
);
7641 store_reg(s
, a
->rd
, t1
);
7645 static bool trans_SDIV(DisasContext
*s
, arg_rrr
*a
)
7647 return op_div(s
, a
, false);
7650 static bool trans_UDIV(DisasContext
*s
, arg_rrr
*a
)
7652 return op_div(s
, a
, true);
7656 * Block data transfer
7659 static TCGv_i32
op_addr_block_pre(DisasContext
*s
, arg_ldst_block
*a
, int n
)
7661 TCGv_i32 addr
= load_reg(s
, a
->rn
);
7666 tcg_gen_addi_i32(addr
, addr
, 4);
7669 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
7671 } else if (!a
->i
&& n
!= 1) {
7672 /* post decrement */
7673 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
7676 if (s
->v8m_stackcheck
&& a
->rn
== 13 && a
->w
) {
7678 * If the writeback is incrementing SP rather than
7679 * decrementing it, and the initial SP is below the
7680 * stack limit but the final written-back SP would
7681 * be above, then then we must not perform any memory
7682 * accesses, but it is IMPDEF whether we generate
7683 * an exception. We choose to do so in this case.
7684 * At this point 'addr' is the lowest address, so
7685 * either the original SP (if incrementing) or our
7686 * final SP (if decrementing), so that's what we check.
7688 gen_helper_v8m_stackcheck(cpu_env
, addr
);
7694 static void op_addr_block_post(DisasContext
*s
, arg_ldst_block
*a
,
7695 TCGv_i32 addr
, int n
)
7701 /* post increment */
7702 tcg_gen_addi_i32(addr
, addr
, 4);
7704 /* post decrement */
7705 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
7707 } else if (!a
->i
&& n
!= 1) {
7709 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
7711 store_reg(s
, a
->rn
, addr
);
7713 tcg_temp_free_i32(addr
);
7717 static bool op_stm(DisasContext
*s
, arg_ldst_block
*a
, int min_n
)
7719 int i
, j
, n
, list
, mem_idx
;
7721 TCGv_i32 addr
, tmp
, tmp2
;
7726 /* Only usable in supervisor mode. */
7727 unallocated_encoding(s
);
7734 if (n
< min_n
|| a
->rn
== 15) {
7735 unallocated_encoding(s
);
7739 addr
= op_addr_block_pre(s
, a
, n
);
7740 mem_idx
= get_mem_index(s
);
7742 for (i
= j
= 0; i
< 16; i
++) {
7743 if (!(list
& (1 << i
))) {
7747 if (user
&& i
!= 15) {
7748 tmp
= tcg_temp_new_i32();
7749 tmp2
= tcg_const_i32(i
);
7750 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
7751 tcg_temp_free_i32(tmp2
);
7753 tmp
= load_reg(s
, i
);
7755 gen_aa32_st32(s
, tmp
, addr
, mem_idx
);
7756 tcg_temp_free_i32(tmp
);
7758 /* No need to add after the last transfer. */
7760 tcg_gen_addi_i32(addr
, addr
, 4);
7764 op_addr_block_post(s
, a
, addr
, n
);
7768 static bool trans_STM(DisasContext
*s
, arg_ldst_block
*a
)
7770 /* BitCount(list) < 1 is UNPREDICTABLE */
7771 return op_stm(s
, a
, 1);
7774 static bool trans_STM_t32(DisasContext
*s
, arg_ldst_block
*a
)
7776 /* Writeback register in register list is UNPREDICTABLE for T32. */
7777 if (a
->w
&& (a
->list
& (1 << a
->rn
))) {
7778 unallocated_encoding(s
);
7781 /* BitCount(list) < 2 is UNPREDICTABLE */
7782 return op_stm(s
, a
, 2);
7785 static bool do_ldm(DisasContext
*s
, arg_ldst_block
*a
, int min_n
)
7787 int i
, j
, n
, list
, mem_idx
;
7790 bool exc_return
= false;
7791 TCGv_i32 addr
, tmp
, tmp2
, loaded_var
;
7794 /* LDM (user), LDM (exception return) */
7796 /* Only usable in supervisor mode. */
7797 unallocated_encoding(s
);
7800 if (extract32(a
->list
, 15, 1)) {
7804 /* LDM (user) does not allow writeback. */
7806 unallocated_encoding(s
);
7814 if (n
< min_n
|| a
->rn
== 15) {
7815 unallocated_encoding(s
);
7819 addr
= op_addr_block_pre(s
, a
, n
);
7820 mem_idx
= get_mem_index(s
);
7821 loaded_base
= false;
7824 for (i
= j
= 0; i
< 16; i
++) {
7825 if (!(list
& (1 << i
))) {
7829 tmp
= tcg_temp_new_i32();
7830 gen_aa32_ld32u(s
, tmp
, addr
, mem_idx
);
7832 tmp2
= tcg_const_i32(i
);
7833 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
7834 tcg_temp_free_i32(tmp2
);
7835 tcg_temp_free_i32(tmp
);
7836 } else if (i
== a
->rn
) {
7839 } else if (i
== 15 && exc_return
) {
7840 store_pc_exc_ret(s
, tmp
);
7842 store_reg_from_load(s
, i
, tmp
);
7845 /* No need to add after the last transfer. */
7847 tcg_gen_addi_i32(addr
, addr
, 4);
7851 op_addr_block_post(s
, a
, addr
, n
);
7854 /* Note that we reject base == pc above. */
7855 store_reg(s
, a
->rn
, loaded_var
);
7859 /* Restore CPSR from SPSR. */
7860 tmp
= load_cpu_field(spsr
);
7861 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
7864 gen_helper_cpsr_write_eret(cpu_env
, tmp
);
7865 tcg_temp_free_i32(tmp
);
7866 /* Must exit loop to check un-masked IRQs */
7867 s
->base
.is_jmp
= DISAS_EXIT
;
7872 static bool trans_LDM_a32(DisasContext
*s
, arg_ldst_block
*a
)
7875 * Writeback register in register list is UNPREDICTABLE
7876 * for ArchVersion() >= 7. Prior to v7, A32 would write
7877 * an UNKNOWN value to the base register.
7879 if (ENABLE_ARCH_7
&& a
->w
&& (a
->list
& (1 << a
->rn
))) {
7880 unallocated_encoding(s
);
7883 /* BitCount(list) < 1 is UNPREDICTABLE */
7884 return do_ldm(s
, a
, 1);
7887 static bool trans_LDM_t32(DisasContext
*s
, arg_ldst_block
*a
)
7889 /* Writeback register in register list is UNPREDICTABLE for T32. */
7890 if (a
->w
&& (a
->list
& (1 << a
->rn
))) {
7891 unallocated_encoding(s
);
7894 /* BitCount(list) < 2 is UNPREDICTABLE */
7895 return do_ldm(s
, a
, 2);
7898 static bool trans_LDM_t16(DisasContext
*s
, arg_ldst_block
*a
)
7900 /* Writeback is conditional on the base register not being loaded. */
7901 a
->w
= !(a
->list
& (1 << a
->rn
));
7902 /* BitCount(list) < 1 is UNPREDICTABLE */
7903 return do_ldm(s
, a
, 1);
7907 * Branch, branch with link
7910 static bool trans_B(DisasContext
*s
, arg_i
*a
)
7912 gen_jmp(s
, read_pc(s
) + a
->imm
);
7916 static bool trans_B_cond_thumb(DisasContext
*s
, arg_ci
*a
)
7918 /* This has cond from encoding, required to be outside IT block. */
7919 if (a
->cond
>= 0xe) {
7922 if (s
->condexec_mask
) {
7923 unallocated_encoding(s
);
7926 arm_skip_unless(s
, a
->cond
);
7927 gen_jmp(s
, read_pc(s
) + a
->imm
);
7931 static bool trans_BL(DisasContext
*s
, arg_i
*a
)
7933 tcg_gen_movi_i32(cpu_R
[14], s
->base
.pc_next
| s
->thumb
);
7934 gen_jmp(s
, read_pc(s
) + a
->imm
);
7938 static bool trans_BLX_i(DisasContext
*s
, arg_BLX_i
*a
)
7942 /* For A32, ARCH(5) is checked near the start of the uncond block. */
7943 if (s
->thumb
&& (a
->imm
& 2)) {
7946 tcg_gen_movi_i32(cpu_R
[14], s
->base
.pc_next
| s
->thumb
);
7947 tmp
= tcg_const_i32(!s
->thumb
);
7948 store_cpu_field(tmp
, thumb
);
7949 gen_jmp(s
, (read_pc(s
) & ~3) + a
->imm
);
7953 static bool trans_BL_BLX_prefix(DisasContext
*s
, arg_BL_BLX_prefix
*a
)
7955 assert(!arm_dc_feature(s
, ARM_FEATURE_THUMB2
));
7956 tcg_gen_movi_i32(cpu_R
[14], read_pc(s
) + (a
->imm
<< 12));
7960 static bool trans_BL_suffix(DisasContext
*s
, arg_BL_suffix
*a
)
7962 TCGv_i32 tmp
= tcg_temp_new_i32();
7964 assert(!arm_dc_feature(s
, ARM_FEATURE_THUMB2
));
7965 tcg_gen_addi_i32(tmp
, cpu_R
[14], (a
->imm
<< 1) | 1);
7966 tcg_gen_movi_i32(cpu_R
[14], s
->base
.pc_next
| 1);
7971 static bool trans_BLX_suffix(DisasContext
*s
, arg_BLX_suffix
*a
)
7975 assert(!arm_dc_feature(s
, ARM_FEATURE_THUMB2
));
7976 if (!ENABLE_ARCH_5
) {
7979 tmp
= tcg_temp_new_i32();
7980 tcg_gen_addi_i32(tmp
, cpu_R
[14], a
->imm
<< 1);
7981 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
7982 tcg_gen_movi_i32(cpu_R
[14], s
->base
.pc_next
| 1);
7987 static bool op_tbranch(DisasContext
*s
, arg_tbranch
*a
, bool half
)
7991 tmp
= load_reg(s
, a
->rm
);
7993 tcg_gen_add_i32(tmp
, tmp
, tmp
);
7995 addr
= load_reg(s
, a
->rn
);
7996 tcg_gen_add_i32(addr
, addr
, tmp
);
7998 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
),
7999 half
? MO_UW
| s
->be_data
: MO_UB
);
8000 tcg_temp_free_i32(addr
);
8002 tcg_gen_add_i32(tmp
, tmp
, tmp
);
8003 tcg_gen_addi_i32(tmp
, tmp
, read_pc(s
));
8004 store_reg(s
, 15, tmp
);
8008 static bool trans_TBB(DisasContext
*s
, arg_tbranch
*a
)
8010 return op_tbranch(s
, a
, false);
8013 static bool trans_TBH(DisasContext
*s
, arg_tbranch
*a
)
8015 return op_tbranch(s
, a
, true);
8018 static bool trans_CBZ(DisasContext
*s
, arg_CBZ
*a
)
8020 TCGv_i32 tmp
= load_reg(s
, a
->rn
);
8022 arm_gen_condlabel(s
);
8023 tcg_gen_brcondi_i32(a
->nz
? TCG_COND_EQ
: TCG_COND_NE
,
8024 tmp
, 0, s
->condlabel
);
8025 tcg_temp_free_i32(tmp
);
8026 gen_jmp(s
, read_pc(s
) + a
->imm
);
8031 * Supervisor call - both T32 & A32 come here so we need to check
8032 * which mode we are in when checking for semihosting.
8035 static bool trans_SVC(DisasContext
*s
, arg_SVC
*a
)
8037 const uint32_t semihost_imm
= s
->thumb
? 0xab : 0x123456;
8039 if (!arm_dc_feature(s
, ARM_FEATURE_M
) && semihosting_enabled() &&
8040 #ifndef CONFIG_USER_ONLY
8043 (a
->imm
== semihost_imm
)) {
8044 gen_exception_internal_insn(s
, s
->pc_curr
, EXCP_SEMIHOST
);
8046 gen_set_pc_im(s
, s
->base
.pc_next
);
8047 s
->svc_imm
= a
->imm
;
8048 s
->base
.is_jmp
= DISAS_SWI
;
8054 * Unconditional system instructions
8057 static bool trans_RFE(DisasContext
*s
, arg_RFE
*a
)
8059 static const int8_t pre_offset
[4] = {
8060 /* DA */ -4, /* IA */ 0, /* DB */ -8, /* IB */ 4
8062 static const int8_t post_offset
[4] = {
8063 /* DA */ -8, /* IA */ 4, /* DB */ -4, /* IB */ 0
8065 TCGv_i32 addr
, t1
, t2
;
8067 if (!ENABLE_ARCH_6
|| arm_dc_feature(s
, ARM_FEATURE_M
)) {
8071 unallocated_encoding(s
);
8075 addr
= load_reg(s
, a
->rn
);
8076 tcg_gen_addi_i32(addr
, addr
, pre_offset
[a
->pu
]);
8078 /* Load PC into tmp and CPSR into tmp2. */
8079 t1
= tcg_temp_new_i32();
8080 gen_aa32_ld32u(s
, t1
, addr
, get_mem_index(s
));
8081 tcg_gen_addi_i32(addr
, addr
, 4);
8082 t2
= tcg_temp_new_i32();
8083 gen_aa32_ld32u(s
, t2
, addr
, get_mem_index(s
));
8086 /* Base writeback. */
8087 tcg_gen_addi_i32(addr
, addr
, post_offset
[a
->pu
]);
8088 store_reg(s
, a
->rn
, addr
);
8090 tcg_temp_free_i32(addr
);
8096 static bool trans_SRS(DisasContext
*s
, arg_SRS
*a
)
8098 if (!ENABLE_ARCH_6
|| arm_dc_feature(s
, ARM_FEATURE_M
)) {
8101 gen_srs(s
, a
->mode
, a
->pu
, a
->w
);
8105 static bool trans_CPS(DisasContext
*s
, arg_CPS
*a
)
8109 if (!ENABLE_ARCH_6
|| arm_dc_feature(s
, ARM_FEATURE_M
)) {
8113 /* Implemented as NOP in user mode. */
8116 /* TODO: There are quite a lot of UNPREDICTABLE argument combinations. */
8138 gen_set_psr_im(s
, mask
, 0, val
);
8143 static bool trans_CPS_v7m(DisasContext
*s
, arg_CPS_v7m
*a
)
8145 TCGv_i32 tmp
, addr
, el
;
8147 if (!arm_dc_feature(s
, ARM_FEATURE_M
)) {
8151 /* Implemented as NOP in user mode. */
8155 tmp
= tcg_const_i32(a
->im
);
8158 addr
= tcg_const_i32(19);
8159 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
8160 tcg_temp_free_i32(addr
);
8164 addr
= tcg_const_i32(16);
8165 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
8166 tcg_temp_free_i32(addr
);
8168 el
= tcg_const_i32(s
->current_el
);
8169 gen_helper_rebuild_hflags_m32(cpu_env
, el
);
8170 tcg_temp_free_i32(el
);
8171 tcg_temp_free_i32(tmp
);
8177 * Clear-Exclusive, Barriers
8180 static bool trans_CLREX(DisasContext
*s
, arg_CLREX
*a
)
8183 ? !ENABLE_ARCH_7
&& !arm_dc_feature(s
, ARM_FEATURE_M
)
8184 : !ENABLE_ARCH_6K
) {
8191 static bool trans_DSB(DisasContext
*s
, arg_DSB
*a
)
8193 if (!ENABLE_ARCH_7
&& !arm_dc_feature(s
, ARM_FEATURE_M
)) {
8196 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
8200 static bool trans_DMB(DisasContext
*s
, arg_DMB
*a
)
8202 return trans_DSB(s
, NULL
);
8205 static bool trans_ISB(DisasContext
*s
, arg_ISB
*a
)
8207 if (!ENABLE_ARCH_7
&& !arm_dc_feature(s
, ARM_FEATURE_M
)) {
8211 * We need to break the TB after this insn to execute
8212 * self-modifying code correctly and also to take
8213 * any pending interrupts immediately.
8215 gen_goto_tb(s
, 0, s
->base
.pc_next
);
8219 static bool trans_SB(DisasContext
*s
, arg_SB
*a
)
8221 if (!dc_isar_feature(aa32_sb
, s
)) {
8225 * TODO: There is no speculation barrier opcode
8226 * for TCG; MB and end the TB instead.
8228 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
8229 gen_goto_tb(s
, 0, s
->base
.pc_next
);
8233 static bool trans_SETEND(DisasContext
*s
, arg_SETEND
*a
)
8235 if (!ENABLE_ARCH_6
) {
8238 if (a
->E
!= (s
->be_data
== MO_BE
)) {
8239 gen_helper_setend(cpu_env
);
8240 s
->base
.is_jmp
= DISAS_UPDATE_EXIT
;
8246 * Preload instructions
8247 * All are nops, contingent on the appropriate arch level.
8250 static bool trans_PLD(DisasContext
*s
, arg_PLD
*a
)
8252 return ENABLE_ARCH_5TE
;
8255 static bool trans_PLDW(DisasContext
*s
, arg_PLD
*a
)
8257 return arm_dc_feature(s
, ARM_FEATURE_V7MP
);
8260 static bool trans_PLI(DisasContext
*s
, arg_PLD
*a
)
8262 return ENABLE_ARCH_7
;
8269 static bool trans_IT(DisasContext
*s
, arg_IT
*a
)
8271 int cond_mask
= a
->cond_mask
;
8274 * No actual code generated for this insn, just setup state.
8276 * Combinations of firstcond and mask which set up an 0b1111
8277 * condition are UNPREDICTABLE; we take the CONSTRAINED
8278 * UNPREDICTABLE choice to treat 0b1111 the same as 0b1110,
8279 * i.e. both meaning "execute always".
8281 s
->condexec_cond
= (cond_mask
>> 4) & 0xe;
8282 s
->condexec_mask
= cond_mask
& 0x1f;
8290 static void disas_arm_insn(DisasContext
*s
, unsigned int insn
)
8292 unsigned int cond
= insn
>> 28;
8294 /* M variants do not implement ARM mode; this must raise the INVSTATE
8295 * UsageFault exception.
8297 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
8298 gen_exception_insn(s
, s
->pc_curr
, EXCP_INVSTATE
, syn_uncategorized(),
8299 default_exception_el(s
));
8304 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
8305 * choose to UNDEF. In ARMv5 and above the space is used
8306 * for miscellaneous unconditional instructions.
8310 /* Unconditional instructions. */
8311 /* TODO: Perhaps merge these into one decodetree output file. */
8312 if (disas_a32_uncond(s
, insn
) ||
8313 disas_vfp_uncond(s
, insn
) ||
8314 disas_neon_dp(s
, insn
) ||
8315 disas_neon_ls(s
, insn
) ||
8316 disas_neon_shared(s
, insn
)) {
8319 /* fall back to legacy decoder */
8321 if ((insn
& 0x0e000f00) == 0x0c000100) {
8322 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
8323 /* iWMMXt register transfer. */
8324 if (extract32(s
->c15_cpar
, 1, 1)) {
8325 if (!disas_iwmmxt_insn(s
, insn
)) {
8334 /* if not always execute, we generate a conditional jump to
8336 arm_skip_unless(s
, cond
);
8339 /* TODO: Perhaps merge these into one decodetree output file. */
8340 if (disas_a32(s
, insn
) ||
8341 disas_vfp(s
, insn
)) {
8344 /* fall back to legacy decoder */
8345 /* TODO: convert xscale/iwmmxt decoder to decodetree ?? */
8346 if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
)) {
8347 if (((insn
& 0x0c000e00) == 0x0c000000)
8348 && ((insn
& 0x03000000) != 0x03000000)) {
8349 /* Coprocessor insn, coprocessor 0 or 1 */
8350 disas_xscale_insn(s
, insn
);
8356 unallocated_encoding(s
);
8359 static bool thumb_insn_is_16bit(DisasContext
*s
, uint32_t pc
, uint32_t insn
)
8362 * Return true if this is a 16 bit instruction. We must be precise
8363 * about this (matching the decode).
8365 if ((insn
>> 11) < 0x1d) {
8366 /* Definitely a 16-bit instruction */
8370 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
8371 * first half of a 32-bit Thumb insn. Thumb-1 cores might
8372 * end up actually treating this as two 16-bit insns, though,
8373 * if it's half of a bl/blx pair that might span a page boundary.
8375 if (arm_dc_feature(s
, ARM_FEATURE_THUMB2
) ||
8376 arm_dc_feature(s
, ARM_FEATURE_M
)) {
8377 /* Thumb2 cores (including all M profile ones) always treat
8378 * 32-bit insns as 32-bit.
8383 if ((insn
>> 11) == 0x1e && pc
- s
->page_start
< TARGET_PAGE_SIZE
- 3) {
8384 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
8385 * is not on the next page; we merge this into a 32-bit
8390 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
8391 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
8392 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
8393 * -- handle as single 16 bit insn
8398 /* Translate a 32-bit thumb instruction. */
8399 static void disas_thumb2_insn(DisasContext
*s
, uint32_t insn
)
8402 * ARMv6-M supports a limited subset of Thumb2 instructions.
8403 * Other Thumb1 architectures allow only 32-bit
8404 * combined BL/BLX prefix and suffix.
8406 if (arm_dc_feature(s
, ARM_FEATURE_M
) &&
8407 !arm_dc_feature(s
, ARM_FEATURE_V7
)) {
8410 static const uint32_t armv6m_insn
[] = {0xf3808000 /* msr */,
8411 0xf3b08040 /* dsb */,
8412 0xf3b08050 /* dmb */,
8413 0xf3b08060 /* isb */,
8414 0xf3e08000 /* mrs */,
8415 0xf000d000 /* bl */};
8416 static const uint32_t armv6m_mask
[] = {0xffe0d000,
8423 for (i
= 0; i
< ARRAY_SIZE(armv6m_insn
); i
++) {
8424 if ((insn
& armv6m_mask
[i
]) == armv6m_insn
[i
]) {
8432 } else if ((insn
& 0xf800e800) != 0xf000e800) {
8436 if ((insn
& 0xef000000) == 0xef000000) {
8438 * T32 encodings 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
8440 * A32 encodings 0b1111_001p_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
8442 uint32_t a32_insn
= (insn
& 0xe2ffffff) |
8443 ((insn
& (1 << 28)) >> 4) | (1 << 28);
8445 if (disas_neon_dp(s
, a32_insn
)) {
8450 if ((insn
& 0xff100000) == 0xf9000000) {
8452 * T32 encodings 0b1111_1001_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
8454 * A32 encodings 0b1111_0100_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
8456 uint32_t a32_insn
= (insn
& 0x00ffffff) | 0xf4000000;
8458 if (disas_neon_ls(s
, a32_insn
)) {
8464 * TODO: Perhaps merge these into one decodetree output file.
8465 * Note disas_vfp is written for a32 with cond field in the
8466 * top nibble. The t32 encoding requires 0xe in the top nibble.
8468 if (disas_t32(s
, insn
) ||
8469 disas_vfp_uncond(s
, insn
) ||
8470 disas_neon_shared(s
, insn
) ||
8471 ((insn
>> 28) == 0xe && disas_vfp(s
, insn
))) {
8474 /* fall back to legacy decoder */
8476 switch ((insn
>> 25) & 0xf) {
8477 case 0: case 1: case 2: case 3:
8478 /* 16-bit instructions. Should never happen. */
8480 case 6: case 7: case 14: case 15:
8482 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
8483 /* 0b111x_11xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx */
8484 if (extract32(insn
, 24, 2) == 3) {
8485 goto illegal_op
; /* op0 = 0b11 : unallocated */
8488 if (((insn
>> 8) & 0xe) == 10 &&
8489 dc_isar_feature(aa32_fpsp_v2
, s
)) {
8490 /* FP, and the CPU supports it */
8493 /* All other insns: NOCP */
8494 gen_exception_insn(s
, s
->pc_curr
, EXCP_NOCP
,
8495 syn_uncategorized(),
8496 default_exception_el(s
));
8500 if (((insn
>> 24) & 3) == 3) {
8501 /* Neon DP, but failed disas_neon_dp() */
8503 } else if (((insn
>> 8) & 0xe) == 10) {
8504 /* VFP, but failed disas_vfp. */
8507 if (insn
& (1 << 28))
8509 if (disas_coproc_insn(s
, insn
)) {
8518 unallocated_encoding(s
);
8522 static void disas_thumb_insn(DisasContext
*s
, uint32_t insn
)
8524 if (!disas_t16(s
, insn
)) {
8525 unallocated_encoding(s
);
8529 static bool insn_crosses_page(CPUARMState
*env
, DisasContext
*s
)
8531 /* Return true if the insn at dc->base.pc_next might cross a page boundary.
8532 * (False positives are OK, false negatives are not.)
8533 * We know this is a Thumb insn, and our caller ensures we are
8534 * only called if dc->base.pc_next is less than 4 bytes from the page
8535 * boundary, so we cross the page if the first 16 bits indicate
8536 * that this is a 32 bit insn.
8538 uint16_t insn
= arm_lduw_code(env
, s
->base
.pc_next
, s
->sctlr_b
);
8540 return !thumb_insn_is_16bit(s
, s
->base
.pc_next
, insn
);
8543 static void arm_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cs
)
8545 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8546 CPUARMState
*env
= cs
->env_ptr
;
8547 ARMCPU
*cpu
= env_archcpu(env
);
8548 uint32_t tb_flags
= dc
->base
.tb
->flags
;
8549 uint32_t condexec
, core_mmu_idx
;
8551 dc
->isar
= &cpu
->isar
;
8555 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
8556 * there is no secure EL1, so we route exceptions to EL3.
8558 dc
->secure_routed_to_el3
= arm_feature(env
, ARM_FEATURE_EL3
) &&
8559 !arm_el_is_aa64(env
, 3);
8560 dc
->thumb
= FIELD_EX32(tb_flags
, TBFLAG_AM32
, THUMB
);
8561 dc
->be_data
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, BE_DATA
) ? MO_BE
: MO_LE
;
8562 condexec
= FIELD_EX32(tb_flags
, TBFLAG_AM32
, CONDEXEC
);
8563 dc
->condexec_mask
= (condexec
& 0xf) << 1;
8564 dc
->condexec_cond
= condexec
>> 4;
8566 core_mmu_idx
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, MMUIDX
);
8567 dc
->mmu_idx
= core_to_arm_mmu_idx(env
, core_mmu_idx
);
8568 dc
->current_el
= arm_mmu_idx_to_el(dc
->mmu_idx
);
8569 #if !defined(CONFIG_USER_ONLY)
8570 dc
->user
= (dc
->current_el
== 0);
8572 dc
->fp_excp_el
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, FPEXC_EL
);
8574 if (arm_feature(env
, ARM_FEATURE_M
)) {
8575 dc
->vfp_enabled
= 1;
8576 dc
->be_data
= MO_TE
;
8577 dc
->v7m_handler_mode
= FIELD_EX32(tb_flags
, TBFLAG_M32
, HANDLER
);
8578 dc
->v8m_secure
= arm_feature(env
, ARM_FEATURE_M_SECURITY
) &&
8579 regime_is_secure(env
, dc
->mmu_idx
);
8580 dc
->v8m_stackcheck
= FIELD_EX32(tb_flags
, TBFLAG_M32
, STACKCHECK
);
8581 dc
->v8m_fpccr_s_wrong
=
8582 FIELD_EX32(tb_flags
, TBFLAG_M32
, FPCCR_S_WRONG
);
8583 dc
->v7m_new_fp_ctxt_needed
=
8584 FIELD_EX32(tb_flags
, TBFLAG_M32
, NEW_FP_CTXT_NEEDED
);
8585 dc
->v7m_lspact
= FIELD_EX32(tb_flags
, TBFLAG_M32
, LSPACT
);
8588 FIELD_EX32(tb_flags
, TBFLAG_ANY
, BE_DATA
) ? MO_BE
: MO_LE
;
8589 dc
->debug_target_el
=
8590 FIELD_EX32(tb_flags
, TBFLAG_ANY
, DEBUG_TARGET_EL
);
8591 dc
->sctlr_b
= FIELD_EX32(tb_flags
, TBFLAG_A32
, SCTLR_B
);
8592 dc
->hstr_active
= FIELD_EX32(tb_flags
, TBFLAG_A32
, HSTR_ACTIVE
);
8593 dc
->ns
= FIELD_EX32(tb_flags
, TBFLAG_A32
, NS
);
8594 dc
->vfp_enabled
= FIELD_EX32(tb_flags
, TBFLAG_A32
, VFPEN
);
8595 if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
8596 dc
->c15_cpar
= FIELD_EX32(tb_flags
, TBFLAG_A32
, XSCALE_CPAR
);
8598 dc
->vec_len
= FIELD_EX32(tb_flags
, TBFLAG_A32
, VECLEN
);
8599 dc
->vec_stride
= FIELD_EX32(tb_flags
, TBFLAG_A32
, VECSTRIDE
);
8602 dc
->cp_regs
= cpu
->cp_regs
;
8603 dc
->features
= env
->features
;
8605 /* Single step state. The code-generation logic here is:
8607 * generate code with no special handling for single-stepping (except
8608 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
8609 * this happens anyway because those changes are all system register or
8611 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
8612 * emit code for one insn
8613 * emit code to clear PSTATE.SS
8614 * emit code to generate software step exception for completed step
8615 * end TB (as usual for having generated an exception)
8616 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
8617 * emit code to generate a software step exception
8620 dc
->ss_active
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, SS_ACTIVE
);
8621 dc
->pstate_ss
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, PSTATE_SS
);
8622 dc
->is_ldex
= false;
8624 dc
->page_start
= dc
->base
.pc_first
& TARGET_PAGE_MASK
;
8626 /* If architectural single step active, limit to 1. */
8627 if (is_singlestepping(dc
)) {
8628 dc
->base
.max_insns
= 1;
8631 /* ARM is a fixed-length ISA. Bound the number of insns to execute
8632 to those left on the page. */
8634 int bound
= -(dc
->base
.pc_first
| TARGET_PAGE_MASK
) / 4;
8635 dc
->base
.max_insns
= MIN(dc
->base
.max_insns
, bound
);
8638 cpu_V0
= tcg_temp_new_i64();
8639 cpu_V1
= tcg_temp_new_i64();
8640 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
8641 cpu_M0
= tcg_temp_new_i64();
8644 static void arm_tr_tb_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
8646 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8648 /* A note on handling of the condexec (IT) bits:
8650 * We want to avoid the overhead of having to write the updated condexec
8651 * bits back to the CPUARMState for every instruction in an IT block. So:
8652 * (1) if the condexec bits are not already zero then we write
8653 * zero back into the CPUARMState now. This avoids complications trying
8654 * to do it at the end of the block. (For example if we don't do this
8655 * it's hard to identify whether we can safely skip writing condexec
8656 * at the end of the TB, which we definitely want to do for the case
8657 * where a TB doesn't do anything with the IT state at all.)
8658 * (2) if we are going to leave the TB then we call gen_set_condexec()
8659 * which will write the correct value into CPUARMState if zero is wrong.
8660 * This is done both for leaving the TB at the end, and for leaving
8661 * it because of an exception we know will happen, which is done in
8662 * gen_exception_insn(). The latter is necessary because we need to
8663 * leave the TB with the PC/IT state just prior to execution of the
8664 * instruction which caused the exception.
8665 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
8666 * then the CPUARMState will be wrong and we need to reset it.
8667 * This is handled in the same way as restoration of the
8668 * PC in these situations; we save the value of the condexec bits
8669 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
8670 * then uses this to restore them after an exception.
8672 * Note that there are no instructions which can read the condexec
8673 * bits, and none which can write non-static values to them, so
8674 * we don't need to care about whether CPUARMState is correct in the
8678 /* Reset the conditional execution bits immediately. This avoids
8679 complications trying to do it at the end of the block. */
8680 if (dc
->condexec_mask
|| dc
->condexec_cond
) {
8681 TCGv_i32 tmp
= tcg_temp_new_i32();
8682 tcg_gen_movi_i32(tmp
, 0);
8683 store_cpu_field(tmp
, condexec_bits
);
8687 static void arm_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
8689 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8691 tcg_gen_insn_start(dc
->base
.pc_next
,
8692 (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1),
8694 dc
->insn_start
= tcg_last_op();
8697 static bool arm_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cpu
,
8698 const CPUBreakpoint
*bp
)
8700 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8702 if (bp
->flags
& BP_CPU
) {
8703 gen_set_condexec(dc
);
8704 gen_set_pc_im(dc
, dc
->base
.pc_next
);
8705 gen_helper_check_breakpoints(cpu_env
);
8706 /* End the TB early; it's likely not going to be executed */
8707 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
8709 gen_exception_internal_insn(dc
, dc
->base
.pc_next
, EXCP_DEBUG
);
8710 /* The address covered by the breakpoint must be
8711 included in [tb->pc, tb->pc + tb->size) in order
8712 to for it to be properly cleared -- thus we
8713 increment the PC here so that the logic setting
8714 tb->size below does the right thing. */
8715 /* TODO: Advance PC by correct instruction length to
8716 * avoid disassembler error messages */
8717 dc
->base
.pc_next
+= 2;
8718 dc
->base
.is_jmp
= DISAS_NORETURN
;
8724 static bool arm_pre_translate_insn(DisasContext
*dc
)
8726 #ifdef CONFIG_USER_ONLY
8727 /* Intercept jump to the magic kernel page. */
8728 if (dc
->base
.pc_next
>= 0xffff0000) {
8729 /* We always get here via a jump, so know we are not in a
8730 conditional execution block. */
8731 gen_exception_internal(EXCP_KERNEL_TRAP
);
8732 dc
->base
.is_jmp
= DISAS_NORETURN
;
8737 if (dc
->ss_active
&& !dc
->pstate_ss
) {
8738 /* Singlestep state is Active-pending.
8739 * If we're in this state at the start of a TB then either
8740 * a) we just took an exception to an EL which is being debugged
8741 * and this is the first insn in the exception handler
8742 * b) debug exceptions were masked and we just unmasked them
8743 * without changing EL (eg by clearing PSTATE.D)
8744 * In either case we're going to take a swstep exception in the
8745 * "did not step an insn" case, and so the syndrome ISV and EX
8746 * bits should be zero.
8748 assert(dc
->base
.num_insns
== 1);
8749 gen_swstep_exception(dc
, 0, 0);
8750 dc
->base
.is_jmp
= DISAS_NORETURN
;
8757 static void arm_post_translate_insn(DisasContext
*dc
)
8759 if (dc
->condjmp
&& !dc
->base
.is_jmp
) {
8760 gen_set_label(dc
->condlabel
);
8763 translator_loop_temp_check(&dc
->base
);
8766 static void arm_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cpu
)
8768 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8769 CPUARMState
*env
= cpu
->env_ptr
;
8772 if (arm_pre_translate_insn(dc
)) {
8776 dc
->pc_curr
= dc
->base
.pc_next
;
8777 insn
= arm_ldl_code(env
, dc
->base
.pc_next
, dc
->sctlr_b
);
8779 dc
->base
.pc_next
+= 4;
8780 disas_arm_insn(dc
, insn
);
8782 arm_post_translate_insn(dc
);
8784 /* ARM is a fixed-length ISA. We performed the cross-page check
8785 in init_disas_context by adjusting max_insns. */
8788 static bool thumb_insn_is_unconditional(DisasContext
*s
, uint32_t insn
)
8790 /* Return true if this Thumb insn is always unconditional,
8791 * even inside an IT block. This is true of only a very few
8792 * instructions: BKPT, HLT, and SG.
8794 * A larger class of instructions are UNPREDICTABLE if used
8795 * inside an IT block; we do not need to detect those here, because
8796 * what we do by default (perform the cc check and update the IT
8797 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
8798 * choice for those situations.
8800 * insn is either a 16-bit or a 32-bit instruction; the two are
8801 * distinguishable because for the 16-bit case the top 16 bits
8802 * are zeroes, and that isn't a valid 32-bit encoding.
8804 if ((insn
& 0xffffff00) == 0xbe00) {
8809 if ((insn
& 0xffffffc0) == 0xba80 && arm_dc_feature(s
, ARM_FEATURE_V8
) &&
8810 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
8811 /* HLT: v8A only. This is unconditional even when it is going to
8812 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
8813 * For v7 cores this was a plain old undefined encoding and so
8814 * honours its cc check. (We might be using the encoding as
8815 * a semihosting trap, but we don't change the cc check behaviour
8816 * on that account, because a debugger connected to a real v7A
8817 * core and emulating semihosting traps by catching the UNDEF
8818 * exception would also only see cases where the cc check passed.
8819 * No guest code should be trying to do a HLT semihosting trap
8820 * in an IT block anyway.
8825 if (insn
== 0xe97fe97f && arm_dc_feature(s
, ARM_FEATURE_V8
) &&
8826 arm_dc_feature(s
, ARM_FEATURE_M
)) {
8834 static void thumb_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cpu
)
8836 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8837 CPUARMState
*env
= cpu
->env_ptr
;
8841 if (arm_pre_translate_insn(dc
)) {
8845 dc
->pc_curr
= dc
->base
.pc_next
;
8846 insn
= arm_lduw_code(env
, dc
->base
.pc_next
, dc
->sctlr_b
);
8847 is_16bit
= thumb_insn_is_16bit(dc
, dc
->base
.pc_next
, insn
);
8848 dc
->base
.pc_next
+= 2;
8850 uint32_t insn2
= arm_lduw_code(env
, dc
->base
.pc_next
, dc
->sctlr_b
);
8852 insn
= insn
<< 16 | insn2
;
8853 dc
->base
.pc_next
+= 2;
8857 if (dc
->condexec_mask
&& !thumb_insn_is_unconditional(dc
, insn
)) {
8858 uint32_t cond
= dc
->condexec_cond
;
8861 * Conditionally skip the insn. Note that both 0xe and 0xf mean
8862 * "always"; 0xf is not "never".
8865 arm_skip_unless(dc
, cond
);
8870 disas_thumb_insn(dc
, insn
);
8872 disas_thumb2_insn(dc
, insn
);
8875 /* Advance the Thumb condexec condition. */
8876 if (dc
->condexec_mask
) {
8877 dc
->condexec_cond
= ((dc
->condexec_cond
& 0xe) |
8878 ((dc
->condexec_mask
>> 4) & 1));
8879 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
8880 if (dc
->condexec_mask
== 0) {
8881 dc
->condexec_cond
= 0;
8885 arm_post_translate_insn(dc
);
8887 /* Thumb is a variable-length ISA. Stop translation when the next insn
8888 * will touch a new page. This ensures that prefetch aborts occur at
8891 * We want to stop the TB if the next insn starts in a new page,
8892 * or if it spans between this page and the next. This means that
8893 * if we're looking at the last halfword in the page we need to
8894 * see if it's a 16-bit Thumb insn (which will fit in this TB)
8895 * or a 32-bit Thumb insn (which won't).
8896 * This is to avoid generating a silly TB with a single 16-bit insn
8897 * in it at the end of this page (which would execute correctly
8898 * but isn't very efficient).
8900 if (dc
->base
.is_jmp
== DISAS_NEXT
8901 && (dc
->base
.pc_next
- dc
->page_start
>= TARGET_PAGE_SIZE
8902 || (dc
->base
.pc_next
- dc
->page_start
>= TARGET_PAGE_SIZE
- 3
8903 && insn_crosses_page(env
, dc
)))) {
8904 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
8908 static void arm_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cpu
)
8910 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8912 if (tb_cflags(dc
->base
.tb
) & CF_LAST_IO
&& dc
->condjmp
) {
8913 /* FIXME: This can theoretically happen with self-modifying code. */
8914 cpu_abort(cpu
, "IO on conditional branch instruction");
8917 /* At this stage dc->condjmp will only be set when the skipped
8918 instruction was a conditional branch or trap, and the PC has
8919 already been written. */
8920 gen_set_condexec(dc
);
8921 if (dc
->base
.is_jmp
== DISAS_BX_EXCRET
) {
8922 /* Exception return branches need some special case code at the
8923 * end of the TB, which is complex enough that it has to
8924 * handle the single-step vs not and the condition-failed
8925 * insn codepath itself.
8927 gen_bx_excret_final_code(dc
);
8928 } else if (unlikely(is_singlestepping(dc
))) {
8929 /* Unconditional and "condition passed" instruction codepath. */
8930 switch (dc
->base
.is_jmp
) {
8933 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
8934 default_exception_el(dc
));
8938 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
8942 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
8945 case DISAS_TOO_MANY
:
8946 case DISAS_UPDATE_EXIT
:
8947 case DISAS_UPDATE_NOCHAIN
:
8948 gen_set_pc_im(dc
, dc
->base
.pc_next
);
8951 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
8952 gen_singlestep_exception(dc
);
8954 case DISAS_NORETURN
:
8958 /* While branches must always occur at the end of an IT block,
8959 there are a few other things that can cause us to terminate
8960 the TB in the middle of an IT block:
8961 - Exception generating instructions (bkpt, swi, undefined).
8963 - Hardware watchpoints.
8964 Hardware breakpoints have already been handled and skip this code.
8966 switch(dc
->base
.is_jmp
) {
8968 case DISAS_TOO_MANY
:
8969 gen_goto_tb(dc
, 1, dc
->base
.pc_next
);
8971 case DISAS_UPDATE_NOCHAIN
:
8972 gen_set_pc_im(dc
, dc
->base
.pc_next
);
8977 case DISAS_UPDATE_EXIT
:
8978 gen_set_pc_im(dc
, dc
->base
.pc_next
);
8981 /* indicate that the hash table must be used to find the next TB */
8982 tcg_gen_exit_tb(NULL
, 0);
8984 case DISAS_NORETURN
:
8985 /* nothing more to generate */
8989 TCGv_i32 tmp
= tcg_const_i32((dc
->thumb
&&
8990 !(dc
->insn
& (1U << 31))) ? 2 : 4);
8992 gen_helper_wfi(cpu_env
, tmp
);
8993 tcg_temp_free_i32(tmp
);
8994 /* The helper doesn't necessarily throw an exception, but we
8995 * must go back to the main loop to check for interrupts anyway.
8997 tcg_gen_exit_tb(NULL
, 0);
9001 gen_helper_wfe(cpu_env
);
9004 gen_helper_yield(cpu_env
);
9007 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
9008 default_exception_el(dc
));
9011 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
9014 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
9020 /* "Condition failed" instruction codepath for the branch/trap insn */
9021 gen_set_label(dc
->condlabel
);
9022 gen_set_condexec(dc
);
9023 if (unlikely(is_singlestepping(dc
))) {
9024 gen_set_pc_im(dc
, dc
->base
.pc_next
);
9025 gen_singlestep_exception(dc
);
9027 gen_goto_tb(dc
, 1, dc
->base
.pc_next
);
9032 static void arm_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cpu
)
9034 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
9036 qemu_log("IN: %s\n", lookup_symbol(dc
->base
.pc_first
));
9037 log_target_disas(cpu
, dc
->base
.pc_first
, dc
->base
.tb
->size
);
9040 static const TranslatorOps arm_translator_ops
= {
9041 .init_disas_context
= arm_tr_init_disas_context
,
9042 .tb_start
= arm_tr_tb_start
,
9043 .insn_start
= arm_tr_insn_start
,
9044 .breakpoint_check
= arm_tr_breakpoint_check
,
9045 .translate_insn
= arm_tr_translate_insn
,
9046 .tb_stop
= arm_tr_tb_stop
,
9047 .disas_log
= arm_tr_disas_log
,
9050 static const TranslatorOps thumb_translator_ops
= {
9051 .init_disas_context
= arm_tr_init_disas_context
,
9052 .tb_start
= arm_tr_tb_start
,
9053 .insn_start
= arm_tr_insn_start
,
9054 .breakpoint_check
= arm_tr_breakpoint_check
,
9055 .translate_insn
= thumb_tr_translate_insn
,
9056 .tb_stop
= arm_tr_tb_stop
,
9057 .disas_log
= arm_tr_disas_log
,
9060 /* generate intermediate code for basic block 'tb'. */
9061 void gen_intermediate_code(CPUState
*cpu
, TranslationBlock
*tb
, int max_insns
)
9063 DisasContext dc
= { };
9064 const TranslatorOps
*ops
= &arm_translator_ops
;
9066 if (FIELD_EX32(tb
->flags
, TBFLAG_AM32
, THUMB
)) {
9067 ops
= &thumb_translator_ops
;
9069 #ifdef TARGET_AARCH64
9070 if (FIELD_EX32(tb
->flags
, TBFLAG_ANY
, AARCH64_STATE
)) {
9071 ops
= &aarch64_translator_ops
;
9075 translator_loop(ops
, &dc
.base
, cpu
, tb
, max_insns
);
9078 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
,
9083 env
->condexec_bits
= 0;
9084 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;
9086 env
->regs
[15] = data
[0];
9087 env
->condexec_bits
= data
[1];
9088 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;