xref: /qemu/disas/riscv-xthead.c (revision b49f4755)
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 }
708