diff options
author | Andrew Waterman <andrew@sifive.com> | 2022-05-13 13:58:10 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-13 13:58:10 -0700 |
commit | 78dfe62633ce4fe6e6a70afae04168e1f102b673 (patch) | |
tree | 8a62f17aa8f261bc9ac8015cd28257da100727ab /disasm/disasm.cc | |
parent | ff645fb4eb9cd8a957dd8826369de8dd7e1fb8a3 (diff) | |
download | riscv-isa-sim-78dfe62633ce4fe6e6a70afae04168e1f102b673.zip riscv-isa-sim-78dfe62633ce4fe6e6a70afae04168e1f102b673.tar.gz riscv-isa-sim-78dfe62633ce4fe6e6a70afae04168e1f102b673.tar.bz2 |
Fix disassembly of custom instructions that overlap standard ones (#999)
Iterate over the instruction chains in reverse order, prioritizing
the last call to `disassembler_t::add_insn`.
To preserve behavior for the standard instructions, reverse the order
in which we add instructions in the `disassembler_t` constructor.
Supersedes #995.
Diffstat (limited to 'disasm/disasm.cc')
-rw-r--r-- | disasm/disasm.cc | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/disasm/disasm.cc b/disasm/disasm.cc index c8e92d6..7df39da 100644 --- a/disasm/disasm.cc +++ b/disasm/disasm.cc @@ -7,6 +7,8 @@ #include <cstdarg> #include <sstream> #include <stdlib.h> +// For std::reverse: +#include <algorithm> // Indicates that the next arg (only) is optional. // If the result of converting the next arg to a string is "" @@ -2116,13 +2118,18 @@ disassembler_t::disassembler_t(const isa_parser_t *isa) // finally: instructions with known opcodes but unknown arguments add_unknown_insns(this); + + // Now, reverse the lists, because we search them back-to-front (so that + // custom instructions later added with add_insn have highest priority). + for (size_t i = 0; i < HASH_SIZE+1; i++) + std::reverse(chain[i].begin(), chain[i].end()); } const disasm_insn_t* disassembler_t::probe_once(insn_t insn, size_t idx) const { - for (size_t j = 0; j < chain[idx].size(); j++) - if(*chain[idx][j] == insn) - return chain[idx][j]; + for (auto it = chain[idx].rbegin(); it != chain[idx].rend(); ++it) + if (*(*it) == insn) + return *it; return NULL; } |