1 /* 2 * QEMU disassembler -- RISC-V specific header. 3 * 4 * SPDX-License-Identifier: GPL-2.0-or-later 5 */ 6 7 #ifndef DISAS_RISCV_H 8 #define DISAS_RISCV_H 9 10 #include "target/riscv/cpu_cfg.h" 11 12 /* types */ 13 14 typedef uint64_t rv_inst; 15 typedef uint16_t rv_opcode; 16 17 /* enums */ 18 19 typedef enum { 20 rv32, 21 rv64, 22 rv128 23 } rv_isa; 24 25 typedef enum { 26 rv_rm_rne = 0, 27 rv_rm_rtz = 1, 28 rv_rm_rdn = 2, 29 rv_rm_rup = 3, 30 rv_rm_rmm = 4, 31 rv_rm_dyn = 7, 32 } rv_rm; 33 34 typedef enum { 35 rv_fence_i = 8, 36 rv_fence_o = 4, 37 rv_fence_r = 2, 38 rv_fence_w = 1, 39 } rv_fence; 40 41 typedef enum { 42 rv_ireg_zero, 43 rv_ireg_ra, 44 rv_ireg_sp, 45 rv_ireg_gp, 46 rv_ireg_tp, 47 rv_ireg_t0, 48 rv_ireg_t1, 49 rv_ireg_t2, 50 rv_ireg_s0, 51 rv_ireg_s1, 52 rv_ireg_a0, 53 rv_ireg_a1, 54 rv_ireg_a2, 55 rv_ireg_a3, 56 rv_ireg_a4, 57 rv_ireg_a5, 58 rv_ireg_a6, 59 rv_ireg_a7, 60 rv_ireg_s2, 61 rv_ireg_s3, 62 rv_ireg_s4, 63 rv_ireg_s5, 64 rv_ireg_s6, 65 rv_ireg_s7, 66 rv_ireg_s8, 67 rv_ireg_s9, 68 rv_ireg_s10, 69 rv_ireg_s11, 70 rv_ireg_t3, 71 rv_ireg_t4, 72 rv_ireg_t5, 73 rv_ireg_t6, 74 } rv_ireg; 75 76 typedef enum { 77 rvc_end, 78 rvc_rd_eq_ra, 79 rvc_rd_eq_x0, 80 rvc_rs1_eq_x0, 81 rvc_rs2_eq_x0, 82 rvc_rs2_eq_rs1, 83 rvc_rs1_eq_ra, 84 rvc_imm_eq_zero, 85 rvc_imm_eq_n1, 86 rvc_imm_eq_p1, 87 rvc_csr_eq_0x001, 88 rvc_csr_eq_0x002, 89 rvc_csr_eq_0x003, 90 rvc_csr_eq_0xc00, 91 rvc_csr_eq_0xc01, 92 rvc_csr_eq_0xc02, 93 rvc_csr_eq_0xc80, 94 rvc_csr_eq_0xc81, 95 rvc_csr_eq_0xc82, 96 } rvc_constraint; 97 98 typedef enum { 99 rv_codec_illegal, 100 rv_codec_none, 101 rv_codec_u, 102 rv_codec_uj, 103 rv_codec_i, 104 rv_codec_i_sh5, 105 rv_codec_i_sh6, 106 rv_codec_i_sh7, 107 rv_codec_i_csr, 108 rv_codec_s, 109 rv_codec_sb, 110 rv_codec_r, 111 rv_codec_r_m, 112 rv_codec_r4_m, 113 rv_codec_r_a, 114 rv_codec_r_l, 115 rv_codec_r_f, 116 rv_codec_cb, 117 rv_codec_cb_imm, 118 rv_codec_cb_sh5, 119 rv_codec_cb_sh6, 120 rv_codec_ci, 121 rv_codec_ci_sh5, 122 rv_codec_ci_sh6, 123 rv_codec_ci_16sp, 124 rv_codec_ci_lwsp, 125 rv_codec_ci_ldsp, 126 rv_codec_ci_lqsp, 127 rv_codec_ci_li, 128 rv_codec_ci_lui, 129 rv_codec_ci_none, 130 rv_codec_ciw_4spn, 131 rv_codec_cj, 132 rv_codec_cj_jal, 133 rv_codec_cl_lw, 134 rv_codec_cl_ld, 135 rv_codec_cl_lq, 136 rv_codec_cr, 137 rv_codec_cr_mv, 138 rv_codec_cr_jalr, 139 rv_codec_cr_jr, 140 rv_codec_cs, 141 rv_codec_cs_sw, 142 rv_codec_cs_sd, 143 rv_codec_cs_sq, 144 rv_codec_css_swsp, 145 rv_codec_css_sdsp, 146 rv_codec_css_sqsp, 147 rv_codec_k_bs, 148 rv_codec_k_rnum, 149 rv_codec_v_r, 150 rv_codec_v_ldst, 151 rv_codec_v_i, 152 rv_codec_vsetvli, 153 rv_codec_vsetivli, 154 rv_codec_vror_vi, 155 rv_codec_zcb_ext, 156 rv_codec_zcb_mul, 157 rv_codec_zcb_lb, 158 rv_codec_zcb_lh, 159 rv_codec_zcmp_cm_pushpop, 160 rv_codec_zcmp_cm_mv, 161 rv_codec_zcmt_jt, 162 rv_codec_r2_imm5, 163 rv_codec_r2, 164 rv_codec_r2_imm6, 165 rv_codec_r_imm2, 166 rv_codec_r2_immhl, 167 rv_codec_r2_imm2_imm5, 168 rv_codec_fli, 169 } rv_codec; 170 171 /* structures */ 172 173 typedef struct { 174 const int op; 175 const rvc_constraint *constraints; 176 } rv_comp_data; 177 178 typedef struct { 179 const char * const name; 180 const rv_codec codec; 181 const char * const format; 182 const rv_comp_data *pseudo; 183 const short decomp_rv32; 184 const short decomp_rv64; 185 const short decomp_rv128; 186 const short decomp_data; 187 } rv_opcode_data; 188 189 typedef struct { 190 RISCVCPUConfig *cfg; 191 uint64_t pc; 192 uint64_t inst; 193 const rv_opcode_data *opcode_data; 194 int32_t imm; 195 int32_t imm1; 196 uint16_t op; 197 uint8_t codec; 198 uint8_t rd; 199 uint8_t rs1; 200 uint8_t rs2; 201 uint8_t rs3; 202 uint8_t rm; 203 uint8_t pred; 204 uint8_t succ; 205 uint8_t aq; 206 uint8_t rl; 207 uint8_t bs; 208 uint8_t rnum; 209 uint8_t vm; 210 uint32_t vzimm; 211 uint8_t rlist; 212 } rv_decode; 213 214 enum { 215 rv_op_illegal = 0 216 }; 217 218 enum { 219 rvcd_imm_nz = 0x1 220 }; 221 222 /* instruction formats */ 223 224 #define rv_fmt_none "O\t" 225 #define rv_fmt_rs1 "O\t1" 226 #define rv_fmt_offset "O\to" 227 #define rv_fmt_pred_succ "O\tp,s" 228 #define rv_fmt_rs1_rs2 "O\t1,2" 229 #define rv_fmt_rd_imm "O\t0,i" 230 #define rv_fmt_rd_uimm "O\t0,Ui" 231 #define rv_fmt_rd_offset "O\t0,o" 232 #define rv_fmt_rd_uoffset "O\t0,Uo" 233 #define rv_fmt_rd_rs1_rs2 "O\t0,1,2" 234 #define rv_fmt_frd_rs1 "O\t3,1" 235 #define rv_fmt_frd_rs1_rs2 "O\t3,1,2" 236 #define rv_fmt_frd_frs1 "O\t3,4" 237 #define rv_fmt_rd_frs1 "O\t0,4" 238 #define rv_fmt_rd_frs1_frs2 "O\t0,4,5" 239 #define rv_fmt_frd_frs1_frs2 "O\t3,4,5" 240 #define rv_fmt_rm_frd_frs1 "O\tr,3,4" 241 #define rv_fmt_rm_frd_rs1 "O\tr,3,1" 242 #define rv_fmt_rm_rd_frs1 "O\tr,0,4" 243 #define rv_fmt_rm_frd_frs1_frs2 "O\tr,3,4,5" 244 #define rv_fmt_rm_frd_frs1_frs2_frs3 "O\tr,3,4,5,6" 245 #define rv_fmt_rd_rs1_imm "O\t0,1,i" 246 #define rv_fmt_rd_rs1_offset "O\t0,1,i" 247 #define rv_fmt_rd_offset_rs1 "O\t0,i(1)" 248 #define rv_fmt_frd_offset_rs1 "O\t3,i(1)" 249 #define rv_fmt_rd_csr_rs1 "O\t0,c,1" 250 #define rv_fmt_rd_csr_zimm "O\t0,c,7" 251 #define rv_fmt_rs2_offset_rs1 "O\t2,i(1)" 252 #define rv_fmt_frs2_offset_rs1 "O\t5,i(1)" 253 #define rv_fmt_rs1_rs2_offset "O\t1,2,o" 254 #define rv_fmt_rs2_rs1_offset "O\t2,1,o" 255 #define rv_fmt_aqrl_rd_rs2_rs1 "OAR\t0,2,(1)" 256 #define rv_fmt_aqrl_rd_rs1 "OAR\t0,(1)" 257 #define rv_fmt_rd "O\t0" 258 #define rv_fmt_rd_zimm "O\t0,7" 259 #define rv_fmt_rd_rs1 "O\t0,1" 260 #define rv_fmt_rd_rs2 "O\t0,2" 261 #define rv_fmt_rs1_offset "O\t1,o" 262 #define rv_fmt_rs2_offset "O\t2,o" 263 #define rv_fmt_rs1_rs2_bs "O\t1,2,b" 264 #define rv_fmt_rd_rs1_rnum "O\t0,1,n" 265 #define rv_fmt_ldst_vd_rs1_vm "O\tD,(1)m" 266 #define rv_fmt_ldst_vd_rs1_rs2_vm "O\tD,(1),2m" 267 #define rv_fmt_ldst_vd_rs1_vs2_vm "O\tD,(1),Fm" 268 #define rv_fmt_vd_vs2_vs1 "O\tD,F,E" 269 #define rv_fmt_vd_vs2_vs1_vl "O\tD,F,El" 270 #define rv_fmt_vd_vs2_vs1_vm "O\tD,F,Em" 271 #define rv_fmt_vd_vs2_rs1_vl "O\tD,F,1l" 272 #define rv_fmt_vd_vs2_fs1_vl "O\tD,F,4l" 273 #define rv_fmt_vd_vs2_rs1_vm "O\tD,F,1m" 274 #define rv_fmt_vd_vs2_fs1_vm "O\tD,F,4m" 275 #define rv_fmt_vd_vs2_imm_vl "O\tD,F,il" 276 #define rv_fmt_vd_vs2_imm_vm "O\tD,F,im" 277 #define rv_fmt_vd_vs2_uimm "O\tD,F,u" 278 #define rv_fmt_vd_vs2_uimm_vm "O\tD,F,um" 279 #define rv_fmt_vd_vs1_vs2_vm "O\tD,E,Fm" 280 #define rv_fmt_vd_rs1_vs2_vm "O\tD,1,Fm" 281 #define rv_fmt_vd_fs1_vs2_vm "O\tD,4,Fm" 282 #define rv_fmt_vd_vs1 "O\tD,E" 283 #define rv_fmt_vd_rs1 "O\tD,1" 284 #define rv_fmt_vd_fs1 "O\tD,4" 285 #define rv_fmt_vd_imm "O\tD,i" 286 #define rv_fmt_vd_vs2 "O\tD,F" 287 #define rv_fmt_vd_vs2_vm "O\tD,Fm" 288 #define rv_fmt_rd_vs2_vm "O\t0,Fm" 289 #define rv_fmt_rd_vs2 "O\t0,F" 290 #define rv_fmt_fd_vs2 "O\t3,F" 291 #define rv_fmt_vd_vm "O\tDm" 292 #define rv_fmt_vsetvli "O\t0,1,v" 293 #define rv_fmt_vsetivli "O\t0,i,v" 294 #define rv_fmt_rs1_rs2_zce_ldst "O\t2,i(1)" 295 #define rv_fmt_push_rlist "O\tx,-i" 296 #define rv_fmt_pop_rlist "O\tx,i" 297 #define rv_fmt_zcmt_index "O\ti" 298 #define rv_fmt_rd_rs1_rs2_imm "O\t0,1,2,i" 299 #define rv_fmt_frd_rs1_rs2_imm "O\t3,1,2,i" 300 #define rv_fmt_rd_rs1_immh_imml "O\t0,1,i,j" 301 #define rv_fmt_rd_rs1_immh_imml_addr "O\t0,(1),i,j" 302 #define rv_fmt_rd2_imm "O\t0,2,(1),i" 303 #define rv_fmt_fli "O\t3,h" 304 305 #endif /* DISAS_RISCV_H */ 306