/* * QEMU RISC-V Disassembler for xthead. * * SPDX-License-Identifier: GPL-2.0-or-later */ #include "qemu/osdep.h" #include "disas/riscv.h" #include "disas/riscv-xthead.h" #define OP(N, ...) static const rv_opcode_data op_##N = { __VA_ARGS__ }; #include "riscv-xthead-op.c.inc" #undef OP const rv_opcode_data *decode_xtheadba(rv_decode *dec, rv_isa isa) { rv_inst inst = dec->inst; switch (((inst >> 0) & 0b11)) { case 3: switch (((inst >> 2) & 0b11111)) { case 2: /* custom-0 */ switch ((inst >> 12) & 0b111) { case 1: switch ((inst >> 25) & 0b1111111) { case 0b0000000: case 0b0000001: case 0b0000010: case 0b0000011: return &op_th_addsl; } break; } break; /* custom-0 */ } break; } return NULL; } const rv_opcode_data *decode_xtheadbb(rv_decode *dec, rv_isa isa) { rv_inst inst = dec->inst; switch (((inst >> 0) & 0b11)) { case 3: switch (((inst >> 2) & 0b11111)) { case 2: /* custom-0 */ switch ((inst >> 12) & 0b111) { case 1: switch ((inst >> 25) & 0b1111111) { case 0b0001010: return &op_th_srriw; case 0b1000000: if (((inst >> 20) & 0b11111) == 0) { return &op_th_tstnbz; } break; case 0b1000001: if (((inst >> 20) & 0b11111) == 0) { return &op_th_rev; } break; case 0b1000010: if (((inst >> 20) & 0b11111) == 0) { return &op_th_ff0; } break; case 0b1000011: if (((inst >> 20) & 0b11111) == 0) { return &op_th_ff1; } break; case 0b1000100: case 0b1001000: if (((inst >> 20) & 0b11111) == 0) { return &op_th_revw; } break; case 0b0001000: case 0b0001001: return &op_th_srri; break; } break; case 2: return &op_th_ext; case 3: return &op_th_extu; } break; /* custom-0 */ } break; } return NULL; } const rv_opcode_data *decode_xtheadbs(rv_decode *dec, rv_isa isa) { rv_inst inst = dec->inst; switch (((inst >> 0) & 0b11)) { case 3: switch (((inst >> 2) & 0b11111)) { case 2: /* custom-0 */ switch ((inst >> 12) & 0b111) { case 1: switch ((inst >> 26) & 0b111111) { case 0b100010: return &op_th_tst; } break; } break; /* custom-0 */ } break; } return NULL; } const rv_opcode_data *decode_xtheadcmo(rv_decode *dec, rv_isa isa) { rv_inst inst = dec->inst; switch (((inst >> 0) & 0b11)) { case 3: switch (((inst >> 2) & 0b11111)) { case 2: /* custom-0 */ switch ((inst >> 12) & 0b111) { case 0: switch ((inst >> 20 & 0b111111111111)) { case 0b000000000001: if (((inst >> 20) & 0b11111) == 0) { return &op_th_dcache_call; } break; case 0b000000000011: if (((inst >> 20) & 0b11111) == 0) { return &op_th_dcache_ciall; } break; case 0b000000000010: if (((inst >> 20) & 0b11111) == 0) { return &op_th_dcache_iall; } break; case 0b000000101001: return &op_th_dcache_cpa; case 0b000000101011: return &op_th_dcache_cipa; case 0b000000101010: return &op_th_dcache_ipa; case 0b000000100101: return &op_th_dcache_cva; case 0b000000100111: return &op_th_dcache_civa; case 0b000000100110: return &op_th_dcache_iva; case 0b000000100001: return &op_th_dcache_csw; case 0b000000100011: return &op_th_dcache_cisw; case 0b000000100010: return &op_th_dcache_isw; case 0b000000101000: return &op_th_dcache_cpal1; case 0b000000100100: return &op_th_dcache_cval1; case 0b000000010000: if (((inst >> 20) & 0b11111) == 0) { return &op_th_icache_iall; } break; case 0b000000010001: if (((inst >> 20) & 0b11111) == 0) { return &op_th_icache_ialls; } break; case 0b000000111000: return &op_th_icache_ipa; case 0b000000110000: return &op_th_icache_iva; case 0b000000010101: if (((inst >> 20) & 0b11111) == 0) { return &op_th_l2cache_call; } break; case 0b000000010111: if (((inst >> 20) & 0b11111) == 0) { return &op_th_l2cache_ciall; } break; case 0b000000010110: if (((inst >> 20) & 0b11111) == 0) { return &op_th_l2cache_iall; } break; } break; } break; /* custom-0 */ } break; } return NULL; } const rv_opcode_data *decode_xtheadcondmov(rv_decode *dec, rv_isa isa) { rv_inst inst = dec->inst; switch (((inst >> 0) & 0b11)) { case 3: switch (((inst >> 2) & 0b11111)) { case 2: /* custom-0 */ switch ((inst >> 12) & 0b111) { case 1: switch ((inst >> 25) & 0b1111111) { case 0b0100000: return &op_th_mveqz; case 0b0100001: return &op_th_mvnez; } break; } break; /* custom-0 */ } break; } return NULL; } const rv_opcode_data *decode_xtheadfmemidx(rv_decode *dec, rv_isa isa) { rv_inst inst = dec->inst; switch (((inst >> 0) & 0b11)) { case 3: switch (((inst >> 2) & 0b11111)) { case 2: /* custom-0 */ switch ((inst >> 12) & 0b111) { case 6: switch ((inst >> 27) & 0b11111) { case 8: return &op_th_flrw; case 10: return &op_th_flurw; case 12: return &op_th_flrd; case 14: return &op_th_flurd; } break; case 7: switch ((inst >> 27) & 0b11111) { case 8: return &op_th_fsrw; case 10: return &op_th_fsurw; case 12: return &op_th_fsrd; case 14: return &op_th_fsurd; } break; } break; /* custom-0 */ } break; } return NULL; } const rv_opcode_data *decode_xtheadfmv(rv_decode *dec, rv_isa isa) { rv_inst inst = dec->inst; switch (((inst >> 0) & 0b11)) { case 3: switch (((inst >> 2) & 0b11111)) { case 2: /* custom-0 */ switch ((inst >> 12) & 0b111) { case 1: switch ((inst >> 25) & 0b1111111) { case 0b1010000: if (((inst >> 20) & 0b11111) == 0) { return &op_th_fmv_hw_x; } break; case 0b1100000: if (((inst >> 20) & 0b11111) == 0) { return &op_th_fmv_x_hw; } break; } break; } break; /* custom-0 */ } break; } return NULL; } const rv_opcode_data *decode_xtheadmac(rv_decode *dec, rv_isa isa) { rv_inst inst = dec->inst; switch (((inst >> 0) & 0b11)) { case 3: switch (((inst >> 2) & 0b11111)) { case 2: /* custom-0 */ switch ((inst >> 12) & 0b111) { case 1: switch ((inst >> 25) & 0b1111111) { case 0b0010000: return &op_th_mula; case 0b0010001: return &op_th_muls; case 0b0010010: return &op_th_mulaw; case 0b0010011: return &op_th_mulsw; case 0b0010100: return &op_th_mulah; case 0b0010101: return &op_th_mulsh; } break; } break; /* custom-0 */ } break; } return NULL; } const rv_opcode_data *decode_xtheadmemidx(rv_decode *dec, rv_isa isa) { rv_inst inst = dec->inst; switch (((inst >> 0) & 0b11)) { case 3: switch (((inst >> 2) & 0b11111)) { case 2: /* custom-0 */ switch ((inst >> 12) & 0b111) { case 4: switch ((inst >> 27) & 0b11111) { case 0: return &op_th_lrb; case 1: return &op_th_lbib; case 2: return &op_th_lurb; case 3: return &op_th_lbia; case 4: return &op_th_lrh; case 5: return &op_th_lhib; case 6: return &op_th_lurh; case 7: return &op_th_lhia; case 8: return &op_th_lrw; case 9: return &op_th_lwib; case 10: return &op_th_lurw; case 11: return &op_th_lwia; case 12: return &op_th_lrd; case 13: return &op_th_ldib; case 14: return &op_th_lurd; case 15: return &op_th_ldia; case 16: return &op_th_lrbu; case 17: return &op_th_lbuib; case 18: return &op_th_lurbu; case 19: return &op_th_lbuia; case 20: return &op_th_lrhu; case 21: return &op_th_lhuib; case 22: return &op_th_lurhu; case 23: return &op_th_lhuia; case 24: return &op_th_lrwu; case 25: return &op_th_lwuib; case 26: return &op_th_lurwu; case 27: return &op_th_lwuia; } break; case 5: switch ((inst >> 27) & 0b11111) { case 0: return &op_th_srb; case 1: return &op_th_sbib; case 2: return &op_th_surb; case 3: return &op_th_sbia; case 4: return &op_th_srh; case 5: return &op_th_shib; case 6: return &op_th_surh; case 7: return &op_th_shia; case 8: return &op_th_srw; case 9: return &op_th_swib; case 10: return &op_th_surw; case 11: return &op_th_swia; case 12: return &op_th_srd; case 13: return &op_th_sdib; case 14: return &op_th_surd; case 15: return &op_th_sdia; } break; break; } break; /* custom-0 */ } break; } return NULL; } const rv_opcode_data *decode_xtheadmempair(rv_decode *dec, rv_isa isa) { rv_inst inst = dec->inst; switch (((inst >> 0) & 0b11)) { case 3: switch (((inst >> 2) & 0b11111)) { case 2: /* custom-0 */ switch ((inst >> 12) & 0b111) { case 4: switch ((inst >> 27) & 0b11111) { case 28: return &op_th_lwd; case 30: return &op_th_lwud; case 31: return &op_th_ldd; } break; case 5: switch ((inst >> 27) & 0b11111) { case 28: return &op_th_swd; case 31: return &op_th_sdd; } break; } break; /* custom-0 */ } break; } return NULL; } const rv_opcode_data *decode_xtheadsync(rv_decode *dec, rv_isa isa) { rv_inst inst = dec->inst; switch (((inst >> 0) & 0b11)) { case 3: switch (((inst >> 2) & 0b11111)) { case 2: /* custom-0 */ switch ((inst >> 12) & 0b111) { case 0: switch ((inst >> 25) & 0b1111111) { case 0b0000010: return &op_th_sfence_vmas; case 0b0000000: switch ((inst >> 20) & 0b11111) { case 0b11000: return &op_th_sync; case 0b11010: return &op_th_sync_i; case 0b11011: return &op_th_sync_is; case 0b11001: return &op_th_sync_s; } break; } break; } break; /* custom-0 */ } break; } return NULL; }