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 {
|
namespace detail {
|
||||||
|
|
||||||
template<size_t N>
|
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{};
|
std::array<char, N> result{};
|
||||||
for (size_t i = 0; i < N; i++) {
|
for (size_t i = 0; i < N; i++) {
|
||||||
result[i] = str[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 '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.
|
* 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) {
|
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);
|
const auto one = static_cast<opcode_type>(1);
|
||||||
opcode_type mask = 0, expect = 0;
|
opcode_type mask = 0, expect = 0;
|
||||||
for (size_t i = 0; i < opcode_bitsize; i++) {
|
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.
|
* An argument is specified by a continuous string of the same character.
|
||||||
*/
|
*/
|
||||||
template<size_t N>
|
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<opcode_type, N> masks = {};
|
||||||
std::array<size_t, N> shifts = {};
|
std::array<size_t, N> shifts = {};
|
||||||
size_t arg_index = 0;
|
size_t arg_index = 0;
|
||||||
|
@ -164,19 +168,23 @@ struct detail {
|
||||||
* Creates a matcher that can match and parse instructions based on bitstring.
|
* Creates a matcher that can match and parse instructions based on bitstring.
|
||||||
* See also: GetMaskAndExpect and GetArgInfo for format of bitstring.
|
* See also: GetMaskAndExpect and GetArgInfo for format of bitstring.
|
||||||
*/
|
*/
|
||||||
template<typename FnT, size_t args_count = mcl::parameter_count_v<FnT>>
|
template<auto bitstring, typename 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) {
|
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>;
|
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);
|
const auto proxy_fn = VisitorCaller<FnT>::Make(Iota(), fn, arg_masks, arg_shifts);
|
||||||
|
|
||||||
return MatcherT(name, mask, expect, proxy_fn);
|
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 detail
|
||||||
} // namespace Dynarmic::Decoder
|
} // namespace Dynarmic::Decoder
|
||||||
|
|
Loading…
Reference in a new issue