1 #pragma once
2 
3 #include <algorithm>
4 #include <functional>
5 #include <vector>
6 #include "common_types.h"
7 #include "crash.h"
8 
9 struct Rejector {
10     u16 mask;
11     u16 unexpected;
RejectsRejector12     bool Rejects(u16 instruction) const {
13         return (instruction & mask) == unexpected;
14     }
15 };
16 
17 template <typename Visitor>
18 class Matcher {
19 public:
20     using visitor_type = Visitor;
21     using handler_return_type = typename Visitor::instruction_return_type;
22     using handler_function = std::function<handler_return_type(Visitor&, u16, u16)>;
23 
Matcher(const char * const name,u16 mask,u16 expected,bool expanded,handler_function func)24     Matcher(const char* const name, u16 mask, u16 expected, bool expanded, handler_function func)
25         : name{name}, mask{mask}, expected{expected}, expanded{expanded}, fn{std::move(func)} {}
26 
AllMatcher(handler_function func)27     static Matcher AllMatcher(handler_function func) {
28         return Matcher("*", 0, 0, false, std::move(func));
29     }
30 
GetName()31     const char* GetName() const {
32         return name;
33     }
34 
NeedExpansion()35     bool NeedExpansion() const {
36         return expanded;
37     }
38 
Matches(u16 instruction)39     bool Matches(u16 instruction) const {
40         return (instruction & mask) == expected &&
41                std::none_of(rejectors.begin(), rejectors.end(),
42                             [instruction](const Rejector& rejector) {
43                                 return rejector.Rejects(instruction);
44                             });
45     }
46 
Except(Rejector rejector)47     Matcher Except(Rejector rejector) const {
48         Matcher new_matcher(*this);
49         new_matcher.rejectors.push_back(rejector);
50         return new_matcher;
51     }
52 
53     handler_return_type call(Visitor& v, u16 instruction, u16 instruction_expansion = 0) const {
54         ASSERT(Matches(instruction));
55         return fn(v, instruction, instruction_expansion);
56     }
57 
58 private:
59     const char* name;
60     u16 mask;
61     u16 expected;
62     bool expanded;
63     handler_function fn;
64     std::vector<Rejector> rejectors;
65 };
66