aboutsummaryrefslogtreecommitdiff
path: root/riscv/processor.cc
diff options
context:
space:
mode:
Diffstat (limited to 'riscv/processor.cc')
-rw-r--r--riscv/processor.cc21
1 files changed, 13 insertions, 8 deletions
diff --git a/riscv/processor.cc b/riscv/processor.cc
index c8cb5be..a813068 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -1064,6 +1064,12 @@ reg_t processor_t::get_csr(int which, insn_t insn, bool write, bool peek)
throw trap_illegal_instruction(insn.bits());
}
+const insn_desc_t insn_desc_t::illegal_instruction = {
+ 0, 0,
+ &::illegal_instruction, &::illegal_instruction, &::illegal_instruction, &::illegal_instruction,
+ &::illegal_instruction, &::illegal_instruction, &::illegal_instruction, &::illegal_instruction
+};
+
reg_t illegal_instruction(processor_t UNUSED *p, insn_t insn, reg_t UNUSED pc)
{
// The illegal instruction can be longer than ILEN bits, where the tval will
@@ -1076,11 +1082,11 @@ insn_func_t processor_t::decode_insn(insn_t insn)
{
// look up opcode in hash table
size_t idx = insn.bits() % OPCODE_CACHE_SIZE;
- insn_desc_t desc = opcode_cache[idx];
+ auto [hit, desc] = opcode_cache[idx].lookup(insn.bits());
bool rve = extension_enabled('E');
- if (unlikely(insn.bits() != desc.match)) {
+ if (unlikely(!hit)) {
// fall back to linear search
auto matching = [insn_bits = insn.bits()](const insn_desc_t &d) {
return (insn_bits & d.mask) == d.match;
@@ -1091,12 +1097,11 @@ insn_func_t processor_t::decode_insn(insn_t insn)
p = std::find_if(instructions.begin(), instructions.end(), matching);
assert(p != instructions.end());
}
- desc = *p;
- opcode_cache[idx] = desc;
- opcode_cache[idx].match = insn.bits();
+ desc = &*p;
+ opcode_cache[idx].replace(insn.bits(), desc);
}
- return desc.func(xlen, rve, log_commits_enabled);
+ return desc->func(xlen, rve, log_commits_enabled);
}
void processor_t::register_insn(insn_desc_t desc, bool is_custom) {
@@ -1112,7 +1117,7 @@ void processor_t::register_insn(insn_desc_t desc, bool is_custom) {
void processor_t::build_opcode_map()
{
for (size_t i = 0; i < OPCODE_CACHE_SIZE; i++)
- opcode_cache[i] = insn_desc_t::illegal();
+ opcode_cache[i].reset();
}
void processor_t::register_extension(extension_t *x) {
@@ -1190,7 +1195,7 @@ void processor_t::register_base_instructions()
#undef DEFINE_INSN
// terminate instruction list with a catch-all
- register_base_insn(insn_desc_t::illegal());
+ register_base_insn(insn_desc_t::illegal_instruction);
build_opcode_map();
}