Message ID | 20230530131843.1186637-4-christoph.muellner@vrull.eu (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | disas/riscv: Add vendor extension support | expand |
On 2023/5/30 21:18, Christoph Muellner wrote: > From: Christoph Müllner <christoph.muellner@vrull.eu> > > In order to enable vendor disassembler support, we need to > move types and constants into a header file so that other > compilation units can use them as well. > > This patch does not introduce any functional changes. > > Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu> Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> Zhiwei > --- > disas/riscv.c | 270 +----------------------------------------------- > disas/riscv.h | 280 ++++++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 281 insertions(+), 269 deletions(-) > create mode 100644 disas/riscv.h > > diff --git a/disas/riscv.c b/disas/riscv.c > index d597161d46..a062fb48cc 100644 > --- a/disas/riscv.c > +++ b/disas/riscv.c > @@ -19,158 +19,7 @@ > > #include "qemu/osdep.h" > #include "disas/dis-asm.h" > - > - > -/* types */ > - > -typedef uint64_t rv_inst; > -typedef uint16_t rv_opcode; > - > -/* enums */ > - > -typedef enum { > - rv32, > - rv64, > - rv128 > -} rv_isa; > - > -typedef enum { > - rv_rm_rne = 0, > - rv_rm_rtz = 1, > - rv_rm_rdn = 2, > - rv_rm_rup = 3, > - rv_rm_rmm = 4, > - rv_rm_dyn = 7, > -} rv_rm; > - > -typedef enum { > - rv_fence_i = 8, > - rv_fence_o = 4, > - rv_fence_r = 2, > - rv_fence_w = 1, > -} rv_fence; > - > -typedef enum { > - rv_ireg_zero, > - rv_ireg_ra, > - rv_ireg_sp, > - rv_ireg_gp, > - rv_ireg_tp, > - rv_ireg_t0, > - rv_ireg_t1, > - rv_ireg_t2, > - rv_ireg_s0, > - rv_ireg_s1, > - rv_ireg_a0, > - rv_ireg_a1, > - rv_ireg_a2, > - rv_ireg_a3, > - rv_ireg_a4, > - rv_ireg_a5, > - rv_ireg_a6, > - rv_ireg_a7, > - rv_ireg_s2, > - rv_ireg_s3, > - rv_ireg_s4, > - rv_ireg_s5, > - rv_ireg_s6, > - rv_ireg_s7, > - rv_ireg_s8, > - rv_ireg_s9, > - rv_ireg_s10, > - rv_ireg_s11, > - rv_ireg_t3, > - rv_ireg_t4, > - rv_ireg_t5, > - rv_ireg_t6, > -} rv_ireg; > - > -typedef enum { > - rvc_end, > - rvc_rd_eq_ra, > - rvc_rd_eq_x0, > - rvc_rs1_eq_x0, > - rvc_rs2_eq_x0, > - rvc_rs2_eq_rs1, > - rvc_rs1_eq_ra, > - rvc_imm_eq_zero, > - rvc_imm_eq_n1, > - rvc_imm_eq_p1, > - rvc_csr_eq_0x001, > - rvc_csr_eq_0x002, > - rvc_csr_eq_0x003, > - rvc_csr_eq_0xc00, > - rvc_csr_eq_0xc01, > - rvc_csr_eq_0xc02, > - rvc_csr_eq_0xc80, > - rvc_csr_eq_0xc81, > - rvc_csr_eq_0xc82, > -} rvc_constraint; > - > -typedef enum { > - rv_codec_illegal, > - rv_codec_none, > - rv_codec_u, > - rv_codec_uj, > - rv_codec_i, > - rv_codec_i_sh5, > - rv_codec_i_sh6, > - rv_codec_i_sh7, > - rv_codec_i_csr, > - rv_codec_s, > - rv_codec_sb, > - rv_codec_r, > - rv_codec_r_m, > - rv_codec_r4_m, > - rv_codec_r_a, > - rv_codec_r_l, > - rv_codec_r_f, > - rv_codec_cb, > - rv_codec_cb_imm, > - rv_codec_cb_sh5, > - rv_codec_cb_sh6, > - rv_codec_ci, > - rv_codec_ci_sh5, > - rv_codec_ci_sh6, > - rv_codec_ci_16sp, > - rv_codec_ci_lwsp, > - rv_codec_ci_ldsp, > - rv_codec_ci_lqsp, > - rv_codec_ci_li, > - rv_codec_ci_lui, > - rv_codec_ci_none, > - rv_codec_ciw_4spn, > - rv_codec_cj, > - rv_codec_cj_jal, > - rv_codec_cl_lw, > - rv_codec_cl_ld, > - rv_codec_cl_lq, > - rv_codec_cr, > - rv_codec_cr_mv, > - rv_codec_cr_jalr, > - rv_codec_cr_jr, > - rv_codec_cs, > - rv_codec_cs_sw, > - rv_codec_cs_sd, > - rv_codec_cs_sq, > - rv_codec_css_swsp, > - rv_codec_css_sdsp, > - rv_codec_css_sqsp, > - rv_codec_k_bs, > - rv_codec_k_rnum, > - rv_codec_v_r, > - rv_codec_v_ldst, > - rv_codec_v_i, > - rv_codec_vsetvli, > - rv_codec_vsetivli, > - rv_codec_zcb_ext, > - rv_codec_zcb_mul, > - rv_codec_zcb_lb, > - rv_codec_zcb_lh, > - rv_codec_zcmp_cm_pushpop, > - rv_codec_zcmp_cm_mv, > - rv_codec_zcmt_jt, > -} rv_codec; > +#include "disas/riscv.h" > > typedef enum { > rv_op_illegal = 0, > @@ -966,50 +815,6 @@ typedef enum { > rv_op_czero_nez = 790, > } rv_op; > > -/* structures */ > - > -typedef struct { > - uint64_t pc; > - uint64_t inst; > - int32_t imm; > - uint16_t op; > - uint8_t codec; > - uint8_t rd; > - uint8_t rs1; > - uint8_t rs2; > - uint8_t rs3; > - uint8_t rm; > - uint8_t pred; > - uint8_t succ; > - uint8_t aq; > - uint8_t rl; > - uint8_t bs; > - uint8_t rnum; > - uint8_t vm; > - uint32_t vzimm; > - uint8_t rlist; > -} rv_decode; > - > -typedef struct { > - const int op; > - const rvc_constraint *constraints; > -} rv_comp_data; > - > -enum { > - rvcd_imm_nz = 0x1 > -}; > - > -typedef struct { > - const char * const name; > - const rv_codec codec; > - const char * const format; > - const rv_comp_data *pseudo; > - const short decomp_rv32; > - const short decomp_rv64; > - const short decomp_rv128; > - const short decomp_data; > -} rv_opcode_data; > - > /* register names */ > > static const char rv_ireg_name_sym[32][5] = { > @@ -1033,79 +838,6 @@ static const char rv_vreg_name_sym[32][4] = { > "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31" > }; > > -/* instruction formats */ > - > -#define rv_fmt_none "O\t" > -#define rv_fmt_rs1 "O\t1" > -#define rv_fmt_offset "O\to" > -#define rv_fmt_pred_succ "O\tp,s" > -#define rv_fmt_rs1_rs2 "O\t1,2" > -#define rv_fmt_rd_imm "O\t0,i" > -#define rv_fmt_rd_offset "O\t0,o" > -#define rv_fmt_rd_rs1_rs2 "O\t0,1,2" > -#define rv_fmt_frd_rs1 "O\t3,1" > -#define rv_fmt_frd_frs1 "O\t3,4" > -#define rv_fmt_rd_frs1 "O\t0,4" > -#define rv_fmt_rd_frs1_frs2 "O\t0,4,5" > -#define rv_fmt_frd_frs1_frs2 "O\t3,4,5" > -#define rv_fmt_rm_frd_frs1 "O\tr,3,4" > -#define rv_fmt_rm_frd_rs1 "O\tr,3,1" > -#define rv_fmt_rm_rd_frs1 "O\tr,0,4" > -#define rv_fmt_rm_frd_frs1_frs2 "O\tr,3,4,5" > -#define rv_fmt_rm_frd_frs1_frs2_frs3 "O\tr,3,4,5,6" > -#define rv_fmt_rd_rs1_imm "O\t0,1,i" > -#define rv_fmt_rd_rs1_offset "O\t0,1,i" > -#define rv_fmt_rd_offset_rs1 "O\t0,i(1)" > -#define rv_fmt_frd_offset_rs1 "O\t3,i(1)" > -#define rv_fmt_rd_csr_rs1 "O\t0,c,1" > -#define rv_fmt_rd_csr_zimm "O\t0,c,7" > -#define rv_fmt_rs2_offset_rs1 "O\t2,i(1)" > -#define rv_fmt_frs2_offset_rs1 "O\t5,i(1)" > -#define rv_fmt_rs1_rs2_offset "O\t1,2,o" > -#define rv_fmt_rs2_rs1_offset "O\t2,1,o" > -#define rv_fmt_aqrl_rd_rs2_rs1 "OAR\t0,2,(1)" > -#define rv_fmt_aqrl_rd_rs1 "OAR\t0,(1)" > -#define rv_fmt_rd "O\t0" > -#define rv_fmt_rd_zimm "O\t0,7" > -#define rv_fmt_rd_rs1 "O\t0,1" > -#define rv_fmt_rd_rs2 "O\t0,2" > -#define rv_fmt_rs1_offset "O\t1,o" > -#define rv_fmt_rs2_offset "O\t2,o" > -#define rv_fmt_rs1_rs2_bs "O\t1,2,b" > -#define rv_fmt_rd_rs1_rnum "O\t0,1,n" > -#define rv_fmt_ldst_vd_rs1_vm "O\tD,(1)m" > -#define rv_fmt_ldst_vd_rs1_rs2_vm "O\tD,(1),2m" > -#define rv_fmt_ldst_vd_rs1_vs2_vm "O\tD,(1),Fm" > -#define rv_fmt_vd_vs2_vs1 "O\tD,F,E" > -#define rv_fmt_vd_vs2_vs1_vl "O\tD,F,El" > -#define rv_fmt_vd_vs2_vs1_vm "O\tD,F,Em" > -#define rv_fmt_vd_vs2_rs1_vl "O\tD,F,1l" > -#define rv_fmt_vd_vs2_fs1_vl "O\tD,F,4l" > -#define rv_fmt_vd_vs2_rs1_vm "O\tD,F,1m" > -#define rv_fmt_vd_vs2_fs1_vm "O\tD,F,4m" > -#define rv_fmt_vd_vs2_imm_vl "O\tD,F,il" > -#define rv_fmt_vd_vs2_imm_vm "O\tD,F,im" > -#define rv_fmt_vd_vs2_uimm_vm "O\tD,F,um" > -#define rv_fmt_vd_vs1_vs2_vm "O\tD,E,Fm" > -#define rv_fmt_vd_rs1_vs2_vm "O\tD,1,Fm" > -#define rv_fmt_vd_fs1_vs2_vm "O\tD,4,Fm" > -#define rv_fmt_vd_vs1 "O\tD,E" > -#define rv_fmt_vd_rs1 "O\tD,1" > -#define rv_fmt_vd_fs1 "O\tD,4" > -#define rv_fmt_vd_imm "O\tD,i" > -#define rv_fmt_vd_vs2 "O\tD,F" > -#define rv_fmt_vd_vs2_vm "O\tD,Fm" > -#define rv_fmt_rd_vs2_vm "O\t0,Fm" > -#define rv_fmt_rd_vs2 "O\t0,F" > -#define rv_fmt_fd_vs2 "O\t3,F" > -#define rv_fmt_vd_vm "O\tDm" > -#define rv_fmt_vsetvli "O\t0,1,v" > -#define rv_fmt_vsetivli "O\t0,u,v" > -#define rv_fmt_rs1_rs2_zce_ldst "O\t2,i(1)" > -#define rv_fmt_push_rlist "O\tx,-i" > -#define rv_fmt_pop_rlist "O\tx,i" > -#define rv_fmt_zcmt_index "O\ti" > - > /* pseudo-instruction constraints */ > > static const rvc_constraint rvcc_jal[] = { rvc_rd_eq_ra, rvc_end }; > diff --git a/disas/riscv.h b/disas/riscv.h > new file mode 100644 > index 0000000000..0f34b71518 > --- /dev/null > +++ b/disas/riscv.h > @@ -0,0 +1,280 @@ > +/* > + * QEMU disassembler -- RISC-V specific header. > + * > + * SPDX-License-Identifier: GPL-2.0-or-later > + */ > + > +#ifndef DISAS_RISCV_H > +#define DISAS_RISCV_H > + > +#include "qemu/osdep.h" > + > +/* types */ > + > +typedef uint64_t rv_inst; > +typedef uint16_t rv_opcode; > + > +/* enums */ > + > +typedef enum { > + rv32, > + rv64, > + rv128 > +} rv_isa; > + > +typedef enum { > + rv_rm_rne = 0, > + rv_rm_rtz = 1, > + rv_rm_rdn = 2, > + rv_rm_rup = 3, > + rv_rm_rmm = 4, > + rv_rm_dyn = 7, > +} rv_rm; > + > +typedef enum { > + rv_fence_i = 8, > + rv_fence_o = 4, > + rv_fence_r = 2, > + rv_fence_w = 1, > +} rv_fence; > + > +typedef enum { > + rv_ireg_zero, > + rv_ireg_ra, > + rv_ireg_sp, > + rv_ireg_gp, > + rv_ireg_tp, > + rv_ireg_t0, > + rv_ireg_t1, > + rv_ireg_t2, > + rv_ireg_s0, > + rv_ireg_s1, > + rv_ireg_a0, > + rv_ireg_a1, > + rv_ireg_a2, > + rv_ireg_a3, > + rv_ireg_a4, > + rv_ireg_a5, > + rv_ireg_a6, > + rv_ireg_a7, > + rv_ireg_s2, > + rv_ireg_s3, > + rv_ireg_s4, > + rv_ireg_s5, > + rv_ireg_s6, > + rv_ireg_s7, > + rv_ireg_s8, > + rv_ireg_s9, > + rv_ireg_s10, > + rv_ireg_s11, > + rv_ireg_t3, > + rv_ireg_t4, > + rv_ireg_t5, > + rv_ireg_t6, > +} rv_ireg; > + > +typedef enum { > + rvc_end, > + rvc_rd_eq_ra, > + rvc_rd_eq_x0, > + rvc_rs1_eq_x0, > + rvc_rs2_eq_x0, > + rvc_rs2_eq_rs1, > + rvc_rs1_eq_ra, > + rvc_imm_eq_zero, > + rvc_imm_eq_n1, > + rvc_imm_eq_p1, > + rvc_csr_eq_0x001, > + rvc_csr_eq_0x002, > + rvc_csr_eq_0x003, > + rvc_csr_eq_0xc00, > + rvc_csr_eq_0xc01, > + rvc_csr_eq_0xc02, > + rvc_csr_eq_0xc80, > + rvc_csr_eq_0xc81, > + rvc_csr_eq_0xc82, > +} rvc_constraint; > + > +typedef enum { > + rv_codec_illegal, > + rv_codec_none, > + rv_codec_u, > + rv_codec_uj, > + rv_codec_i, > + rv_codec_i_sh5, > + rv_codec_i_sh6, > + rv_codec_i_sh7, > + rv_codec_i_csr, > + rv_codec_s, > + rv_codec_sb, > + rv_codec_r, > + rv_codec_r_m, > + rv_codec_r4_m, > + rv_codec_r_a, > + rv_codec_r_l, > + rv_codec_r_f, > + rv_codec_cb, > + rv_codec_cb_imm, > + rv_codec_cb_sh5, > + rv_codec_cb_sh6, > + rv_codec_ci, > + rv_codec_ci_sh5, > + rv_codec_ci_sh6, > + rv_codec_ci_16sp, > + rv_codec_ci_lwsp, > + rv_codec_ci_ldsp, > + rv_codec_ci_lqsp, > + rv_codec_ci_li, > + rv_codec_ci_lui, > + rv_codec_ci_none, > + rv_codec_ciw_4spn, > + rv_codec_cj, > + rv_codec_cj_jal, > + rv_codec_cl_lw, > + rv_codec_cl_ld, > + rv_codec_cl_lq, > + rv_codec_cr, > + rv_codec_cr_mv, > + rv_codec_cr_jalr, > + rv_codec_cr_jr, > + rv_codec_cs, > + rv_codec_cs_sw, > + rv_codec_cs_sd, > + rv_codec_cs_sq, > + rv_codec_css_swsp, > + rv_codec_css_sdsp, > + rv_codec_css_sqsp, > + rv_codec_k_bs, > + rv_codec_k_rnum, > + rv_codec_v_r, > + rv_codec_v_ldst, > + rv_codec_v_i, > + rv_codec_vsetvli, > + rv_codec_vsetivli, > + rv_codec_zcb_ext, > + rv_codec_zcb_mul, > + rv_codec_zcb_lb, > + rv_codec_zcb_lh, > + rv_codec_zcmp_cm_pushpop, > + rv_codec_zcmp_cm_mv, > + rv_codec_zcmt_jt, > +} rv_codec; > + > +/* structures */ > + > +typedef struct { > + uint64_t pc; > + uint64_t inst; > + int32_t imm; > + uint16_t op; > + uint8_t codec; > + uint8_t rd; > + uint8_t rs1; > + uint8_t rs2; > + uint8_t rs3; > + uint8_t rm; > + uint8_t pred; > + uint8_t succ; > + uint8_t aq; > + uint8_t rl; > + uint8_t bs; > + uint8_t rnum; > + uint8_t vm; > + uint32_t vzimm; > + uint8_t rlist; > +} rv_decode; > + > +typedef struct { > + const int op; > + const rvc_constraint *constraints; > +} rv_comp_data; > + > +enum { > + rvcd_imm_nz = 0x1 > +}; > + > +typedef struct { > + const char * const name; > + const rv_codec codec; > + const char * const format; > + const rv_comp_data *pseudo; > + const short decomp_rv32; > + const short decomp_rv64; > + const short decomp_rv128; > + const short decomp_data; > +} rv_opcode_data; > + > +/* instruction formats */ > + > +#define rv_fmt_none "O\t" > +#define rv_fmt_rs1 "O\t1" > +#define rv_fmt_offset "O\to" > +#define rv_fmt_pred_succ "O\tp,s" > +#define rv_fmt_rs1_rs2 "O\t1,2" > +#define rv_fmt_rd_imm "O\t0,i" > +#define rv_fmt_rd_offset "O\t0,o" > +#define rv_fmt_rd_rs1_rs2 "O\t0,1,2" > +#define rv_fmt_frd_rs1 "O\t3,1" > +#define rv_fmt_frd_frs1 "O\t3,4" > +#define rv_fmt_rd_frs1 "O\t0,4" > +#define rv_fmt_rd_frs1_frs2 "O\t0,4,5" > +#define rv_fmt_frd_frs1_frs2 "O\t3,4,5" > +#define rv_fmt_rm_frd_frs1 "O\tr,3,4" > +#define rv_fmt_rm_frd_rs1 "O\tr,3,1" > +#define rv_fmt_rm_rd_frs1 "O\tr,0,4" > +#define rv_fmt_rm_frd_frs1_frs2 "O\tr,3,4,5" > +#define rv_fmt_rm_frd_frs1_frs2_frs3 "O\tr,3,4,5,6" > +#define rv_fmt_rd_rs1_imm "O\t0,1,i" > +#define rv_fmt_rd_rs1_offset "O\t0,1,i" > +#define rv_fmt_rd_offset_rs1 "O\t0,i(1)" > +#define rv_fmt_frd_offset_rs1 "O\t3,i(1)" > +#define rv_fmt_rd_csr_rs1 "O\t0,c,1" > +#define rv_fmt_rd_csr_zimm "O\t0,c,7" > +#define rv_fmt_rs2_offset_rs1 "O\t2,i(1)" > +#define rv_fmt_frs2_offset_rs1 "O\t5,i(1)" > +#define rv_fmt_rs1_rs2_offset "O\t1,2,o" > +#define rv_fmt_rs2_rs1_offset "O\t2,1,o" > +#define rv_fmt_aqrl_rd_rs2_rs1 "OAR\t0,2,(1)" > +#define rv_fmt_aqrl_rd_rs1 "OAR\t0,(1)" > +#define rv_fmt_rd "O\t0" > +#define rv_fmt_rd_zimm "O\t0,7" > +#define rv_fmt_rd_rs1 "O\t0,1" > +#define rv_fmt_rd_rs2 "O\t0,2" > +#define rv_fmt_rs1_offset "O\t1,o" > +#define rv_fmt_rs2_offset "O\t2,o" > +#define rv_fmt_rs1_rs2_bs "O\t1,2,b" > +#define rv_fmt_rd_rs1_rnum "O\t0,1,n" > +#define rv_fmt_ldst_vd_rs1_vm "O\tD,(1)m" > +#define rv_fmt_ldst_vd_rs1_rs2_vm "O\tD,(1),2m" > +#define rv_fmt_ldst_vd_rs1_vs2_vm "O\tD,(1),Fm" > +#define rv_fmt_vd_vs2_vs1 "O\tD,F,E" > +#define rv_fmt_vd_vs2_vs1_vl "O\tD,F,El" > +#define rv_fmt_vd_vs2_vs1_vm "O\tD,F,Em" > +#define rv_fmt_vd_vs2_rs1_vl "O\tD,F,1l" > +#define rv_fmt_vd_vs2_fs1_vl "O\tD,F,4l" > +#define rv_fmt_vd_vs2_rs1_vm "O\tD,F,1m" > +#define rv_fmt_vd_vs2_fs1_vm "O\tD,F,4m" > +#define rv_fmt_vd_vs2_imm_vl "O\tD,F,il" > +#define rv_fmt_vd_vs2_imm_vm "O\tD,F,im" > +#define rv_fmt_vd_vs2_uimm_vm "O\tD,F,um" > +#define rv_fmt_vd_vs1_vs2_vm "O\tD,E,Fm" > +#define rv_fmt_vd_rs1_vs2_vm "O\tD,1,Fm" > +#define rv_fmt_vd_fs1_vs2_vm "O\tD,4,Fm" > +#define rv_fmt_vd_vs1 "O\tD,E" > +#define rv_fmt_vd_rs1 "O\tD,1" > +#define rv_fmt_vd_fs1 "O\tD,4" > +#define rv_fmt_vd_imm "O\tD,i" > +#define rv_fmt_vd_vs2 "O\tD,F" > +#define rv_fmt_vd_vs2_vm "O\tD,Fm" > +#define rv_fmt_rd_vs2_vm "O\t0,Fm" > +#define rv_fmt_rd_vs2 "O\t0,F" > +#define rv_fmt_fd_vs2 "O\t3,F" > +#define rv_fmt_vd_vm "O\tDm" > +#define rv_fmt_vsetvli "O\t0,1,v" > +#define rv_fmt_vsetivli "O\t0,u,v" > +#define rv_fmt_rs1_rs2_zce_ldst "O\t2,i(1)" > +#define rv_fmt_push_rlist "O\tx,-i" > +#define rv_fmt_pop_rlist "O\tx,i" > +#define rv_fmt_zcmt_index "O\ti" > + > +#endif /* DISAS_RISCV_H */
On Tue, May 30, 2023 at 11:23 PM Christoph Muellner <christoph.muellner@vrull.eu> wrote: > > From: Christoph Müllner <christoph.muellner@vrull.eu> > > In order to enable vendor disassembler support, we need to > move types and constants into a header file so that other > compilation units can use them as well. > > This patch does not introduce any functional changes. > > Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Alistair > --- > disas/riscv.c | 270 +----------------------------------------------- > disas/riscv.h | 280 ++++++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 281 insertions(+), 269 deletions(-) > create mode 100644 disas/riscv.h > > diff --git a/disas/riscv.c b/disas/riscv.c > index d597161d46..a062fb48cc 100644 > --- a/disas/riscv.c > +++ b/disas/riscv.c > @@ -19,158 +19,7 @@ > > #include "qemu/osdep.h" > #include "disas/dis-asm.h" > - > - > -/* types */ > - > -typedef uint64_t rv_inst; > -typedef uint16_t rv_opcode; > - > -/* enums */ > - > -typedef enum { > - rv32, > - rv64, > - rv128 > -} rv_isa; > - > -typedef enum { > - rv_rm_rne = 0, > - rv_rm_rtz = 1, > - rv_rm_rdn = 2, > - rv_rm_rup = 3, > - rv_rm_rmm = 4, > - rv_rm_dyn = 7, > -} rv_rm; > - > -typedef enum { > - rv_fence_i = 8, > - rv_fence_o = 4, > - rv_fence_r = 2, > - rv_fence_w = 1, > -} rv_fence; > - > -typedef enum { > - rv_ireg_zero, > - rv_ireg_ra, > - rv_ireg_sp, > - rv_ireg_gp, > - rv_ireg_tp, > - rv_ireg_t0, > - rv_ireg_t1, > - rv_ireg_t2, > - rv_ireg_s0, > - rv_ireg_s1, > - rv_ireg_a0, > - rv_ireg_a1, > - rv_ireg_a2, > - rv_ireg_a3, > - rv_ireg_a4, > - rv_ireg_a5, > - rv_ireg_a6, > - rv_ireg_a7, > - rv_ireg_s2, > - rv_ireg_s3, > - rv_ireg_s4, > - rv_ireg_s5, > - rv_ireg_s6, > - rv_ireg_s7, > - rv_ireg_s8, > - rv_ireg_s9, > - rv_ireg_s10, > - rv_ireg_s11, > - rv_ireg_t3, > - rv_ireg_t4, > - rv_ireg_t5, > - rv_ireg_t6, > -} rv_ireg; > - > -typedef enum { > - rvc_end, > - rvc_rd_eq_ra, > - rvc_rd_eq_x0, > - rvc_rs1_eq_x0, > - rvc_rs2_eq_x0, > - rvc_rs2_eq_rs1, > - rvc_rs1_eq_ra, > - rvc_imm_eq_zero, > - rvc_imm_eq_n1, > - rvc_imm_eq_p1, > - rvc_csr_eq_0x001, > - rvc_csr_eq_0x002, > - rvc_csr_eq_0x003, > - rvc_csr_eq_0xc00, > - rvc_csr_eq_0xc01, > - rvc_csr_eq_0xc02, > - rvc_csr_eq_0xc80, > - rvc_csr_eq_0xc81, > - rvc_csr_eq_0xc82, > -} rvc_constraint; > - > -typedef enum { > - rv_codec_illegal, > - rv_codec_none, > - rv_codec_u, > - rv_codec_uj, > - rv_codec_i, > - rv_codec_i_sh5, > - rv_codec_i_sh6, > - rv_codec_i_sh7, > - rv_codec_i_csr, > - rv_codec_s, > - rv_codec_sb, > - rv_codec_r, > - rv_codec_r_m, > - rv_codec_r4_m, > - rv_codec_r_a, > - rv_codec_r_l, > - rv_codec_r_f, > - rv_codec_cb, > - rv_codec_cb_imm, > - rv_codec_cb_sh5, > - rv_codec_cb_sh6, > - rv_codec_ci, > - rv_codec_ci_sh5, > - rv_codec_ci_sh6, > - rv_codec_ci_16sp, > - rv_codec_ci_lwsp, > - rv_codec_ci_ldsp, > - rv_codec_ci_lqsp, > - rv_codec_ci_li, > - rv_codec_ci_lui, > - rv_codec_ci_none, > - rv_codec_ciw_4spn, > - rv_codec_cj, > - rv_codec_cj_jal, > - rv_codec_cl_lw, > - rv_codec_cl_ld, > - rv_codec_cl_lq, > - rv_codec_cr, > - rv_codec_cr_mv, > - rv_codec_cr_jalr, > - rv_codec_cr_jr, > - rv_codec_cs, > - rv_codec_cs_sw, > - rv_codec_cs_sd, > - rv_codec_cs_sq, > - rv_codec_css_swsp, > - rv_codec_css_sdsp, > - rv_codec_css_sqsp, > - rv_codec_k_bs, > - rv_codec_k_rnum, > - rv_codec_v_r, > - rv_codec_v_ldst, > - rv_codec_v_i, > - rv_codec_vsetvli, > - rv_codec_vsetivli, > - rv_codec_zcb_ext, > - rv_codec_zcb_mul, > - rv_codec_zcb_lb, > - rv_codec_zcb_lh, > - rv_codec_zcmp_cm_pushpop, > - rv_codec_zcmp_cm_mv, > - rv_codec_zcmt_jt, > -} rv_codec; > +#include "disas/riscv.h" > > typedef enum { > rv_op_illegal = 0, > @@ -966,50 +815,6 @@ typedef enum { > rv_op_czero_nez = 790, > } rv_op; > > -/* structures */ > - > -typedef struct { > - uint64_t pc; > - uint64_t inst; > - int32_t imm; > - uint16_t op; > - uint8_t codec; > - uint8_t rd; > - uint8_t rs1; > - uint8_t rs2; > - uint8_t rs3; > - uint8_t rm; > - uint8_t pred; > - uint8_t succ; > - uint8_t aq; > - uint8_t rl; > - uint8_t bs; > - uint8_t rnum; > - uint8_t vm; > - uint32_t vzimm; > - uint8_t rlist; > -} rv_decode; > - > -typedef struct { > - const int op; > - const rvc_constraint *constraints; > -} rv_comp_data; > - > -enum { > - rvcd_imm_nz = 0x1 > -}; > - > -typedef struct { > - const char * const name; > - const rv_codec codec; > - const char * const format; > - const rv_comp_data *pseudo; > - const short decomp_rv32; > - const short decomp_rv64; > - const short decomp_rv128; > - const short decomp_data; > -} rv_opcode_data; > - > /* register names */ > > static const char rv_ireg_name_sym[32][5] = { > @@ -1033,79 +838,6 @@ static const char rv_vreg_name_sym[32][4] = { > "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31" > }; > > -/* instruction formats */ > - > -#define rv_fmt_none "O\t" > -#define rv_fmt_rs1 "O\t1" > -#define rv_fmt_offset "O\to" > -#define rv_fmt_pred_succ "O\tp,s" > -#define rv_fmt_rs1_rs2 "O\t1,2" > -#define rv_fmt_rd_imm "O\t0,i" > -#define rv_fmt_rd_offset "O\t0,o" > -#define rv_fmt_rd_rs1_rs2 "O\t0,1,2" > -#define rv_fmt_frd_rs1 "O\t3,1" > -#define rv_fmt_frd_frs1 "O\t3,4" > -#define rv_fmt_rd_frs1 "O\t0,4" > -#define rv_fmt_rd_frs1_frs2 "O\t0,4,5" > -#define rv_fmt_frd_frs1_frs2 "O\t3,4,5" > -#define rv_fmt_rm_frd_frs1 "O\tr,3,4" > -#define rv_fmt_rm_frd_rs1 "O\tr,3,1" > -#define rv_fmt_rm_rd_frs1 "O\tr,0,4" > -#define rv_fmt_rm_frd_frs1_frs2 "O\tr,3,4,5" > -#define rv_fmt_rm_frd_frs1_frs2_frs3 "O\tr,3,4,5,6" > -#define rv_fmt_rd_rs1_imm "O\t0,1,i" > -#define rv_fmt_rd_rs1_offset "O\t0,1,i" > -#define rv_fmt_rd_offset_rs1 "O\t0,i(1)" > -#define rv_fmt_frd_offset_rs1 "O\t3,i(1)" > -#define rv_fmt_rd_csr_rs1 "O\t0,c,1" > -#define rv_fmt_rd_csr_zimm "O\t0,c,7" > -#define rv_fmt_rs2_offset_rs1 "O\t2,i(1)" > -#define rv_fmt_frs2_offset_rs1 "O\t5,i(1)" > -#define rv_fmt_rs1_rs2_offset "O\t1,2,o" > -#define rv_fmt_rs2_rs1_offset "O\t2,1,o" > -#define rv_fmt_aqrl_rd_rs2_rs1 "OAR\t0,2,(1)" > -#define rv_fmt_aqrl_rd_rs1 "OAR\t0,(1)" > -#define rv_fmt_rd "O\t0" > -#define rv_fmt_rd_zimm "O\t0,7" > -#define rv_fmt_rd_rs1 "O\t0,1" > -#define rv_fmt_rd_rs2 "O\t0,2" > -#define rv_fmt_rs1_offset "O\t1,o" > -#define rv_fmt_rs2_offset "O\t2,o" > -#define rv_fmt_rs1_rs2_bs "O\t1,2,b" > -#define rv_fmt_rd_rs1_rnum "O\t0,1,n" > -#define rv_fmt_ldst_vd_rs1_vm "O\tD,(1)m" > -#define rv_fmt_ldst_vd_rs1_rs2_vm "O\tD,(1),2m" > -#define rv_fmt_ldst_vd_rs1_vs2_vm "O\tD,(1),Fm" > -#define rv_fmt_vd_vs2_vs1 "O\tD,F,E" > -#define rv_fmt_vd_vs2_vs1_vl "O\tD,F,El" > -#define rv_fmt_vd_vs2_vs1_vm "O\tD,F,Em" > -#define rv_fmt_vd_vs2_rs1_vl "O\tD,F,1l" > -#define rv_fmt_vd_vs2_fs1_vl "O\tD,F,4l" > -#define rv_fmt_vd_vs2_rs1_vm "O\tD,F,1m" > -#define rv_fmt_vd_vs2_fs1_vm "O\tD,F,4m" > -#define rv_fmt_vd_vs2_imm_vl "O\tD,F,il" > -#define rv_fmt_vd_vs2_imm_vm "O\tD,F,im" > -#define rv_fmt_vd_vs2_uimm_vm "O\tD,F,um" > -#define rv_fmt_vd_vs1_vs2_vm "O\tD,E,Fm" > -#define rv_fmt_vd_rs1_vs2_vm "O\tD,1,Fm" > -#define rv_fmt_vd_fs1_vs2_vm "O\tD,4,Fm" > -#define rv_fmt_vd_vs1 "O\tD,E" > -#define rv_fmt_vd_rs1 "O\tD,1" > -#define rv_fmt_vd_fs1 "O\tD,4" > -#define rv_fmt_vd_imm "O\tD,i" > -#define rv_fmt_vd_vs2 "O\tD,F" > -#define rv_fmt_vd_vs2_vm "O\tD,Fm" > -#define rv_fmt_rd_vs2_vm "O\t0,Fm" > -#define rv_fmt_rd_vs2 "O\t0,F" > -#define rv_fmt_fd_vs2 "O\t3,F" > -#define rv_fmt_vd_vm "O\tDm" > -#define rv_fmt_vsetvli "O\t0,1,v" > -#define rv_fmt_vsetivli "O\t0,u,v" > -#define rv_fmt_rs1_rs2_zce_ldst "O\t2,i(1)" > -#define rv_fmt_push_rlist "O\tx,-i" > -#define rv_fmt_pop_rlist "O\tx,i" > -#define rv_fmt_zcmt_index "O\ti" > - > /* pseudo-instruction constraints */ > > static const rvc_constraint rvcc_jal[] = { rvc_rd_eq_ra, rvc_end }; > diff --git a/disas/riscv.h b/disas/riscv.h > new file mode 100644 > index 0000000000..0f34b71518 > --- /dev/null > +++ b/disas/riscv.h > @@ -0,0 +1,280 @@ > +/* > + * QEMU disassembler -- RISC-V specific header. > + * > + * SPDX-License-Identifier: GPL-2.0-or-later > + */ > + > +#ifndef DISAS_RISCV_H > +#define DISAS_RISCV_H > + > +#include "qemu/osdep.h" > + > +/* types */ > + > +typedef uint64_t rv_inst; > +typedef uint16_t rv_opcode; > + > +/* enums */ > + > +typedef enum { > + rv32, > + rv64, > + rv128 > +} rv_isa; > + > +typedef enum { > + rv_rm_rne = 0, > + rv_rm_rtz = 1, > + rv_rm_rdn = 2, > + rv_rm_rup = 3, > + rv_rm_rmm = 4, > + rv_rm_dyn = 7, > +} rv_rm; > + > +typedef enum { > + rv_fence_i = 8, > + rv_fence_o = 4, > + rv_fence_r = 2, > + rv_fence_w = 1, > +} rv_fence; > + > +typedef enum { > + rv_ireg_zero, > + rv_ireg_ra, > + rv_ireg_sp, > + rv_ireg_gp, > + rv_ireg_tp, > + rv_ireg_t0, > + rv_ireg_t1, > + rv_ireg_t2, > + rv_ireg_s0, > + rv_ireg_s1, > + rv_ireg_a0, > + rv_ireg_a1, > + rv_ireg_a2, > + rv_ireg_a3, > + rv_ireg_a4, > + rv_ireg_a5, > + rv_ireg_a6, > + rv_ireg_a7, > + rv_ireg_s2, > + rv_ireg_s3, > + rv_ireg_s4, > + rv_ireg_s5, > + rv_ireg_s6, > + rv_ireg_s7, > + rv_ireg_s8, > + rv_ireg_s9, > + rv_ireg_s10, > + rv_ireg_s11, > + rv_ireg_t3, > + rv_ireg_t4, > + rv_ireg_t5, > + rv_ireg_t6, > +} rv_ireg; > + > +typedef enum { > + rvc_end, > + rvc_rd_eq_ra, > + rvc_rd_eq_x0, > + rvc_rs1_eq_x0, > + rvc_rs2_eq_x0, > + rvc_rs2_eq_rs1, > + rvc_rs1_eq_ra, > + rvc_imm_eq_zero, > + rvc_imm_eq_n1, > + rvc_imm_eq_p1, > + rvc_csr_eq_0x001, > + rvc_csr_eq_0x002, > + rvc_csr_eq_0x003, > + rvc_csr_eq_0xc00, > + rvc_csr_eq_0xc01, > + rvc_csr_eq_0xc02, > + rvc_csr_eq_0xc80, > + rvc_csr_eq_0xc81, > + rvc_csr_eq_0xc82, > +} rvc_constraint; > + > +typedef enum { > + rv_codec_illegal, > + rv_codec_none, > + rv_codec_u, > + rv_codec_uj, > + rv_codec_i, > + rv_codec_i_sh5, > + rv_codec_i_sh6, > + rv_codec_i_sh7, > + rv_codec_i_csr, > + rv_codec_s, > + rv_codec_sb, > + rv_codec_r, > + rv_codec_r_m, > + rv_codec_r4_m, > + rv_codec_r_a, > + rv_codec_r_l, > + rv_codec_r_f, > + rv_codec_cb, > + rv_codec_cb_imm, > + rv_codec_cb_sh5, > + rv_codec_cb_sh6, > + rv_codec_ci, > + rv_codec_ci_sh5, > + rv_codec_ci_sh6, > + rv_codec_ci_16sp, > + rv_codec_ci_lwsp, > + rv_codec_ci_ldsp, > + rv_codec_ci_lqsp, > + rv_codec_ci_li, > + rv_codec_ci_lui, > + rv_codec_ci_none, > + rv_codec_ciw_4spn, > + rv_codec_cj, > + rv_codec_cj_jal, > + rv_codec_cl_lw, > + rv_codec_cl_ld, > + rv_codec_cl_lq, > + rv_codec_cr, > + rv_codec_cr_mv, > + rv_codec_cr_jalr, > + rv_codec_cr_jr, > + rv_codec_cs, > + rv_codec_cs_sw, > + rv_codec_cs_sd, > + rv_codec_cs_sq, > + rv_codec_css_swsp, > + rv_codec_css_sdsp, > + rv_codec_css_sqsp, > + rv_codec_k_bs, > + rv_codec_k_rnum, > + rv_codec_v_r, > + rv_codec_v_ldst, > + rv_codec_v_i, > + rv_codec_vsetvli, > + rv_codec_vsetivli, > + rv_codec_zcb_ext, > + rv_codec_zcb_mul, > + rv_codec_zcb_lb, > + rv_codec_zcb_lh, > + rv_codec_zcmp_cm_pushpop, > + rv_codec_zcmp_cm_mv, > + rv_codec_zcmt_jt, > +} rv_codec; > + > +/* structures */ > + > +typedef struct { > + uint64_t pc; > + uint64_t inst; > + int32_t imm; > + uint16_t op; > + uint8_t codec; > + uint8_t rd; > + uint8_t rs1; > + uint8_t rs2; > + uint8_t rs3; > + uint8_t rm; > + uint8_t pred; > + uint8_t succ; > + uint8_t aq; > + uint8_t rl; > + uint8_t bs; > + uint8_t rnum; > + uint8_t vm; > + uint32_t vzimm; > + uint8_t rlist; > +} rv_decode; > + > +typedef struct { > + const int op; > + const rvc_constraint *constraints; > +} rv_comp_data; > + > +enum { > + rvcd_imm_nz = 0x1 > +}; > + > +typedef struct { > + const char * const name; > + const rv_codec codec; > + const char * const format; > + const rv_comp_data *pseudo; > + const short decomp_rv32; > + const short decomp_rv64; > + const short decomp_rv128; > + const short decomp_data; > +} rv_opcode_data; > + > +/* instruction formats */ > + > +#define rv_fmt_none "O\t" > +#define rv_fmt_rs1 "O\t1" > +#define rv_fmt_offset "O\to" > +#define rv_fmt_pred_succ "O\tp,s" > +#define rv_fmt_rs1_rs2 "O\t1,2" > +#define rv_fmt_rd_imm "O\t0,i" > +#define rv_fmt_rd_offset "O\t0,o" > +#define rv_fmt_rd_rs1_rs2 "O\t0,1,2" > +#define rv_fmt_frd_rs1 "O\t3,1" > +#define rv_fmt_frd_frs1 "O\t3,4" > +#define rv_fmt_rd_frs1 "O\t0,4" > +#define rv_fmt_rd_frs1_frs2 "O\t0,4,5" > +#define rv_fmt_frd_frs1_frs2 "O\t3,4,5" > +#define rv_fmt_rm_frd_frs1 "O\tr,3,4" > +#define rv_fmt_rm_frd_rs1 "O\tr,3,1" > +#define rv_fmt_rm_rd_frs1 "O\tr,0,4" > +#define rv_fmt_rm_frd_frs1_frs2 "O\tr,3,4,5" > +#define rv_fmt_rm_frd_frs1_frs2_frs3 "O\tr,3,4,5,6" > +#define rv_fmt_rd_rs1_imm "O\t0,1,i" > +#define rv_fmt_rd_rs1_offset "O\t0,1,i" > +#define rv_fmt_rd_offset_rs1 "O\t0,i(1)" > +#define rv_fmt_frd_offset_rs1 "O\t3,i(1)" > +#define rv_fmt_rd_csr_rs1 "O\t0,c,1" > +#define rv_fmt_rd_csr_zimm "O\t0,c,7" > +#define rv_fmt_rs2_offset_rs1 "O\t2,i(1)" > +#define rv_fmt_frs2_offset_rs1 "O\t5,i(1)" > +#define rv_fmt_rs1_rs2_offset "O\t1,2,o" > +#define rv_fmt_rs2_rs1_offset "O\t2,1,o" > +#define rv_fmt_aqrl_rd_rs2_rs1 "OAR\t0,2,(1)" > +#define rv_fmt_aqrl_rd_rs1 "OAR\t0,(1)" > +#define rv_fmt_rd "O\t0" > +#define rv_fmt_rd_zimm "O\t0,7" > +#define rv_fmt_rd_rs1 "O\t0,1" > +#define rv_fmt_rd_rs2 "O\t0,2" > +#define rv_fmt_rs1_offset "O\t1,o" > +#define rv_fmt_rs2_offset "O\t2,o" > +#define rv_fmt_rs1_rs2_bs "O\t1,2,b" > +#define rv_fmt_rd_rs1_rnum "O\t0,1,n" > +#define rv_fmt_ldst_vd_rs1_vm "O\tD,(1)m" > +#define rv_fmt_ldst_vd_rs1_rs2_vm "O\tD,(1),2m" > +#define rv_fmt_ldst_vd_rs1_vs2_vm "O\tD,(1),Fm" > +#define rv_fmt_vd_vs2_vs1 "O\tD,F,E" > +#define rv_fmt_vd_vs2_vs1_vl "O\tD,F,El" > +#define rv_fmt_vd_vs2_vs1_vm "O\tD,F,Em" > +#define rv_fmt_vd_vs2_rs1_vl "O\tD,F,1l" > +#define rv_fmt_vd_vs2_fs1_vl "O\tD,F,4l" > +#define rv_fmt_vd_vs2_rs1_vm "O\tD,F,1m" > +#define rv_fmt_vd_vs2_fs1_vm "O\tD,F,4m" > +#define rv_fmt_vd_vs2_imm_vl "O\tD,F,il" > +#define rv_fmt_vd_vs2_imm_vm "O\tD,F,im" > +#define rv_fmt_vd_vs2_uimm_vm "O\tD,F,um" > +#define rv_fmt_vd_vs1_vs2_vm "O\tD,E,Fm" > +#define rv_fmt_vd_rs1_vs2_vm "O\tD,1,Fm" > +#define rv_fmt_vd_fs1_vs2_vm "O\tD,4,Fm" > +#define rv_fmt_vd_vs1 "O\tD,E" > +#define rv_fmt_vd_rs1 "O\tD,1" > +#define rv_fmt_vd_fs1 "O\tD,4" > +#define rv_fmt_vd_imm "O\tD,i" > +#define rv_fmt_vd_vs2 "O\tD,F" > +#define rv_fmt_vd_vs2_vm "O\tD,Fm" > +#define rv_fmt_rd_vs2_vm "O\t0,Fm" > +#define rv_fmt_rd_vs2 "O\t0,F" > +#define rv_fmt_fd_vs2 "O\t3,F" > +#define rv_fmt_vd_vm "O\tDm" > +#define rv_fmt_vsetvli "O\t0,1,v" > +#define rv_fmt_vsetivli "O\t0,u,v" > +#define rv_fmt_rs1_rs2_zce_ldst "O\t2,i(1)" > +#define rv_fmt_push_rlist "O\tx,-i" > +#define rv_fmt_pop_rlist "O\tx,i" > +#define rv_fmt_zcmt_index "O\ti" > + > +#endif /* DISAS_RISCV_H */ > -- > 2.40.1 > >
diff --git a/disas/riscv.c b/disas/riscv.c index d597161d46..a062fb48cc 100644 --- a/disas/riscv.c +++ b/disas/riscv.c @@ -19,158 +19,7 @@ #include "qemu/osdep.h" #include "disas/dis-asm.h" - - -/* types */ - -typedef uint64_t rv_inst; -typedef uint16_t rv_opcode; - -/* enums */ - -typedef enum { - rv32, - rv64, - rv128 -} rv_isa; - -typedef enum { - rv_rm_rne = 0, - rv_rm_rtz = 1, - rv_rm_rdn = 2, - rv_rm_rup = 3, - rv_rm_rmm = 4, - rv_rm_dyn = 7, -} rv_rm; - -typedef enum { - rv_fence_i = 8, - rv_fence_o = 4, - rv_fence_r = 2, - rv_fence_w = 1, -} rv_fence; - -typedef enum { - rv_ireg_zero, - rv_ireg_ra, - rv_ireg_sp, - rv_ireg_gp, - rv_ireg_tp, - rv_ireg_t0, - rv_ireg_t1, - rv_ireg_t2, - rv_ireg_s0, - rv_ireg_s1, - rv_ireg_a0, - rv_ireg_a1, - rv_ireg_a2, - rv_ireg_a3, - rv_ireg_a4, - rv_ireg_a5, - rv_ireg_a6, - rv_ireg_a7, - rv_ireg_s2, - rv_ireg_s3, - rv_ireg_s4, - rv_ireg_s5, - rv_ireg_s6, - rv_ireg_s7, - rv_ireg_s8, - rv_ireg_s9, - rv_ireg_s10, - rv_ireg_s11, - rv_ireg_t3, - rv_ireg_t4, - rv_ireg_t5, - rv_ireg_t6, -} rv_ireg; - -typedef enum { - rvc_end, - rvc_rd_eq_ra, - rvc_rd_eq_x0, - rvc_rs1_eq_x0, - rvc_rs2_eq_x0, - rvc_rs2_eq_rs1, - rvc_rs1_eq_ra, - rvc_imm_eq_zero, - rvc_imm_eq_n1, - rvc_imm_eq_p1, - rvc_csr_eq_0x001, - rvc_csr_eq_0x002, - rvc_csr_eq_0x003, - rvc_csr_eq_0xc00, - rvc_csr_eq_0xc01, - rvc_csr_eq_0xc02, - rvc_csr_eq_0xc80, - rvc_csr_eq_0xc81, - rvc_csr_eq_0xc82, -} rvc_constraint; - -typedef enum { - rv_codec_illegal, - rv_codec_none, - rv_codec_u, - rv_codec_uj, - rv_codec_i, - rv_codec_i_sh5, - rv_codec_i_sh6, - rv_codec_i_sh7, - rv_codec_i_csr, - rv_codec_s, - rv_codec_sb, - rv_codec_r, - rv_codec_r_m, - rv_codec_r4_m, - rv_codec_r_a, - rv_codec_r_l, - rv_codec_r_f, - rv_codec_cb, - rv_codec_cb_imm, - rv_codec_cb_sh5, - rv_codec_cb_sh6, - rv_codec_ci, - rv_codec_ci_sh5, - rv_codec_ci_sh6, - rv_codec_ci_16sp, - rv_codec_ci_lwsp, - rv_codec_ci_ldsp, - rv_codec_ci_lqsp, - rv_codec_ci_li, - rv_codec_ci_lui, - rv_codec_ci_none, - rv_codec_ciw_4spn, - rv_codec_cj, - rv_codec_cj_jal, - rv_codec_cl_lw, - rv_codec_cl_ld, - rv_codec_cl_lq, - rv_codec_cr, - rv_codec_cr_mv, - rv_codec_cr_jalr, - rv_codec_cr_jr, - rv_codec_cs, - rv_codec_cs_sw, - rv_codec_cs_sd, - rv_codec_cs_sq, - rv_codec_css_swsp, - rv_codec_css_sdsp, - rv_codec_css_sqsp, - rv_codec_k_bs, - rv_codec_k_rnum, - rv_codec_v_r, - rv_codec_v_ldst, - rv_codec_v_i, - rv_codec_vsetvli, - rv_codec_vsetivli, - rv_codec_zcb_ext, - rv_codec_zcb_mul, - rv_codec_zcb_lb, - rv_codec_zcb_lh, - rv_codec_zcmp_cm_pushpop, - rv_codec_zcmp_cm_mv, - rv_codec_zcmt_jt, -} rv_codec; +#include "disas/riscv.h" typedef enum { rv_op_illegal = 0, @@ -966,50 +815,6 @@ typedef enum { rv_op_czero_nez = 790, } rv_op; -/* structures */ - -typedef struct { - uint64_t pc; - uint64_t inst; - int32_t imm; - uint16_t op; - uint8_t codec; - uint8_t rd; - uint8_t rs1; - uint8_t rs2; - uint8_t rs3; - uint8_t rm; - uint8_t pred; - uint8_t succ; - uint8_t aq; - uint8_t rl; - uint8_t bs; - uint8_t rnum; - uint8_t vm; - uint32_t vzimm; - uint8_t rlist; -} rv_decode; - -typedef struct { - const int op; - const rvc_constraint *constraints; -} rv_comp_data; - -enum { - rvcd_imm_nz = 0x1 -}; - -typedef struct { - const char * const name; - const rv_codec codec; - const char * const format; - const rv_comp_data *pseudo; - const short decomp_rv32; - const short decomp_rv64; - const short decomp_rv128; - const short decomp_data; -} rv_opcode_data; - /* register names */ static const char rv_ireg_name_sym[32][5] = { @@ -1033,79 +838,6 @@ static const char rv_vreg_name_sym[32][4] = { "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31" }; -/* instruction formats */ - -#define rv_fmt_none "O\t" -#define rv_fmt_rs1 "O\t1" -#define rv_fmt_offset "O\to" -#define rv_fmt_pred_succ "O\tp,s" -#define rv_fmt_rs1_rs2 "O\t1,2" -#define rv_fmt_rd_imm "O\t0,i" -#define rv_fmt_rd_offset "O\t0,o" -#define rv_fmt_rd_rs1_rs2 "O\t0,1,2" -#define rv_fmt_frd_rs1 "O\t3,1" -#define rv_fmt_frd_frs1 "O\t3,4" -#define rv_fmt_rd_frs1 "O\t0,4" -#define rv_fmt_rd_frs1_frs2 "O\t0,4,5" -#define rv_fmt_frd_frs1_frs2 "O\t3,4,5" -#define rv_fmt_rm_frd_frs1 "O\tr,3,4" -#define rv_fmt_rm_frd_rs1 "O\tr,3,1" -#define rv_fmt_rm_rd_frs1 "O\tr,0,4" -#define rv_fmt_rm_frd_frs1_frs2 "O\tr,3,4,5" -#define rv_fmt_rm_frd_frs1_frs2_frs3 "O\tr,3,4,5,6" -#define rv_fmt_rd_rs1_imm "O\t0,1,i" -#define rv_fmt_rd_rs1_offset "O\t0,1,i" -#define rv_fmt_rd_offset_rs1 "O\t0,i(1)" -#define rv_fmt_frd_offset_rs1 "O\t3,i(1)" -#define rv_fmt_rd_csr_rs1 "O\t0,c,1" -#define rv_fmt_rd_csr_zimm "O\t0,c,7" -#define rv_fmt_rs2_offset_rs1 "O\t2,i(1)" -#define rv_fmt_frs2_offset_rs1 "O\t5,i(1)" -#define rv_fmt_rs1_rs2_offset "O\t1,2,o" -#define rv_fmt_rs2_rs1_offset "O\t2,1,o" -#define rv_fmt_aqrl_rd_rs2_rs1 "OAR\t0,2,(1)" -#define rv_fmt_aqrl_rd_rs1 "OAR\t0,(1)" -#define rv_fmt_rd "O\t0" -#define rv_fmt_rd_zimm "O\t0,7" -#define rv_fmt_rd_rs1 "O\t0,1" -#define rv_fmt_rd_rs2 "O\t0,2" -#define rv_fmt_rs1_offset "O\t1,o" -#define rv_fmt_rs2_offset "O\t2,o" -#define rv_fmt_rs1_rs2_bs "O\t1,2,b" -#define rv_fmt_rd_rs1_rnum "O\t0,1,n" -#define rv_fmt_ldst_vd_rs1_vm "O\tD,(1)m" -#define rv_fmt_ldst_vd_rs1_rs2_vm "O\tD,(1),2m" -#define rv_fmt_ldst_vd_rs1_vs2_vm "O\tD,(1),Fm" -#define rv_fmt_vd_vs2_vs1 "O\tD,F,E" -#define rv_fmt_vd_vs2_vs1_vl "O\tD,F,El" -#define rv_fmt_vd_vs2_vs1_vm "O\tD,F,Em" -#define rv_fmt_vd_vs2_rs1_vl "O\tD,F,1l" -#define rv_fmt_vd_vs2_fs1_vl "O\tD,F,4l" -#define rv_fmt_vd_vs2_rs1_vm "O\tD,F,1m" -#define rv_fmt_vd_vs2_fs1_vm "O\tD,F,4m" -#define rv_fmt_vd_vs2_imm_vl "O\tD,F,il" -#define rv_fmt_vd_vs2_imm_vm "O\tD,F,im" -#define rv_fmt_vd_vs2_uimm_vm "O\tD,F,um" -#define rv_fmt_vd_vs1_vs2_vm "O\tD,E,Fm" -#define rv_fmt_vd_rs1_vs2_vm "O\tD,1,Fm" -#define rv_fmt_vd_fs1_vs2_vm "O\tD,4,Fm" -#define rv_fmt_vd_vs1 "O\tD,E" -#define rv_fmt_vd_rs1 "O\tD,1" -#define rv_fmt_vd_fs1 "O\tD,4" -#define rv_fmt_vd_imm "O\tD,i" -#define rv_fmt_vd_vs2 "O\tD,F" -#define rv_fmt_vd_vs2_vm "O\tD,Fm" -#define rv_fmt_rd_vs2_vm "O\t0,Fm" -#define rv_fmt_rd_vs2 "O\t0,F" -#define rv_fmt_fd_vs2 "O\t3,F" -#define rv_fmt_vd_vm "O\tDm" -#define rv_fmt_vsetvli "O\t0,1,v" -#define rv_fmt_vsetivli "O\t0,u,v" -#define rv_fmt_rs1_rs2_zce_ldst "O\t2,i(1)" -#define rv_fmt_push_rlist "O\tx,-i" -#define rv_fmt_pop_rlist "O\tx,i" -#define rv_fmt_zcmt_index "O\ti" - /* pseudo-instruction constraints */ static const rvc_constraint rvcc_jal[] = { rvc_rd_eq_ra, rvc_end }; diff --git a/disas/riscv.h b/disas/riscv.h new file mode 100644 index 0000000000..0f34b71518 --- /dev/null +++ b/disas/riscv.h @@ -0,0 +1,280 @@ +/* + * QEMU disassembler -- RISC-V specific header. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef DISAS_RISCV_H +#define DISAS_RISCV_H + +#include "qemu/osdep.h" + +/* types */ + +typedef uint64_t rv_inst; +typedef uint16_t rv_opcode; + +/* enums */ + +typedef enum { + rv32, + rv64, + rv128 +} rv_isa; + +typedef enum { + rv_rm_rne = 0, + rv_rm_rtz = 1, + rv_rm_rdn = 2, + rv_rm_rup = 3, + rv_rm_rmm = 4, + rv_rm_dyn = 7, +} rv_rm; + +typedef enum { + rv_fence_i = 8, + rv_fence_o = 4, + rv_fence_r = 2, + rv_fence_w = 1, +} rv_fence; + +typedef enum { + rv_ireg_zero, + rv_ireg_ra, + rv_ireg_sp, + rv_ireg_gp, + rv_ireg_tp, + rv_ireg_t0, + rv_ireg_t1, + rv_ireg_t2, + rv_ireg_s0, + rv_ireg_s1, + rv_ireg_a0, + rv_ireg_a1, + rv_ireg_a2, + rv_ireg_a3, + rv_ireg_a4, + rv_ireg_a5, + rv_ireg_a6, + rv_ireg_a7, + rv_ireg_s2, + rv_ireg_s3, + rv_ireg_s4, + rv_ireg_s5, + rv_ireg_s6, + rv_ireg_s7, + rv_ireg_s8, + rv_ireg_s9, + rv_ireg_s10, + rv_ireg_s11, + rv_ireg_t3, + rv_ireg_t4, + rv_ireg_t5, + rv_ireg_t6, +} rv_ireg; + +typedef enum { + rvc_end, + rvc_rd_eq_ra, + rvc_rd_eq_x0, + rvc_rs1_eq_x0, + rvc_rs2_eq_x0, + rvc_rs2_eq_rs1, + rvc_rs1_eq_ra, + rvc_imm_eq_zero, + rvc_imm_eq_n1, + rvc_imm_eq_p1, + rvc_csr_eq_0x001, + rvc_csr_eq_0x002, + rvc_csr_eq_0x003, + rvc_csr_eq_0xc00, + rvc_csr_eq_0xc01, + rvc_csr_eq_0xc02, + rvc_csr_eq_0xc80, + rvc_csr_eq_0xc81, + rvc_csr_eq_0xc82, +} rvc_constraint; + +typedef enum { + rv_codec_illegal, + rv_codec_none, + rv_codec_u, + rv_codec_uj, + rv_codec_i, + rv_codec_i_sh5, + rv_codec_i_sh6, + rv_codec_i_sh7, + rv_codec_i_csr, + rv_codec_s, + rv_codec_sb, + rv_codec_r, + rv_codec_r_m, + rv_codec_r4_m, + rv_codec_r_a, + rv_codec_r_l, + rv_codec_r_f, + rv_codec_cb, + rv_codec_cb_imm, + rv_codec_cb_sh5, + rv_codec_cb_sh6, + rv_codec_ci, + rv_codec_ci_sh5, + rv_codec_ci_sh6, + rv_codec_ci_16sp, + rv_codec_ci_lwsp, + rv_codec_ci_ldsp, + rv_codec_ci_lqsp, + rv_codec_ci_li, + rv_codec_ci_lui, + rv_codec_ci_none, + rv_codec_ciw_4spn, + rv_codec_cj, + rv_codec_cj_jal, + rv_codec_cl_lw, + rv_codec_cl_ld, + rv_codec_cl_lq, + rv_codec_cr, + rv_codec_cr_mv, + rv_codec_cr_jalr, + rv_codec_cr_jr, + rv_codec_cs, + rv_codec_cs_sw, + rv_codec_cs_sd, + rv_codec_cs_sq, + rv_codec_css_swsp, + rv_codec_css_sdsp, + rv_codec_css_sqsp, + rv_codec_k_bs, + rv_codec_k_rnum, + rv_codec_v_r, + rv_codec_v_ldst, + rv_codec_v_i, + rv_codec_vsetvli, + rv_codec_vsetivli, + rv_codec_zcb_ext, + rv_codec_zcb_mul, + rv_codec_zcb_lb, + rv_codec_zcb_lh, + rv_codec_zcmp_cm_pushpop, + rv_codec_zcmp_cm_mv, + rv_codec_zcmt_jt, +} rv_codec; + +/* structures */ + +typedef struct { + uint64_t pc; + uint64_t inst; + int32_t imm; + uint16_t op; + uint8_t codec; + uint8_t rd; + uint8_t rs1; + uint8_t rs2; + uint8_t rs3; + uint8_t rm; + uint8_t pred; + uint8_t succ; + uint8_t aq; + uint8_t rl; + uint8_t bs; + uint8_t rnum; + uint8_t vm; + uint32_t vzimm; + uint8_t rlist; +} rv_decode; + +typedef struct { + const int op; + const rvc_constraint *constraints; +} rv_comp_data; + +enum { + rvcd_imm_nz = 0x1 +}; + +typedef struct { + const char * const name; + const rv_codec codec; + const char * const format; + const rv_comp_data *pseudo; + const short decomp_rv32; + const short decomp_rv64; + const short decomp_rv128; + const short decomp_data; +} rv_opcode_data; + +/* instruction formats */ + +#define rv_fmt_none "O\t" +#define rv_fmt_rs1 "O\t1" +#define rv_fmt_offset "O\to" +#define rv_fmt_pred_succ "O\tp,s" +#define rv_fmt_rs1_rs2 "O\t1,2" +#define rv_fmt_rd_imm "O\t0,i" +#define rv_fmt_rd_offset "O\t0,o" +#define rv_fmt_rd_rs1_rs2 "O\t0,1,2" +#define rv_fmt_frd_rs1 "O\t3,1" +#define rv_fmt_frd_frs1 "O\t3,4" +#define rv_fmt_rd_frs1 "O\t0,4" +#define rv_fmt_rd_frs1_frs2 "O\t0,4,5" +#define rv_fmt_frd_frs1_frs2 "O\t3,4,5" +#define rv_fmt_rm_frd_frs1 "O\tr,3,4" +#define rv_fmt_rm_frd_rs1 "O\tr,3,1" +#define rv_fmt_rm_rd_frs1 "O\tr,0,4" +#define rv_fmt_rm_frd_frs1_frs2 "O\tr,3,4,5" +#define rv_fmt_rm_frd_frs1_frs2_frs3 "O\tr,3,4,5,6" +#define rv_fmt_rd_rs1_imm "O\t0,1,i" +#define rv_fmt_rd_rs1_offset "O\t0,1,i" +#define rv_fmt_rd_offset_rs1 "O\t0,i(1)" +#define rv_fmt_frd_offset_rs1 "O\t3,i(1)" +#define rv_fmt_rd_csr_rs1 "O\t0,c,1" +#define rv_fmt_rd_csr_zimm "O\t0,c,7" +#define rv_fmt_rs2_offset_rs1 "O\t2,i(1)" +#define rv_fmt_frs2_offset_rs1 "O\t5,i(1)" +#define rv_fmt_rs1_rs2_offset "O\t1,2,o" +#define rv_fmt_rs2_rs1_offset "O\t2,1,o" +#define rv_fmt_aqrl_rd_rs2_rs1 "OAR\t0,2,(1)" +#define rv_fmt_aqrl_rd_rs1 "OAR\t0,(1)" +#define rv_fmt_rd "O\t0" +#define rv_fmt_rd_zimm "O\t0,7" +#define rv_fmt_rd_rs1 "O\t0,1" +#define rv_fmt_rd_rs2 "O\t0,2" +#define rv_fmt_rs1_offset "O\t1,o" +#define rv_fmt_rs2_offset "O\t2,o" +#define rv_fmt_rs1_rs2_bs "O\t1,2,b" +#define rv_fmt_rd_rs1_rnum "O\t0,1,n" +#define rv_fmt_ldst_vd_rs1_vm "O\tD,(1)m" +#define rv_fmt_ldst_vd_rs1_rs2_vm "O\tD,(1),2m" +#define rv_fmt_ldst_vd_rs1_vs2_vm "O\tD,(1),Fm" +#define rv_fmt_vd_vs2_vs1 "O\tD,F,E" +#define rv_fmt_vd_vs2_vs1_vl "O\tD,F,El" +#define rv_fmt_vd_vs2_vs1_vm "O\tD,F,Em" +#define rv_fmt_vd_vs2_rs1_vl "O\tD,F,1l" +#define rv_fmt_vd_vs2_fs1_vl "O\tD,F,4l" +#define rv_fmt_vd_vs2_rs1_vm "O\tD,F,1m" +#define rv_fmt_vd_vs2_fs1_vm "O\tD,F,4m" +#define rv_fmt_vd_vs2_imm_vl "O\tD,F,il" +#define rv_fmt_vd_vs2_imm_vm "O\tD,F,im" +#define rv_fmt_vd_vs2_uimm_vm "O\tD,F,um" +#define rv_fmt_vd_vs1_vs2_vm "O\tD,E,Fm" +#define rv_fmt_vd_rs1_vs2_vm "O\tD,1,Fm" +#define rv_fmt_vd_fs1_vs2_vm "O\tD,4,Fm" +#define rv_fmt_vd_vs1 "O\tD,E" +#define rv_fmt_vd_rs1 "O\tD,1" +#define rv_fmt_vd_fs1 "O\tD,4" +#define rv_fmt_vd_imm "O\tD,i" +#define rv_fmt_vd_vs2 "O\tD,F" +#define rv_fmt_vd_vs2_vm "O\tD,Fm" +#define rv_fmt_rd_vs2_vm "O\t0,Fm" +#define rv_fmt_rd_vs2 "O\t0,F" +#define rv_fmt_fd_vs2 "O\t3,F" +#define rv_fmt_vd_vm "O\tDm" +#define rv_fmt_vsetvli "O\t0,1,v" +#define rv_fmt_vsetivli "O\t0,u,v" +#define rv_fmt_rs1_rs2_zce_ldst "O\t2,i(1)" +#define rv_fmt_push_rlist "O\tx,-i" +#define rv_fmt_pop_rlist "O\tx,i" +#define rv_fmt_zcmt_index "O\ti" + +#endif /* DISAS_RISCV_H */