mirror of
https://git.suyu.dev/suyu/dynarmic.git
synced 2026-03-11 01:46:29 +00:00
emit_x64: Extract BlockRangeInformation, remove template parameter
This commit is contained in:
@@ -31,40 +31,33 @@ void EmitContext::EraseInstruction(IR::Inst* inst) {
|
||||
inst->ClearArgs();
|
||||
}
|
||||
|
||||
template <typename JST>
|
||||
EmitX64<JST>::EmitX64(BlockOfCode* code)
|
||||
EmitX64::EmitX64(BlockOfCode* code)
|
||||
: code(code) {}
|
||||
|
||||
template <typename JST>
|
||||
EmitX64<JST>::~EmitX64() {}
|
||||
EmitX64::~EmitX64() {}
|
||||
|
||||
template <typename JST>
|
||||
boost::optional<typename EmitX64<JST>::BlockDescriptor> EmitX64<JST>::GetBasicBlock(IR::LocationDescriptor descriptor) const {
|
||||
boost::optional<typename EmitX64::BlockDescriptor> EmitX64::GetBasicBlock(IR::LocationDescriptor descriptor) const {
|
||||
auto iter = block_descriptors.find(descriptor);
|
||||
if (iter == block_descriptors.end())
|
||||
return boost::none;
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
template <typename JST>
|
||||
void EmitX64<JST>::EmitVoid(EmitContext&, IR::Inst*) {
|
||||
void EmitX64::EmitVoid(EmitContext&, IR::Inst*) {
|
||||
}
|
||||
|
||||
template <typename JST>
|
||||
void EmitX64<JST>::EmitBreakpoint(EmitContext&, IR::Inst*) {
|
||||
void EmitX64::EmitBreakpoint(EmitContext&, IR::Inst*) {
|
||||
code->int3();
|
||||
}
|
||||
|
||||
template <typename JST>
|
||||
void EmitX64<JST>::EmitIdentity(EmitContext& ctx, IR::Inst* inst) {
|
||||
void EmitX64::EmitIdentity(EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
if (!args[0].IsImmediate()) {
|
||||
ctx.reg_alloc.DefineValue(inst, args[0]);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename JST>
|
||||
void EmitX64<JST>::PushRSBHelper(Xbyak::Reg64 loc_desc_reg, Xbyak::Reg64 index_reg, IR::LocationDescriptor target) {
|
||||
void EmitX64::PushRSBHelper(Xbyak::Reg64 loc_desc_reg, Xbyak::Reg64 index_reg, IR::LocationDescriptor target) {
|
||||
using namespace Xbyak::util;
|
||||
|
||||
auto iter = block_descriptors.find(target);
|
||||
@@ -87,8 +80,7 @@ void EmitX64<JST>::PushRSBHelper(Xbyak::Reg64 loc_desc_reg, Xbyak::Reg64 index_r
|
||||
code->mov(dword[r15 + code->GetJitStateInfo().offsetof_rsb_ptr], index_reg.cvt32());
|
||||
}
|
||||
|
||||
template <typename JST>
|
||||
void EmitX64<JST>::EmitPushRSB(EmitContext& ctx, IR::Inst* inst) {
|
||||
void EmitX64::EmitPushRSB(EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
ASSERT(args[0].IsImmediate());
|
||||
u64 unique_hash_of_target = args[0].GetImmediateU64();
|
||||
@@ -100,23 +92,19 @@ void EmitX64<JST>::EmitPushRSB(EmitContext& ctx, IR::Inst* inst) {
|
||||
PushRSBHelper(loc_desc_reg, index_reg, IR::LocationDescriptor{unique_hash_of_target});
|
||||
}
|
||||
|
||||
template <typename JST>
|
||||
void EmitX64<JST>::EmitGetCarryFromOp(EmitContext&, IR::Inst*) {
|
||||
void EmitX64::EmitGetCarryFromOp(EmitContext&, IR::Inst*) {
|
||||
ASSERT_MSG(false, "should never happen");
|
||||
}
|
||||
|
||||
template <typename JST>
|
||||
void EmitX64<JST>::EmitGetOverflowFromOp(EmitContext&, IR::Inst*) {
|
||||
void EmitX64::EmitGetOverflowFromOp(EmitContext&, IR::Inst*) {
|
||||
ASSERT_MSG(false, "should never happen");
|
||||
}
|
||||
|
||||
template <typename JST>
|
||||
void EmitX64<JST>::EmitGetGEFromOp(EmitContext&, IR::Inst*) {
|
||||
void EmitX64::EmitGetGEFromOp(EmitContext&, IR::Inst*) {
|
||||
ASSERT_MSG(false, "should never happen");
|
||||
}
|
||||
|
||||
template <typename JST>
|
||||
void EmitX64<JST>::EmitGetNZCVFromOp(EmitContext& ctx, IR::Inst* inst) {
|
||||
void EmitX64::EmitGetNZCVFromOp(EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
||||
const int bitsize = [&]{
|
||||
@@ -143,14 +131,12 @@ void EmitX64<JST>::EmitGetNZCVFromOp(EmitContext& ctx, IR::Inst* inst) {
|
||||
ctx.reg_alloc.DefineValue(inst, nzcv);
|
||||
}
|
||||
|
||||
template <typename JST>
|
||||
void EmitX64<JST>::EmitAddCycles(size_t cycles) {
|
||||
void EmitX64::EmitAddCycles(size_t cycles) {
|
||||
ASSERT(cycles < std::numeric_limits<u32>::max());
|
||||
code->sub(qword[r15 + code->GetJitStateInfo().offsetof_cycles_remaining], static_cast<u32>(cycles));
|
||||
}
|
||||
|
||||
template <typename JST>
|
||||
Xbyak::Label EmitX64<JST>::EmitCond(IR::Cond cond) {
|
||||
Xbyak::Label EmitX64::EmitCond(IR::Cond cond) {
|
||||
Xbyak::Label label;
|
||||
|
||||
const Xbyak::Reg32 cpsr = eax;
|
||||
@@ -262,8 +248,7 @@ Xbyak::Label EmitX64<JST>::EmitCond(IR::Cond cond) {
|
||||
return label;
|
||||
}
|
||||
|
||||
template <typename JST>
|
||||
void EmitX64<JST>::EmitCondPrelude(const IR::Block& block) {
|
||||
void EmitX64::EmitCondPrelude(const IR::Block& block) {
|
||||
if (block.GetCondition() == IR::Cond::AL) {
|
||||
ASSERT(!block.HasConditionFailedLocation());
|
||||
return;
|
||||
@@ -277,8 +262,7 @@ void EmitX64<JST>::EmitCondPrelude(const IR::Block& block) {
|
||||
code->L(pass);
|
||||
}
|
||||
|
||||
template <typename JST>
|
||||
void EmitX64<JST>::EmitTerminal(IR::Terminal terminal, IR::LocationDescriptor initial_location) {
|
||||
void EmitX64::EmitTerminal(IR::Terminal terminal, IR::LocationDescriptor initial_location) {
|
||||
Common::VisitVariant<void>(terminal, [this, &initial_location](auto x) {
|
||||
using T = std::decay_t<decltype(x)>;
|
||||
if constexpr (!std::is_same_v<T, IR::Term::Invalid>) {
|
||||
@@ -289,8 +273,7 @@ void EmitX64<JST>::EmitTerminal(IR::Terminal terminal, IR::LocationDescriptor in
|
||||
});
|
||||
}
|
||||
|
||||
template <typename JST>
|
||||
void EmitX64<JST>::Patch(const IR::LocationDescriptor& desc, CodePtr bb) {
|
||||
void EmitX64::Patch(const IR::LocationDescriptor& desc, CodePtr bb) {
|
||||
const CodePtr save_code_ptr = code->getCurr();
|
||||
const PatchInformation& patch_info = patch_information[desc];
|
||||
|
||||
@@ -312,39 +295,28 @@ void EmitX64<JST>::Patch(const IR::LocationDescriptor& desc, CodePtr bb) {
|
||||
code->SetCodePtr(save_code_ptr);
|
||||
}
|
||||
|
||||
template <typename JST>
|
||||
void EmitX64<JST>::Unpatch(const IR::LocationDescriptor& desc) {
|
||||
void EmitX64::Unpatch(const IR::LocationDescriptor& desc) {
|
||||
Patch(desc, nullptr);
|
||||
}
|
||||
|
||||
template <typename JST>
|
||||
void EmitX64<JST>::ClearCache() {
|
||||
void EmitX64::ClearCache() {
|
||||
block_descriptors.clear();
|
||||
patch_information.clear();
|
||||
}
|
||||
|
||||
template <typename JST>
|
||||
void EmitX64<JST>::InvalidateCacheRanges(const boost::icl::interval_set<ProgramCounterType>& ranges) {
|
||||
// Remove cached block descriptors and patch information overlapping with the given range.
|
||||
for (auto invalidate_interval : ranges) {
|
||||
auto pair = block_ranges.equal_range(invalidate_interval);
|
||||
for (auto it = pair.first; it != pair.second; ++it) {
|
||||
for (const auto& descriptor : it->second) {
|
||||
if (patch_information.count(descriptor)) {
|
||||
Unpatch(descriptor);
|
||||
}
|
||||
block_descriptors.erase(descriptor);
|
||||
}
|
||||
void EmitX64::InvalidateBasicBlocks(const std::unordered_set<IR::LocationDescriptor>& locations) {
|
||||
for (const auto &descriptor : locations) {
|
||||
auto it = block_descriptors.find(descriptor);
|
||||
if (it == block_descriptors.end()) {
|
||||
continue;
|
||||
}
|
||||
block_ranges.erase(pair.first, pair.second);
|
||||
|
||||
if (patch_information.count(descriptor)) {
|
||||
Unpatch(descriptor);
|
||||
}
|
||||
block_descriptors.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace BackendX64
|
||||
} // namespace Dynarmic
|
||||
|
||||
#include "backend_x64/a32_jitstate.h"
|
||||
#include "backend_x64/a64_jitstate.h"
|
||||
|
||||
template class Dynarmic::BackendX64::EmitX64<Dynarmic::BackendX64::A32JitState>;
|
||||
template class Dynarmic::BackendX64::EmitX64<Dynarmic::BackendX64::A64JitState>;
|
||||
|
||||
Reference in New Issue
Block a user