xref: /qemu/disas/riscv.h (revision dcaaf2bf)
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_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_vm         "O\tD,F,um"
278 #define rv_fmt_vd_vs1_vs2_vm          "O\tD,E,Fm"
279 #define rv_fmt_vd_rs1_vs2_vm          "O\tD,1,Fm"
280 #define rv_fmt_vd_fs1_vs2_vm          "O\tD,4,Fm"
281 #define rv_fmt_vd_vs1                 "O\tD,E"
282 #define rv_fmt_vd_rs1                 "O\tD,1"
283 #define rv_fmt_vd_fs1                 "O\tD,4"
284 #define rv_fmt_vd_imm                 "O\tD,i"
285 #define rv_fmt_vd_vs2                 "O\tD,F"
286 #define rv_fmt_vd_vs2_vm              "O\tD,Fm"
287 #define rv_fmt_rd_vs2_vm              "O\t0,Fm"
288 #define rv_fmt_rd_vs2                 "O\t0,F"
289 #define rv_fmt_fd_vs2                 "O\t3,F"
290 #define rv_fmt_vd_vm                  "O\tDm"
291 #define rv_fmt_vsetvli                "O\t0,1,v"
292 #define rv_fmt_vsetivli               "O\t0,u,v"
293 #define rv_fmt_rs1_rs2_zce_ldst       "O\t2,i(1)"
294 #define rv_fmt_push_rlist             "O\tx,-i"
295 #define rv_fmt_pop_rlist              "O\tx,i"
296 #define rv_fmt_zcmt_index             "O\ti"
297 #define rv_fmt_rd_rs1_rs2_imm         "O\t0,1,2,i"
298 #define rv_fmt_frd_rs1_rs2_imm        "O\t3,1,2,i"
299 #define rv_fmt_rd_rs1_immh_imml       "O\t0,1,i,j"
300 #define rv_fmt_rd_rs1_immh_imml_addr  "O\t0,(1),i,j"
301 #define rv_fmt_rd2_imm                "O\t0,2,(1),i"
302 #define rv_fmt_fli                    "O\t3,h"
303 
304 #endif /* DISAS_RISCV_H */
305