2016-07-01 15:01:06 +02:00
|
|
|
/* This file is part of the dynarmic project.
|
|
|
|
|
* Copyright (c) 2016 MerryMage
|
|
|
|
|
* This software may be used and distributed according to the terms of the GNU
|
|
|
|
|
* General Public License version 2 or any later version.
|
|
|
|
|
*
|
|
|
|
|
* Original version of table by Lioncash.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
#include <functional>
|
2018-10-14 23:17:56 +02:00
|
|
|
#include <optional>
|
2016-07-18 11:28:17 +02:00
|
|
|
#include <vector>
|
2016-07-01 15:01:06 +02:00
|
|
|
|
2016-12-22 16:25:38 +01:00
|
|
|
#include "common/bit_util.h"
|
2016-07-01 15:01:06 +02:00
|
|
|
#include "common/common_types.h"
|
2016-07-04 11:22:11 +02:00
|
|
|
#include "frontend/decoder/decoder_detail.h"
|
2016-09-17 10:48:18 +02:00
|
|
|
#include "frontend/decoder/matcher.h"
|
2016-07-01 15:01:06 +02:00
|
|
|
|
2018-01-26 14:51:48 +01:00
|
|
|
namespace Dynarmic::A32 {
|
2016-07-01 15:01:06 +02:00
|
|
|
|
|
|
|
|
template <typename Visitor>
|
2018-01-01 16:23:56 +01:00
|
|
|
using ArmMatcher = Decoder::Matcher<Visitor, u32>;
|
2016-07-01 15:01:06 +02:00
|
|
|
|
2016-08-06 18:17:58 +02:00
|
|
|
template <typename V>
|
|
|
|
|
std::vector<ArmMatcher<V>> GetArmDecodeTable() {
|
|
|
|
|
std::vector<ArmMatcher<V>> table = {
|
2016-07-01 15:01:06 +02:00
|
|
|
|
2018-08-11 19:12:22 +02:00
|
|
|
#define INST(fn, name, bitstring) Decoder::detail::detail<ArmMatcher<V>>::GetMatcher(&V::fn, name, bitstring),
|
|
|
|
|
#include "arm.inc"
|
2016-07-01 15:01:06 +02:00
|
|
|
#undef INST
|
|
|
|
|
|
2016-07-18 11:28:17 +02:00
|
|
|
};
|
2016-07-01 15:01:06 +02:00
|
|
|
|
2016-12-22 16:25:38 +01:00
|
|
|
// If a matcher has more bits in its mask it is more specific, so it should come first.
|
|
|
|
|
std::stable_sort(table.begin(), table.end(), [](const auto& matcher1, const auto& matcher2) {
|
|
|
|
|
return Common::BitCount(matcher1.GetMask()) > Common::BitCount(matcher2.GetMask());
|
|
|
|
|
});
|
2016-08-06 18:17:58 +02:00
|
|
|
|
|
|
|
|
return table;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename V>
|
2018-10-14 23:17:56 +02:00
|
|
|
std::optional<std::reference_wrapper<const ArmMatcher<V>>> DecodeArm(u32 instruction) {
|
2017-09-29 02:23:45 +02:00
|
|
|
static const auto table = GetArmDecodeTable<V>();
|
2016-08-06 18:17:58 +02:00
|
|
|
|
2016-07-18 11:28:17 +02:00
|
|
|
const auto matches_instruction = [instruction](const auto& matcher) { return matcher.Matches(instruction); };
|
2016-07-01 15:01:06 +02:00
|
|
|
|
|
|
|
|
auto iter = std::find_if(table.begin(), table.end(), matches_instruction);
|
2018-10-14 23:17:56 +02:00
|
|
|
return iter != table.end() ? std::optional<std::reference_wrapper<const ArmMatcher<V>>>(*iter) : std::nullopt;
|
2016-07-01 15:01:06 +02:00
|
|
|
}
|
|
|
|
|
|
2018-01-26 14:51:48 +01:00
|
|
|
} // namespace Dynarmic::A32
|