[v2,11/11] RISC-V: Move disassembler private data initialization
Checks
Commit Message
From: Tsukasa OI <research_trasio@irq.a4lg.com>
Because disassemble_info.private_data could be used not only by
riscv_disassemble_insn, this commit splits the initialization of the
private data to a separate function.
This commit now allows storing mapping symbol and/or section-related
information to riscv_private_data.
In performance perspective, it also has a penalty. However, it can be
easily paid back by other optimizations and it makes implementing
some optimizations easier.
opcodes/ChangeLog:
* riscv-dis.c (init_riscv_dis_private_data): New.
(riscv_disassemble_insn): Move private data initialization to
init_riscv_dis_private_data.
(print_insn_riscv): Start initializing the private data
instead of instruction only riscv_disassemble_insn function.
---
opcodes/riscv-dis.c | 51 +++++++++++++++++++++++++--------------------
1 file changed, 28 insertions(+), 23 deletions(-)
@@ -219,6 +219,29 @@ init_riscv_dis_state_for_arch_and_options (void)
is_arch_changed = false;
}
+/* Initialize private data of the disassemble_info. */
+
+static void
+init_riscv_dis_private_data (struct disassemble_info *info)
+{
+ struct riscv_private_data *pd;
+
+ pd = info->private_data = xcalloc (1, sizeof (struct riscv_private_data));
+ pd->gp = 0;
+ pd->print_addr = 0;
+ for (int i = 0; i < (int)ARRAY_SIZE (pd->hi_addr); i++)
+ pd->hi_addr[i] = -1;
+ pd->to_print_addr = false;
+ pd->has_gp = false;
+
+ for (int i = 0; i < info->symtab_size; i++)
+ if (strcmp (bfd_asymbol_name (info->symtab[i]), RISCV_GP_SYMBOL) == 0)
+ {
+ pd->gp = bfd_asymbol_value (info->symtab[i]);
+ pd->has_gp = true;
+ }
+}
+
/* Update architecture for disassembler with its context.
Call initialization functions if either:
- the architecture for current context is changed or
@@ -809,7 +832,7 @@ riscv_disassemble_insn (bfd_vma memaddr,
const struct riscv_opcode *op, *matched_op;
static bool init = false;
static const struct riscv_opcode *riscv_hash[OP_MASK_OP + 1];
- struct riscv_private_data *pd;
+ struct riscv_private_data *pd = info->private_data;
int insnlen;
#define OP_HASH_IDX(i) ((i) & (riscv_insn_length (i) == 2 ? 0x3 : OP_MASK_OP))
@@ -824,28 +847,6 @@ riscv_disassemble_insn (bfd_vma memaddr,
init = true;
}
- if (info->private_data == NULL)
- {
- int i;
-
- pd = info->private_data = xcalloc (1, sizeof (struct riscv_private_data));
- pd->gp = 0;
- pd->print_addr = 0;
- for (i = 0; i < (int)ARRAY_SIZE (pd->hi_addr); i++)
- pd->hi_addr[i] = -1;
- pd->to_print_addr = false;
- pd->has_gp = false;
-
- for (i = 0; i < info->symtab_size; i++)
- if (strcmp (bfd_asymbol_name (info->symtab[i]), RISCV_GP_SYMBOL) == 0)
- {
- pd->gp = bfd_asymbol_value (info->symtab[i]);
- pd->has_gp = true;
- }
- }
- else
- pd = info->private_data;
-
insnlen = riscv_insn_length (word);
/* RISC-V instructions are always little-endian. */
@@ -1219,6 +1220,10 @@ print_insn_riscv (bfd_vma memaddr, struct disassemble_info *info)
int (*riscv_disassembler) (bfd_vma, insn_t, const bfd_byte *,
struct disassemble_info *);
+ /* Initialize the private data. */
+ if (info->private_data == NULL)
+ init_riscv_dis_private_data (info);
+
/* Guess and update XLEN if we haven't determined it yet. */
if (xlen == 0)
update_riscv_dis_xlen (info);