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