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