xref: /qemu/disas/riscv.h (revision 7653b1ea)
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,u,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