|
|
@ -14,16 +14,12 @@ |
|
|
|
|
|
|
|
|
namespace Dynarmic::Decoder { |
|
|
namespace Dynarmic::Decoder { |
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Generic instruction handling construct. |
|
|
|
|
|
* |
|
|
|
|
|
* @tparam Visitor An arbitrary visitor type that will be passed through |
|
|
|
|
|
* to the function being handled. This type must be the |
|
|
|
|
|
* type of the first parameter in a handler function. |
|
|
|
|
|
* |
|
|
|
|
|
* @tparam OpcodeType Type representing an opcode. This must be the |
|
|
|
|
|
* type of the second parameter in a handler function. |
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
/// Generic instruction handling construct. |
|
|
|
|
|
/// @tparam Visitor An arbitrary visitor type that will be passed through |
|
|
|
|
|
/// to the function being handled. This type must be the |
|
|
|
|
|
/// type of the first parameter in a handler function. |
|
|
|
|
|
/// @tparam OpcodeType Type representing an opcode. This must be the |
|
|
|
|
|
/// type of the second parameter in a handler function. |
|
|
template<typename Visitor, typename OpcodeType> |
|
|
template<typename Visitor, typename OpcodeType> |
|
|
class Matcher { |
|
|
class Matcher { |
|
|
public: |
|
|
public: |
|
|
@ -35,30 +31,26 @@ public: |
|
|
: mask{mask}, expected{expected}, fn{std::move(func)} {} |
|
|
: mask{mask}, expected{expected}, fn{std::move(func)} {} |
|
|
|
|
|
|
|
|
/// Gets the mask for this instruction. |
|
|
/// Gets the mask for this instruction. |
|
|
opcode_type GetMask() const { |
|
|
|
|
|
|
|
|
inline opcode_type GetMask() const noexcept { |
|
|
return mask; |
|
|
return mask; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/// Gets the expected value after masking for this instruction. |
|
|
/// Gets the expected value after masking for this instruction. |
|
|
opcode_type GetExpected() const { |
|
|
|
|
|
|
|
|
inline opcode_type GetExpected() const noexcept { |
|
|
return expected; |
|
|
return expected; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Tests to see if the given instruction is the instruction this matcher represents. |
|
|
|
|
|
* @param instruction The instruction to test |
|
|
|
|
|
* @returns true if the given instruction matches. |
|
|
|
|
|
*/ |
|
|
|
|
|
bool Matches(opcode_type instruction) const { |
|
|
|
|
|
|
|
|
/// Tests to see if the given instruction is the instruction this matcher represents. |
|
|
|
|
|
/// @param instruction The instruction to test |
|
|
|
|
|
/// @returns true if the given instruction matches. |
|
|
|
|
|
inline bool Matches(opcode_type instruction) const noexcept { |
|
|
return (instruction & mask) == expected; |
|
|
return (instruction & mask) == expected; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Calls the corresponding instruction handler on visitor for this type of instruction. |
|
|
|
|
|
* @param v The visitor to use |
|
|
|
|
|
* @param instruction The instruction to decode. |
|
|
|
|
|
*/ |
|
|
|
|
|
handler_return_type call(Visitor& v, opcode_type instruction) const { |
|
|
|
|
|
|
|
|
/// Calls the corresponding instruction handler on visitor for this type of instruction. |
|
|
|
|
|
/// @param v The visitor to use |
|
|
|
|
|
/// @param instruction The instruction to decode. |
|
|
|
|
|
inline handler_return_type call(Visitor& v, opcode_type instruction) const noexcept { |
|
|
ASSERT(Matches(instruction)); |
|
|
ASSERT(Matches(instruction)); |
|
|
return fn(v, instruction); |
|
|
return fn(v, instruction); |
|
|
} |
|
|
} |
|
|
|