xref: /qemu/disas/riscv.h (revision 3910de6f)
15d326db2SChristoph Müllner /*
25d326db2SChristoph Müllner  * QEMU disassembler -- RISC-V specific header.
35d326db2SChristoph Müllner  *
45d326db2SChristoph Müllner  * SPDX-License-Identifier: GPL-2.0-or-later
55d326db2SChristoph Müllner  */
65d326db2SChristoph Müllner 
75d326db2SChristoph Müllner #ifndef DISAS_RISCV_H
85d326db2SChristoph Müllner #define DISAS_RISCV_H
95d326db2SChristoph Müllner 
105d326db2SChristoph Müllner #include "target/riscv/cpu_cfg.h"
115d326db2SChristoph Müllner 
125d326db2SChristoph Müllner /* types */
135d326db2SChristoph Müllner 
145d326db2SChristoph Müllner typedef uint64_t rv_inst;
155d326db2SChristoph Müllner typedef uint16_t rv_opcode;
165d326db2SChristoph Müllner 
175d326db2SChristoph Müllner /* enums */
185d326db2SChristoph Müllner 
195d326db2SChristoph Müllner typedef enum {
205d326db2SChristoph Müllner     rv32,
215d326db2SChristoph Müllner     rv64,
225d326db2SChristoph Müllner     rv128
235d326db2SChristoph Müllner } rv_isa;
245d326db2SChristoph Müllner 
255d326db2SChristoph Müllner typedef enum {
265d326db2SChristoph Müllner     rv_rm_rne = 0,
275d326db2SChristoph Müllner     rv_rm_rtz = 1,
285d326db2SChristoph Müllner     rv_rm_rdn = 2,
295d326db2SChristoph Müllner     rv_rm_rup = 3,
305d326db2SChristoph Müllner     rv_rm_rmm = 4,
315d326db2SChristoph Müllner     rv_rm_dyn = 7,
325d326db2SChristoph Müllner } rv_rm;
335d326db2SChristoph Müllner 
345d326db2SChristoph Müllner typedef enum {
355d326db2SChristoph Müllner     rv_fence_i = 8,
365d326db2SChristoph Müllner     rv_fence_o = 4,
375d326db2SChristoph Müllner     rv_fence_r = 2,
385d326db2SChristoph Müllner     rv_fence_w = 1,
395d326db2SChristoph Müllner } rv_fence;
405d326db2SChristoph Müllner 
415d326db2SChristoph Müllner typedef enum {
425d326db2SChristoph Müllner     rv_ireg_zero,
435d326db2SChristoph Müllner     rv_ireg_ra,
445d326db2SChristoph Müllner     rv_ireg_sp,
455d326db2SChristoph Müllner     rv_ireg_gp,
465d326db2SChristoph Müllner     rv_ireg_tp,
475d326db2SChristoph Müllner     rv_ireg_t0,
485d326db2SChristoph Müllner     rv_ireg_t1,
495d326db2SChristoph Müllner     rv_ireg_t2,
505d326db2SChristoph Müllner     rv_ireg_s0,
515d326db2SChristoph Müllner     rv_ireg_s1,
525d326db2SChristoph Müllner     rv_ireg_a0,
535d326db2SChristoph Müllner     rv_ireg_a1,
545d326db2SChristoph Müllner     rv_ireg_a2,
555d326db2SChristoph Müllner     rv_ireg_a3,
565d326db2SChristoph Müllner     rv_ireg_a4,
575d326db2SChristoph Müllner     rv_ireg_a5,
585d326db2SChristoph Müllner     rv_ireg_a6,
595d326db2SChristoph Müllner     rv_ireg_a7,
605d326db2SChristoph Müllner     rv_ireg_s2,
615d326db2SChristoph Müllner     rv_ireg_s3,
625d326db2SChristoph Müllner     rv_ireg_s4,
635d326db2SChristoph Müllner     rv_ireg_s5,
645d326db2SChristoph Müllner     rv_ireg_s6,
655d326db2SChristoph Müllner     rv_ireg_s7,
665d326db2SChristoph Müllner     rv_ireg_s8,
675d326db2SChristoph Müllner     rv_ireg_s9,
685d326db2SChristoph Müllner     rv_ireg_s10,
695d326db2SChristoph Müllner     rv_ireg_s11,
705d326db2SChristoph Müllner     rv_ireg_t3,
715d326db2SChristoph Müllner     rv_ireg_t4,
725d326db2SChristoph Müllner     rv_ireg_t5,
735d326db2SChristoph Müllner     rv_ireg_t6,
745d326db2SChristoph Müllner } rv_ireg;
755d326db2SChristoph Müllner 
765d326db2SChristoph Müllner typedef enum {
775d326db2SChristoph Müllner     rvc_end,
785d326db2SChristoph Müllner     rvc_rd_eq_ra,
795d326db2SChristoph Müllner     rvc_rd_eq_x0,
805d326db2SChristoph Müllner     rvc_rs1_eq_x0,
815d326db2SChristoph Müllner     rvc_rs2_eq_x0,
825d326db2SChristoph Müllner     rvc_rs2_eq_rs1,
835d326db2SChristoph Müllner     rvc_rs1_eq_ra,
845d326db2SChristoph Müllner     rvc_imm_eq_zero,
855d326db2SChristoph Müllner     rvc_imm_eq_n1,
865d326db2SChristoph Müllner     rvc_imm_eq_p1,
875d326db2SChristoph Müllner     rvc_csr_eq_0x001,
885d326db2SChristoph Müllner     rvc_csr_eq_0x002,
895d326db2SChristoph Müllner     rvc_csr_eq_0x003,
905d326db2SChristoph Müllner     rvc_csr_eq_0xc00,
915d326db2SChristoph Müllner     rvc_csr_eq_0xc01,
925d326db2SChristoph Müllner     rvc_csr_eq_0xc02,
935d326db2SChristoph Müllner     rvc_csr_eq_0xc80,
945d326db2SChristoph Müllner     rvc_csr_eq_0xc81,
955d326db2SChristoph Müllner     rvc_csr_eq_0xc82,
965d326db2SChristoph Müllner } rvc_constraint;
975d326db2SChristoph Müllner 
985d326db2SChristoph Müllner typedef enum {
995d326db2SChristoph Müllner     rv_codec_illegal,
1005d326db2SChristoph Müllner     rv_codec_none,
1015d326db2SChristoph Müllner     rv_codec_u,
1025d326db2SChristoph Müllner     rv_codec_uj,
1035d326db2SChristoph Müllner     rv_codec_i,
1045d326db2SChristoph Müllner     rv_codec_i_sh5,
1055d326db2SChristoph Müllner     rv_codec_i_sh6,
1065d326db2SChristoph Müllner     rv_codec_i_sh7,
1075d326db2SChristoph Müllner     rv_codec_i_csr,
1085d326db2SChristoph Müllner     rv_codec_s,
1095d326db2SChristoph Müllner     rv_codec_sb,
1105d326db2SChristoph Müllner     rv_codec_r,
1115d326db2SChristoph Müllner     rv_codec_r_m,
1125d326db2SChristoph Müllner     rv_codec_r4_m,
1135d326db2SChristoph Müllner     rv_codec_r_a,
1145d326db2SChristoph Müllner     rv_codec_r_l,
1155d326db2SChristoph Müllner     rv_codec_r_f,
1165d326db2SChristoph Müllner     rv_codec_cb,
1175d326db2SChristoph Müllner     rv_codec_cb_imm,
1185d326db2SChristoph Müllner     rv_codec_cb_sh5,
1195d326db2SChristoph Müllner     rv_codec_cb_sh6,
1205d326db2SChristoph Müllner     rv_codec_ci,
1215d326db2SChristoph Müllner     rv_codec_ci_sh5,
1225d326db2SChristoph Müllner     rv_codec_ci_sh6,
1235d326db2SChristoph Müllner     rv_codec_ci_16sp,
1245d326db2SChristoph Müllner     rv_codec_ci_lwsp,
1255d326db2SChristoph Müllner     rv_codec_ci_ldsp,
1265d326db2SChristoph Müllner     rv_codec_ci_lqsp,
1275d326db2SChristoph Müllner     rv_codec_ci_li,
1285d326db2SChristoph Müllner     rv_codec_ci_lui,
1295d326db2SChristoph Müllner     rv_codec_ci_none,
1305d326db2SChristoph Müllner     rv_codec_ciw_4spn,
1315d326db2SChristoph Müllner     rv_codec_cj,
1325d326db2SChristoph Müllner     rv_codec_cj_jal,
1335d326db2SChristoph Müllner     rv_codec_cl_lw,
1345d326db2SChristoph Müllner     rv_codec_cl_ld,
1355d326db2SChristoph Müllner     rv_codec_cl_lq,
1365d326db2SChristoph Müllner     rv_codec_cr,
1375d326db2SChristoph Müllner     rv_codec_cr_mv,
1385d326db2SChristoph Müllner     rv_codec_cr_jalr,
1395d326db2SChristoph Müllner     rv_codec_cr_jr,
1405d326db2SChristoph Müllner     rv_codec_cs,
1415d326db2SChristoph Müllner     rv_codec_cs_sw,
1425d326db2SChristoph Müllner     rv_codec_cs_sd,
1435d326db2SChristoph Müllner     rv_codec_cs_sq,
1445d326db2SChristoph Müllner     rv_codec_css_swsp,
1455d326db2SChristoph Müllner     rv_codec_css_sdsp,
1465d326db2SChristoph Müllner     rv_codec_css_sqsp,
1475d326db2SChristoph Müllner     rv_codec_k_bs,
1485d326db2SChristoph Müllner     rv_codec_k_rnum,
1495d326db2SChristoph Müllner     rv_codec_v_r,
1505d326db2SChristoph Müllner     rv_codec_v_ldst,
1515d326db2SChristoph Müllner     rv_codec_v_i,
1525d326db2SChristoph Müllner     rv_codec_vsetvli,
1535d326db2SChristoph Müllner     rv_codec_vsetivli,
154434c609bSMax Chou     rv_codec_vror_vi,
1555d326db2SChristoph Müllner     rv_codec_zcb_ext,
1565d326db2SChristoph Müllner     rv_codec_zcb_mul,
1575d326db2SChristoph Müllner     rv_codec_zcb_lb,
1585d326db2SChristoph Müllner     rv_codec_zcb_lh,
1595d326db2SChristoph Müllner     rv_codec_zcmp_cm_pushpop,
1605d326db2SChristoph Müllner     rv_codec_zcmp_cm_mv,
1615d326db2SChristoph Müllner     rv_codec_zcmt_jt,
162318df723SChristoph Müllner     rv_codec_r2_imm5,
163318df723SChristoph Müllner     rv_codec_r2,
164318df723SChristoph Müllner     rv_codec_r2_imm6,
165318df723SChristoph Müllner     rv_codec_r_imm2,
166318df723SChristoph Müllner     rv_codec_r2_immhl,
167318df723SChristoph Müllner     rv_codec_r2_imm2_imm5,
168a47842d1SChristoph Müllner     rv_codec_fli,
1695d326db2SChristoph Müllner } rv_codec;
1705d326db2SChristoph Müllner 
1715d326db2SChristoph Müllner /* structures */
1725d326db2SChristoph Müllner 
1735d326db2SChristoph Müllner typedef struct {
174fd7c64f6SChristoph Müllner     const int op;
175fd7c64f6SChristoph Müllner     const rvc_constraint *constraints;
176fd7c64f6SChristoph Müllner } rv_comp_data;
177fd7c64f6SChristoph Müllner 
178fd7c64f6SChristoph Müllner typedef struct {
179fd7c64f6SChristoph Müllner     const char * const name;
180fd7c64f6SChristoph Müllner     const rv_codec codec;
181fd7c64f6SChristoph Müllner     const char * const format;
182fd7c64f6SChristoph Müllner     const rv_comp_data *pseudo;
183fd7c64f6SChristoph Müllner     const short decomp_rv32;
184fd7c64f6SChristoph Müllner     const short decomp_rv64;
185fd7c64f6SChristoph Müllner     const short decomp_rv128;
186fd7c64f6SChristoph Müllner     const short decomp_data;
187fd7c64f6SChristoph Müllner } rv_opcode_data;
188fd7c64f6SChristoph Müllner 
189fd7c64f6SChristoph Müllner typedef struct {
1905d326db2SChristoph Müllner     RISCVCPUConfig *cfg;
1915d326db2SChristoph Müllner     uint64_t  pc;
1925d326db2SChristoph Müllner     uint64_t  inst;
193fd7c64f6SChristoph Müllner     const rv_opcode_data *opcode_data;
1945d326db2SChristoph Müllner     int32_t   imm;
195318df723SChristoph Müllner     int32_t   imm1;
1965d326db2SChristoph Müllner     uint16_t  op;
1975d326db2SChristoph Müllner     uint8_t   codec;
1985d326db2SChristoph Müllner     uint8_t   rd;
1995d326db2SChristoph Müllner     uint8_t   rs1;
2005d326db2SChristoph Müllner     uint8_t   rs2;
2015d326db2SChristoph Müllner     uint8_t   rs3;
2025d326db2SChristoph Müllner     uint8_t   rm;
2035d326db2SChristoph Müllner     uint8_t   pred;
2045d326db2SChristoph Müllner     uint8_t   succ;
2055d326db2SChristoph Müllner     uint8_t   aq;
2065d326db2SChristoph Müllner     uint8_t   rl;
2075d326db2SChristoph Müllner     uint8_t   bs;
2085d326db2SChristoph Müllner     uint8_t   rnum;
2095d326db2SChristoph Müllner     uint8_t   vm;
2105d326db2SChristoph Müllner     uint32_t  vzimm;
2115d326db2SChristoph Müllner     uint8_t   rlist;
2125d326db2SChristoph Müllner } rv_decode;
2135d326db2SChristoph Müllner 
2145d326db2SChristoph Müllner enum {
21501b1361fSChristoph Müllner     rv_op_illegal = 0
21601b1361fSChristoph Müllner };
21701b1361fSChristoph Müllner 
21801b1361fSChristoph Müllner enum {
2195d326db2SChristoph Müllner     rvcd_imm_nz = 0x1
2205d326db2SChristoph Müllner };
2215d326db2SChristoph Müllner 
2225d326db2SChristoph Müllner /* instruction formats */
2235d326db2SChristoph Müllner 
2245d326db2SChristoph Müllner #define rv_fmt_none                   "O\t"
2255d326db2SChristoph Müllner #define rv_fmt_rs1                    "O\t1"
2265d326db2SChristoph Müllner #define rv_fmt_offset                 "O\to"
2275d326db2SChristoph Müllner #define rv_fmt_pred_succ              "O\tp,s"
2285d326db2SChristoph Müllner #define rv_fmt_rs1_rs2                "O\t1,2"
2295d326db2SChristoph Müllner #define rv_fmt_rd_imm                 "O\t0,i"
23036df75a0SChristoph Müllner #define rv_fmt_rd_uimm                "O\t0,Ui"
2315d326db2SChristoph Müllner #define rv_fmt_rd_offset              "O\t0,o"
23236df75a0SChristoph Müllner #define rv_fmt_rd_uoffset             "O\t0,Uo"
2335d326db2SChristoph Müllner #define rv_fmt_rd_rs1_rs2             "O\t0,1,2"
2345d326db2SChristoph Müllner #define rv_fmt_frd_rs1                "O\t3,1"
235a47842d1SChristoph Müllner #define rv_fmt_frd_rs1_rs2            "O\t3,1,2"
2365d326db2SChristoph Müllner #define rv_fmt_frd_frs1               "O\t3,4"
2375d326db2SChristoph Müllner #define rv_fmt_rd_frs1                "O\t0,4"
2385d326db2SChristoph Müllner #define rv_fmt_rd_frs1_frs2           "O\t0,4,5"
2395d326db2SChristoph Müllner #define rv_fmt_frd_frs1_frs2          "O\t3,4,5"
2405d326db2SChristoph Müllner #define rv_fmt_rm_frd_frs1            "O\tr,3,4"
2415d326db2SChristoph Müllner #define rv_fmt_rm_frd_rs1             "O\tr,3,1"
2425d326db2SChristoph Müllner #define rv_fmt_rm_rd_frs1             "O\tr,0,4"
2435d326db2SChristoph Müllner #define rv_fmt_rm_frd_frs1_frs2       "O\tr,3,4,5"
2445d326db2SChristoph Müllner #define rv_fmt_rm_frd_frs1_frs2_frs3  "O\tr,3,4,5,6"
2455d326db2SChristoph Müllner #define rv_fmt_rd_rs1_imm             "O\t0,1,i"
2465d326db2SChristoph Müllner #define rv_fmt_rd_rs1_offset          "O\t0,1,i"
2475d326db2SChristoph Müllner #define rv_fmt_rd_offset_rs1          "O\t0,i(1)"
2485d326db2SChristoph Müllner #define rv_fmt_frd_offset_rs1         "O\t3,i(1)"
2495d326db2SChristoph Müllner #define rv_fmt_rd_csr_rs1             "O\t0,c,1"
2505d326db2SChristoph Müllner #define rv_fmt_rd_csr_zimm            "O\t0,c,7"
2515d326db2SChristoph Müllner #define rv_fmt_rs2_offset_rs1         "O\t2,i(1)"
2525d326db2SChristoph Müllner #define rv_fmt_frs2_offset_rs1        "O\t5,i(1)"
2535d326db2SChristoph Müllner #define rv_fmt_rs1_rs2_offset         "O\t1,2,o"
2545d326db2SChristoph Müllner #define rv_fmt_rs2_rs1_offset         "O\t2,1,o"
2555d326db2SChristoph Müllner #define rv_fmt_aqrl_rd_rs2_rs1        "OAR\t0,2,(1)"
2565d326db2SChristoph Müllner #define rv_fmt_aqrl_rd_rs1            "OAR\t0,(1)"
2575d326db2SChristoph Müllner #define rv_fmt_rd                     "O\t0"
2585d326db2SChristoph Müllner #define rv_fmt_rd_zimm                "O\t0,7"
2595d326db2SChristoph Müllner #define rv_fmt_rd_rs1                 "O\t0,1"
2605d326db2SChristoph Müllner #define rv_fmt_rd_rs2                 "O\t0,2"
2615d326db2SChristoph Müllner #define rv_fmt_rs1_offset             "O\t1,o"
2625d326db2SChristoph Müllner #define rv_fmt_rs2_offset             "O\t2,o"
2635d326db2SChristoph Müllner #define rv_fmt_rs1_rs2_bs             "O\t1,2,b"
2645d326db2SChristoph Müllner #define rv_fmt_rd_rs1_rnum            "O\t0,1,n"
2655d326db2SChristoph Müllner #define rv_fmt_ldst_vd_rs1_vm         "O\tD,(1)m"
2665d326db2SChristoph Müllner #define rv_fmt_ldst_vd_rs1_rs2_vm     "O\tD,(1),2m"
2675d326db2SChristoph Müllner #define rv_fmt_ldst_vd_rs1_vs2_vm     "O\tD,(1),Fm"
2685d326db2SChristoph Müllner #define rv_fmt_vd_vs2_vs1             "O\tD,F,E"
2695d326db2SChristoph Müllner #define rv_fmt_vd_vs2_vs1_vl          "O\tD,F,El"
2705d326db2SChristoph Müllner #define rv_fmt_vd_vs2_vs1_vm          "O\tD,F,Em"
2715d326db2SChristoph Müllner #define rv_fmt_vd_vs2_rs1_vl          "O\tD,F,1l"
2725d326db2SChristoph Müllner #define rv_fmt_vd_vs2_fs1_vl          "O\tD,F,4l"
2735d326db2SChristoph Müllner #define rv_fmt_vd_vs2_rs1_vm          "O\tD,F,1m"
2745d326db2SChristoph Müllner #define rv_fmt_vd_vs2_fs1_vm          "O\tD,F,4m"
2755d326db2SChristoph Müllner #define rv_fmt_vd_vs2_imm_vl          "O\tD,F,il"
2765d326db2SChristoph Müllner #define rv_fmt_vd_vs2_imm_vm          "O\tD,F,im"
277ea363626SMax Chou #define rv_fmt_vd_vs2_uimm            "O\tD,F,u"
2785d326db2SChristoph Müllner #define rv_fmt_vd_vs2_uimm_vm         "O\tD,F,um"
2795d326db2SChristoph Müllner #define rv_fmt_vd_vs1_vs2_vm          "O\tD,E,Fm"
2805d326db2SChristoph Müllner #define rv_fmt_vd_rs1_vs2_vm          "O\tD,1,Fm"
2815d326db2SChristoph Müllner #define rv_fmt_vd_fs1_vs2_vm          "O\tD,4,Fm"
2825d326db2SChristoph Müllner #define rv_fmt_vd_vs1                 "O\tD,E"
2835d326db2SChristoph Müllner #define rv_fmt_vd_rs1                 "O\tD,1"
2845d326db2SChristoph Müllner #define rv_fmt_vd_fs1                 "O\tD,4"
2855d326db2SChristoph Müllner #define rv_fmt_vd_imm                 "O\tD,i"
2865d326db2SChristoph Müllner #define rv_fmt_vd_vs2                 "O\tD,F"
2875d326db2SChristoph Müllner #define rv_fmt_vd_vs2_vm              "O\tD,Fm"
2885d326db2SChristoph Müllner #define rv_fmt_rd_vs2_vm              "O\t0,Fm"
2895d326db2SChristoph Müllner #define rv_fmt_rd_vs2                 "O\t0,F"
2905d326db2SChristoph Müllner #define rv_fmt_fd_vs2                 "O\t3,F"
2915d326db2SChristoph Müllner #define rv_fmt_vd_vm                  "O\tDm"
2925d326db2SChristoph Müllner #define rv_fmt_vsetvli                "O\t0,1,v"
2935d326db2SChristoph Müllner #define rv_fmt_vsetivli               "O\t0,u,v"
2945d326db2SChristoph Müllner #define rv_fmt_rs1_rs2_zce_ldst       "O\t2,i(1)"
2955d326db2SChristoph Müllner #define rv_fmt_push_rlist             "O\tx,-i"
2965d326db2SChristoph Müllner #define rv_fmt_pop_rlist              "O\tx,i"
2975d326db2SChristoph Müllner #define rv_fmt_zcmt_index             "O\ti"
298318df723SChristoph Müllner #define rv_fmt_rd_rs1_rs2_imm         "O\t0,1,2,i"
299318df723SChristoph Müllner #define rv_fmt_frd_rs1_rs2_imm        "O\t3,1,2,i"
300318df723SChristoph Müllner #define rv_fmt_rd_rs1_immh_imml       "O\t0,1,i,j"
301318df723SChristoph Müllner #define rv_fmt_rd_rs1_immh_imml_addr  "O\t0,(1),i,j"
302318df723SChristoph Müllner #define rv_fmt_rd2_imm                "O\t0,2,(1),i"
303a47842d1SChristoph Müllner #define rv_fmt_fli                    "O\t3,h"
3045d326db2SChristoph Müllner 
3055d326db2SChristoph Müllner #endif /* DISAS_RISCV_H */
306