Browse Source

Speed up disassembler_t::lookup

Optimize the hash functions for RISC-V instruction encodings.  This is
only a perf optimization; instructions that don't adhere to RISC-V
standard practice will still disassemble correctly, just more slowly.
pull/839/head
Andrew Waterman 5 years ago
parent
commit
1453b3588b
  1. 27
      disasm/disasm.cc
  2. 12
      riscv/disasm.h

27
disasm/disasm.cc

@ -1826,14 +1826,8 @@ disassembler_t::disassembler_t(int xlen)
add_unknown_insns(this);
}
const disasm_insn_t* disassembler_t::lookup(insn_t insn) const
const disasm_insn_t* disassembler_t::probe_once(insn_t insn, size_t idx) const
{
size_t idx = insn.bits() % HASH_SIZE;
for (size_t j = 0; j < chain[idx].size(); j++)
if(*chain[idx][j] == insn)
return chain[idx][j];
idx = HASH_SIZE;
for (size_t j = 0; j < chain[idx].size(); j++)
if(*chain[idx][j] == insn)
return chain[idx][j];
@ -1841,11 +1835,24 @@ const disasm_insn_t* disassembler_t::lookup(insn_t insn) const
return NULL;
}
const disasm_insn_t* disassembler_t::lookup(insn_t insn) const
{
if (auto p = probe_once(insn, hash(insn.bits(), MASK1)))
return p;
if (auto p = probe_once(insn, hash(insn.bits(), MASK2)))
return p;
return probe_once(insn, HASH_SIZE);
}
void NOINLINE disassembler_t::add_insn(disasm_insn_t* insn)
{
size_t idx = HASH_SIZE;
if (insn->get_mask() % HASH_SIZE == HASH_SIZE - 1)
idx = insn->get_match() % HASH_SIZE;
size_t idx =
(insn->get_mask() & MASK1) == MASK1 ? hash(insn->get_match(), MASK1) :
(insn->get_mask() & MASK2) == MASK2 ? hash(insn->get_match(), MASK2) :
HASH_SIZE;
chain[idx].push_back(insn);
}

12
riscv/disasm.h

@ -88,8 +88,18 @@ class disassembler_t
void add_insn(disasm_insn_t* insn);
private:
static const int HASH_SIZE = 256;
static const int HASH_SIZE = 255;
std::vector<const disasm_insn_t*> chain[HASH_SIZE+1];
const disasm_insn_t* probe_once(insn_t insn, size_t idx) const;
static const unsigned int MASK1 = 0x7f;
static const unsigned int MASK2 = 0xe003;
static const unsigned int hash(insn_bits_t insn, unsigned int mask)
{
return (insn & mask) % HASH_SIZE;
}
};
#endif

Loading…
Cancel
Save