Christoph Müllner | 318df72 | 2023-06-12 13:10:34 +0200 | [diff] [blame] | 1 | /* |
| 2 | * QEMU RISC-V Disassembler for xthead. |
| 3 | * |
| 4 | * SPDX-License-Identifier: GPL-2.0-or-later |
| 5 | */ |
| 6 | |
Peter Maydell | 3910de6 | 2024-01-25 16:34:01 +0000 | [diff] [blame] | 7 | #include "qemu/osdep.h" |
Christoph Müllner | 318df72 | 2023-06-12 13:10:34 +0200 | [diff] [blame] | 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 | } |