4 * Copyright (c) 2013 Alexander Graf <agraf@suse.de>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 #include "qemu/osdep.h"
22 #include "exec/exec-all.h"
26 #include "translate.h"
27 #include "internals.h"
28 #include "qemu/host-utils.h"
30 #include "exec/semihost.h"
31 #include "exec/gen-icount.h"
33 #include "exec/helper-proto.h"
34 #include "exec/helper-gen.h"
37 #include "trace-tcg.h"
39 static TCGv_i64 cpu_X
[32];
40 static TCGv_i64 cpu_pc
;
42 /* Load/store exclusive handling */
43 static TCGv_i64 cpu_exclusive_high
;
45 static const char *regnames
[] = {
46 "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",
47 "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",
48 "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23",
49 "x24", "x25", "x26", "x27", "x28", "x29", "lr", "sp"
53 A64_SHIFT_TYPE_LSL
= 0,
54 A64_SHIFT_TYPE_LSR
= 1,
55 A64_SHIFT_TYPE_ASR
= 2,
56 A64_SHIFT_TYPE_ROR
= 3
59 /* Table based decoder typedefs - used when the relevant bits for decode
60 * are too awkwardly scattered across the instruction (eg SIMD).
62 typedef void AArch64DecodeFn(DisasContext
*s
, uint32_t insn
);
64 typedef struct AArch64DecodeTable
{
67 AArch64DecodeFn
*disas_fn
;
70 /* Function prototype for gen_ functions for calling Neon helpers */
71 typedef void NeonGenOneOpEnvFn(TCGv_i32
, TCGv_ptr
, TCGv_i32
);
72 typedef void NeonGenTwoOpFn(TCGv_i32
, TCGv_i32
, TCGv_i32
);
73 typedef void NeonGenTwoOpEnvFn(TCGv_i32
, TCGv_ptr
, TCGv_i32
, TCGv_i32
);
74 typedef void NeonGenTwo64OpFn(TCGv_i64
, TCGv_i64
, TCGv_i64
);
75 typedef void NeonGenTwo64OpEnvFn(TCGv_i64
, TCGv_ptr
, TCGv_i64
, TCGv_i64
);
76 typedef void NeonGenNarrowFn(TCGv_i32
, TCGv_i64
);
77 typedef void NeonGenNarrowEnvFn(TCGv_i32
, TCGv_ptr
, TCGv_i64
);
78 typedef void NeonGenWidenFn(TCGv_i64
, TCGv_i32
);
79 typedef void NeonGenTwoSingleOPFn(TCGv_i32
, TCGv_i32
, TCGv_i32
, TCGv_ptr
);
80 typedef void NeonGenTwoDoubleOPFn(TCGv_i64
, TCGv_i64
, TCGv_i64
, TCGv_ptr
);
81 typedef void NeonGenOneOpFn(TCGv_i64
, TCGv_i64
);
82 typedef void CryptoTwoOpEnvFn(TCGv_ptr
, TCGv_i32
, TCGv_i32
);
83 typedef void CryptoThreeOpEnvFn(TCGv_ptr
, TCGv_i32
, TCGv_i32
, TCGv_i32
);
85 /* initialize TCG globals. */
86 void a64_translate_init(void)
90 cpu_pc
= tcg_global_mem_new_i64(cpu_env
,
91 offsetof(CPUARMState
, pc
),
93 for (i
= 0; i
< 32; i
++) {
94 cpu_X
[i
] = tcg_global_mem_new_i64(cpu_env
,
95 offsetof(CPUARMState
, xregs
[i
]),
99 cpu_exclusive_high
= tcg_global_mem_new_i64(cpu_env
,
100 offsetof(CPUARMState
, exclusive_high
), "exclusive_high");
103 static inline ARMMMUIdx
get_a64_user_mem_index(DisasContext
*s
)
105 /* Return the mmu_idx to use for A64 "unprivileged load/store" insns:
106 * if EL1, access as if EL0; otherwise access at current EL
108 switch (s
->mmu_idx
) {
109 case ARMMMUIdx_S12NSE1
:
110 return ARMMMUIdx_S12NSE0
;
111 case ARMMMUIdx_S1SE1
:
112 return ARMMMUIdx_S1SE0
;
114 g_assert_not_reached();
120 void aarch64_cpu_dump_state(CPUState
*cs
, FILE *f
,
121 fprintf_function cpu_fprintf
, int flags
)
123 ARMCPU
*cpu
= ARM_CPU(cs
);
124 CPUARMState
*env
= &cpu
->env
;
125 uint32_t psr
= pstate_read(env
);
127 int el
= arm_current_el(env
);
128 const char *ns_status
;
130 cpu_fprintf(f
, "PC=%016"PRIx64
" SP=%016"PRIx64
"\n",
131 env
->pc
, env
->xregs
[31]);
132 for (i
= 0; i
< 31; i
++) {
133 cpu_fprintf(f
, "X%02d=%016"PRIx64
, i
, env
->xregs
[i
]);
135 cpu_fprintf(f
, "\n");
141 if (arm_feature(env
, ARM_FEATURE_EL3
) && el
!= 3) {
142 ns_status
= env
->cp15
.scr_el3
& SCR_NS ?
"NS " : "S ";
147 cpu_fprintf(f
, "\nPSTATE=%08x %c%c%c%c %sEL%d%c\n",
149 psr
& PSTATE_N ?
'N' : '-',
150 psr
& PSTATE_Z ?
'Z' : '-',
151 psr
& PSTATE_C ?
'C' : '-',
152 psr
& PSTATE_V ?
'V' : '-',
155 psr
& PSTATE_SP ?
'h' : 't');
157 if (flags
& CPU_DUMP_FPU
) {
159 for (i
= 0; i
< numvfpregs
; i
+= 2) {
160 uint64_t vlo
= float64_val(env
->vfp
.regs
[i
* 2]);
161 uint64_t vhi
= float64_val(env
->vfp
.regs
[(i
* 2) + 1]);
162 cpu_fprintf(f
, "q%02d=%016" PRIx64
":%016" PRIx64
" ",
164 vlo
= float64_val(env
->vfp
.regs
[(i
+ 1) * 2]);
165 vhi
= float64_val(env
->vfp
.regs
[((i
+ 1) * 2) + 1]);
166 cpu_fprintf(f
, "q%02d=%016" PRIx64
":%016" PRIx64
"\n",
169 cpu_fprintf(f
, "FPCR: %08x FPSR: %08x\n",
170 vfp_get_fpcr(env
), vfp_get_fpsr(env
));
174 void gen_a64_set_pc_im(uint64_t val
)
176 tcg_gen_movi_i64(cpu_pc
, val
);
179 typedef struct DisasCompare64
{
184 static void a64_test_cc(DisasCompare64
*c64
, int cc
)
188 arm_test_cc(&c32
, cc
);
190 /* Sign-extend the 32-bit value so that the GE/LT comparisons work
191 * properly. The NE/EQ comparisons are also fine with this choice. */
192 c64
->cond
= c32
.cond
;
193 c64
->value
= tcg_temp_new_i64();
194 tcg_gen_ext_i32_i64(c64
->value
, c32
.value
);
199 static void a64_free_cc(DisasCompare64
*c64
)
201 tcg_temp_free_i64(c64
->value
);
204 static void gen_exception_internal(int excp
)
206 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
208 assert(excp_is_internal(excp
));
209 gen_helper_exception_internal(cpu_env
, tcg_excp
);
210 tcg_temp_free_i32(tcg_excp
);
213 static void gen_exception(int excp
, uint32_t syndrome
, uint32_t target_el
)
215 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
216 TCGv_i32 tcg_syn
= tcg_const_i32(syndrome
);
217 TCGv_i32 tcg_el
= tcg_const_i32(target_el
);
219 gen_helper_exception_with_syndrome(cpu_env
, tcg_excp
,
221 tcg_temp_free_i32(tcg_el
);
222 tcg_temp_free_i32(tcg_syn
);
223 tcg_temp_free_i32(tcg_excp
);
226 static void gen_exception_internal_insn(DisasContext
*s
, int offset
, int excp
)
228 gen_a64_set_pc_im(s
->pc
- offset
);
229 gen_exception_internal(excp
);
230 s
->is_jmp
= DISAS_EXC
;
233 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
,
234 uint32_t syndrome
, uint32_t target_el
)
236 gen_a64_set_pc_im(s
->pc
- offset
);
237 gen_exception(excp
, syndrome
, target_el
);
238 s
->is_jmp
= DISAS_EXC
;
241 static void gen_ss_advance(DisasContext
*s
)
243 /* If the singlestep state is Active-not-pending, advance to
248 gen_helper_clear_pstate_ss(cpu_env
);
252 static void gen_step_complete_exception(DisasContext
*s
)
254 /* We just completed step of an insn. Move from Active-not-pending
255 * to Active-pending, and then also take the swstep exception.
256 * This corresponds to making the (IMPDEF) choice to prioritize
257 * swstep exceptions over asynchronous exceptions taken to an exception
258 * level where debug is disabled. This choice has the advantage that
259 * we do not need to maintain internal state corresponding to the
260 * ISV/EX syndrome bits between completion of the step and generation
261 * of the exception, and our syndrome information is always correct.
264 gen_exception(EXCP_UDEF
, syn_swstep(s
->ss_same_el
, 1, s
->is_ldex
),
265 default_exception_el(s
));
266 s
->is_jmp
= DISAS_EXC
;
269 static inline bool use_goto_tb(DisasContext
*s
, int n
, uint64_t dest
)
271 /* No direct tb linking with singlestep (either QEMU's or the ARM
272 * debug architecture kind) or deterministic io
274 if (s
->singlestep_enabled
|| s
->ss_active
|| (s
->tb
->cflags
& CF_LAST_IO
)) {
278 #ifndef CONFIG_USER_ONLY
279 /* Only link tbs from inside the same guest page */
280 if ((s
->tb
->pc
& TARGET_PAGE_MASK
) != (dest
& TARGET_PAGE_MASK
)) {
288 static inline void gen_goto_tb(DisasContext
*s
, int n
, uint64_t dest
)
290 TranslationBlock
*tb
;
293 if (use_goto_tb(s
, n
, dest
)) {
295 gen_a64_set_pc_im(dest
);
296 tcg_gen_exit_tb((intptr_t)tb
+ n
);
297 s
->is_jmp
= DISAS_TB_JUMP
;
299 gen_a64_set_pc_im(dest
);
301 gen_step_complete_exception(s
);
302 } else if (s
->singlestep_enabled
) {
303 gen_exception_internal(EXCP_DEBUG
);
306 s
->is_jmp
= DISAS_TB_JUMP
;
311 static void disas_set_insn_syndrome(DisasContext
*s
, uint32_t syn
)
313 /* We don't need to save all of the syndrome so we mask and shift
314 * out uneeded bits to help the sleb128 encoder do a better job.
316 syn
&= ARM_INSN_START_WORD2_MASK
;
317 syn
>>= ARM_INSN_START_WORD2_SHIFT
;
319 /* We check and clear insn_start_idx to catch multiple updates. */
320 assert(s
->insn_start_idx
!= 0);
321 tcg_set_insn_param(s
->insn_start_idx
, 2, syn
);
322 s
->insn_start_idx
= 0;
325 static void unallocated_encoding(DisasContext
*s
)
327 /* Unallocated and reserved encodings are uncategorized */
328 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
329 default_exception_el(s
));
332 #define unsupported_encoding(s, insn) \
334 qemu_log_mask(LOG_UNIMP, \
335 "%s:%d: unsupported instruction encoding 0x%08x " \
336 "at pc=%016" PRIx64 "\n", \
337 __FILE__, __LINE__, insn, s->pc - 4); \
338 unallocated_encoding(s); \
341 static void init_tmp_a64_array(DisasContext
*s
)
343 #ifdef CONFIG_DEBUG_TCG
345 for (i
= 0; i
< ARRAY_SIZE(s
->tmp_a64
); i
++) {
346 TCGV_UNUSED_I64(s
->tmp_a64
[i
]);
349 s
->tmp_a64_count
= 0;
352 static void free_tmp_a64(DisasContext
*s
)
355 for (i
= 0; i
< s
->tmp_a64_count
; i
++) {
356 tcg_temp_free_i64(s
->tmp_a64
[i
]);
358 init_tmp_a64_array(s
);
361 static TCGv_i64
new_tmp_a64(DisasContext
*s
)
363 assert(s
->tmp_a64_count
< TMP_A64_MAX
);
364 return s
->tmp_a64
[s
->tmp_a64_count
++] = tcg_temp_new_i64();
367 static TCGv_i64
new_tmp_a64_zero(DisasContext
*s
)
369 TCGv_i64 t
= new_tmp_a64(s
);
370 tcg_gen_movi_i64(t
, 0);
375 * Register access functions
377 * These functions are used for directly accessing a register in where
378 * changes to the final register value are likely to be made. If you
379 * need to use a register for temporary calculation (e.g. index type
380 * operations) use the read_* form.
382 * B1.2.1 Register mappings
384 * In instruction register encoding 31 can refer to ZR (zero register) or
385 * the SP (stack pointer) depending on context. In QEMU's case we map SP
386 * to cpu_X[31] and ZR accesses to a temporary which can be discarded.
387 * This is the point of the _sp forms.
389 static TCGv_i64
cpu_reg(DisasContext
*s
, int reg
)
392 return new_tmp_a64_zero(s
);
398 /* register access for when 31 == SP */
399 static TCGv_i64
cpu_reg_sp(DisasContext
*s
, int reg
)
404 /* read a cpu register in 32bit/64bit mode. Returns a TCGv_i64
405 * representing the register contents. This TCGv is an auto-freed
406 * temporary so it need not be explicitly freed, and may be modified.
408 static TCGv_i64
read_cpu_reg(DisasContext
*s
, int reg
, int sf
)
410 TCGv_i64 v
= new_tmp_a64(s
);
413 tcg_gen_mov_i64(v
, cpu_X
[reg
]);
415 tcg_gen_ext32u_i64(v
, cpu_X
[reg
]);
418 tcg_gen_movi_i64(v
, 0);
423 static TCGv_i64
read_cpu_reg_sp(DisasContext
*s
, int reg
, int sf
)
425 TCGv_i64 v
= new_tmp_a64(s
);
427 tcg_gen_mov_i64(v
, cpu_X
[reg
]);
429 tcg_gen_ext32u_i64(v
, cpu_X
[reg
]);
434 /* We should have at some point before trying to access an FP register
435 * done the necessary access check, so assert that
436 * (a) we did the check and
437 * (b) we didn't then just plough ahead anyway if it failed.
438 * Print the instruction pattern in the abort message so we can figure
439 * out what we need to fix if a user encounters this problem in the wild.
441 static inline void assert_fp_access_checked(DisasContext
*s
)
443 #ifdef CONFIG_DEBUG_TCG
444 if (unlikely(!s
->fp_access_checked
|| s
->fp_excp_el
)) {
445 fprintf(stderr
, "target-arm: FP access check missing for "
446 "instruction 0x%08x\n", s
->insn
);
452 /* Return the offset into CPUARMState of an element of specified
453 * size, 'element' places in from the least significant end of
454 * the FP/vector register Qn.
456 static inline int vec_reg_offset(DisasContext
*s
, int regno
,
457 int element
, TCGMemOp size
)
459 int offs
= offsetof(CPUARMState
, vfp
.regs
[regno
* 2]);
460 #ifdef HOST_WORDS_BIGENDIAN
461 /* This is complicated slightly because vfp.regs[2n] is
462 * still the low half and vfp.regs[2n+1] the high half
463 * of the 128 bit vector, even on big endian systems.
464 * Calculate the offset assuming a fully bigendian 128 bits,
465 * then XOR to account for the order of the two 64 bit halves.
467 offs
+= (16 - ((element
+ 1) * (1 << size
)));
470 offs
+= element
* (1 << size
);
472 assert_fp_access_checked(s
);
476 /* Return the offset into CPUARMState of a slice (from
477 * the least significant end) of FP register Qn (ie
479 * (Note that this is not the same mapping as for A32; see cpu.h)
481 static inline int fp_reg_offset(DisasContext
*s
, int regno
, TCGMemOp size
)
483 int offs
= offsetof(CPUARMState
, vfp
.regs
[regno
* 2]);
484 #ifdef HOST_WORDS_BIGENDIAN
485 offs
+= (8 - (1 << size
));
487 assert_fp_access_checked(s
);
491 /* Offset of the high half of the 128 bit vector Qn */
492 static inline int fp_reg_hi_offset(DisasContext
*s
, int regno
)
494 assert_fp_access_checked(s
);
495 return offsetof(CPUARMState
, vfp
.regs
[regno
* 2 + 1]);
498 /* Convenience accessors for reading and writing single and double
499 * FP registers. Writing clears the upper parts of the associated
500 * 128 bit vector register, as required by the architecture.
501 * Note that unlike the GP register accessors, the values returned
502 * by the read functions must be manually freed.
504 static TCGv_i64
read_fp_dreg(DisasContext
*s
, int reg
)
506 TCGv_i64 v
= tcg_temp_new_i64();
508 tcg_gen_ld_i64(v
, cpu_env
, fp_reg_offset(s
, reg
, MO_64
));
512 static TCGv_i32
read_fp_sreg(DisasContext
*s
, int reg
)
514 TCGv_i32 v
= tcg_temp_new_i32();
516 tcg_gen_ld_i32(v
, cpu_env
, fp_reg_offset(s
, reg
, MO_32
));
520 static void write_fp_dreg(DisasContext
*s
, int reg
, TCGv_i64 v
)
522 TCGv_i64 tcg_zero
= tcg_const_i64(0);
524 tcg_gen_st_i64(v
, cpu_env
, fp_reg_offset(s
, reg
, MO_64
));
525 tcg_gen_st_i64(tcg_zero
, cpu_env
, fp_reg_hi_offset(s
, reg
));
526 tcg_temp_free_i64(tcg_zero
);
529 static void write_fp_sreg(DisasContext
*s
, int reg
, TCGv_i32 v
)
531 TCGv_i64 tmp
= tcg_temp_new_i64();
533 tcg_gen_extu_i32_i64(tmp
, v
);
534 write_fp_dreg(s
, reg
, tmp
);
535 tcg_temp_free_i64(tmp
);
538 static TCGv_ptr
get_fpstatus_ptr(void)
540 TCGv_ptr statusptr
= tcg_temp_new_ptr();
543 /* In A64 all instructions (both FP and Neon) use the FPCR;
544 * there is no equivalent of the A32 Neon "standard FPSCR value"
545 * and all operations use vfp.fp_status.
547 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
548 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
552 /* Set ZF and NF based on a 64 bit result. This is alas fiddlier
553 * than the 32 bit equivalent.
555 static inline void gen_set_NZ64(TCGv_i64 result
)
557 tcg_gen_extr_i64_i32(cpu_ZF
, cpu_NF
, result
);
558 tcg_gen_or_i32(cpu_ZF
, cpu_ZF
, cpu_NF
);
561 /* Set NZCV as for a logical operation: NZ as per result, CV cleared. */
562 static inline void gen_logic_CC(int sf
, TCGv_i64 result
)
565 gen_set_NZ64(result
);
567 tcg_gen_extrl_i64_i32(cpu_ZF
, result
);
568 tcg_gen_mov_i32(cpu_NF
, cpu_ZF
);
570 tcg_gen_movi_i32(cpu_CF
, 0);
571 tcg_gen_movi_i32(cpu_VF
, 0);
574 /* dest = T0 + T1; compute C, N, V and Z flags */
575 static void gen_add_CC(int sf
, TCGv_i64 dest
, TCGv_i64 t0
, TCGv_i64 t1
)
578 TCGv_i64 result
, flag
, tmp
;
579 result
= tcg_temp_new_i64();
580 flag
= tcg_temp_new_i64();
581 tmp
= tcg_temp_new_i64();
583 tcg_gen_movi_i64(tmp
, 0);
584 tcg_gen_add2_i64(result
, flag
, t0
, tmp
, t1
, tmp
);
586 tcg_gen_extrl_i64_i32(cpu_CF
, flag
);
588 gen_set_NZ64(result
);
590 tcg_gen_xor_i64(flag
, result
, t0
);
591 tcg_gen_xor_i64(tmp
, t0
, t1
);
592 tcg_gen_andc_i64(flag
, flag
, tmp
);
593 tcg_temp_free_i64(tmp
);
594 tcg_gen_extrh_i64_i32(cpu_VF
, flag
);
596 tcg_gen_mov_i64(dest
, result
);
597 tcg_temp_free_i64(result
);
598 tcg_temp_free_i64(flag
);
600 /* 32 bit arithmetic */
601 TCGv_i32 t0_32
= tcg_temp_new_i32();
602 TCGv_i32 t1_32
= tcg_temp_new_i32();
603 TCGv_i32 tmp
= tcg_temp_new_i32();
605 tcg_gen_movi_i32(tmp
, 0);
606 tcg_gen_extrl_i64_i32(t0_32
, t0
);
607 tcg_gen_extrl_i64_i32(t1_32
, t1
);
608 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0_32
, tmp
, t1_32
, tmp
);
609 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
610 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0_32
);
611 tcg_gen_xor_i32(tmp
, t0_32
, t1_32
);
612 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
613 tcg_gen_extu_i32_i64(dest
, cpu_NF
);
615 tcg_temp_free_i32(tmp
);
616 tcg_temp_free_i32(t0_32
);
617 tcg_temp_free_i32(t1_32
);
621 /* dest = T0 - T1; compute C, N, V and Z flags */
622 static void gen_sub_CC(int sf
, TCGv_i64 dest
, TCGv_i64 t0
, TCGv_i64 t1
)
625 /* 64 bit arithmetic */
626 TCGv_i64 result
, flag
, tmp
;
628 result
= tcg_temp_new_i64();
629 flag
= tcg_temp_new_i64();
630 tcg_gen_sub_i64(result
, t0
, t1
);
632 gen_set_NZ64(result
);
634 tcg_gen_setcond_i64(TCG_COND_GEU
, flag
, t0
, t1
);
635 tcg_gen_extrl_i64_i32(cpu_CF
, flag
);
637 tcg_gen_xor_i64(flag
, result
, t0
);
638 tmp
= tcg_temp_new_i64();
639 tcg_gen_xor_i64(tmp
, t0
, t1
);
640 tcg_gen_and_i64(flag
, flag
, tmp
);
641 tcg_temp_free_i64(tmp
);
642 tcg_gen_extrh_i64_i32(cpu_VF
, flag
);
643 tcg_gen_mov_i64(dest
, result
);
644 tcg_temp_free_i64(flag
);
645 tcg_temp_free_i64(result
);
647 /* 32 bit arithmetic */
648 TCGv_i32 t0_32
= tcg_temp_new_i32();
649 TCGv_i32 t1_32
= tcg_temp_new_i32();
652 tcg_gen_extrl_i64_i32(t0_32
, t0
);
653 tcg_gen_extrl_i64_i32(t1_32
, t1
);
654 tcg_gen_sub_i32(cpu_NF
, t0_32
, t1_32
);
655 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
656 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_CF
, t0_32
, t1_32
);
657 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0_32
);
658 tmp
= tcg_temp_new_i32();
659 tcg_gen_xor_i32(tmp
, t0_32
, t1_32
);
660 tcg_temp_free_i32(t0_32
);
661 tcg_temp_free_i32(t1_32
);
662 tcg_gen_and_i32(cpu_VF
, cpu_VF
, tmp
);
663 tcg_temp_free_i32(tmp
);
664 tcg_gen_extu_i32_i64(dest
, cpu_NF
);
668 /* dest = T0 + T1 + CF; do not compute flags. */
669 static void gen_adc(int sf
, TCGv_i64 dest
, TCGv_i64 t0
, TCGv_i64 t1
)
671 TCGv_i64 flag
= tcg_temp_new_i64();
672 tcg_gen_extu_i32_i64(flag
, cpu_CF
);
673 tcg_gen_add_i64(dest
, t0
, t1
);
674 tcg_gen_add_i64(dest
, dest
, flag
);
675 tcg_temp_free_i64(flag
);
678 tcg_gen_ext32u_i64(dest
, dest
);
682 /* dest = T0 + T1 + CF; compute C, N, V and Z flags. */
683 static void gen_adc_CC(int sf
, TCGv_i64 dest
, TCGv_i64 t0
, TCGv_i64 t1
)
686 TCGv_i64 result
, cf_64
, vf_64
, tmp
;
687 result
= tcg_temp_new_i64();
688 cf_64
= tcg_temp_new_i64();
689 vf_64
= tcg_temp_new_i64();
690 tmp
= tcg_const_i64(0);
692 tcg_gen_extu_i32_i64(cf_64
, cpu_CF
);
693 tcg_gen_add2_i64(result
, cf_64
, t0
, tmp
, cf_64
, tmp
);
694 tcg_gen_add2_i64(result
, cf_64
, result
, cf_64
, t1
, tmp
);
695 tcg_gen_extrl_i64_i32(cpu_CF
, cf_64
);
696 gen_set_NZ64(result
);
698 tcg_gen_xor_i64(vf_64
, result
, t0
);
699 tcg_gen_xor_i64(tmp
, t0
, t1
);
700 tcg_gen_andc_i64(vf_64
, vf_64
, tmp
);
701 tcg_gen_extrh_i64_i32(cpu_VF
, vf_64
);
703 tcg_gen_mov_i64(dest
, result
);
705 tcg_temp_free_i64(tmp
);
706 tcg_temp_free_i64(vf_64
);
707 tcg_temp_free_i64(cf_64
);
708 tcg_temp_free_i64(result
);
710 TCGv_i32 t0_32
, t1_32
, tmp
;
711 t0_32
= tcg_temp_new_i32();
712 t1_32
= tcg_temp_new_i32();
713 tmp
= tcg_const_i32(0);
715 tcg_gen_extrl_i64_i32(t0_32
, t0
);
716 tcg_gen_extrl_i64_i32(t1_32
, t1
);
717 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0_32
, tmp
, cpu_CF
, tmp
);
718 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, cpu_NF
, cpu_CF
, t1_32
, tmp
);
720 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
721 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0_32
);
722 tcg_gen_xor_i32(tmp
, t0_32
, t1_32
);
723 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
724 tcg_gen_extu_i32_i64(dest
, cpu_NF
);
726 tcg_temp_free_i32(tmp
);
727 tcg_temp_free_i32(t1_32
);
728 tcg_temp_free_i32(t0_32
);
733 * Load/Store generators
737 * Store from GPR register to memory.
739 static void do_gpr_st_memidx(DisasContext
*s
, TCGv_i64 source
,
740 TCGv_i64 tcg_addr
, int size
, int memidx
,
742 unsigned int iss_srt
,
743 bool iss_sf
, bool iss_ar
)
746 tcg_gen_qemu_st_i64(source
, tcg_addr
, memidx
, s
->be_data
+ size
);
751 syn
= syn_data_abort_with_iss(0,
757 0, 0, 0, 0, 0, false);
758 disas_set_insn_syndrome(s
, syn
);
762 static void do_gpr_st(DisasContext
*s
, TCGv_i64 source
,
763 TCGv_i64 tcg_addr
, int size
,
765 unsigned int iss_srt
,
766 bool iss_sf
, bool iss_ar
)
768 do_gpr_st_memidx(s
, source
, tcg_addr
, size
, get_mem_index(s
),
769 iss_valid
, iss_srt
, iss_sf
, iss_ar
);
773 * Load from memory to GPR register
775 static void do_gpr_ld_memidx(DisasContext
*s
,
776 TCGv_i64 dest
, TCGv_i64 tcg_addr
,
777 int size
, bool is_signed
,
778 bool extend
, int memidx
,
779 bool iss_valid
, unsigned int iss_srt
,
780 bool iss_sf
, bool iss_ar
)
782 TCGMemOp memop
= s
->be_data
+ size
;
790 tcg_gen_qemu_ld_i64(dest
, tcg_addr
, memidx
, memop
);
792 if (extend
&& is_signed
) {
794 tcg_gen_ext32u_i64(dest
, dest
);
800 syn
= syn_data_abort_with_iss(0,
806 0, 0, 0, 0, 0, false);
807 disas_set_insn_syndrome(s
, syn
);
811 static void do_gpr_ld(DisasContext
*s
,
812 TCGv_i64 dest
, TCGv_i64 tcg_addr
,
813 int size
, bool is_signed
, bool extend
,
814 bool iss_valid
, unsigned int iss_srt
,
815 bool iss_sf
, bool iss_ar
)
817 do_gpr_ld_memidx(s
, dest
, tcg_addr
, size
, is_signed
, extend
,
819 iss_valid
, iss_srt
, iss_sf
, iss_ar
);
823 * Store from FP register to memory
825 static void do_fp_st(DisasContext
*s
, int srcidx
, TCGv_i64 tcg_addr
, int size
)
827 /* This writes the bottom N bits of a 128 bit wide vector to memory */
828 TCGv_i64 tmp
= tcg_temp_new_i64();
829 tcg_gen_ld_i64(tmp
, cpu_env
, fp_reg_offset(s
, srcidx
, MO_64
));
831 tcg_gen_qemu_st_i64(tmp
, tcg_addr
, get_mem_index(s
),
834 bool be
= s
->be_data
== MO_BE
;
835 TCGv_i64 tcg_hiaddr
= tcg_temp_new_i64();
837 tcg_gen_addi_i64(tcg_hiaddr
, tcg_addr
, 8);
838 tcg_gen_qemu_st_i64(tmp
, be ? tcg_hiaddr
: tcg_addr
, get_mem_index(s
),
840 tcg_gen_ld_i64(tmp
, cpu_env
, fp_reg_hi_offset(s
, srcidx
));
841 tcg_gen_qemu_st_i64(tmp
, be ? tcg_addr
: tcg_hiaddr
, get_mem_index(s
),
843 tcg_temp_free_i64(tcg_hiaddr
);
846 tcg_temp_free_i64(tmp
);
850 * Load from memory to FP register
852 static void do_fp_ld(DisasContext
*s
, int destidx
, TCGv_i64 tcg_addr
, int size
)
854 /* This always zero-extends and writes to a full 128 bit wide vector */
855 TCGv_i64 tmplo
= tcg_temp_new_i64();
859 TCGMemOp memop
= s
->be_data
+ size
;
860 tmphi
= tcg_const_i64(0);
861 tcg_gen_qemu_ld_i64(tmplo
, tcg_addr
, get_mem_index(s
), memop
);
863 bool be
= s
->be_data
== MO_BE
;
866 tmphi
= tcg_temp_new_i64();
867 tcg_hiaddr
= tcg_temp_new_i64();
869 tcg_gen_addi_i64(tcg_hiaddr
, tcg_addr
, 8);
870 tcg_gen_qemu_ld_i64(tmplo
, be ? tcg_hiaddr
: tcg_addr
, get_mem_index(s
),
872 tcg_gen_qemu_ld_i64(tmphi
, be ? tcg_addr
: tcg_hiaddr
, get_mem_index(s
),
874 tcg_temp_free_i64(tcg_hiaddr
);
877 tcg_gen_st_i64(tmplo
, cpu_env
, fp_reg_offset(s
, destidx
, MO_64
));
878 tcg_gen_st_i64(tmphi
, cpu_env
, fp_reg_hi_offset(s
, destidx
));
880 tcg_temp_free_i64(tmplo
);
881 tcg_temp_free_i64(tmphi
);
885 * Vector load/store helpers.
887 * The principal difference between this and a FP load is that we don't
888 * zero extend as we are filling a partial chunk of the vector register.
889 * These functions don't support 128 bit loads/stores, which would be
890 * normal load/store operations.
892 * The _i32 versions are useful when operating on 32 bit quantities
893 * (eg for floating point single or using Neon helper functions).
896 /* Get value of an element within a vector register */
897 static void read_vec_element(DisasContext
*s
, TCGv_i64 tcg_dest
, int srcidx
,
898 int element
, TCGMemOp memop
)
900 int vect_off
= vec_reg_offset(s
, srcidx
, element
, memop
& MO_SIZE
);
903 tcg_gen_ld8u_i64(tcg_dest
, cpu_env
, vect_off
);
906 tcg_gen_ld16u_i64(tcg_dest
, cpu_env
, vect_off
);
909 tcg_gen_ld32u_i64(tcg_dest
, cpu_env
, vect_off
);
912 tcg_gen_ld8s_i64(tcg_dest
, cpu_env
, vect_off
);
915 tcg_gen_ld16s_i64(tcg_dest
, cpu_env
, vect_off
);
918 tcg_gen_ld32s_i64(tcg_dest
, cpu_env
, vect_off
);
922 tcg_gen_ld_i64(tcg_dest
, cpu_env
, vect_off
);
925 g_assert_not_reached();
929 static void read_vec_element_i32(DisasContext
*s
, TCGv_i32 tcg_dest
, int srcidx
,
930 int element
, TCGMemOp memop
)
932 int vect_off
= vec_reg_offset(s
, srcidx
, element
, memop
& MO_SIZE
);
935 tcg_gen_ld8u_i32(tcg_dest
, cpu_env
, vect_off
);
938 tcg_gen_ld16u_i32(tcg_dest
, cpu_env
, vect_off
);
941 tcg_gen_ld8s_i32(tcg_dest
, cpu_env
, vect_off
);
944 tcg_gen_ld16s_i32(tcg_dest
, cpu_env
, vect_off
);
948 tcg_gen_ld_i32(tcg_dest
, cpu_env
, vect_off
);
951 g_assert_not_reached();
955 /* Set value of an element within a vector register */
956 static void write_vec_element(DisasContext
*s
, TCGv_i64 tcg_src
, int destidx
,
957 int element
, TCGMemOp memop
)
959 int vect_off
= vec_reg_offset(s
, destidx
, element
, memop
& MO_SIZE
);
962 tcg_gen_st8_i64(tcg_src
, cpu_env
, vect_off
);
965 tcg_gen_st16_i64(tcg_src
, cpu_env
, vect_off
);
968 tcg_gen_st32_i64(tcg_src
, cpu_env
, vect_off
);
971 tcg_gen_st_i64(tcg_src
, cpu_env
, vect_off
);
974 g_assert_not_reached();
978 static void write_vec_element_i32(DisasContext
*s
, TCGv_i32 tcg_src
,
979 int destidx
, int element
, TCGMemOp memop
)
981 int vect_off
= vec_reg_offset(s
, destidx
, element
, memop
& MO_SIZE
);
984 tcg_gen_st8_i32(tcg_src
, cpu_env
, vect_off
);
987 tcg_gen_st16_i32(tcg_src
, cpu_env
, vect_off
);
990 tcg_gen_st_i32(tcg_src
, cpu_env
, vect_off
);
993 g_assert_not_reached();
997 /* Clear the high 64 bits of a 128 bit vector (in general non-quad
998 * vector ops all need to do this).
1000 static void clear_vec_high(DisasContext
*s
, int rd
)
1002 TCGv_i64 tcg_zero
= tcg_const_i64(0);
1004 write_vec_element(s
, tcg_zero
, rd
, 1, MO_64
);
1005 tcg_temp_free_i64(tcg_zero
);
1008 /* Store from vector register to memory */
1009 static void do_vec_st(DisasContext
*s
, int srcidx
, int element
,
1010 TCGv_i64 tcg_addr
, int size
)
1012 TCGMemOp memop
= s
->be_data
+ size
;
1013 TCGv_i64 tcg_tmp
= tcg_temp_new_i64();
1015 read_vec_element(s
, tcg_tmp
, srcidx
, element
, size
);
1016 tcg_gen_qemu_st_i64(tcg_tmp
, tcg_addr
, get_mem_index(s
), memop
);
1018 tcg_temp_free_i64(tcg_tmp
);
1021 /* Load from memory to vector register */
1022 static void do_vec_ld(DisasContext
*s
, int destidx
, int element
,
1023 TCGv_i64 tcg_addr
, int size
)
1025 TCGMemOp memop
= s
->be_data
+ size
;
1026 TCGv_i64 tcg_tmp
= tcg_temp_new_i64();
1028 tcg_gen_qemu_ld_i64(tcg_tmp
, tcg_addr
, get_mem_index(s
), memop
);
1029 write_vec_element(s
, tcg_tmp
, destidx
, element
, size
);
1031 tcg_temp_free_i64(tcg_tmp
);
1034 /* Check that FP/Neon access is enabled. If it is, return
1035 * true. If not, emit code to generate an appropriate exception,
1036 * and return false; the caller should not emit any code for
1037 * the instruction. Note that this check must happen after all
1038 * unallocated-encoding checks (otherwise the syndrome information
1039 * for the resulting exception will be incorrect).
1041 static inline bool fp_access_check(DisasContext
*s
)
1043 assert(!s
->fp_access_checked
);
1044 s
->fp_access_checked
= true;
1046 if (!s
->fp_excp_el
) {
1050 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_fp_access_trap(1, 0xe, false),
1056 * This utility function is for doing register extension with an
1057 * optional shift. You will likely want to pass a temporary for the
1058 * destination register. See DecodeRegExtend() in the ARM ARM.
1060 static void ext_and_shift_reg(TCGv_i64 tcg_out
, TCGv_i64 tcg_in
,
1061 int option
, unsigned int shift
)
1063 int extsize
= extract32(option
, 0, 2);
1064 bool is_signed
= extract32(option
, 2, 1);
1069 tcg_gen_ext8s_i64(tcg_out
, tcg_in
);
1072 tcg_gen_ext16s_i64(tcg_out
, tcg_in
);
1075 tcg_gen_ext32s_i64(tcg_out
, tcg_in
);
1078 tcg_gen_mov_i64(tcg_out
, tcg_in
);
1084 tcg_gen_ext8u_i64(tcg_out
, tcg_in
);
1087 tcg_gen_ext16u_i64(tcg_out
, tcg_in
);
1090 tcg_gen_ext32u_i64(tcg_out
, tcg_in
);
1093 tcg_gen_mov_i64(tcg_out
, tcg_in
);
1099 tcg_gen_shli_i64(tcg_out
, tcg_out
, shift
);
1103 static inline void gen_check_sp_alignment(DisasContext
*s
)
1105 /* The AArch64 architecture mandates that (if enabled via PSTATE
1106 * or SCTLR bits) there is a check that SP is 16-aligned on every
1107 * SP-relative load or store (with an exception generated if it is not).
1108 * In line with general QEMU practice regarding misaligned accesses,
1109 * we omit these checks for the sake of guest program performance.
1110 * This function is provided as a hook so we can more easily add these
1111 * checks in future (possibly as a "favour catching guest program bugs
1112 * over speed" user selectable option).
1117 * This provides a simple table based table lookup decoder. It is
1118 * intended to be used when the relevant bits for decode are too
1119 * awkwardly placed and switch/if based logic would be confusing and
1120 * deeply nested. Since it's a linear search through the table, tables
1121 * should be kept small.
1123 * It returns the first handler where insn & mask == pattern, or
1124 * NULL if there is no match.
1125 * The table is terminated by an empty mask (i.e. 0)
1127 static inline AArch64DecodeFn
*lookup_disas_fn(const AArch64DecodeTable
*table
,
1130 const AArch64DecodeTable
*tptr
= table
;
1132 while (tptr
->mask
) {
1133 if ((insn
& tptr
->mask
) == tptr
->pattern
) {
1134 return tptr
->disas_fn
;
1142 * the instruction disassembly implemented here matches
1143 * the instruction encoding classifications in chapter 3 (C3)
1144 * of the ARM Architecture Reference Manual (DDI0487A_a)
1147 /* C3.2.7 Unconditional branch (immediate)
1149 * +----+-----------+-------------------------------------+
1150 * | op | 0 0 1 0 1 | imm26 |
1151 * +----+-----------+-------------------------------------+
1153 static void disas_uncond_b_imm(DisasContext
*s
, uint32_t insn
)
1155 uint64_t addr
= s
->pc
+ sextract32(insn
, 0, 26) * 4 - 4;
1157 if (insn
& (1U << 31)) {
1158 /* C5.6.26 BL Branch with link */
1159 tcg_gen_movi_i64(cpu_reg(s
, 30), s
->pc
);
1162 /* C5.6.20 B Branch / C5.6.26 BL Branch with link */
1163 gen_goto_tb(s
, 0, addr
);
1166 /* C3.2.1 Compare & branch (immediate)
1167 * 31 30 25 24 23 5 4 0
1168 * +----+-------------+----+---------------------+--------+
1169 * | sf | 0 1 1 0 1 0 | op | imm19 | Rt |
1170 * +----+-------------+----+---------------------+--------+
1172 static void disas_comp_b_imm(DisasContext
*s
, uint32_t insn
)
1174 unsigned int sf
, op
, rt
;
1176 TCGLabel
*label_match
;
1179 sf
= extract32(insn
, 31, 1);
1180 op
= extract32(insn
, 24, 1); /* 0: CBZ; 1: CBNZ */
1181 rt
= extract32(insn
, 0, 5);
1182 addr
= s
->pc
+ sextract32(insn
, 5, 19) * 4 - 4;
1184 tcg_cmp
= read_cpu_reg(s
, rt
, sf
);
1185 label_match
= gen_new_label();
1187 tcg_gen_brcondi_i64(op ? TCG_COND_NE
: TCG_COND_EQ
,
1188 tcg_cmp
, 0, label_match
);
1190 gen_goto_tb(s
, 0, s
->pc
);
1191 gen_set_label(label_match
);
1192 gen_goto_tb(s
, 1, addr
);
1195 /* C3.2.5 Test & branch (immediate)
1196 * 31 30 25 24 23 19 18 5 4 0
1197 * +----+-------------+----+-------+-------------+------+
1198 * | b5 | 0 1 1 0 1 1 | op | b40 | imm14 | Rt |
1199 * +----+-------------+----+-------+-------------+------+
1201 static void disas_test_b_imm(DisasContext
*s
, uint32_t insn
)
1203 unsigned int bit_pos
, op
, rt
;
1205 TCGLabel
*label_match
;
1208 bit_pos
= (extract32(insn
, 31, 1) << 5) | extract32(insn
, 19, 5);
1209 op
= extract32(insn
, 24, 1); /* 0: TBZ; 1: TBNZ */
1210 addr
= s
->pc
+ sextract32(insn
, 5, 14) * 4 - 4;
1211 rt
= extract32(insn
, 0, 5);
1213 tcg_cmp
= tcg_temp_new_i64();
1214 tcg_gen_andi_i64(tcg_cmp
, cpu_reg(s
, rt
), (1ULL << bit_pos
));
1215 label_match
= gen_new_label();
1216 tcg_gen_brcondi_i64(op ? TCG_COND_NE
: TCG_COND_EQ
,
1217 tcg_cmp
, 0, label_match
);
1218 tcg_temp_free_i64(tcg_cmp
);
1219 gen_goto_tb(s
, 0, s
->pc
);
1220 gen_set_label(label_match
);
1221 gen_goto_tb(s
, 1, addr
);
1224 /* C3.2.2 / C5.6.19 Conditional branch (immediate)
1225 * 31 25 24 23 5 4 3 0
1226 * +---------------+----+---------------------+----+------+
1227 * | 0 1 0 1 0 1 0 | o1 | imm19 | o0 | cond |
1228 * +---------------+----+---------------------+----+------+
1230 static void disas_cond_b_imm(DisasContext
*s
, uint32_t insn
)
1235 if ((insn
& (1 << 4)) || (insn
& (1 << 24))) {
1236 unallocated_encoding(s
);
1239 addr
= s
->pc
+ sextract32(insn
, 5, 19) * 4 - 4;
1240 cond
= extract32(insn
, 0, 4);
1243 /* genuinely conditional branches */
1244 TCGLabel
*label_match
= gen_new_label();
1245 arm_gen_test_cc(cond
, label_match
);
1246 gen_goto_tb(s
, 0, s
->pc
);
1247 gen_set_label(label_match
);
1248 gen_goto_tb(s
, 1, addr
);
1250 /* 0xe and 0xf are both "always" conditions */
1251 gen_goto_tb(s
, 0, addr
);
1256 static void handle_hint(DisasContext
*s
, uint32_t insn
,
1257 unsigned int op1
, unsigned int op2
, unsigned int crm
)
1259 unsigned int selector
= crm
<< 3 | op2
;
1262 unallocated_encoding(s
);
1270 s
->is_jmp
= DISAS_WFI
;
1273 s
->is_jmp
= DISAS_YIELD
;
1276 s
->is_jmp
= DISAS_WFE
;
1280 /* we treat all as NOP at least for now */
1283 /* default specified as NOP equivalent */
1288 static void gen_clrex(DisasContext
*s
, uint32_t insn
)
1290 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
1293 /* CLREX, DSB, DMB, ISB */
1294 static void handle_sync(DisasContext
*s
, uint32_t insn
,
1295 unsigned int op1
, unsigned int op2
, unsigned int crm
)
1298 unallocated_encoding(s
);
1308 /* We don't emulate caches so barriers are no-ops */
1311 /* We need to break the TB after this insn to execute
1312 * a self-modified code correctly and also to take
1313 * any pending interrupts immediately.
1315 s
->is_jmp
= DISAS_UPDATE
;
1318 unallocated_encoding(s
);
1323 /* C5.6.130 MSR (immediate) - move immediate to processor state field */
1324 static void handle_msr_i(DisasContext
*s
, uint32_t insn
,
1325 unsigned int op1
, unsigned int op2
, unsigned int crm
)
1327 int op
= op1
<< 3 | op2
;
1329 case 0x05: /* SPSel */
1330 if (s
->current_el
== 0) {
1331 unallocated_encoding(s
);
1335 case 0x1e: /* DAIFSet */
1336 case 0x1f: /* DAIFClear */
1338 TCGv_i32 tcg_imm
= tcg_const_i32(crm
);
1339 TCGv_i32 tcg_op
= tcg_const_i32(op
);
1340 gen_a64_set_pc_im(s
->pc
- 4);
1341 gen_helper_msr_i_pstate(cpu_env
, tcg_op
, tcg_imm
);
1342 tcg_temp_free_i32(tcg_imm
);
1343 tcg_temp_free_i32(tcg_op
);
1344 s
->is_jmp
= DISAS_UPDATE
;
1348 unallocated_encoding(s
);
1353 static void gen_get_nzcv(TCGv_i64 tcg_rt
)
1355 TCGv_i32 tmp
= tcg_temp_new_i32();
1356 TCGv_i32 nzcv
= tcg_temp_new_i32();
1358 /* build bit 31, N */
1359 tcg_gen_andi_i32(nzcv
, cpu_NF
, (1U << 31));
1360 /* build bit 30, Z */
1361 tcg_gen_setcondi_i32(TCG_COND_EQ
, tmp
, cpu_ZF
, 0);
1362 tcg_gen_deposit_i32(nzcv
, nzcv
, tmp
, 30, 1);
1363 /* build bit 29, C */
1364 tcg_gen_deposit_i32(nzcv
, nzcv
, cpu_CF
, 29, 1);
1365 /* build bit 28, V */
1366 tcg_gen_shri_i32(tmp
, cpu_VF
, 31);
1367 tcg_gen_deposit_i32(nzcv
, nzcv
, tmp
, 28, 1);
1368 /* generate result */
1369 tcg_gen_extu_i32_i64(tcg_rt
, nzcv
);
1371 tcg_temp_free_i32(nzcv
);
1372 tcg_temp_free_i32(tmp
);
1375 static void gen_set_nzcv(TCGv_i64 tcg_rt
)
1378 TCGv_i32 nzcv
= tcg_temp_new_i32();
1380 /* take NZCV from R[t] */
1381 tcg_gen_extrl_i64_i32(nzcv
, tcg_rt
);
1384 tcg_gen_andi_i32(cpu_NF
, nzcv
, (1U << 31));
1386 tcg_gen_andi_i32(cpu_ZF
, nzcv
, (1 << 30));
1387 tcg_gen_setcondi_i32(TCG_COND_EQ
, cpu_ZF
, cpu_ZF
, 0);
1389 tcg_gen_andi_i32(cpu_CF
, nzcv
, (1 << 29));
1390 tcg_gen_shri_i32(cpu_CF
, cpu_CF
, 29);
1392 tcg_gen_andi_i32(cpu_VF
, nzcv
, (1 << 28));
1393 tcg_gen_shli_i32(cpu_VF
, cpu_VF
, 3);
1394 tcg_temp_free_i32(nzcv
);
1397 /* C5.6.129 MRS - move from system register
1398 * C5.6.131 MSR (register) - move to system register
1401 * These are all essentially the same insn in 'read' and 'write'
1402 * versions, with varying op0 fields.
1404 static void handle_sys(DisasContext
*s
, uint32_t insn
, bool isread
,
1405 unsigned int op0
, unsigned int op1
, unsigned int op2
,
1406 unsigned int crn
, unsigned int crm
, unsigned int rt
)
1408 const ARMCPRegInfo
*ri
;
1411 ri
= get_arm_cp_reginfo(s
->cp_regs
,
1412 ENCODE_AA64_CP_REG(CP_REG_ARM64_SYSREG_CP
,
1413 crn
, crm
, op0
, op1
, op2
));
1416 /* Unknown register; this might be a guest error or a QEMU
1417 * unimplemented feature.
1419 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch64 "
1420 "system register op0:%d op1:%d crn:%d crm:%d op2:%d\n",
1421 isread ?
"read" : "write", op0
, op1
, crn
, crm
, op2
);
1422 unallocated_encoding(s
);
1426 /* Check access permissions */
1427 if (!cp_access_ok(s
->current_el
, ri
, isread
)) {
1428 unallocated_encoding(s
);
1433 /* Emit code to perform further access permissions checks at
1434 * runtime; this may result in an exception.
1437 TCGv_i32 tcg_syn
, tcg_isread
;
1440 gen_a64_set_pc_im(s
->pc
- 4);
1441 tmpptr
= tcg_const_ptr(ri
);
1442 syndrome
= syn_aa64_sysregtrap(op0
, op1
, op2
, crn
, crm
, rt
, isread
);
1443 tcg_syn
= tcg_const_i32(syndrome
);
1444 tcg_isread
= tcg_const_i32(isread
);
1445 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
, tcg_isread
);
1446 tcg_temp_free_ptr(tmpptr
);
1447 tcg_temp_free_i32(tcg_syn
);
1448 tcg_temp_free_i32(tcg_isread
);
1451 /* Handle special cases first */
1452 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
1456 tcg_rt
= cpu_reg(s
, rt
);
1458 gen_get_nzcv(tcg_rt
);
1460 gen_set_nzcv(tcg_rt
);
1463 case ARM_CP_CURRENTEL
:
1464 /* Reads as current EL value from pstate, which is
1465 * guaranteed to be constant by the tb flags.
1467 tcg_rt
= cpu_reg(s
, rt
);
1468 tcg_gen_movi_i64(tcg_rt
, s
->current_el
<< 2);
1471 /* Writes clear the aligned block of memory which rt points into. */
1472 tcg_rt
= cpu_reg(s
, rt
);
1473 gen_helper_dc_zva(cpu_env
, tcg_rt
);
1479 if ((s
->tb
->cflags
& CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
1483 tcg_rt
= cpu_reg(s
, rt
);
1486 if (ri
->type
& ARM_CP_CONST
) {
1487 tcg_gen_movi_i64(tcg_rt
, ri
->resetvalue
);
1488 } else if (ri
->readfn
) {
1490 tmpptr
= tcg_const_ptr(ri
);
1491 gen_helper_get_cp_reg64(tcg_rt
, cpu_env
, tmpptr
);
1492 tcg_temp_free_ptr(tmpptr
);
1494 tcg_gen_ld_i64(tcg_rt
, cpu_env
, ri
->fieldoffset
);
1497 if (ri
->type
& ARM_CP_CONST
) {
1498 /* If not forbidden by access permissions, treat as WI */
1500 } else if (ri
->writefn
) {
1502 tmpptr
= tcg_const_ptr(ri
);
1503 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tcg_rt
);
1504 tcg_temp_free_ptr(tmpptr
);
1506 tcg_gen_st_i64(tcg_rt
, cpu_env
, ri
->fieldoffset
);
1510 if ((s
->tb
->cflags
& CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
1511 /* I/O operations must end the TB here (whether read or write) */
1513 s
->is_jmp
= DISAS_UPDATE
;
1514 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
1515 /* We default to ending the TB on a coprocessor register write,
1516 * but allow this to be suppressed by the register definition
1517 * (usually only necessary to work around guest bugs).
1519 s
->is_jmp
= DISAS_UPDATE
;
1524 * 31 22 21 20 19 18 16 15 12 11 8 7 5 4 0
1525 * +---------------------+---+-----+-----+-------+-------+-----+------+
1526 * | 1 1 0 1 0 1 0 1 0 0 | L | op0 | op1 | CRn | CRm | op2 | Rt |
1527 * +---------------------+---+-----+-----+-------+-------+-----+------+
1529 static void disas_system(DisasContext
*s
, uint32_t insn
)
1531 unsigned int l
, op0
, op1
, crn
, crm
, op2
, rt
;
1532 l
= extract32(insn
, 21, 1);
1533 op0
= extract32(insn
, 19, 2);
1534 op1
= extract32(insn
, 16, 3);
1535 crn
= extract32(insn
, 12, 4);
1536 crm
= extract32(insn
, 8, 4);
1537 op2
= extract32(insn
, 5, 3);
1538 rt
= extract32(insn
, 0, 5);
1541 if (l
|| rt
!= 31) {
1542 unallocated_encoding(s
);
1546 case 2: /* C5.6.68 HINT */
1547 handle_hint(s
, insn
, op1
, op2
, crm
);
1549 case 3: /* CLREX, DSB, DMB, ISB */
1550 handle_sync(s
, insn
, op1
, op2
, crm
);
1552 case 4: /* C5.6.130 MSR (immediate) */
1553 handle_msr_i(s
, insn
, op1
, op2
, crm
);
1556 unallocated_encoding(s
);
1561 handle_sys(s
, insn
, l
, op0
, op1
, op2
, crn
, crm
, rt
);
1564 /* C3.2.3 Exception generation
1566 * 31 24 23 21 20 5 4 2 1 0
1567 * +-----------------+-----+------------------------+-----+----+
1568 * | 1 1 0 1 0 1 0 0 | opc | imm16 | op2 | LL |
1569 * +-----------------------+------------------------+----------+
1571 static void disas_exc(DisasContext
*s
, uint32_t insn
)
1573 int opc
= extract32(insn
, 21, 3);
1574 int op2_ll
= extract32(insn
, 0, 5);
1575 int imm16
= extract32(insn
, 5, 16);
1580 /* For SVC, HVC and SMC we advance the single-step state
1581 * machine before taking the exception. This is architecturally
1582 * mandated, to ensure that single-stepping a system call
1583 * instruction works properly.
1588 gen_exception_insn(s
, 0, EXCP_SWI
, syn_aa64_svc(imm16
),
1589 default_exception_el(s
));
1592 if (s
->current_el
== 0) {
1593 unallocated_encoding(s
);
1596 /* The pre HVC helper handles cases when HVC gets trapped
1597 * as an undefined insn by runtime configuration.
1599 gen_a64_set_pc_im(s
->pc
- 4);
1600 gen_helper_pre_hvc(cpu_env
);
1602 gen_exception_insn(s
, 0, EXCP_HVC
, syn_aa64_hvc(imm16
), 2);
1605 if (s
->current_el
== 0) {
1606 unallocated_encoding(s
);
1609 gen_a64_set_pc_im(s
->pc
- 4);
1610 tmp
= tcg_const_i32(syn_aa64_smc(imm16
));
1611 gen_helper_pre_smc(cpu_env
, tmp
);
1612 tcg_temp_free_i32(tmp
);
1614 gen_exception_insn(s
, 0, EXCP_SMC
, syn_aa64_smc(imm16
), 3);
1617 unallocated_encoding(s
);
1623 unallocated_encoding(s
);
1627 gen_exception_insn(s
, 4, EXCP_BKPT
, syn_aa64_bkpt(imm16
),
1628 default_exception_el(s
));
1632 unallocated_encoding(s
);
1635 /* HLT. This has two purposes.
1636 * Architecturally, it is an external halting debug instruction.
1637 * Since QEMU doesn't implement external debug, we treat this as
1638 * it is required for halting debug disabled: it will UNDEF.
1639 * Secondly, "HLT 0xf000" is the A64 semihosting syscall instruction.
1641 if (semihosting_enabled() && imm16
== 0xf000) {
1642 #ifndef CONFIG_USER_ONLY
1643 /* In system mode, don't allow userspace access to semihosting,
1644 * to provide some semblance of security (and for consistency
1645 * with our 32-bit semihosting).
1647 if (s
->current_el
== 0) {
1648 unsupported_encoding(s
, insn
);
1652 gen_exception_internal_insn(s
, 0, EXCP_SEMIHOST
);
1654 unsupported_encoding(s
, insn
);
1658 if (op2_ll
< 1 || op2_ll
> 3) {
1659 unallocated_encoding(s
);
1662 /* DCPS1, DCPS2, DCPS3 */
1663 unsupported_encoding(s
, insn
);
1666 unallocated_encoding(s
);
1671 /* C3.2.7 Unconditional branch (register)
1672 * 31 25 24 21 20 16 15 10 9 5 4 0
1673 * +---------------+-------+-------+-------+------+-------+
1674 * | 1 1 0 1 0 1 1 | opc | op2 | op3 | Rn | op4 |
1675 * +---------------+-------+-------+-------+------+-------+
1677 static void disas_uncond_b_reg(DisasContext
*s
, uint32_t insn
)
1679 unsigned int opc
, op2
, op3
, rn
, op4
;
1681 opc
= extract32(insn
, 21, 4);
1682 op2
= extract32(insn
, 16, 5);
1683 op3
= extract32(insn
, 10, 6);
1684 rn
= extract32(insn
, 5, 5);
1685 op4
= extract32(insn
, 0, 5);
1687 if (op4
!= 0x0 || op3
!= 0x0 || op2
!= 0x1f) {
1688 unallocated_encoding(s
);
1695 tcg_gen_mov_i64(cpu_pc
, cpu_reg(s
, rn
));
1698 tcg_gen_mov_i64(cpu_pc
, cpu_reg(s
, rn
));
1699 tcg_gen_movi_i64(cpu_reg(s
, 30), s
->pc
);
1702 if (s
->current_el
== 0) {
1703 unallocated_encoding(s
);
1706 gen_helper_exception_return(cpu_env
);
1707 s
->is_jmp
= DISAS_JUMP
;
1711 unallocated_encoding(s
);
1713 unsupported_encoding(s
, insn
);
1717 unallocated_encoding(s
);
1721 s
->is_jmp
= DISAS_JUMP
;
1724 /* C3.2 Branches, exception generating and system instructions */
1725 static void disas_b_exc_sys(DisasContext
*s
, uint32_t insn
)
1727 switch (extract32(insn
, 25, 7)) {
1728 case 0x0a: case 0x0b:
1729 case 0x4a: case 0x4b: /* Unconditional branch (immediate) */
1730 disas_uncond_b_imm(s
, insn
);
1732 case 0x1a: case 0x5a: /* Compare & branch (immediate) */
1733 disas_comp_b_imm(s
, insn
);
1735 case 0x1b: case 0x5b: /* Test & branch (immediate) */
1736 disas_test_b_imm(s
, insn
);
1738 case 0x2a: /* Conditional branch (immediate) */
1739 disas_cond_b_imm(s
, insn
);
1741 case 0x6a: /* Exception generation / System */
1742 if (insn
& (1 << 24)) {
1743 disas_system(s
, insn
);
1748 case 0x6b: /* Unconditional branch (register) */
1749 disas_uncond_b_reg(s
, insn
);
1752 unallocated_encoding(s
);
1758 * Load/Store exclusive instructions are implemented by remembering
1759 * the value/address loaded, and seeing if these are the same
1760 * when the store is performed. This is not actually the architecturally
1761 * mandated semantics, but it works for typical guest code sequences
1762 * and avoids having to monitor regular stores.
1764 * In system emulation mode only one CPU will be running at once, so
1765 * this sequence is effectively atomic. In user emulation mode we
1766 * throw an exception and handle the atomic operation elsewhere.
1768 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
1769 TCGv_i64 addr
, int size
, bool is_pair
)
1771 TCGv_i64 tmp
= tcg_temp_new_i64();
1772 TCGMemOp memop
= s
->be_data
+ size
;
1774 g_assert(size
<= 3);
1775 tcg_gen_qemu_ld_i64(tmp
, addr
, get_mem_index(s
), memop
);
1778 TCGv_i64 addr2
= tcg_temp_new_i64();
1779 TCGv_i64 hitmp
= tcg_temp_new_i64();
1781 g_assert(size
>= 2);
1782 tcg_gen_addi_i64(addr2
, addr
, 1 << size
);
1783 tcg_gen_qemu_ld_i64(hitmp
, addr2
, get_mem_index(s
), memop
);
1784 tcg_temp_free_i64(addr2
);
1785 tcg_gen_mov_i64(cpu_exclusive_high
, hitmp
);
1786 tcg_gen_mov_i64(cpu_reg(s
, rt2
), hitmp
);
1787 tcg_temp_free_i64(hitmp
);
1790 tcg_gen_mov_i64(cpu_exclusive_val
, tmp
);
1791 tcg_gen_mov_i64(cpu_reg(s
, rt
), tmp
);
1793 tcg_temp_free_i64(tmp
);
1794 tcg_gen_mov_i64(cpu_exclusive_addr
, addr
);
1797 #ifdef CONFIG_USER_ONLY
1798 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
1799 TCGv_i64 addr
, int size
, int is_pair
)
1801 tcg_gen_mov_i64(cpu_exclusive_test
, addr
);
1802 tcg_gen_movi_i32(cpu_exclusive_info
,
1803 size
| is_pair
<< 2 | (rd
<< 4) | (rt
<< 9) | (rt2
<< 14));
1804 gen_exception_internal_insn(s
, 4, EXCP_STREX
);
1807 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
1808 TCGv_i64 inaddr
, int size
, int is_pair
)
1810 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]
1811 * && (!is_pair || env->exclusive_high == [addr + datasize])) {
1814 * [addr + datasize] = {Rt2};
1820 * env->exclusive_addr = -1;
1822 TCGLabel
*fail_label
= gen_new_label();
1823 TCGLabel
*done_label
= gen_new_label();
1824 TCGv_i64 addr
= tcg_temp_local_new_i64();
1827 /* Copy input into a local temp so it is not trashed when the
1828 * basic block ends at the branch insn.
1830 tcg_gen_mov_i64(addr
, inaddr
);
1831 tcg_gen_brcond_i64(TCG_COND_NE
, addr
, cpu_exclusive_addr
, fail_label
);
1833 tmp
= tcg_temp_new_i64();
1834 tcg_gen_qemu_ld_i64(tmp
, addr
, get_mem_index(s
), s
->be_data
+ size
);
1835 tcg_gen_brcond_i64(TCG_COND_NE
, tmp
, cpu_exclusive_val
, fail_label
);
1836 tcg_temp_free_i64(tmp
);
1839 TCGv_i64 addrhi
= tcg_temp_new_i64();
1840 TCGv_i64 tmphi
= tcg_temp_new_i64();
1842 tcg_gen_addi_i64(addrhi
, addr
, 1 << size
);
1843 tcg_gen_qemu_ld_i64(tmphi
, addrhi
, get_mem_index(s
),
1845 tcg_gen_brcond_i64(TCG_COND_NE
, tmphi
, cpu_exclusive_high
, fail_label
);
1847 tcg_temp_free_i64(tmphi
);
1848 tcg_temp_free_i64(addrhi
);
1851 /* We seem to still have the exclusive monitor, so do the store */
1852 tcg_gen_qemu_st_i64(cpu_reg(s
, rt
), addr
, get_mem_index(s
),
1855 TCGv_i64 addrhi
= tcg_temp_new_i64();
1857 tcg_gen_addi_i64(addrhi
, addr
, 1 << size
);
1858 tcg_gen_qemu_st_i64(cpu_reg(s
, rt2
), addrhi
,
1859 get_mem_index(s
), s
->be_data
+ size
);
1860 tcg_temp_free_i64(addrhi
);
1863 tcg_temp_free_i64(addr
);
1865 tcg_gen_movi_i64(cpu_reg(s
, rd
), 0);
1866 tcg_gen_br(done_label
);
1867 gen_set_label(fail_label
);
1868 tcg_gen_movi_i64(cpu_reg(s
, rd
), 1);
1869 gen_set_label(done_label
);
1870 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
1875 /* Update the Sixty-Four bit (SF) registersize. This logic is derived
1876 * from the ARMv8 specs for LDR (Shared decode for all encodings).
1878 static bool disas_ldst_compute_iss_sf(int size
, bool is_signed
, int opc
)
1880 int opc0
= extract32(opc
, 0, 1);
1884 regsize
= opc0 ?
32 : 64;
1886 regsize
= size
== 3 ?
64 : 32;
1888 return regsize
== 64;
1891 /* C3.3.6 Load/store exclusive
1893 * 31 30 29 24 23 22 21 20 16 15 14 10 9 5 4 0
1894 * +-----+-------------+----+---+----+------+----+-------+------+------+
1895 * | sz | 0 0 1 0 0 0 | o2 | L | o1 | Rs | o0 | Rt2 | Rn | Rt |
1896 * +-----+-------------+----+---+----+------+----+-------+------+------+
1898 * sz: 00 -> 8 bit, 01 -> 16 bit, 10 -> 32 bit, 11 -> 64 bit
1899 * L: 0 -> store, 1 -> load
1900 * o2: 0 -> exclusive, 1 -> not
1901 * o1: 0 -> single register, 1 -> register pair
1902 * o0: 1 -> load-acquire/store-release, 0 -> not
1904 static void disas_ldst_excl(DisasContext
*s
, uint32_t insn
)
1906 int rt
= extract32(insn
, 0, 5);
1907 int rn
= extract32(insn
, 5, 5);
1908 int rt2
= extract32(insn
, 10, 5);
1909 int is_lasr
= extract32(insn
, 15, 1);
1910 int rs
= extract32(insn
, 16, 5);
1911 int is_pair
= extract32(insn
, 21, 1);
1912 int is_store
= !extract32(insn
, 22, 1);
1913 int is_excl
= !extract32(insn
, 23, 1);
1914 int size
= extract32(insn
, 30, 2);
1917 if ((!is_excl
&& !is_pair
&& !is_lasr
) ||
1918 (!is_excl
&& is_pair
) ||
1919 (is_pair
&& size
< 2)) {
1920 unallocated_encoding(s
);
1925 gen_check_sp_alignment(s
);
1927 tcg_addr
= read_cpu_reg_sp(s
, rn
, 1);
1929 /* Note that since TCG is single threaded load-acquire/store-release
1930 * semantics require no extra if (is_lasr) { ... } handling.
1936 gen_load_exclusive(s
, rt
, rt2
, tcg_addr
, size
, is_pair
);
1938 gen_store_exclusive(s
, rs
, rt
, rt2
, tcg_addr
, size
, is_pair
);
1941 TCGv_i64 tcg_rt
= cpu_reg(s
, rt
);
1942 bool iss_sf
= disas_ldst_compute_iss_sf(size
, false, 0);
1944 /* Generate ISS for non-exclusive accesses including LASR. */
1946 do_gpr_st(s
, tcg_rt
, tcg_addr
, size
,
1947 true, rt
, iss_sf
, is_lasr
);
1949 do_gpr_ld(s
, tcg_rt
, tcg_addr
, size
, false, false,
1950 true, rt
, iss_sf
, is_lasr
);
1956 * C3.3.5 Load register (literal)
1958 * 31 30 29 27 26 25 24 23 5 4 0
1959 * +-----+-------+---+-----+-------------------+-------+
1960 * | opc | 0 1 1 | V | 0 0 | imm19 | Rt |
1961 * +-----+-------+---+-----+-------------------+-------+
1963 * V: 1 -> vector (simd/fp)
1964 * opc (non-vector): 00 -> 32 bit, 01 -> 64 bit,
1965 * 10-> 32 bit signed, 11 -> prefetch
1966 * opc (vector): 00 -> 32 bit, 01 -> 64 bit, 10 -> 128 bit (11 unallocated)
1968 static void disas_ld_lit(DisasContext
*s
, uint32_t insn
)
1970 int rt
= extract32(insn
, 0, 5);
1971 int64_t imm
= sextract32(insn
, 5, 19) << 2;
1972 bool is_vector
= extract32(insn
, 26, 1);
1973 int opc
= extract32(insn
, 30, 2);
1974 bool is_signed
= false;
1976 TCGv_i64 tcg_rt
, tcg_addr
;
1980 unallocated_encoding(s
);
1984 if (!fp_access_check(s
)) {
1989 /* PRFM (literal) : prefetch */
1992 size
= 2 + extract32(opc
, 0, 1);
1993 is_signed
= extract32(opc
, 1, 1);
1996 tcg_rt
= cpu_reg(s
, rt
);
1998 tcg_addr
= tcg_const_i64((s
->pc
- 4) + imm
);
2000 do_fp_ld(s
, rt
, tcg_addr
, size
);
2002 /* Only unsigned 32bit loads target 32bit registers. */
2003 bool iss_sf
= opc
== 0 ?
32 : 64;
2005 do_gpr_ld(s
, tcg_rt
, tcg_addr
, size
, is_signed
, false,
2006 true, rt
, iss_sf
, false);
2008 tcg_temp_free_i64(tcg_addr
);
2012 * C5.6.80 LDNP (Load Pair - non-temporal hint)
2013 * C5.6.81 LDP (Load Pair - non vector)
2014 * C5.6.82 LDPSW (Load Pair Signed Word - non vector)
2015 * C5.6.176 STNP (Store Pair - non-temporal hint)
2016 * C5.6.177 STP (Store Pair - non vector)
2017 * C6.3.165 LDNP (Load Pair of SIMD&FP - non-temporal hint)
2018 * C6.3.165 LDP (Load Pair of SIMD&FP)
2019 * C6.3.284 STNP (Store Pair of SIMD&FP - non-temporal hint)
2020 * C6.3.284 STP (Store Pair of SIMD&FP)
2022 * 31 30 29 27 26 25 24 23 22 21 15 14 10 9 5 4 0
2023 * +-----+-------+---+---+-------+---+-----------------------------+
2024 * | opc | 1 0 1 | V | 0 | index | L | imm7 | Rt2 | Rn | Rt |
2025 * +-----+-------+---+---+-------+---+-------+-------+------+------+
2027 * opc: LDP/STP/LDNP/STNP 00 -> 32 bit, 10 -> 64 bit
2029 * LDP/STP/LDNP/STNP (SIMD) 00 -> 32 bit, 01 -> 64 bit, 10 -> 128 bit
2030 * V: 0 -> GPR, 1 -> Vector
2031 * idx: 00 -> signed offset with non-temporal hint, 01 -> post-index,
2032 * 10 -> signed offset, 11 -> pre-index
2033 * L: 0 -> Store 1 -> Load
2035 * Rt, Rt2 = GPR or SIMD registers to be stored
2036 * Rn = general purpose register containing address
2037 * imm7 = signed offset (multiple of 4 or 8 depending on size)
2039 static void disas_ldst_pair(DisasContext
*s
, uint32_t insn
)
2041 int rt
= extract32(insn
, 0, 5);
2042 int rn
= extract32(insn
, 5, 5);
2043 int rt2
= extract32(insn
, 10, 5);
2044 uint64_t offset
= sextract64(insn
, 15, 7);
2045 int index
= extract32(insn
, 23, 2);
2046 bool is_vector
= extract32(insn
, 26, 1);
2047 bool is_load
= extract32(insn
, 22, 1);
2048 int opc
= extract32(insn
, 30, 2);
2050 bool is_signed
= false;
2051 bool postindex
= false;
2054 TCGv_i64 tcg_addr
; /* calculated address */
2058 unallocated_encoding(s
);
2065 size
= 2 + extract32(opc
, 1, 1);
2066 is_signed
= extract32(opc
, 0, 1);
2067 if (!is_load
&& is_signed
) {
2068 unallocated_encoding(s
);
2074 case 1: /* post-index */
2079 /* signed offset with "non-temporal" hint. Since we don't emulate
2080 * caches we don't care about hints to the cache system about
2081 * data access patterns, and handle this identically to plain
2085 /* There is no non-temporal-hint version of LDPSW */
2086 unallocated_encoding(s
);
2091 case 2: /* signed offset, rn not updated */
2094 case 3: /* pre-index */
2100 if (is_vector
&& !fp_access_check(s
)) {
2107 gen_check_sp_alignment(s
);
2110 tcg_addr
= read_cpu_reg_sp(s
, rn
, 1);
2113 tcg_gen_addi_i64(tcg_addr
, tcg_addr
, offset
);
2118 do_fp_ld(s
, rt
, tcg_addr
, size
);
2120 do_fp_st(s
, rt
, tcg_addr
, size
);
2123 TCGv_i64 tcg_rt
= cpu_reg(s
, rt
);
2125 do_gpr_ld(s
, tcg_rt
, tcg_addr
, size
, is_signed
, false,
2126 false, 0, false, false);
2128 do_gpr_st(s
, tcg_rt
, tcg_addr
, size
,
2129 false, 0, false, false);
2132 tcg_gen_addi_i64(tcg_addr
, tcg_addr
, 1 << size
);
2135 do_fp_ld(s
, rt2
, tcg_addr
, size
);
2137 do_fp_st(s
, rt2
, tcg_addr
, size
);
2140 TCGv_i64 tcg_rt2
= cpu_reg(s
, rt2
);
2142 do_gpr_ld(s
, tcg_rt2
, tcg_addr
, size
, is_signed
, false,
2143 false, 0, false, false);
2145 do_gpr_st(s
, tcg_rt2
, tcg_addr
, size
,
2146 false, 0, false, false);
2152 tcg_gen_addi_i64(tcg_addr
, tcg_addr
, offset
- (1 << size
));
2154 tcg_gen_subi_i64(tcg_addr
, tcg_addr
, 1 << size
);
2156 tcg_gen_mov_i64(cpu_reg_sp(s
, rn
), tcg_addr
);
2161 * C3.3.8 Load/store (immediate post-indexed)
2162 * C3.3.9 Load/store (immediate pre-indexed)
2163 * C3.3.12 Load/store (unscaled immediate)
2165 * 31 30 29 27 26 25 24 23 22 21 20 12 11 10 9 5 4 0
2166 * +----+-------+---+-----+-----+---+--------+-----+------+------+
2167 * |size| 1 1 1 | V | 0 0 | opc | 0 | imm9 | idx | Rn | Rt |
2168 * +----+-------+---+-----+-----+---+--------+-----+------+------+
2170 * idx = 01 -> post-indexed, 11 pre-indexed, 00 unscaled imm. (no writeback)
2172 * V = 0 -> non-vector
2173 * size: 00 -> 8 bit, 01 -> 16 bit, 10 -> 32 bit, 11 -> 64bit
2174 * opc: 00 -> store, 01 -> loadu, 10 -> loads 64, 11 -> loads 32
2176 static void disas_ldst_reg_imm9(DisasContext
*s
, uint32_t insn
,
2182 int rn
= extract32(insn
, 5, 5);
2183 int imm9
= sextract32(insn
, 12, 9);
2184 int idx
= extract32(insn
, 10, 2);
2185 bool is_signed
= false;
2186 bool is_store
= false;
2187 bool is_extended
= false;
2188 bool is_unpriv
= (idx
== 2);
2189 bool iss_valid
= !is_vector
;
2196 size
|= (opc
& 2) << 1;
2197 if (size
> 4 || is_unpriv
) {
2198 unallocated_encoding(s
);
2201 is_store
= ((opc
& 1) == 0);
2202 if (!fp_access_check(s
)) {
2206 if (size
== 3 && opc
== 2) {
2207 /* PRFM - prefetch */
2209 unallocated_encoding(s
);
2214 if (opc
== 3 && size
> 1) {
2215 unallocated_encoding(s
);
2218 is_store
= (opc
== 0);
2219 is_signed
= extract32(opc
, 1, 1);
2220 is_extended
= (size
< 3) && extract32(opc
, 0, 1);
2240 gen_check_sp_alignment(s
);
2242 tcg_addr
= read_cpu_reg_sp(s
, rn
, 1);
2245 tcg_gen_addi_i64(tcg_addr
, tcg_addr
, imm9
);
2250 do_fp_st(s
, rt
, tcg_addr
, size
);
2252 do_fp_ld(s
, rt
, tcg_addr
, size
);
2255 TCGv_i64 tcg_rt
= cpu_reg(s
, rt
);
2256 int memidx
= is_unpriv ?
get_a64_user_mem_index(s
) : get_mem_index(s
);
2257 bool iss_sf
= disas_ldst_compute_iss_sf(size
, is_signed
, opc
);
2260 do_gpr_st_memidx(s
, tcg_rt
, tcg_addr
, size
, memidx
,
2261 iss_valid
, rt
, iss_sf
, false);
2263 do_gpr_ld_memidx(s
, tcg_rt
, tcg_addr
, size
,
2264 is_signed
, is_extended
, memidx
,
2265 iss_valid
, rt
, iss_sf
, false);
2270 TCGv_i64 tcg_rn
= cpu_reg_sp(s
, rn
);
2272 tcg_gen_addi_i64(tcg_addr
, tcg_addr
, imm9
);
2274 tcg_gen_mov_i64(tcg_rn
, tcg_addr
);
2279 * C3.3.10 Load/store (register offset)
2281 * 31 30 29 27 26 25 24 23 22 21 20 16 15 13 12 11 10 9 5 4 0
2282 * +----+-------+---+-----+-----+---+------+-----+--+-----+----+----+
2283 * |size| 1 1 1 | V | 0 0 | opc | 1 | Rm | opt | S| 1 0 | Rn | Rt |
2284 * +----+-------+---+-----+-----+---+------+-----+--+-----+----+----+
2287 * size: 00-> byte, 01 -> 16 bit, 10 -> 32bit, 11 -> 64bit
2288 * opc: 00 -> store, 01 -> loadu, 10 -> loads 64, 11 -> loads 32
2290 * size is opc<1>:size<1:0> so 100 -> 128 bit; 110 and 111 unallocated
2291 * opc<0>: 0 -> store, 1 -> load
2292 * V: 1 -> vector/simd
2293 * opt: extend encoding (see DecodeRegExtend)
2294 * S: if S=1 then scale (essentially index by sizeof(size))
2295 * Rt: register to transfer into/out of
2296 * Rn: address register or SP for base
2297 * Rm: offset register or ZR for offset
2299 static void disas_ldst_reg_roffset(DisasContext
*s
, uint32_t insn
,
2305 int rn
= extract32(insn
, 5, 5);
2306 int shift
= extract32(insn
, 12, 1);
2307 int rm
= extract32(insn
, 16, 5);
2308 int opt
= extract32(insn
, 13, 3);
2309 bool is_signed
= false;
2310 bool is_store
= false;
2311 bool is_extended
= false;
2316 if (extract32(opt
, 1, 1) == 0) {
2317 unallocated_encoding(s
);
2322 size
|= (opc
& 2) << 1;
2324 unallocated_encoding(s
);
2327 is_store
= !extract32(opc
, 0, 1);
2328 if (!fp_access_check(s
)) {
2332 if (size
== 3 && opc
== 2) {
2333 /* PRFM - prefetch */
2336 if (opc
== 3 && size
> 1) {
2337 unallocated_encoding(s
);
2340 is_store
= (opc
== 0);
2341 is_signed
= extract32(opc
, 1, 1);
2342 is_extended
= (size
< 3) && extract32(opc
, 0, 1);
2346 gen_check_sp_alignment(s
);
2348 tcg_addr
= read_cpu_reg_sp(s
, rn
, 1);
2350 tcg_rm
= read_cpu_reg(s
, rm
, 1);
2351 ext_and_shift_reg(tcg_rm
, tcg_rm
, opt
, shift ? size
: 0);
2353 tcg_gen_add_i64(tcg_addr
, tcg_addr
, tcg_rm
);
2357 do_fp_st(s
, rt
, tcg_addr
, size
);
2359 do_fp_ld(s
, rt
, tcg_addr
, size
);
2362 TCGv_i64 tcg_rt
= cpu_reg(s
, rt
);
2363 bool iss_sf
= disas_ldst_compute_iss_sf(size
, is_signed
, opc
);
2365 do_gpr_st(s
, tcg_rt
, tcg_addr
, size
,
2366 true, rt
, iss_sf
, false);
2368 do_gpr_ld(s
, tcg_rt
, tcg_addr
, size
,
2369 is_signed
, is_extended
,
2370 true, rt
, iss_sf
, false);
2376 * C3.3.13 Load/store (unsigned immediate)
2378 * 31 30 29 27 26 25 24 23 22 21 10 9 5
2379 * +----+-------+---+-----+-----+------------+-------+------+
2380 * |size| 1 1 1 | V | 0 1 | opc | imm12 | Rn | Rt |
2381 * +----+-------+---+-----+-----+------------+-------+------+
2384 * size: 00-> byte, 01 -> 16 bit, 10 -> 32bit, 11 -> 64bit
2385 * opc: 00 -> store, 01 -> loadu, 10 -> loads 64, 11 -> loads 32
2387 * size is opc<1>:size<1:0> so 100 -> 128 bit; 110 and 111 unallocated
2388 * opc<0>: 0 -> store, 1 -> load
2389 * Rn: base address register (inc SP)
2390 * Rt: target register
2392 static void disas_ldst_reg_unsigned_imm(DisasContext
*s
, uint32_t insn
,
2398 int rn
= extract32(insn
, 5, 5);
2399 unsigned int imm12
= extract32(insn
, 10, 12);
2400 unsigned int offset
;
2405 bool is_signed
= false;
2406 bool is_extended
= false;
2409 size
|= (opc
& 2) << 1;
2411 unallocated_encoding(s
);
2414 is_store
= !extract32(opc
, 0, 1);
2415 if (!fp_access_check(s
)) {
2419 if (size
== 3 && opc
== 2) {
2420 /* PRFM - prefetch */
2423 if (opc
== 3 && size
> 1) {
2424 unallocated_encoding(s
);
2427 is_store
= (opc
== 0);
2428 is_signed
= extract32(opc
, 1, 1);
2429 is_extended
= (size
< 3) && extract32(opc
, 0, 1);
2433 gen_check_sp_alignment(s
);
2435 tcg_addr
= read_cpu_reg_sp(s
, rn
, 1);
2436 offset
= imm12
<< size
;
2437 tcg_gen_addi_i64(tcg_addr
, tcg_addr
, offset
);
2441 do_fp_st(s
, rt
, tcg_addr
, size
);
2443 do_fp_ld(s
, rt
, tcg_addr
, size
);
2446 TCGv_i64 tcg_rt
= cpu_reg(s
, rt
);
2447 bool iss_sf
= disas_ldst_compute_iss_sf(size
, is_signed
, opc
);
2449 do_gpr_st(s
, tcg_rt
, tcg_addr
, size
,
2450 true, rt
, iss_sf
, false);
2452 do_gpr_ld(s
, tcg_rt
, tcg_addr
, size
, is_signed
, is_extended
,
2453 true, rt
, iss_sf
, false);
2458 /* Load/store register (all forms) */
2459 static void disas_ldst_reg(DisasContext
*s
, uint32_t insn
)
2461 int rt
= extract32(insn
, 0, 5);
2462 int opc
= extract32(insn
, 22, 2);
2463 bool is_vector
= extract32(insn
, 26, 1);
2464 int size
= extract32(insn
, 30, 2);
2466 switch (extract32(insn
, 24, 2)) {
2468 if (extract32(insn
, 21, 1) == 1 && extract32(insn
, 10, 2) == 2) {
2469 disas_ldst_reg_roffset(s
, insn
, opc
, size
, rt
, is_vector
);
2471 /* Load/store register (unscaled immediate)
2472 * Load/store immediate pre/post-indexed
2473 * Load/store register unprivileged
2475 disas_ldst_reg_imm9(s
, insn
, opc
, size
, rt
, is_vector
);
2479 disas_ldst_reg_unsigned_imm(s
, insn
, opc
, size
, rt
, is_vector
);
2482 unallocated_encoding(s
);
2487 /* C3.3.1 AdvSIMD load/store multiple structures
2489 * 31 30 29 23 22 21 16 15 12 11 10 9 5 4 0
2490 * +---+---+---------------+---+-------------+--------+------+------+------+
2491 * | 0 | Q | 0 0 1 1 0 0 0 | L | 0 0 0 0 0 0 | opcode | size | Rn | Rt |
2492 * +---+---+---------------+---+-------------+--------+------+------+------+
2494 * C3.3.2 AdvSIMD load/store multiple structures (post-indexed)
2496 * 31 30 29 23 22 21 20 16 15 12 11 10 9 5 4 0
2497 * +---+---+---------------+---+---+---------+--------+------+------+------+
2498 * | 0 | Q | 0 0 1 1 0 0 1 | L | 0 | Rm | opcode | size | Rn | Rt |
2499 * +---+---+---------------+---+---+---------+--------+------+------+------+
2501 * Rt: first (or only) SIMD&FP register to be transferred
2502 * Rn: base address or SP
2503 * Rm (post-index only): post-index register (when !31) or size dependent #imm
2505 static void disas_ldst_multiple_struct(DisasContext
*s
, uint32_t insn
)
2507 int rt
= extract32(insn
, 0, 5);
2508 int rn
= extract32(insn
, 5, 5);
2509 int size
= extract32(insn
, 10, 2);
2510 int opcode
= extract32(insn
, 12, 4);
2511 bool is_store
= !extract32(insn
, 22, 1);
2512 bool is_postidx
= extract32(insn
, 23, 1);
2513 bool is_q
= extract32(insn
, 30, 1);
2514 TCGv_i64 tcg_addr
, tcg_rn
;
2516 int ebytes
= 1 << size
;
2517 int elements
= (is_q ?
128 : 64) / (8 << size
);
2518 int rpt
; /* num iterations */
2519 int selem
; /* structure elements */
2522 if (extract32(insn
, 31, 1) || extract32(insn
, 21, 1)) {
2523 unallocated_encoding(s
);
2527 /* From the shared decode logic */
2558 unallocated_encoding(s
);
2562 if (size
== 3 && !is_q
&& selem
!= 1) {
2564 unallocated_encoding(s
);
2568 if (!fp_access_check(s
)) {
2573 gen_check_sp_alignment(s
);
2576 tcg_rn
= cpu_reg_sp(s
, rn
);
2577 tcg_addr
= tcg_temp_new_i64();
2578 tcg_gen_mov_i64(tcg_addr
, tcg_rn
);
2580 for (r
= 0; r
< rpt
; r
++) {
2582 for (e
= 0; e
< elements
; e
++) {
2583 int tt
= (rt
+ r
) % 32;
2585 for (xs
= 0; xs
< selem
; xs
++) {
2587 do_vec_st(s
, tt
, e
, tcg_addr
, size
);
2589 do_vec_ld(s
, tt
, e
, tcg_addr
, size
);
2591 /* For non-quad operations, setting a slice of the low
2592 * 64 bits of the register clears the high 64 bits (in
2593 * the ARM ARM pseudocode this is implicit in the fact
2594 * that 'rval' is a 64 bit wide variable). We optimize
2595 * by noticing that we only need to do this the first
2596 * time we touch a register.
2598 if (!is_q
&& e
== 0 && (r
== 0 || xs
== selem
- 1)) {
2599 clear_vec_high(s
, tt
);
2602 tcg_gen_addi_i64(tcg_addr
, tcg_addr
, ebytes
);
2609 int rm
= extract32(insn
, 16, 5);
2611 tcg_gen_mov_i64(tcg_rn
, tcg_addr
);
2613 tcg_gen_add_i64(tcg_rn
, tcg_rn
, cpu_reg(s
, rm
));
2616 tcg_temp_free_i64(tcg_addr
);
2619 /* C3.3.3 AdvSIMD load/store single structure
2621 * 31 30 29 23 22 21 20 16 15 13 12 11 10 9 5 4 0
2622 * +---+---+---------------+-----+-----------+-----+---+------+------+------+
2623 * | 0 | Q | 0 0 1 1 0 1 0 | L R | 0 0 0 0 0 | opc | S | size | Rn | Rt |
2624 * +---+---+---------------+-----+-----------+-----+---+------+------+------+
2626 * C3.3.4 AdvSIMD load/store single structure (post-indexed)
2628 * 31 30 29 23 22 21 20 16 15 13 12 11 10 9 5 4 0
2629 * +---+---+---------------+-----+-----------+-----+---+------+------+------+
2630 * | 0 | Q | 0 0 1 1 0 1 1 | L R | Rm | opc | S | size | Rn | Rt |
2631 * +---+---+---------------+-----+-----------+-----+---+------+------+------+
2633 * Rt: first (or only) SIMD&FP register to be transferred
2634 * Rn: base address or SP
2635 * Rm (post-index only): post-index register (when !31) or size dependent #imm
2636 * index = encoded in Q:S:size dependent on size
2638 * lane_size = encoded in R, opc
2639 * transfer width = encoded in opc, S, size
2641 static void disas_ldst_single_struct(DisasContext
*s
, uint32_t insn
)
2643 int rt
= extract32(insn
, 0, 5);
2644 int rn
= extract32(insn
, 5, 5);
2645 int size
= extract32(insn
, 10, 2);
2646 int S
= extract32(insn
, 12, 1);
2647 int opc
= extract32(insn
, 13, 3);
2648 int R
= extract32(insn
, 21, 1);
2649 int is_load
= extract32(insn
, 22, 1);
2650 int is_postidx
= extract32(insn
, 23, 1);
2651 int is_q
= extract32(insn
, 30, 1);
2653 int scale
= extract32(opc
, 1, 2);
2654 int selem
= (extract32(opc
, 0, 1) << 1 | R
) + 1;
2655 bool replicate
= false;
2656 int index
= is_q
<< 3 | S
<< 2 | size
;
2658 TCGv_i64 tcg_addr
, tcg_rn
;
2662 if (!is_load
|| S
) {
2663 unallocated_encoding(s
);
2672 if (extract32(size
, 0, 1)) {
2673 unallocated_encoding(s
);
2679 if (extract32(size
, 1, 1)) {
2680 unallocated_encoding(s
);
2683 if (!extract32(size
, 0, 1)) {
2687 unallocated_encoding(s
);
2695 g_assert_not_reached();
2698 if (!fp_access_check(s
)) {
2702 ebytes
= 1 << scale
;
2705 gen_check_sp_alignment(s
);
2708 tcg_rn
= cpu_reg_sp(s
, rn
);
2709 tcg_addr
= tcg_temp_new_i64();
2710 tcg_gen_mov_i64(tcg_addr
, tcg_rn
);
2712 for (xs
= 0; xs
< selem
; xs
++) {
2714 /* Load and replicate to all elements */
2716 TCGv_i64 tcg_tmp
= tcg_temp_new_i64();
2718 tcg_gen_qemu_ld_i64(tcg_tmp
, tcg_addr
,
2719 get_mem_index(s
), s
->be_data
+ scale
);
2722 mulconst
= 0x0101010101010101ULL
;
2725 mulconst
= 0x0001000100010001ULL
;
2728 mulconst
= 0x0000000100000001ULL
;
2734 g_assert_not_reached();
2737 tcg_gen_muli_i64(tcg_tmp
, tcg_tmp
, mulconst
);
2739 write_vec_element(s
, tcg_tmp
, rt
, 0, MO_64
);
2741 write_vec_element(s
, tcg_tmp
, rt
, 1, MO_64
);
2743 clear_vec_high(s
, rt
);
2745 tcg_temp_free_i64(tcg_tmp
);
2747 /* Load/store one element per register */
2749 do_vec_ld(s
, rt
, index
, tcg_addr
, s
->be_data
+ scale
);
2751 do_vec_st(s
, rt
, index
, tcg_addr
, s
->be_data
+ scale
);
2754 tcg_gen_addi_i64(tcg_addr
, tcg_addr
, ebytes
);
2759 int rm
= extract32(insn
, 16, 5);
2761 tcg_gen_mov_i64(tcg_rn
, tcg_addr
);
2763 tcg_gen_add_i64(tcg_rn
, tcg_rn
, cpu_reg(s
, rm
));
2766 tcg_temp_free_i64(tcg_addr
);
2769 /* C3.3 Loads and stores */
2770 static void disas_ldst(DisasContext
*s
, uint32_t insn
)
2772 switch (extract32(insn
, 24, 6)) {
2773 case 0x08: /* Load/store exclusive */
2774 disas_ldst_excl(s
, insn
);
2776 case 0x18: case 0x1c: /* Load register (literal) */
2777 disas_ld_lit(s
, insn
);
2779 case 0x28: case 0x29:
2780 case 0x2c: case 0x2d: /* Load/store pair (all forms) */
2781 disas_ldst_pair(s
, insn
);
2783 case 0x38: case 0x39:
2784 case 0x3c: case 0x3d: /* Load/store register (all forms) */
2785 disas_ldst_reg(s
, insn
);
2787 case 0x0c: /* AdvSIMD load/store multiple structures */
2788 disas_ldst_multiple_struct(s
, insn
);
2790 case 0x0d: /* AdvSIMD load/store single structure */
2791 disas_ldst_single_struct(s
, insn
);
2794 unallocated_encoding(s
);
2799 /* C3.4.6 PC-rel. addressing
2800 * 31 30 29 28 24 23 5 4 0
2801 * +----+-------+-----------+-------------------+------+
2802 * | op | immlo | 1 0 0 0 0 | immhi | Rd |
2803 * +----+-------+-----------+-------------------+------+
2805 static void disas_pc_rel_adr(DisasContext
*s
, uint32_t insn
)
2807 unsigned int page
, rd
;
2811 page
= extract32(insn
, 31, 1);
2812 /* SignExtend(immhi:immlo) -> offset */
2813 offset
= sextract64(insn
, 5, 19);
2814 offset
= offset
<< 2 | extract32(insn
, 29, 2);
2815 rd
= extract32(insn
, 0, 5);
2819 /* ADRP (page based) */
2824 tcg_gen_movi_i64(cpu_reg(s
, rd
), base
+ offset
);
2828 * C3.4.1 Add/subtract (immediate)
2830 * 31 30 29 28 24 23 22 21 10 9 5 4 0
2831 * +--+--+--+-----------+-----+-------------+-----+-----+
2832 * |sf|op| S| 1 0 0 0 1 |shift| imm12 | Rn | Rd |
2833 * +--+--+--+-----------+-----+-------------+-----+-----+
2835 * sf: 0 -> 32bit, 1 -> 64bit
2836 * op: 0 -> add , 1 -> sub
2838 * shift: 00 -> LSL imm by 0, 01 -> LSL imm by 12
2840 static void disas_add_sub_imm(DisasContext
*s
, uint32_t insn
)
2842 int rd
= extract32(insn
, 0, 5);
2843 int rn
= extract32(insn
, 5, 5);
2844 uint64_t imm
= extract32(insn
, 10, 12);
2845 int shift
= extract32(insn
, 22, 2);
2846 bool setflags
= extract32(insn
, 29, 1);
2847 bool sub_op
= extract32(insn
, 30, 1);
2848 bool is_64bit
= extract32(insn
, 31, 1);
2850 TCGv_i64 tcg_rn
= cpu_reg_sp(s
, rn
);
2851 TCGv_i64 tcg_rd
= setflags ?
cpu_reg(s
, rd
) : cpu_reg_sp(s
, rd
);
2852 TCGv_i64 tcg_result
;
2861 unallocated_encoding(s
);
2865 tcg_result
= tcg_temp_new_i64();
2868 tcg_gen_subi_i64(tcg_result
, tcg_rn
, imm
);
2870 tcg_gen_addi_i64(tcg_result
, tcg_rn
, imm
);
2873 TCGv_i64 tcg_imm
= tcg_const_i64(imm
);
2875 gen_sub_CC(is_64bit
, tcg_result
, tcg_rn
, tcg_imm
);
2877 gen_add_CC(is_64bit
, tcg_result
, tcg_rn
, tcg_imm
);
2879 tcg_temp_free_i64(tcg_imm
);
2883 tcg_gen_mov_i64(tcg_rd
, tcg_result
);
2885 tcg_gen_ext32u_i64(tcg_rd
, tcg_result
);
2888 tcg_temp_free_i64(tcg_result
);
2891 /* The input should be a value in the bottom e bits (with higher
2892 * bits zero); returns that value replicated into every element
2893 * of size e in a 64 bit integer.
2895 static uint64_t bitfield_replicate(uint64_t mask
, unsigned int e
)
2905 /* Return a value with the bottom len bits set (where 0 < len <= 64) */
2906 static inline uint64_t bitmask64(unsigned int length
)
2908 assert(length
> 0 && length
<= 64);
2909 return ~0ULL >> (64 - length
);
2912 /* Simplified variant of pseudocode DecodeBitMasks() for the case where we
2913 * only require the wmask. Returns false if the imms/immr/immn are a reserved
2914 * value (ie should cause a guest UNDEF exception), and true if they are
2915 * valid, in which case the decoded bit pattern is written to result.
2917 static bool logic_imm_decode_wmask(uint64_t *result
, unsigned int immn
,
2918 unsigned int imms
, unsigned int immr
)
2921 unsigned e
, levels
, s
, r
;
2924 assert(immn
< 2 && imms
< 64 && immr
< 64);
2926 /* The bit patterns we create here are 64 bit patterns which
2927 * are vectors of identical elements of size e = 2, 4, 8, 16, 32 or
2928 * 64 bits each. Each element contains the same value: a run
2929 * of between 1 and e-1 non-zero bits, rotated within the
2930 * element by between 0 and e-1 bits.
2932 * The element size and run length are encoded into immn (1 bit)
2933 * and imms (6 bits) as follows:
2934 * 64 bit elements: immn = 1, imms = <length of run - 1>
2935 * 32 bit elements: immn = 0, imms = 0 : <length of run - 1>
2936 * 16 bit elements: immn = 0, imms = 10 : <length of run - 1>
2937 * 8 bit elements: immn = 0, imms = 110 : <length of run - 1>
2938 * 4 bit elements: immn = 0, imms = 1110 : <length of run - 1>
2939 * 2 bit elements: immn = 0, imms = 11110 : <length of run - 1>
2940 * Notice that immn = 0, imms = 11111x is the only combination
2941 * not covered by one of the above options; this is reserved.
2942 * Further, <length of run - 1> all-ones is a reserved pattern.
2944 * In all cases the rotation is by immr % e (and immr is 6 bits).
2947 /* First determine the element size */
2948 len
= 31 - clz32((immn
<< 6) | (~imms
& 0x3f));
2950 /* This is the immn == 0, imms == 0x11111x case */
2960 /* <length of run - 1> mustn't be all-ones. */
2964 /* Create the value of one element: s+1 set bits rotated
2965 * by r within the element (which is e bits wide)...
2967 mask
= bitmask64(s
+ 1);
2969 mask
= (mask
>> r
) | (mask
<< (e
- r
));
2970 mask
&= bitmask64(e
);
2972 /* ...then replicate the element over the whole 64 bit value */
2973 mask
= bitfield_replicate(mask
, e
);
2978 /* C3.4.4 Logical (immediate)
2979 * 31 30 29 28 23 22 21 16 15 10 9 5 4 0
2980 * +----+-----+-------------+---+------+------+------+------+
2981 * | sf | opc | 1 0 0 1 0 0 | N | immr | imms | Rn | Rd |
2982 * +----+-----+-------------+---+------+------+------+------+
2984 static void disas_logic_imm(DisasContext
*s
, uint32_t insn
)
2986 unsigned int sf
, opc
, is_n
, immr
, imms
, rn
, rd
;
2987 TCGv_i64 tcg_rd
, tcg_rn
;
2989 bool is_and
= false;
2991 sf
= extract32(insn
, 31, 1);
2992 opc
= extract32(insn
, 29, 2);
2993 is_n
= extract32(insn
, 22, 1);
2994 immr
= extract32(insn
, 16, 6);
2995 imms
= extract32(insn
, 10, 6);
2996 rn
= extract32(insn
, 5, 5);
2997 rd
= extract32(insn
, 0, 5);
3000 unallocated_encoding(s
);
3004 if (opc
== 0x3) { /* ANDS */
3005 tcg_rd
= cpu_reg(s
, rd
);
3007 tcg_rd
= cpu_reg_sp(s
, rd
);
3009 tcg_rn
= cpu_reg(s
, rn
);
3011 if (!logic_imm_decode_wmask(&wmask
, is_n
, imms
, immr
)) {
3012 /* some immediate field values are reserved */
3013 unallocated_encoding(s
);
3018 wmask
&= 0xffffffff;
3022 case 0x3: /* ANDS */
3024 tcg_gen_andi_i64(tcg_rd
, tcg_rn
, wmask
);
3028 tcg_gen_ori_i64(tcg_rd
, tcg_rn
, wmask
);
3031 tcg_gen_xori_i64(tcg_rd
, tcg_rn
, wmask
);
3034 assert(FALSE
); /* must handle all above */
3038 if (!sf
&& !is_and
) {
3039 /* zero extend final result; we know we can skip this for AND
3040 * since the immediate had the high 32 bits clear.
3042 tcg_gen_ext32u_i64(tcg_rd
, tcg_rd
);
3045 if (opc
== 3) { /* ANDS */
3046 gen_logic_CC(sf
, tcg_rd
);
3051 * C3.4.5 Move wide (immediate)
3053 * 31 30 29 28 23 22 21 20 5 4 0
3054 * +--+-----+-------------+-----+----------------+------+
3055 * |sf| opc | 1 0 0 1 0 1 | hw | imm16 | Rd |
3056 * +--+-----+-------------+-----+----------------+------+
3058 * sf: 0 -> 32 bit, 1 -> 64 bit
3059 * opc: 00 -> N, 10 -> Z, 11 -> K
3060 * hw: shift/16 (0,16, and sf only 32, 48)
3062 static void disas_movw_imm(DisasContext
*s
, uint32_t insn
)
3064 int rd
= extract32(insn
, 0, 5);
3065 uint64_t imm
= extract32(insn
, 5, 16);
3066 int sf
= extract32(insn
, 31, 1);
3067 int opc
= extract32(insn
, 29, 2);
3068 int pos
= extract32(insn
, 21, 2) << 4;
3069 TCGv_i64 tcg_rd
= cpu_reg(s
, rd
);
3072 if (!sf
&& (pos
>= 32)) {
3073 unallocated_encoding(s
);
3087 tcg_gen_movi_i64(tcg_rd
, imm
);
3090 tcg_imm
= tcg_const_i64(imm
);
3091 tcg_gen_deposit_i64(tcg_rd
, tcg_rd
, tcg_imm
, pos
, 16);
3092 tcg_temp_free_i64(tcg_imm
);
3094 tcg_gen_ext32u_i64(tcg_rd
, tcg_rd
);
3098 unallocated_encoding(s
);
3104 * 31 30 29 28 23 22 21 16 15 10 9 5 4 0
3105 * +----+-----+-------------+---+------+------+------+------+
3106 * | sf | opc | 1 0 0 1 1 0 | N | immr | imms | Rn | Rd |
3107 * +----+-----+-------------+---+------+------+------+------+
3109 static void disas_bitfield(DisasContext
*s
, uint32_t insn
)
3111 unsigned int sf
, n
, opc
, ri
, si
, rn
, rd
, bitsize
, pos
, len
;
3112 TCGv_i64 tcg_rd
, tcg_tmp
;
3114 sf
= extract32(insn
, 31, 1);
3115 opc
= extract32(insn
, 29, 2);
3116 n
= extract32(insn
, 22, 1);
3117 ri
= extract32(insn
, 16, 6);
3118 si
= extract32(insn
, 10, 6);
3119 rn
= extract32(insn
, 5, 5);
3120 rd
= extract32(insn
, 0, 5);
3121 bitsize
= sf ?
64 : 32;
3123 if (sf
!= n
|| ri
>= bitsize
|| si
>= bitsize
|| opc
> 2) {
3124 unallocated_encoding(s
);
3128 tcg_rd
= cpu_reg(s
, rd
);
3130 /* Suppress the zero-extend for !sf. Since RI and SI are constrained
3131 to be smaller than bitsize, we'll never reference data outside the
3132 low 32-bits anyway. */
3133 tcg_tmp
= read_cpu_reg(s
, rn
, 1);
3135 /* Recognize the common aliases. */
3136 if (opc
== 0) { /* SBFM */
3138 if (si
== 7) { /* SXTB */
3139 tcg_gen_ext8s_i64(tcg_rd
, tcg_tmp
);
3141 } else if (si
== 15) { /* SXTH */
3142 tcg_gen_ext16s_i64(tcg_rd
, tcg_tmp
);
3144 } else if (si
== 31) { /* SXTW */
3145 tcg_gen_ext32s_i64(tcg_rd
, tcg_tmp
);
3149 if (si
== 63 || (si
== 31 && ri
<= si
)) { /* ASR */
3151 tcg_gen_ext32s_i64(tcg_tmp
, tcg_tmp
);
3153 tcg_gen_sari_i64(tcg_rd
, tcg_tmp
, ri
);
3156 } else if (opc
== 2) { /* UBFM */
3157 if (ri
== 0) { /* UXTB, UXTH, plus non-canonical AND */
3158 tcg_gen_andi_i64(tcg_rd
, tcg_tmp
, bitmask64(si
+ 1));
3161 if (si
== 63 || (si
== 31 && ri
<= si
)) { /* LSR */
3163 tcg_gen_ext32u_i64(tcg_tmp
, tcg_tmp
);
3165 tcg_gen_shri_i64(tcg_rd
, tcg_tmp
, ri
);
3168 if (si
+ 1 == ri
&& si
!= bitsize
- 1) { /* LSL */
3169 int shift
= bitsize
- 1 - si
;
3170 tcg_gen_shli_i64(tcg_rd
, tcg_tmp
, shift
);
3175 if (opc
!= 1) { /* SBFM or UBFM */
3176 tcg_gen_movi_i64(tcg_rd
, 0);
3179 /* do the bit move operation */
3181 /* Wd<s-r:0> = Wn<s:r> */
3182 tcg_gen_shri_i64(tcg_tmp
, tcg_tmp
, ri
);
3184 len
= (si
- ri
) + 1;
3186 /* Wd<32+s-r,32-r> = Wn<s:0> */
3191 tcg_gen_deposit_i64(tcg_rd
, tcg_rd
, tcg_tmp
, pos
, len
);
3193 if (opc
== 0) { /* SBFM - sign extend the destination field */
3194 tcg_gen_shli_i64(tcg_rd
, tcg_rd
, 64 - (pos
+ len
));
3195 tcg_gen_sari_i64(tcg_rd
, tcg_rd
, 64 - (pos
+ len
));
3199 if (!sf
) { /* zero extend final result */
3200 tcg_gen_ext32u_i64(tcg_rd
, tcg_rd
);
3205 * 31 30 29 28 23 22 21 20 16 15 10 9 5 4 0
3206 * +----+------+-------------+---+----+------+--------+------+------+
3207 * | sf | op21 | 1 0 0 1 1 1 | N | o0 | Rm | imms | Rn | Rd |
3208 * +----+------+-------------+---+----+------+--------+------+------+
3210 static void disas_extract(DisasContext
*s
, uint32_t insn
)
3212 unsigned int sf
, n
, rm
, imm
, rn
, rd
, bitsize
, op21
, op0
;
3214 sf
= extract32(insn
, 31, 1);
3215 n
= extract32(insn
, 22, 1);
3216 rm
= extract32(insn
, 16, 5);
3217 imm
= extract32(insn
, 10