]>
Commit | Line | Data |
---|---|---|
318df723 CM |
1 | /* |
2 | * QEMU RISC-V Disassembler for xthead. | |
3 | * | |
4 | * SPDX-License-Identifier: GPL-2.0-or-later | |
5 | */ | |
6 | ||
7 | #include "disas/riscv.h" | |
8 | #include "disas/riscv-xthead.h" | |
9 | ||
10 | typedef enum { | |
11 | /* 0 is reserved for rv_op_illegal. */ | |
12 | /* XTheadBa */ | |
13 | rv_op_th_addsl = 1, | |
14 | /* XTheadBb */ | |
15 | rv_op_th_srri, | |
16 | rv_op_th_srriw, | |
17 | rv_op_th_ext, | |
18 | rv_op_th_extu, | |
19 | rv_op_th_ff0, | |
20 | rv_op_th_ff1, | |
21 | rv_op_th_rev, | |
22 | rv_op_th_revw, | |
23 | rv_op_th_tstnbz, | |
24 | /* XTheadBs */ | |
25 | rv_op_th_tst, | |
26 | /* XTheadCmo */ | |
27 | rv_op_th_dcache_call, | |
28 | rv_op_th_dcache_ciall, | |
29 | rv_op_th_dcache_iall, | |
30 | rv_op_th_dcache_cpa, | |
31 | rv_op_th_dcache_cipa, | |
32 | rv_op_th_dcache_ipa, | |
33 | rv_op_th_dcache_cva, | |
34 | rv_op_th_dcache_civa, | |
35 | rv_op_th_dcache_iva, | |
36 | rv_op_th_dcache_csw, | |
37 | rv_op_th_dcache_cisw, | |
38 | rv_op_th_dcache_isw, | |
39 | rv_op_th_dcache_cpal1, | |
40 | rv_op_th_dcache_cval1, | |
41 | rv_op_th_icache_iall, | |
42 | rv_op_th_icache_ialls, | |
43 | rv_op_th_icache_ipa, | |
44 | rv_op_th_icache_iva, | |
45 | rv_op_th_l2cache_call, | |
46 | rv_op_th_l2cache_ciall, | |
47 | rv_op_th_l2cache_iall, | |
48 | /* XTheadCondMov */ | |
49 | rv_op_th_mveqz, | |
50 | rv_op_th_mvnez, | |
51 | /* XTheadFMemIdx */ | |
52 | rv_op_th_flrd, | |
53 | rv_op_th_flrw, | |
54 | rv_op_th_flurd, | |
55 | rv_op_th_flurw, | |
56 | rv_op_th_fsrd, | |
57 | rv_op_th_fsrw, | |
58 | rv_op_th_fsurd, | |
59 | rv_op_th_fsurw, | |
60 | /* XTheadFmv */ | |
61 | rv_op_th_fmv_hw_x, | |
62 | rv_op_th_fmv_x_hw, | |
63 | /* XTheadMac */ | |
64 | rv_op_th_mula, | |
65 | rv_op_th_mulah, | |
66 | rv_op_th_mulaw, | |
67 | rv_op_th_muls, | |
68 | rv_op_th_mulsw, | |
69 | rv_op_th_mulsh, | |
70 | /* XTheadMemIdx */ | |
71 | rv_op_th_lbia, | |
72 | rv_op_th_lbib, | |
73 | rv_op_th_lbuia, | |
74 | rv_op_th_lbuib, | |
75 | rv_op_th_lhia, | |
76 | rv_op_th_lhib, | |
77 | rv_op_th_lhuia, | |
78 | rv_op_th_lhuib, | |
79 | rv_op_th_lwia, | |
80 | rv_op_th_lwib, | |
81 | rv_op_th_lwuia, | |
82 | rv_op_th_lwuib, | |
83 | rv_op_th_ldia, | |
84 | rv_op_th_ldib, | |
85 | rv_op_th_sbia, | |
86 | rv_op_th_sbib, | |
87 | rv_op_th_shia, | |
88 | rv_op_th_shib, | |
89 | rv_op_th_swia, | |
90 | rv_op_th_swib, | |
91 | rv_op_th_sdia, | |
92 | rv_op_th_sdib, | |
93 | rv_op_th_lrb, | |
94 | rv_op_th_lrbu, | |
95 | rv_op_th_lrh, | |
96 | rv_op_th_lrhu, | |
97 | rv_op_th_lrw, | |
98 | rv_op_th_lrwu, | |
99 | rv_op_th_lrd, | |
100 | rv_op_th_srb, | |
101 | rv_op_th_srh, | |
102 | rv_op_th_srw, | |
103 | rv_op_th_srd, | |
104 | rv_op_th_lurb, | |
105 | rv_op_th_lurbu, | |
106 | rv_op_th_lurh, | |
107 | rv_op_th_lurhu, | |
108 | rv_op_th_lurw, | |
109 | rv_op_th_lurwu, | |
110 | rv_op_th_lurd, | |
111 | rv_op_th_surb, | |
112 | rv_op_th_surh, | |
113 | rv_op_th_surw, | |
114 | rv_op_th_surd, | |
115 | /* XTheadMemPair */ | |
116 | rv_op_th_ldd, | |
117 | rv_op_th_lwd, | |
118 | rv_op_th_lwud, | |
119 | rv_op_th_sdd, | |
120 | rv_op_th_swd, | |
121 | /* XTheadSync */ | |
122 | rv_op_th_sfence_vmas, | |
123 | rv_op_th_sync, | |
124 | rv_op_th_sync_i, | |
125 | rv_op_th_sync_is, | |
126 | rv_op_th_sync_s, | |
127 | } rv_xthead_op; | |
128 | ||
129 | const rv_opcode_data xthead_opcode_data[] = { | |
130 | { "th.illegal", rv_codec_illegal, rv_fmt_none, NULL, 0, 0, 0 }, | |
131 | /* XTheadBa */ | |
132 | { "th.addsl", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 }, | |
133 | /* XTheadBb */ | |
134 | { "th.srri", rv_codec_r2_imm6, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 }, | |
135 | { "th.srriw", rv_codec_r2_imm5, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 }, | |
136 | { "th.ext", rv_codec_r2_immhl, rv_fmt_rd_rs1_immh_imml, NULL, 0, 0, 0 }, | |
137 | { "th.extu", rv_codec_r2_immhl, rv_fmt_rd_rs1_immh_imml, NULL, 0, 0, 0 }, | |
138 | { "th.ff0", rv_codec_r2, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, | |
139 | { "th.ff1", rv_codec_r2, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, | |
140 | { "th.rev", rv_codec_r2, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, | |
141 | { "th.revw", rv_codec_r2, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, | |
142 | { "th.tstnbz", rv_codec_r2, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, | |
143 | /* XTheadBs */ | |
144 | { "th.tst", rv_codec_r2_imm6, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 }, | |
145 | /* XTheadCmo */ | |
146 | { "th.dcache.call", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 }, | |
147 | { "th.dcache.ciall", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 }, | |
148 | { "th.dcache.iall", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 }, | |
149 | { "th.dcache.cpa", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 }, | |
150 | { "th.dcache.cipa", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 }, | |
151 | { "th.dcache.ipa", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 }, | |
152 | { "th.dcache.cva", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 }, | |
153 | { "th.dcache.civa", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 }, | |
154 | { "th.dcache.iva", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 }, | |
155 | { "th.dcache.csw", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 }, | |
156 | { "th.dcache.cisw", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 }, | |
157 | { "th.dcache.isw", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 }, | |
158 | { "th.dcache.cpal1", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 }, | |
159 | { "th.dcache.cval1", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 }, | |
160 | { "th.icache.iall", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 }, | |
161 | { "th.icache.ialls", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 }, | |
162 | { "th.icache.ipa", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 }, | |
163 | { "th.icache.iva", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 }, | |
164 | { "th.l2cache.call", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 }, | |
165 | { "th.l2cache.ciall", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 }, | |
166 | { "th.l2cache.iall", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 }, | |
167 | /* XTheadCondMov */ | |
168 | { "th.mveqz", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, | |
169 | { "th.mvnez", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, | |
170 | /* XTheadFMemIdx */ | |
171 | { "th.flrd", rv_codec_r_imm2, rv_fmt_frd_rs1_rs2_imm, NULL, 0, 0, 0 }, | |
172 | { "th.flrw", rv_codec_r_imm2, rv_fmt_frd_rs1_rs2_imm, NULL, 0, 0, 0 }, | |
173 | { "th.flurd", rv_codec_r_imm2, rv_fmt_frd_rs1_rs2_imm, NULL, 0, 0, 0 }, | |
174 | { "th.flurw", rv_codec_r_imm2, rv_fmt_frd_rs1_rs2_imm, NULL, 0, 0, 0 }, | |
175 | { "th.fsrd", rv_codec_r_imm2, rv_fmt_frd_rs1_rs2_imm, NULL, 0, 0, 0 }, | |
176 | { "th.fsrw", rv_codec_r_imm2, rv_fmt_frd_rs1_rs2_imm, NULL, 0, 0, 0 }, | |
177 | { "th.fsurd", rv_codec_r_imm2, rv_fmt_frd_rs1_rs2_imm, NULL, 0, 0, 0 }, | |
178 | { "th.fsurw", rv_codec_r_imm2, rv_fmt_frd_rs1_rs2_imm, NULL, 0, 0, 0 }, | |
179 | /* XTheadFmv */ | |
180 | { "th.fmv.hw.x", rv_codec_r, rv_fmt_rd_frs1, NULL, 0, 0, 0 }, | |
181 | { "th.fmv.x.hw", rv_codec_r, rv_fmt_rd_frs1, NULL, 0, 0, 0 }, | |
182 | /* XTheadMac */ | |
183 | { "th.mula", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, | |
184 | { "th.mulaw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, | |
185 | { "th.mulah", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, | |
186 | { "th.muls", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, | |
187 | { "th.mulsw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, | |
188 | { "th.mulsh", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, | |
189 | /* XTheadMemIdx */ | |
190 | { "th.lbia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 }, | |
191 | { "th.lbib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml, NULL, 0, 0, 0 }, | |
192 | { "th.lbuia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 }, | |
193 | { "th.lbuib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 }, | |
194 | { "th.lhia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 }, | |
195 | { "th.lhib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 }, | |
196 | { "th.lhuia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 }, | |
197 | { "th.lhuib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 }, | |
198 | { "th.lwia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 }, | |
199 | { "th.lwib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 }, | |
200 | { "th.lwuia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 }, | |
201 | { "th.lwuib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 }, | |
202 | { "th.ldia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 }, | |
203 | { "th.ldib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 }, | |
204 | { "th.sbia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 }, | |
205 | { "th.sbib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 }, | |
206 | { "th.shia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 }, | |
207 | { "th.shib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 }, | |
208 | { "th.swia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 }, | |
209 | { "th.swib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 }, | |
210 | { "th.sdia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 }, | |
211 | { "th.sdib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 }, | |
212 | { "th.lrb", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 }, | |
213 | { "th.lrbu", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 }, | |
214 | { "th.lrh", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 }, | |
215 | { "th.lrhu", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 }, | |
216 | { "th.lrw", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 }, | |
217 | { "th.lrwu", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 }, | |
218 | { "th.lrd", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 }, | |
219 | { "th.srb", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 }, | |
220 | { "th.srh", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 }, | |
221 | { "th.srw", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 }, | |
222 | { "th.srd", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 }, | |
223 | { "th.lurb", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 }, | |
224 | { "th.lurbu", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 }, | |
225 | { "th.lurh", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 }, | |
226 | { "th.lurhu", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 }, | |
227 | { "th.lurw", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 }, | |
228 | { "th.lurwu", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 }, | |
229 | { "th.lurd", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 }, | |
230 | { "th.surb", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 }, | |
231 | { "th.surh", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 }, | |
232 | { "th.surw", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 }, | |
233 | { "th.surd", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 }, | |
234 | /* XTheadMemPair */ | |
235 | { "th.ldd", rv_codec_r_imm2, rv_fmt_rd2_imm, NULL, 0, 0, 0 }, | |
236 | { "th.lwd", rv_codec_r_imm2, rv_fmt_rd2_imm, NULL, 0, 0, 0 }, | |
237 | { "th.lwud", rv_codec_r_imm2, rv_fmt_rd2_imm, NULL, 0, 0, 0 }, | |
238 | { "th.sdd", rv_codec_r_imm2, rv_fmt_rd2_imm, NULL, 0, 0, 0 }, | |
239 | { "th.swd", rv_codec_r_imm2, rv_fmt_rd2_imm, NULL, 0, 0, 0 }, | |
240 | /* XTheadSync */ | |
241 | { "th.sfence.vmas", rv_codec_r, rv_fmt_rs1_rs2, NULL, 0, 0, 0 }, | |
242 | { "th.sync", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 }, | |
243 | { "th.sync.i", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 }, | |
244 | { "th.sync.is", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 }, | |
245 | { "th.sync.s", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 }, | |
246 | }; | |
247 | ||
248 | void decode_xtheadba(rv_decode *dec, rv_isa isa) | |
249 | { | |
250 | rv_inst inst = dec->inst; | |
251 | rv_opcode op = rv_op_illegal; | |
252 | ||
253 | switch (((inst >> 0) & 0b11)) { | |
254 | case 3: | |
255 | switch (((inst >> 2) & 0b11111)) { | |
256 | case 2: | |
257 | /* custom-0 */ | |
258 | switch ((inst >> 12) & 0b111) { | |
259 | case 1: | |
260 | switch ((inst >> 25) & 0b1111111) { | |
261 | case 0b0000000: | |
262 | case 0b0000001: | |
263 | case 0b0000010: | |
264 | case 0b0000011: op = rv_op_th_addsl; break; | |
265 | } | |
266 | break; | |
267 | } | |
268 | break; | |
269 | /* custom-0 */ | |
270 | } | |
271 | break; | |
272 | } | |
273 | ||
274 | dec->op = op; | |
275 | } | |
276 | ||
277 | void decode_xtheadbb(rv_decode *dec, rv_isa isa) | |
278 | { | |
279 | rv_inst inst = dec->inst; | |
280 | rv_opcode op = rv_op_illegal; | |
281 | ||
282 | switch (((inst >> 0) & 0b11)) { | |
283 | case 3: | |
284 | switch (((inst >> 2) & 0b11111)) { | |
285 | case 2: | |
286 | /* custom-0 */ | |
287 | switch ((inst >> 12) & 0b111) { | |
288 | case 1: | |
289 | switch ((inst >> 25) & 0b1111111) { | |
290 | case 0b0001010: op = rv_op_th_srriw; break; | |
291 | case 0b1000000: | |
292 | if (((inst >> 20) & 0b11111) == 0) { | |
293 | op = rv_op_th_tstnbz; | |
294 | } | |
295 | break; | |
296 | case 0b1000001: | |
297 | if (((inst >> 20) & 0b11111) == 0) { | |
298 | op = rv_op_th_rev; | |
299 | } | |
300 | break; | |
301 | case 0b1000010: | |
302 | if (((inst >> 20) & 0b11111) == 0) { | |
303 | op = rv_op_th_ff0; | |
304 | } | |
305 | break; | |
306 | case 0b1000011: | |
307 | if (((inst >> 20) & 0b11111) == 0) { | |
308 | op = rv_op_th_ff1; | |
309 | } | |
310 | break; | |
311 | case 0b1000100: | |
312 | case 0b1001000: | |
313 | if (((inst >> 20) & 0b11111) == 0) { | |
314 | op = rv_op_th_revw; | |
315 | } | |
316 | break; | |
317 | case 0b0000100: | |
318 | case 0b0000101: op = rv_op_th_srri; break; | |
319 | } | |
320 | break; | |
321 | case 2: op = rv_op_th_ext; break; | |
322 | case 3: op = rv_op_th_extu; break; | |
323 | } | |
324 | break; | |
325 | /* custom-0 */ | |
326 | } | |
327 | break; | |
328 | } | |
329 | ||
330 | dec->op = op; | |
331 | } | |
332 | ||
333 | void decode_xtheadbs(rv_decode *dec, rv_isa isa) | |
334 | { | |
335 | rv_inst inst = dec->inst; | |
336 | rv_opcode op = rv_op_illegal; | |
337 | ||
338 | switch (((inst >> 0) & 0b11)) { | |
339 | case 3: | |
340 | switch (((inst >> 2) & 0b11111)) { | |
341 | case 2: | |
342 | /* custom-0 */ | |
343 | switch ((inst >> 12) & 0b111) { | |
344 | case 1: | |
345 | switch ((inst >> 26) & 0b111111) { | |
346 | case 0b100010: op = rv_op_th_tst; break; | |
347 | } | |
348 | break; | |
349 | } | |
350 | break; | |
351 | /* custom-0 */ | |
352 | } | |
353 | break; | |
354 | } | |
355 | ||
356 | dec->op = op; | |
357 | } | |
358 | ||
359 | void decode_xtheadcmo(rv_decode *dec, rv_isa isa) | |
360 | { | |
361 | rv_inst inst = dec->inst; | |
362 | rv_opcode op = rv_op_illegal; | |
363 | ||
364 | switch (((inst >> 0) & 0b11)) { | |
365 | case 3: | |
366 | switch (((inst >> 2) & 0b11111)) { | |
367 | case 2: | |
368 | /* custom-0 */ | |
369 | switch ((inst >> 12) & 0b111) { | |
370 | case 0: | |
371 | switch ((inst >> 20 & 0b111111111111)) { | |
372 | case 0b000000000001: | |
373 | if (((inst >> 20) & 0b11111) == 0) { | |
374 | op = rv_op_th_dcache_call; | |
375 | } | |
376 | break; | |
377 | case 0b000000000011: | |
378 | if (((inst >> 20) & 0b11111) == 0) { | |
379 | op = rv_op_th_dcache_ciall; | |
380 | } | |
381 | break; | |
382 | case 0b000000000010: | |
383 | if (((inst >> 20) & 0b11111) == 0) { | |
384 | op = rv_op_th_dcache_iall; | |
385 | } | |
386 | break; | |
387 | case 0b000000101001: op = rv_op_th_dcache_cpa; break; | |
388 | case 0b000000101011: op = rv_op_th_dcache_cipa; break; | |
389 | case 0b000000101010: op = rv_op_th_dcache_ipa; break; | |
390 | case 0b000000100101: op = rv_op_th_dcache_cva; break; | |
391 | case 0b000000100111: op = rv_op_th_dcache_civa; break; | |
392 | case 0b000000100110: op = rv_op_th_dcache_iva; break; | |
393 | case 0b000000100001: op = rv_op_th_dcache_csw; break; | |
394 | case 0b000000100011: op = rv_op_th_dcache_cisw; break; | |
395 | case 0b000000100010: op = rv_op_th_dcache_isw; break; | |
396 | case 0b000000101000: op = rv_op_th_dcache_cpal1; break; | |
397 | case 0b000000100100: op = rv_op_th_dcache_cval1; break; | |
398 | case 0b000000010000: | |
399 | if (((inst >> 20) & 0b11111) == 0) { | |
400 | op = rv_op_th_icache_iall; | |
401 | } | |
402 | break; | |
403 | case 0b000000010001: | |
404 | if (((inst >> 20) & 0b11111) == 0) { | |
405 | op = rv_op_th_icache_ialls; | |
406 | } | |
407 | break; | |
408 | case 0b000000111000: op = rv_op_th_icache_ipa; break; | |
409 | case 0b000000110000: op = rv_op_th_icache_iva; break; | |
410 | case 0b000000010101: | |
411 | if (((inst >> 20) & 0b11111) == 0) { | |
412 | op = rv_op_th_l2cache_call; | |
413 | } | |
414 | break; | |
415 | case 0b000000010111: | |
416 | if (((inst >> 20) & 0b11111) == 0) { | |
417 | op = rv_op_th_l2cache_ciall; | |
418 | } | |
419 | break; | |
420 | case 0b000000010110: | |
421 | if (((inst >> 20) & 0b11111) == 0) { | |
422 | op = rv_op_th_l2cache_iall; | |
423 | } | |
424 | break; | |
425 | } | |
426 | break; | |
427 | } | |
428 | break; | |
429 | /* custom-0 */ | |
430 | } | |
431 | break; | |
432 | } | |
433 | ||
434 | dec->op = op; | |
435 | } | |
436 | ||
437 | void decode_xtheadcondmov(rv_decode *dec, rv_isa isa) | |
438 | { | |
439 | rv_inst inst = dec->inst; | |
440 | rv_opcode op = rv_op_illegal; | |
441 | ||
442 | switch (((inst >> 0) & 0b11)) { | |
443 | case 3: | |
444 | switch (((inst >> 2) & 0b11111)) { | |
445 | case 2: | |
446 | /* custom-0 */ | |
447 | switch ((inst >> 12) & 0b111) { | |
448 | case 1: | |
449 | switch ((inst >> 25) & 0b1111111) { | |
450 | case 0b0100000: op = rv_op_th_mveqz; break; | |
451 | case 0b0100001: op = rv_op_th_mvnez; break; | |
452 | } | |
453 | break; | |
454 | } | |
455 | break; | |
456 | /* custom-0 */ | |
457 | } | |
458 | break; | |
459 | } | |
460 | ||
461 | dec->op = op; | |
462 | } | |
463 | ||
464 | void decode_xtheadfmemidx(rv_decode *dec, rv_isa isa) | |
465 | { | |
466 | rv_inst inst = dec->inst; | |
467 | rv_opcode op = rv_op_illegal; | |
468 | ||
469 | switch (((inst >> 0) & 0b11)) { | |
470 | case 3: | |
471 | switch (((inst >> 2) & 0b11111)) { | |
472 | case 2: | |
473 | /* custom-0 */ | |
474 | switch ((inst >> 12) & 0b111) { | |
475 | case 6: | |
476 | switch ((inst >> 27) & 0b11111) { | |
477 | case 8: op = rv_op_th_flrw; break; | |
478 | case 10: op = rv_op_th_flurw; break; | |
479 | case 12: op = rv_op_th_flrd; break; | |
480 | case 14: op = rv_op_th_flurd; break; | |
481 | } | |
482 | break; | |
483 | case 7: | |
484 | switch ((inst >> 27) & 0b11111) { | |
485 | case 8: op = rv_op_th_fsrw; break; | |
486 | case 10: op = rv_op_th_fsurw; break; | |
487 | case 12: op = rv_op_th_fsrd; break; | |
488 | case 14: op = rv_op_th_fsurd; break; | |
489 | } | |
490 | break; | |
491 | } | |
492 | break; | |
493 | /* custom-0 */ | |
494 | } | |
495 | break; | |
496 | } | |
497 | ||
498 | dec->op = op; | |
499 | } | |
500 | ||
501 | void decode_xtheadfmv(rv_decode *dec, rv_isa isa) | |
502 | { | |
503 | rv_inst inst = dec->inst; | |
504 | rv_opcode op = rv_op_illegal; | |
505 | ||
506 | switch (((inst >> 0) & 0b11)) { | |
507 | case 3: | |
508 | switch (((inst >> 2) & 0b11111)) { | |
509 | case 2: | |
510 | /* custom-0 */ | |
511 | switch ((inst >> 12) & 0b111) { | |
512 | case 1: | |
513 | switch ((inst >> 25) & 0b1111111) { | |
514 | case 0b1010000: | |
515 | if (((inst >> 20) & 0b11111) == 0) { | |
516 | op = rv_op_th_fmv_hw_x; | |
517 | } | |
518 | break; | |
519 | case 0b1100000: | |
520 | if (((inst >> 20) & 0b11111) == 0) { | |
521 | op = rv_op_th_fmv_x_hw; | |
522 | } | |
523 | break; | |
524 | } | |
525 | break; | |
526 | } | |
527 | break; | |
528 | /* custom-0 */ | |
529 | } | |
530 | break; | |
531 | } | |
532 | ||
533 | dec->op = op; | |
534 | } | |
535 | ||
536 | void decode_xtheadmac(rv_decode *dec, rv_isa isa) | |
537 | { | |
538 | rv_inst inst = dec->inst; | |
539 | rv_opcode op = rv_op_illegal; | |
540 | ||
541 | switch (((inst >> 0) & 0b11)) { | |
542 | case 3: | |
543 | switch (((inst >> 2) & 0b11111)) { | |
544 | case 2: | |
545 | /* custom-0 */ | |
546 | switch ((inst >> 12) & 0b111) { | |
547 | case 1: | |
548 | switch ((inst >> 25) & 0b1111111) { | |
549 | case 0b0010000: op = rv_op_th_mula; break; | |
550 | case 0b0010001: op = rv_op_th_muls; break; | |
551 | case 0b0010010: op = rv_op_th_mulaw; break; | |
552 | case 0b0010011: op = rv_op_th_mulsw; break; | |
553 | case 0b0010100: op = rv_op_th_mulah; break; | |
554 | case 0b0010101: op = rv_op_th_mulsh; break; | |
555 | } | |
556 | break; | |
557 | } | |
558 | break; | |
559 | /* custom-0 */ | |
560 | } | |
561 | break; | |
562 | } | |
563 | ||
564 | dec->op = op; | |
565 | } | |
566 | ||
567 | void decode_xtheadmemidx(rv_decode *dec, rv_isa isa) | |
568 | { | |
569 | rv_inst inst = dec->inst; | |
570 | rv_opcode op = rv_op_illegal; | |
571 | ||
572 | switch (((inst >> 0) & 0b11)) { | |
573 | case 3: | |
574 | switch (((inst >> 2) & 0b11111)) { | |
575 | case 2: | |
576 | /* custom-0 */ | |
577 | switch ((inst >> 12) & 0b111) { | |
578 | case 4: | |
579 | switch ((inst >> 27) & 0b11111) { | |
580 | case 0: op = rv_op_th_lrb; break; | |
581 | case 1: op = rv_op_th_lbib; break; | |
582 | case 2: op = rv_op_th_lurb; break; | |
583 | case 3: op = rv_op_th_lbia; break; | |
584 | case 4: op = rv_op_th_lrh; break; | |
585 | case 5: op = rv_op_th_lhib; break; | |
586 | case 6: op = rv_op_th_lurh; break; | |
587 | case 7: op = rv_op_th_lhia; break; | |
588 | case 8: op = rv_op_th_lrw; break; | |
589 | case 9: op = rv_op_th_lwib; break; | |
590 | case 10: op = rv_op_th_lurw; break; | |
591 | case 11: op = rv_op_th_lwia; break; | |
592 | case 12: op = rv_op_th_lrd; break; | |
593 | case 13: op = rv_op_th_ldib; break; | |
594 | case 14: op = rv_op_th_lurd; break; | |
595 | case 15: op = rv_op_th_ldia; break; | |
596 | case 16: op = rv_op_th_lrbu; break; | |
597 | case 17: op = rv_op_th_lbuib; break; | |
598 | case 18: op = rv_op_th_lurbu; break; | |
599 | case 19: op = rv_op_th_lbuia; break; | |
600 | case 20: op = rv_op_th_lrhu; break; | |
601 | case 21: op = rv_op_th_lhuib; break; | |
602 | case 22: op = rv_op_th_lurhu; break; | |
603 | case 23: op = rv_op_th_lhuia; break; | |
604 | case 24: op = rv_op_th_lrwu; break; | |
605 | case 25: op = rv_op_th_lwuib; break; | |
606 | case 26: op = rv_op_th_lurwu; break; | |
607 | case 27: op = rv_op_th_lwuia; break; | |
608 | } | |
609 | break; | |
610 | case 5: | |
611 | switch ((inst >> 27) & 0b11111) { | |
612 | case 0: op = rv_op_th_srb; break; | |
613 | case 1: op = rv_op_th_sbib; break; | |
614 | case 2: op = rv_op_th_surb; break; | |
615 | case 3: op = rv_op_th_sbia; break; | |
616 | case 4: op = rv_op_th_srh; break; | |
617 | case 5: op = rv_op_th_shib; break; | |
618 | case 6: op = rv_op_th_surh; break; | |
619 | case 7: op = rv_op_th_shia; break; | |
620 | case 8: op = rv_op_th_srw; break; | |
621 | case 9: op = rv_op_th_swib; break; | |
622 | case 10: op = rv_op_th_surw; break; | |
623 | case 11: op = rv_op_th_swia; break; | |
624 | case 12: op = rv_op_th_srd; break; | |
625 | case 13: op = rv_op_th_sdib; break; | |
626 | case 14: op = rv_op_th_surd; break; | |
627 | case 15: op = rv_op_th_sdia; break; | |
628 | } | |
629 | break; | |
630 | break; | |
631 | } | |
632 | break; | |
633 | /* custom-0 */ | |
634 | } | |
635 | break; | |
636 | } | |
637 | ||
638 | dec->op = op; | |
639 | } | |
640 | ||
641 | void decode_xtheadmempair(rv_decode *dec, rv_isa isa) | |
642 | { | |
643 | rv_inst inst = dec->inst; | |
644 | rv_opcode op = rv_op_illegal; | |
645 | ||
646 | switch (((inst >> 0) & 0b11)) { | |
647 | case 3: | |
648 | switch (((inst >> 2) & 0b11111)) { | |
649 | case 2: | |
650 | /* custom-0 */ | |
651 | switch ((inst >> 12) & 0b111) { | |
652 | case 4: | |
653 | switch ((inst >> 27) & 0b11111) { | |
654 | case 28: op = rv_op_th_lwd; break; | |
655 | case 30: op = rv_op_th_lwud; break; | |
656 | case 31: op = rv_op_th_ldd; break; | |
657 | } | |
658 | break; | |
659 | case 5: | |
660 | switch ((inst >> 27) & 0b11111) { | |
661 | case 28: op = rv_op_th_swd; break; | |
662 | case 31: op = rv_op_th_sdd; break; | |
663 | } | |
664 | break; | |
665 | } | |
666 | break; | |
667 | /* custom-0 */ | |
668 | } | |
669 | break; | |
670 | } | |
671 | ||
672 | dec->op = op; | |
673 | } | |
674 | ||
675 | void decode_xtheadsync(rv_decode *dec, rv_isa isa) | |
676 | { | |
677 | rv_inst inst = dec->inst; | |
678 | rv_opcode op = rv_op_illegal; | |
679 | ||
680 | switch (((inst >> 0) & 0b11)) { | |
681 | case 3: | |
682 | switch (((inst >> 2) & 0b11111)) { | |
683 | case 2: | |
684 | /* custom-0 */ | |
685 | switch ((inst >> 12) & 0b111) { | |
686 | case 0: | |
687 | switch ((inst >> 25) & 0b1111111) { | |
688 | case 0b0000010: op = rv_op_th_sfence_vmas; break; | |
689 | case 0b0000000: | |
690 | switch ((inst >> 20) & 0b11111) { | |
691 | case 0b11000: op = rv_op_th_sync; break; | |
692 | case 0b11010: op = rv_op_th_sync_i; break; | |
693 | case 0b11011: op = rv_op_th_sync_is; break; | |
694 | case 0b11001: op = rv_op_th_sync_s; break; | |
695 | } | |
696 | break; | |
697 | } | |
698 | break; | |
699 | } | |
700 | break; | |
701 | /* custom-0 */ | |
702 | } | |
703 | break; | |
704 | } | |
705 | ||
706 | dec->op = op; | |
707 | } |