diff options
author | Andrew Waterman <andrew@sifive.com> | 2023-06-17 16:53:34 -0700 |
---|---|---|
committer | Andrew Waterman <andrew@sifive.com> | 2023-06-17 18:47:59 -0700 |
commit | 057cfbcca6dc6c65f1fd69b754e499ccabebe273 (patch) | |
tree | 2339c8e857268ff2fe83def41668a10c4a50fee2 | |
parent | e58d89aa2c38ca40e68ad4e010c91239c4794e00 (diff) | |
download | riscv-isa-sim-057cfbcca6dc6c65f1fd69b754e499ccabebe273.zip riscv-isa-sim-057cfbcca6dc6c65f1fd69b754e499ccabebe273.tar.gz riscv-isa-sim-057cfbcca6dc6c65f1fd69b754e499ccabebe273.tar.bz2 |
Add test that ensures opcodes don't overlap unless explicitly specified
-rw-r--r-- | riscv/check-opcode-overlap.t.cc | 57 | ||||
-rw-r--r-- | riscv/riscv.mk.in | 3 |
2 files changed, 59 insertions, 1 deletions
diff --git a/riscv/check-opcode-overlap.t.cc b/riscv/check-opcode-overlap.t.cc new file mode 100644 index 0000000..2922001 --- /dev/null +++ b/riscv/check-opcode-overlap.t.cc @@ -0,0 +1,57 @@ +#include "decode.h" +#include "common.h" +#include <unordered_set> +#include <vector> +#include <string> +#include <cstdio> + +struct opcode { + insn_bits_t match; + insn_bits_t mask; + std::string name; +}; + +static void check_overlap(const opcode& a, const opcode& b) +{ + if ((a.match & b.mask) == b.match) { + fprintf(stderr, "Instruction %s (%" PRIx64 ") overlaps instruction %s (%" PRIx64 ", mask %" PRIx64 ")\n", + a.name.c_str(), a.match, b.name.c_str(), b.match, b.mask); + exit(-1); + } +} + +int main() +{ + #define DECLARE_INSN(name, match, mask) \ + const insn_bits_t UNUSED name##_match = (match), name##_mask = (mask); + #include "encoding.h" + #undef DECLARE_INSN + + static const opcode static_list[] = { + #define DEFINE_INSN(name) \ + {name##_match, name##_mask, #name}, + #include "insn_list.h" + #undef DEFINE_INSN + }; + + std::unordered_set<std::string> overlap_list; + #define DECLARE_OVERLAP_INSN(name, ext) \ + overlap_list.insert(std::string(#name)); + #include "overlap_list.h" + #undef DECLARE_OVERLAP_INSN + + std::vector<const opcode*> list; + for (size_t i = 0; i < sizeof(static_list) / sizeof(static_list[0]); i++) { + if (!overlap_list.count(static_list[i].name)) + list.push_back(&static_list[i]); + } + + for (size_t i = 1; i < list.size(); i++) { + for (size_t j = 0; j < i; j++) { + check_overlap(*list[i], *list[j]); + check_overlap(*list[j], *list[i]); + } + } + + return 0; +} diff --git a/riscv/riscv.mk.in b/riscv/riscv.mk.in index 1cfe627..ac45b28 100644 --- a/riscv/riscv.mk.in +++ b/riscv/riscv.mk.in @@ -75,7 +75,8 @@ riscv_srcs = \ cfg.cc \ $(riscv_gen_srcs) \ -riscv_test_srcs = +riscv_test_srcs = \ + check-opcode-overlap.t.cc \ riscv_gen_hdrs = \ insn_list.h \ |