Skip to content

Commit 30b8505

Browse files
committed
RISC-V: Cache instruction support
Calling riscv_subset_supports repeatedly harms the performance in a measurable way (about 3-13% in total on the most cases). As a simple solution, this commit now caches instruction class support (whether specific instruction class is supported) as a signed char array. It is expected to have 5-7% performance improvements when disassembling linked RISC-V ELF programs using objdump but this is particularly effective with programs with many CSR instructions (up to ~42% on the author's PC). include/ChangeLog: * opcode/riscv.h (enum riscv_insn_class): Add NUM_INSN_CLASSES. opcodes/ChangeLog: * riscv-dis.c (riscv_insn_support_cache) New. (init_riscv_dis_state_for_arch): Clear the instruction support cache. (riscv_disassemble_insn): Cache the instruction support.
1 parent 7fbe1bf commit 30b8505

File tree

2 files changed

+16
-1
lines changed

2 files changed

+16
-1
lines changed

include/opcode/riscv.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,8 @@ enum riscv_insn_class
456456
INSN_CLASS_XTHEADMEMPAIR,
457457
INSN_CLASS_XTHEADSYNC,
458458
INSN_CLASS_XVENTANACONDOPS,
459+
460+
NUM_INSN_CLASSES,
459461
};
460462

461463
/* This structure holds information for a particular instruction. */

opcodes/riscv-dis.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,9 @@ static bool no_aliases = false;
110110

111111
/* If set, disassemble with numeric register names. */
112112
static bool is_numeric = false;
113+
114+
/* Instruction support cache. */
115+
static signed char riscv_insn_support_cache[NUM_INSN_CLASSES];
113116

114117

115118
/* Set current disassembler context (dis_arch_context_current).
@@ -219,6 +222,9 @@ static void
219222
init_riscv_dis_state_for_arch (void)
220223
{
221224
is_arch_changed = true;
225+
/* Clear instruction support cache. */
226+
for (size_t i = 0; i < NUM_INSN_CLASSES; i++)
227+
riscv_insn_support_cache[i] = 0;
222228
}
223229

224230
/* Initialization (for arch and options). */
@@ -1033,7 +1039,14 @@ riscv_disassemble_insn (bfd_vma memaddr,
10331039
if ((op->xlen_requirement != 0) && (op->xlen_requirement != xlen))
10341040
continue;
10351041
/* Is this instruction supported by the current architecture? */
1036-
if (!riscv_multi_subset_supports (&riscv_rps_dis, op->insn_class))
1042+
if (riscv_insn_support_cache[op->insn_class] == 0)
1043+
{
1044+
riscv_insn_support_cache[op->insn_class]
1045+
= riscv_multi_subset_supports (&riscv_rps_dis, op->insn_class)
1046+
? +1
1047+
: -1;
1048+
}
1049+
if (riscv_insn_support_cache[op->insn_class] < 0)
10371050
continue;
10381051

10391052
matched_op = op;

0 commit comments

Comments
 (0)