aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2024-06-10 18:30:34 -0700
committerAndrew Waterman <andrew@sifive.com>2024-06-11 13:51:14 -0700
commit625e9451a75b3094597a1b1647cb71fa65bd8b98 (patch)
tree73e0a94c00972b239c0717cb7a5ebda763a2690d
parentacd43e0191ae9afa8099a00bb9162b134233b01f (diff)
downloadriscv-isa-sim-625e9451a75b3094597a1b1647cb71fa65bd8b98.zip
riscv-isa-sim-625e9451a75b3094597a1b1647cb71fa65bd8b98.tar.gz
riscv-isa-sim-625e9451a75b3094597a1b1647cb71fa65bd8b98.tar.bz2
Keep potentially overlapping instructions in order at head of list
-rw-r--r--riscv/processor.cc52
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());