xref: /qemu/target/arm/tcg/translate-a32.h (revision 4f4c2a4ba25eea18100e17b51a92716d7190d202)
15ce389f2SPeter Maydell /*
25ce389f2SPeter Maydell  *  AArch32 translation, common definitions.
35ce389f2SPeter Maydell  *
45ce389f2SPeter Maydell  * Copyright (c) 2021 Linaro, Ltd.
55ce389f2SPeter Maydell  *
65ce389f2SPeter Maydell  * This library is free software; you can redistribute it and/or
75ce389f2SPeter Maydell  * modify it under the terms of the GNU Lesser General Public
85ce389f2SPeter Maydell  * License as published by the Free Software Foundation; either
95ce389f2SPeter Maydell  * version 2.1 of the License, or (at your option) any later version.
105ce389f2SPeter Maydell  *
115ce389f2SPeter Maydell  * This library is distributed in the hope that it will be useful,
125ce389f2SPeter Maydell  * but WITHOUT ANY WARRANTY; without even the implied warranty of
135ce389f2SPeter Maydell  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
145ce389f2SPeter Maydell  * Lesser General Public License for more details.
155ce389f2SPeter Maydell  *
165ce389f2SPeter Maydell  * You should have received a copy of the GNU Lesser General Public
175ce389f2SPeter Maydell  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
185ce389f2SPeter Maydell  */
195ce389f2SPeter Maydell 
205ce389f2SPeter Maydell #ifndef TARGET_ARM_TRANSLATE_A64_H
215ce389f2SPeter Maydell #define TARGET_ARM_TRANSLATE_A64_H
225ce389f2SPeter Maydell 
239a5071abSPeter Maydell /* Prototypes for autogenerated disassembler functions */
249a5071abSPeter Maydell bool disas_m_nocp(DisasContext *dc, uint32_t insn);
256390eed4SPeter Maydell bool disas_mve(DisasContext *dc, uint32_t insn);
2645fbd5a9SPeter Maydell bool disas_vfp(DisasContext *s, uint32_t insn);
2745fbd5a9SPeter Maydell bool disas_vfp_uncond(DisasContext *s, uint32_t insn);
284800b852SPeter Maydell bool disas_neon_dp(DisasContext *s, uint32_t insn);
294800b852SPeter Maydell bool disas_neon_ls(DisasContext *s, uint32_t insn);
304800b852SPeter Maydell bool disas_neon_shared(DisasContext *s, uint32_t insn);
319a5071abSPeter Maydell 
325ce389f2SPeter Maydell void load_reg_var(DisasContext *s, TCGv_i32 var, int reg);
335ce389f2SPeter Maydell void arm_gen_condlabel(DisasContext *s);
345ce389f2SPeter Maydell bool vfp_access_check(DisasContext *s);
3588137f78SPeter Maydell bool vfp_access_check_m(DisasContext *s, bool skip_context_update);
365ce389f2SPeter Maydell void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop);
375ce389f2SPeter Maydell void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop);
385ce389f2SPeter Maydell void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop);
395ce389f2SPeter Maydell void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop);
404a800a73SPeter Maydell TCGv_i32 add_reg_for_lit(DisasContext *s, int reg, int ofs);
414a800a73SPeter Maydell void gen_set_cpsr(TCGv_i32 var, uint32_t mask);
424a800a73SPeter Maydell void gen_set_condexec(DisasContext *s);
434a800a73SPeter Maydell void gen_set_pc_im(DisasContext *s, target_ulong val);
444a800a73SPeter Maydell void gen_lookup_tb(DisasContext *s);
454a800a73SPeter Maydell long vfp_reg_offset(bool dp, unsigned reg);
464a800a73SPeter Maydell long neon_full_reg_offset(unsigned reg);
47b5c8a457SPeter Maydell long neon_element_offset(int reg, int element, MemOp memop);
48b5c8a457SPeter Maydell void gen_rev16(TCGv_i32 dest, TCGv_i32 var);
495138bd01SPeter Maydell void clear_eci_state(DisasContext *s);
504f57ef95SPeter Maydell bool mve_eci_check(DisasContext *s);
510f31e37cSPeter Maydell void mve_update_eci(DisasContext *s);
524f57ef95SPeter Maydell void mve_update_and_store_eci(DisasContext *s);
531241f148SPeter Maydell bool mve_skip_vmov(DisasContext *s, int vn, int index, int size);
545ce389f2SPeter Maydell 
555ce389f2SPeter Maydell static inline TCGv_i32 load_cpu_offset(int offset)
565ce389f2SPeter Maydell {
575ce389f2SPeter Maydell     TCGv_i32 tmp = tcg_temp_new_i32();
585ce389f2SPeter Maydell     tcg_gen_ld_i32(tmp, cpu_env, offset);
595ce389f2SPeter Maydell     return tmp;
605ce389f2SPeter Maydell }
615ce389f2SPeter Maydell 
625ce389f2SPeter Maydell #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
635ce389f2SPeter Maydell 
644f4c2a4bSRichard Henderson void store_cpu_offset(TCGv_i32 var, int offset, int size);
655ce389f2SPeter Maydell 
665ce389f2SPeter Maydell #define store_cpu_field(var, name)                              \
674f4c2a4bSRichard Henderson     store_cpu_offset(var, offsetof(CPUARMState, name),          \
684f4c2a4bSRichard Henderson                      sizeof_field(CPUARMState, name))
695ce389f2SPeter Maydell 
70daf7a181SPhilippe Mathieu-Daudé #define store_cpu_field_constant(val, name) \
714f4c2a4bSRichard Henderson     store_cpu_field(tcg_constant_i32(val), name)
72daf7a181SPhilippe Mathieu-Daudé 
735ce389f2SPeter Maydell /* Create a new temporary and set it to the value of a CPU register.  */
745ce389f2SPeter Maydell static inline TCGv_i32 load_reg(DisasContext *s, int reg)
755ce389f2SPeter Maydell {
765ce389f2SPeter Maydell     TCGv_i32 tmp = tcg_temp_new_i32();
775ce389f2SPeter Maydell     load_reg_var(s, tmp, reg);
785ce389f2SPeter Maydell     return tmp;
795ce389f2SPeter Maydell }
805ce389f2SPeter Maydell 
814a800a73SPeter Maydell void store_reg(DisasContext *s, int reg, TCGv_i32 var);
824a800a73SPeter Maydell 
8373d2f5d2SPeter Maydell void gen_aa32_ld_internal_i32(DisasContext *s, TCGv_i32 val,
8473d2f5d2SPeter Maydell                               TCGv_i32 a32, int index, MemOp opc);
8573d2f5d2SPeter Maydell void gen_aa32_st_internal_i32(DisasContext *s, TCGv_i32 val,
8673d2f5d2SPeter Maydell                               TCGv_i32 a32, int index, MemOp opc);
8773d2f5d2SPeter Maydell void gen_aa32_ld_internal_i64(DisasContext *s, TCGv_i64 val,
8873d2f5d2SPeter Maydell                               TCGv_i32 a32, int index, MemOp opc);
8973d2f5d2SPeter Maydell void gen_aa32_st_internal_i64(DisasContext *s, TCGv_i64 val,
9073d2f5d2SPeter Maydell                               TCGv_i32 a32, int index, MemOp opc);
9173d2f5d2SPeter Maydell void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
9273d2f5d2SPeter Maydell                      int index, MemOp opc);
9373d2f5d2SPeter Maydell void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
9473d2f5d2SPeter Maydell                      int index, MemOp opc);
9573d2f5d2SPeter Maydell void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
9673d2f5d2SPeter Maydell                      int index, MemOp opc);
9773d2f5d2SPeter Maydell void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
9873d2f5d2SPeter Maydell                      int index, MemOp opc);
9973d2f5d2SPeter Maydell 
10073d2f5d2SPeter Maydell #define DO_GEN_LD(SUFF, OPC)                                            \
10173d2f5d2SPeter Maydell     static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
10273d2f5d2SPeter Maydell                                          TCGv_i32 a32, int index)       \
10373d2f5d2SPeter Maydell     {                                                                   \
10473d2f5d2SPeter Maydell         gen_aa32_ld_i32(s, val, a32, index, OPC);                       \
10573d2f5d2SPeter Maydell     }
10673d2f5d2SPeter Maydell 
10773d2f5d2SPeter Maydell #define DO_GEN_ST(SUFF, OPC)                                            \
10873d2f5d2SPeter Maydell     static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
10973d2f5d2SPeter Maydell                                          TCGv_i32 a32, int index)       \
11073d2f5d2SPeter Maydell     {                                                                   \
11173d2f5d2SPeter Maydell         gen_aa32_st_i32(s, val, a32, index, OPC);                       \
11273d2f5d2SPeter Maydell     }
11373d2f5d2SPeter Maydell 
11473d2f5d2SPeter Maydell static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
11573d2f5d2SPeter Maydell                                  TCGv_i32 a32, int index)
11673d2f5d2SPeter Maydell {
117fc313c64SFrédéric Pétrot     gen_aa32_ld_i64(s, val, a32, index, MO_UQ);
11873d2f5d2SPeter Maydell }
11973d2f5d2SPeter Maydell 
12073d2f5d2SPeter Maydell static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
12173d2f5d2SPeter Maydell                                  TCGv_i32 a32, int index)
12273d2f5d2SPeter Maydell {
123fc313c64SFrédéric Pétrot     gen_aa32_st_i64(s, val, a32, index, MO_UQ);
12473d2f5d2SPeter Maydell }
12573d2f5d2SPeter Maydell 
12673d2f5d2SPeter Maydell DO_GEN_LD(8u, MO_UB)
12773d2f5d2SPeter Maydell DO_GEN_LD(16u, MO_UW)
12873d2f5d2SPeter Maydell DO_GEN_LD(32u, MO_UL)
12973d2f5d2SPeter Maydell DO_GEN_ST(8, MO_UB)
13073d2f5d2SPeter Maydell DO_GEN_ST(16, MO_UW)
13173d2f5d2SPeter Maydell DO_GEN_ST(32, MO_UL)
13273d2f5d2SPeter Maydell 
13373d2f5d2SPeter Maydell #undef DO_GEN_LD
13473d2f5d2SPeter Maydell #undef DO_GEN_ST
13573d2f5d2SPeter Maydell 
1364a800a73SPeter Maydell #if defined(CONFIG_USER_ONLY)
1374a800a73SPeter Maydell #define IS_USER(s) 1
1384a800a73SPeter Maydell #else
1394a800a73SPeter Maydell #define IS_USER(s) (s->user)
1404a800a73SPeter Maydell #endif
1414a800a73SPeter Maydell 
1424a800a73SPeter Maydell /* Set NZCV flags from the high 4 bits of var.  */
1434a800a73SPeter Maydell #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
1444a800a73SPeter Maydell 
145b5c8a457SPeter Maydell /* Swap low and high halfwords.  */
146b5c8a457SPeter Maydell static inline void gen_swap_half(TCGv_i32 dest, TCGv_i32 var)
147b5c8a457SPeter Maydell {
148b5c8a457SPeter Maydell     tcg_gen_rotri_i32(dest, var, 16);
149b5c8a457SPeter Maydell }
150b5c8a457SPeter Maydell 
1515ce389f2SPeter Maydell #endif
152