aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2023-06-17 16:53:34 -0700
committerAndrew Waterman <andrew@sifive.com>2023-06-17 18:47:59 -0700
commit057cfbcca6dc6c65f1fd69b754e499ccabebe273 (patch)
tree2339c8e857268ff2fe83def41668a10c4a50fee2
parente58d89aa2c38ca40e68ad4e010c91239c4794e00 (diff)
downloadriscv-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.cc57
-rw-r--r--riscv/riscv.mk.in3
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 \