diff options
author | Andrew Waterman <andrew@sifive.com> | 2024-06-10 18:30:34 -0700 |
---|---|---|
committer | Andrew Waterman <andrew@sifive.com> | 2024-06-11 13:51:14 -0700 |
commit | 625e9451a75b3094597a1b1647cb71fa65bd8b98 (patch) | |
tree | 73e0a94c00972b239c0717cb7a5ebda763a2690d /riscv | |
parent | acd43e0191ae9afa8099a00bb9162b134233b01f (diff) | |
download | spike-625e9451a75b3094597a1b1647cb71fa65bd8b98.zip spike-625e9451a75b3094597a1b1647cb71fa65bd8b98.tar.gz spike-625e9451a75b3094597a1b1647cb71fa65bd8b98.tar.bz2 |
Keep potentially overlapping instructions in order at head of list
Diffstat (limited to 'riscv')
-rw-r--r-- | riscv/processor.cc | 52 |
1 files changed, 32 insertions, 20 deletions
diff --git a/riscv/processor.cc b/riscv/processor.cc index 3a9c0d9..c8cb5be 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -1111,17 +1111,6 @@ void processor_t::register_insn(insn_desc_t desc, bool is_custom) { void processor_t::build_opcode_map() { - struct cmp { - bool operator()(const insn_desc_t& lhs, const insn_desc_t& rhs) { - if (lhs.match == rhs.match) - return lhs.mask > rhs.mask; - return lhs.match > rhs.match; - } - }; - - std::sort(instructions.begin(), instructions.end(), cmp()); - std::sort(custom_instructions.begin(), custom_instructions.end(), cmp()); - for (size_t i = 0; i < OPCODE_CACHE_SIZE; i++) opcode_cache[i] = insn_desc_t::illegal(); } @@ -1145,15 +1134,12 @@ void processor_t::register_base_instructions() { #define DECLARE_INSN(name, match, mask) \ insn_bits_t name##_match = (match), name##_mask = (mask); \ - bool name##_supported = true; + isa_extension_t name##_ext = NUM_ISA_EXTENSIONS; \ + bool name##_overlapping = false; #include "encoding.h" #undef DECLARE_INSN - #define DECLARE_OVERLAP_INSN(name, ext) { name##_supported = isa->extension_enabled(ext); } - #include "overlap_list.h" - #undef DECLARE_OVERLAP_INSN - #define DEFINE_INSN(name) \ extern reg_t fast_rv32i_##name(processor_t*, insn_t, reg_t); \ extern reg_t fast_rv64i_##name(processor_t*, insn_t, reg_t); \ @@ -1162,8 +1148,14 @@ void processor_t::register_base_instructions() extern reg_t logged_rv32i_##name(processor_t*, insn_t, reg_t); \ extern reg_t logged_rv64i_##name(processor_t*, insn_t, reg_t); \ extern reg_t logged_rv32e_##name(processor_t*, insn_t, reg_t); \ - extern reg_t logged_rv64e_##name(processor_t*, insn_t, reg_t); \ - if (name##_supported) { \ + extern reg_t logged_rv64e_##name(processor_t*, insn_t, reg_t); + #include "insn_list.h" + #undef DEFINE_INSN + + // add overlapping instructions first, in order + #define DECLARE_OVERLAP_INSN(name, ext) \ + name##_overlapping = true; \ + if (isa->extension_enabled(ext)) \ register_base_insn((insn_desc_t) { \ name##_match, \ name##_mask, \ @@ -1174,9 +1166,29 @@ void processor_t::register_base_instructions() logged_rv32i_##name, \ logged_rv64i_##name, \ logged_rv32e_##name, \ - logged_rv64e_##name}); \ - } + logged_rv64e_##name}); + #include "overlap_list.h" + #undef DECLARE_OVERLAP_INSN + + // add all other instructions. since they are non-overlapping, the order + // does not affect correctness, but more frequent instructions should + // appear earlier to improve search time on opcode_cache misses. + #define DEFINE_INSN(name) \ + if (!name##_overlapping) \ + register_base_insn((insn_desc_t) { \ + name##_match, \ + name##_mask, \ + fast_rv32i_##name, \ + fast_rv64i_##name, \ + fast_rv32e_##name, \ + fast_rv64e_##name, \ + logged_rv32i_##name, \ + logged_rv64i_##name, \ + logged_rv32e_##name, \ + logged_rv64e_##name}); #include "insn_list.h" + #undef DEFINE_INSN + // terminate instruction list with a catch-all register_base_insn(insn_desc_t::illegal()); |