Created
August 7, 2023 14:46
-
-
Save luhenry/c31f951abc6b22a91955b8c2a0b43fd4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c | |
index f8d391ee98b..17f8208c15a 100644 | |
--- a/opcodes/riscv-dis.c | |
+++ b/opcodes/riscv-dis.c | |
@@ -676,23 +676,9 @@ riscv_disassemble_insn (bfd_vma memaddr, | |
disassemble_info *info) | |
{ | |
const struct riscv_opcode *op; | |
- static bool init = false; | |
- static const struct riscv_opcode *riscv_hash[OP_MASK_OP + 1]; | |
struct riscv_private_data *pd; | |
int insnlen; | |
-#define OP_HASH_IDX(i) ((i) & (riscv_insn_length (i) == 2 ? 0x3 : OP_MASK_OP)) | |
- | |
- /* Build a hash table to shorten the search time. */ | |
- if (! init) | |
- { | |
- for (op = riscv_opcodes; op->name; op++) | |
- if (!riscv_hash[OP_HASH_IDX (op->match)]) | |
- riscv_hash[OP_HASH_IDX (op->match)] = op; | |
- | |
- init = true; | |
- } | |
- | |
if (info->private_data == NULL) | |
{ | |
int i; | |
@@ -731,85 +717,81 @@ riscv_disassemble_insn (bfd_vma memaddr, | |
info->target = 0; | |
info->target2 = 0; | |
- op = riscv_hash[OP_HASH_IDX (word)]; | |
- if (op != NULL) | |
+ /* If XLEN is not known, get its value from the ELF class. */ | |
+ if (info->mach == bfd_mach_riscv64) | |
+ xlen = 64; | |
+ else if (info->mach == bfd_mach_riscv32) | |
+ xlen = 32; | |
+ else if (info->section != NULL) | |
{ | |
- /* If XLEN is not known, get its value from the ELF class. */ | |
- if (info->mach == bfd_mach_riscv64) | |
- xlen = 64; | |
- else if (info->mach == bfd_mach_riscv32) | |
- xlen = 32; | |
- else if (info->section != NULL) | |
- { | |
- Elf_Internal_Ehdr *ehdr = elf_elfheader (info->section->owner); | |
- xlen = ehdr->e_ident[EI_CLASS] == ELFCLASS64 ? 64 : 32; | |
- } | |
- | |
- /* If arch has the Zfinx extension, replace FPR with GPR. */ | |
- if (riscv_subset_supports (&riscv_rps_dis, "zfinx")) | |
- riscv_fpr_names = riscv_gpr_names; | |
- else | |
- riscv_fpr_names = riscv_gpr_names == riscv_gpr_names_abi ? | |
- riscv_fpr_names_abi : riscv_fpr_names_numeric; | |
- | |
- for (; op->name; op++) | |
- { | |
- /* Does the opcode match? */ | |
- if (! (op->match_func) (op, word)) | |
- continue; | |
- /* Is this a pseudo-instruction and may we print it as such? */ | |
- if (no_aliases && (op->pinfo & INSN_ALIAS)) | |
- continue; | |
- /* Is this instruction restricted to a certain value of XLEN? */ | |
- if ((op->xlen_requirement != 0) && (op->xlen_requirement != xlen)) | |
- continue; | |
- /* Is this instruction supported by the current architecture? */ | |
- if (!riscv_multi_subset_supports (&riscv_rps_dis, op->insn_class)) | |
- continue; | |
- | |
- /* It's a match. */ | |
- (*info->fprintf_styled_func) (info->stream, dis_style_mnemonic, | |
- "%s", op->name); | |
- print_insn_args (op->args, word, memaddr, info); | |
- | |
- /* Try to disassemble multi-instruction addressing sequences. */ | |
- if (pd->to_print_addr) | |
- { | |
- info->target = pd->print_addr; | |
- (*info->fprintf_styled_func) | |
- (info->stream, dis_style_comment_start, " # "); | |
- (*info->print_address_func) (info->target, info); | |
- pd->to_print_addr = false; | |
- } | |
- | |
- /* Finish filling out insn_info fields. */ | |
- switch (op->pinfo & INSN_TYPE) | |
- { | |
- case INSN_BRANCH: | |
- info->insn_type = dis_branch; | |
- break; | |
- case INSN_CONDBRANCH: | |
- info->insn_type = dis_condbranch; | |
- break; | |
- case INSN_JSR: | |
- info->insn_type = dis_jsr; | |
- break; | |
- case INSN_DREF: | |
- info->insn_type = dis_dref; | |
- break; | |
- default: | |
- break; | |
- } | |
+ Elf_Internal_Ehdr *ehdr = elf_elfheader (info->section->owner); | |
+ xlen = ehdr->e_ident[EI_CLASS] == ELFCLASS64 ? 64 : 32; | |
+ } | |
- if (op->pinfo & INSN_DATA_SIZE) | |
- { | |
- int size = ((op->pinfo & INSN_DATA_SIZE) | |
- >> INSN_DATA_SIZE_SHIFT); | |
- info->data_size = 1 << (size - 1); | |
- } | |
+ /* If arch has the Zfinx extension, replace FPR with GPR. */ | |
+ if (riscv_subset_supports (&riscv_rps_dis, "zfinx")) | |
+ riscv_fpr_names = riscv_gpr_names; | |
+ else | |
+ riscv_fpr_names = riscv_gpr_names == riscv_gpr_names_abi ? | |
+ riscv_fpr_names_abi : riscv_fpr_names_numeric; | |
- return insnlen; | |
- } | |
+ for (op = riscv_opcodes; op->name; op++) | |
+ { | |
+ /* Does the opcode match? */ | |
+ if (! (op->match_func) (op, word)) | |
+ continue; | |
+ /* Is this a pseudo-instruction and may we print it as such? */ | |
+ if (no_aliases && (op->pinfo & INSN_ALIAS)) | |
+ continue; | |
+ /* Is this instruction restricted to a certain value of XLEN? */ | |
+ if ((op->xlen_requirement != 0) && (op->xlen_requirement != xlen)) | |
+ continue; | |
+ /* Is this instruction supported by the current architecture? */ | |
+ if (!riscv_multi_subset_supports (&riscv_rps_dis, op->insn_class)) | |
+ continue; | |
+ | |
+ /* It's a match. */ | |
+ (*info->fprintf_styled_func) (info->stream, dis_style_mnemonic, | |
+ "%s", op->name); | |
+ print_insn_args (op->args, word, memaddr, info); | |
+ | |
+ /* Try to disassemble multi-instruction addressing sequences. */ | |
+ if (pd->to_print_addr) | |
+ { | |
+ info->target = pd->print_addr; | |
+ (*info->fprintf_styled_func) | |
+ (info->stream, dis_style_comment_start, " # "); | |
+ (*info->print_address_func) (info->target, info); | |
+ pd->to_print_addr = false; | |
+ } | |
+ | |
+ /* Finish filling out insn_info fields. */ | |
+ switch (op->pinfo & INSN_TYPE) | |
+ { | |
+ case INSN_BRANCH: | |
+ info->insn_type = dis_branch; | |
+ break; | |
+ case INSN_CONDBRANCH: | |
+ info->insn_type = dis_condbranch; | |
+ break; | |
+ case INSN_JSR: | |
+ info->insn_type = dis_jsr; | |
+ break; | |
+ case INSN_DREF: | |
+ info->insn_type = dis_dref; | |
+ break; | |
+ default: | |
+ break; | |
+ } | |
+ | |
+ if (op->pinfo & INSN_DATA_SIZE) | |
+ { | |
+ int size = ((op->pinfo & INSN_DATA_SIZE) | |
+ >> INSN_DATA_SIZE_SHIFT); | |
+ info->data_size = 1 << (size - 1); | |
+ } | |
+ | |
+ return insnlen; | |
} | |
/* We did not find a match, so just print the instruction bits. */ | |
@@ -1120,7 +1102,7 @@ print_insn_riscv (bfd_vma memaddr, struct disassemble_info *info) | |
disassembler_ftype | |
riscv_get_disassembler (bfd *abfd) | |
{ | |
- const char *default_arch = "rv64gc"; | |
+ const char *default_arch = "rv64gcv_zba_zbb_zbs_zicbom_zicboz_zicbop_zihintpause_zvknha_zvknhb_zacas"; | |
if (abfd && bfd_get_flavour (abfd) == bfd_target_elf_flavour) | |
{ | |
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c | |
index dc710921287..1d03e1afc6f 100644 | |
--- a/opcodes/riscv-opc.c | |
+++ b/opcodes/riscv-opc.c | |
@@ -154,7 +154,8 @@ const char * const riscv_vma[2] = | |
static int | |
match_opcode (const struct riscv_opcode *op, insn_t insn) | |
{ | |
- return ((insn ^ op->match) & op->mask) == 0; | |
+ return (insn & op->mask) == op->match; | |
+ // return ((insn ^ op->match) & op->mask) == 0; | |
} | |
static int |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment