From 86ee168194c9d09eb10328d347e410fb13ae7f83 Mon Sep 17 00:00:00 2001 From: Tsukasa OI Date: Mon, 11 Jul 2022 16:33:37 +0900 Subject: [PATCH] RISC-V: Cache instruction class support It caches instruction class support values to suppress many per- instruction calls to the riscv_multi_subset_supports function. include/ChangeLog: * opcode/riscv.h (enum riscv_insn_class): Add NUM_INSN_CLASSES. opcodes/ChangeLog: * riscv-dis.c (init_riscv_dis_state_for_arch): Clear insn class cache. (riscv_disassemble_insn): Cache support results. --- include/opcode/riscv.h | 2 ++ opcodes/riscv-dis.c | 14 +++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h index b115e338a05..c7d9fd7a59e 100644 --- a/include/opcode/riscv.h +++ b/include/opcode/riscv.h @@ -397,6 +397,8 @@ enum riscv_insn_class INSN_CLASS_ZICBOP, INSN_CLASS_ZICBOZ, INSN_CLASS_H, + + NUM_INSN_CLASSES, }; /* This structure holds information for a particular instruction. */ diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c index b18e9da2b46..29a7cd0ca41 100644 --- a/opcodes/riscv-dis.c +++ b/opcodes/riscv-dis.c @@ -64,6 +64,9 @@ static enum riscv_seg_mstate last_map_state; static const char * const *riscv_gpr_names; static const char * const *riscv_fpr_names; +/* Instruction class support cache. */ +static signed char riscv_insn_class_support_cache[NUM_INSN_CLASSES]; + /* If set, disassemble as most general instruction. */ static bool no_aliases = false; @@ -79,6 +82,8 @@ static bool is_init_csr = false; static void init_riscv_dis_state_for_arch (void) { + for (size_t i = 0; i < NUM_INSN_CLASSES; i++) + riscv_insn_class_support_cache[i] = 0; } static void @@ -759,7 +764,14 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info) 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)) + if (riscv_insn_class_support_cache[op->insn_class] == 0) + { + riscv_insn_class_support_cache[op->insn_class] + = riscv_multi_subset_supports (&riscv_rps_dis, op->insn_class) + ? +1 + : -1; + } + if (riscv_insn_class_support_cache[op->insn_class] < 0) continue; matched_op = op;