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