decoder_detail: Simplify DYNARMIC_DECODER_GET_MATCHER
This commit is contained in:
parent
a62dc19605
commit
bf422a190a
1 changed files with 16 additions and 8 deletions
|
@ -17,7 +17,7 @@ namespace Dynarmic::Decoder {
|
|||
namespace detail {
|
||||
|
||||
template<size_t N>
|
||||
inline constexpr std::array<char, N> StringToArray(const char (&str)[N + 1]) {
|
||||
inline consteval std::array<char, N> StringToArray(const char (&str)[N + 1]) {
|
||||
std::array<char, N> result{};
|
||||
for (size_t i = 0; i < N; i++) {
|
||||
result[i] = str[i];
|
||||
|
@ -42,7 +42,11 @@ struct detail {
|
|||
* A '0' in a bitstring indicates that a zero must be present at that bit position.
|
||||
* A '1' in a bitstring indicates that a one must be present at that bit position.
|
||||
*/
|
||||
#ifdef __APPLE__ // AppleClang workaround
|
||||
static constexpr auto GetMaskAndExpect(std::array<char, opcode_bitsize> bitstring) {
|
||||
#else
|
||||
static consteval auto GetMaskAndExpect(std::array<char, opcode_bitsize> bitstring) {
|
||||
#endif
|
||||
const auto one = static_cast<opcode_type>(1);
|
||||
opcode_type mask = 0, expect = 0;
|
||||
for (size_t i = 0; i < opcode_bitsize; i++) {
|
||||
|
@ -69,7 +73,7 @@ struct detail {
|
|||
* An argument is specified by a continuous string of the same character.
|
||||
*/
|
||||
template<size_t N>
|
||||
static constexpr auto GetArgInfo(std::array<char, opcode_bitsize> bitstring) {
|
||||
static consteval auto GetArgInfo(std::array<char, opcode_bitsize> bitstring) {
|
||||
std::array<opcode_type, N> masks = {};
|
||||
std::array<size_t, N> shifts = {};
|
||||
size_t arg_index = 0;
|
||||
|
@ -164,19 +168,23 @@ struct detail {
|
|||
* Creates a matcher that can match and parse instructions based on bitstring.
|
||||
* See also: GetMaskAndExpect and GetArgInfo for format of bitstring.
|
||||
*/
|
||||
template<typename FnT, size_t args_count = mcl::parameter_count_v<FnT>>
|
||||
static auto GetMatcher(FnT fn, const char* const name, std::tuple<opcode_type, opcode_type> mask_and_expect, std::tuple<std::array<opcode_type, args_count>, std::array<size_t, args_count>> masks_and_shifts) {
|
||||
template<auto bitstring, typename FnT>
|
||||
static auto GetMatcher(FnT fn, const char* const name) {
|
||||
constexpr size_t args_count = mcl::parameter_count_v<FnT>;
|
||||
|
||||
constexpr auto mask = std::get<0>(GetMaskAndExpect(bitstring));
|
||||
constexpr auto expect = std::get<1>(GetMaskAndExpect(bitstring));
|
||||
constexpr auto arg_masks = std::get<0>(GetArgInfo<args_count>(bitstring));
|
||||
constexpr auto arg_shifts = std::get<1>(GetArgInfo<args_count>(bitstring));
|
||||
|
||||
using Iota = std::make_index_sequence<args_count>;
|
||||
|
||||
const auto [mask, expect] = mask_and_expect;
|
||||
const auto [arg_masks, arg_shifts] = masks_and_shifts;
|
||||
const auto proxy_fn = VisitorCaller<FnT>::Make(Iota(), fn, arg_masks, arg_shifts);
|
||||
|
||||
return MatcherT(name, mask, expect, proxy_fn);
|
||||
}
|
||||
};
|
||||
|
||||
#define DYNARMIC_DECODER_GET_MATCHER(MatcherT, fn, name, bitstring) Decoder::detail::detail<MatcherT<V>>::GetMatcher(&V::fn, name, Decoder::detail::detail<MatcherT<V>>::GetMaskAndExpect(bitstring), Decoder::detail::detail<MatcherT<V>>::template GetArgInfo<mcl::parameter_count_v<decltype(&V::fn)>>(bitstring))
|
||||
#define DYNARMIC_DECODER_GET_MATCHER(MatcherT, fn, name, bitstring) Decoder::detail::detail<MatcherT<V>>::template GetMatcher<bitstring>(&V::fn, name)
|
||||
|
||||
} // namespace detail
|
||||
} // namespace Dynarmic::Decoder
|
||||
|
|
Loading…
Reference in a new issue