|
|
|
@ -37,34 +37,31 @@ inline size_t ToFastLookupIndex(u32 instruction) { |
|
|
|
|
|
|
|
template<typename V> |
|
|
|
constexpr DecodeTable<V> GetDecodeTable() { |
|
|
|
std::vector<Matcher<V>> list = { |
|
|
|
#define INST(fn, name, bitstring) DYNARMIC_DECODER_GET_MATCHER(Matcher, fn, name, Decoder::detail::StringToArray<32>(bitstring)), |
|
|
|
std::vector<std::pair<const char*, Matcher<V>>> list = { |
|
|
|
#define INST(fn, name, bitstring) { name, DYNARMIC_DECODER_GET_MATCHER(Matcher, fn, name, Decoder::detail::StringToArray<32>(bitstring)) }, |
|
|
|
#include "./a64.inc" |
|
|
|
#undef INST |
|
|
|
}; |
|
|
|
|
|
|
|
// If a matcher has more bits in its mask it is more specific, so it should come first. |
|
|
|
std::stable_sort(list.begin(), list.end(), [](const auto& matcher1, const auto& matcher2) { |
|
|
|
std::stable_sort(list.begin(), list.end(), [](const auto& a, const auto& b) { |
|
|
|
// If a matcher has more bits in its mask it is more specific, so it should come first. |
|
|
|
return mcl::bit::count_ones(matcher1.GetMask()) > mcl::bit::count_ones(matcher2.GetMask()); |
|
|
|
return mcl::bit::count_ones(a.second.GetMask()) > mcl::bit::count_ones(b.second.GetMask()); |
|
|
|
}); |
|
|
|
|
|
|
|
// Exceptions to the above rule of thumb. |
|
|
|
std::stable_partition(list.begin(), list.end(), [&](const auto& matcher) { |
|
|
|
std::stable_partition(list.begin(), list.end(), [&](const auto& e) { |
|
|
|
return std::set<std::string>{ |
|
|
|
"MOVI, MVNI, ORR, BIC (vector, immediate)", |
|
|
|
"FMOV (vector, immediate)", |
|
|
|
"Unallocated SIMD modified immediate", |
|
|
|
}.count(matcher.GetName()) > 0; |
|
|
|
}.count(e.first) > 0; |
|
|
|
}); |
|
|
|
|
|
|
|
DecodeTable<V> table{}; |
|
|
|
for (size_t i = 0; i < table.size(); ++i) { |
|
|
|
for (auto matcher : list) { |
|
|
|
const auto expect = detail::ToFastLookupIndex(matcher.GetExpected()); |
|
|
|
const auto mask = detail::ToFastLookupIndex(matcher.GetMask()); |
|
|
|
for (auto const& e : list) { |
|
|
|
const auto expect = detail::ToFastLookupIndex(e.second.GetExpected()); |
|
|
|
const auto mask = detail::ToFastLookupIndex(e.second.GetMask()); |
|
|
|
if ((i & mask) == expect) { |
|
|
|
table[i].push_back(matcher); |
|
|
|
table[i].push_back(e.second); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|