1 /* 2 * QEMU RISC-V Disassembler for xthead. 3 * 4 * SPDX-License-Identifier: GPL-2.0-or-later 5 */ 6 7 #include "qemu/osdep.h" 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 } 709