[dynarmic] fix NSBU regressions (#3533)
Signed-off-by: lizzie <lizzie@eden-emu.dev> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3533 Reviewed-by: Maufeat <sahyno1996@gmail.com> Reviewed-by: MaranBr <maranbr@eden-emu.dev> Co-authored-by: lizzie <lizzie@eden-emu.dev> Co-committed-by: lizzie <lizzie@eden-emu.dev>
This commit is contained in:
parent
c263b6af6f
commit
72973fe582
|
|
@ -65,11 +65,10 @@ static Optimization::PolyfillOptions GenPolyfillOptions(const BlockOfCode& code)
|
|||
|
||||
struct Jit::Impl {
|
||||
Impl(Jit* jit, A32::UserConfig conf) noexcept
|
||||
: ir_block{LocationDescriptor(0, PSR(0), FPSCR(0), false)}
|
||||
, conf(std::move(conf))
|
||||
, block_of_code(GenRunCodeCallbacks(conf.callbacks, &GetCurrentBlockThunk, this, conf), JitStateInfo{jit_state}, conf.code_cache_size, GenRCP(conf))
|
||||
: block_of_code(GenRunCodeCallbacks(conf.callbacks, &GetCurrentBlockThunk, this, conf), JitStateInfo{jit_state}, conf.code_cache_size, GenRCP(conf))
|
||||
, emitter(block_of_code, conf, jit)
|
||||
, polyfill_options(GenPolyfillOptions(block_of_code))
|
||||
, conf(std::move(conf))
|
||||
, jit_interface(jit)
|
||||
{}
|
||||
|
||||
|
|
@ -204,8 +203,7 @@ private:
|
|||
}
|
||||
|
||||
A32EmitX64::BlockDescriptor GetBasicBlock(IR::LocationDescriptor descriptor) {
|
||||
auto block = emitter.GetBasicBlock(descriptor);
|
||||
if (block)
|
||||
if (auto block = emitter.GetBasicBlock(descriptor))
|
||||
return *block;
|
||||
|
||||
constexpr size_t MINIMUM_REMAINING_CODESIZE = 1 * 1024 * 1024;
|
||||
|
|
@ -215,8 +213,10 @@ private:
|
|||
}
|
||||
block_of_code.EnsureMemoryCommitted(MINIMUM_REMAINING_CODESIZE);
|
||||
|
||||
ir_block.Reset(descriptor);
|
||||
A32::Translate(ir_block, A32::LocationDescriptor{descriptor}, conf.callbacks, {conf.arch_version, conf.define_unpredictable_behaviour, conf.hook_hint_instructions});
|
||||
// LocationDescriptor ctor() does important ops (like tflags) do not skip
|
||||
auto const arch_descriptor = A32::LocationDescriptor{descriptor};
|
||||
ir_block.Reset(arch_descriptor);
|
||||
A32::Translate(ir_block, arch_descriptor, conf.callbacks, {conf.arch_version, conf.define_unpredictable_behaviour, conf.hook_hint_instructions});
|
||||
Optimization::Optimize(ir_block, conf, polyfill_options);
|
||||
return emitter.Emit(ir_block);
|
||||
}
|
||||
|
|
@ -243,12 +243,13 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
IR::Block ir_block;
|
||||
const A32::UserConfig conf;
|
||||
IR::Block ir_block = {LocationDescriptor(0, PSR(0), FPSCR(0), false)};
|
||||
A32JitState jit_state;
|
||||
BlockOfCode block_of_code;
|
||||
A32EmitX64 emitter;
|
||||
Optimization::PolyfillOptions polyfill_options;
|
||||
// Keep it here, you don't wanna mess with the fuckery that's initializer lists
|
||||
const A32::UserConfig conf;
|
||||
Jit* jit_interface;
|
||||
|
||||
// Requests made during execution to invalidate the cache are queued up here.
|
||||
|
|
|
|||
|
|
@ -62,8 +62,7 @@ static Optimization::PolyfillOptions GenPolyfillOptions(const BlockOfCode& code)
|
|||
struct Jit::Impl final {
|
||||
public:
|
||||
Impl(Jit* jit, UserConfig conf)
|
||||
: ir_block{LocationDescriptor(0, FP::FPCR(0), false)}
|
||||
, conf(conf)
|
||||
: conf(conf)
|
||||
, block_of_code(GenRunCodeCallbacks(conf.callbacks, &GetCurrentBlockThunk, this, conf), JitStateInfo{jit_state}, conf.code_cache_size, GenRCP(conf))
|
||||
, emitter(block_of_code, conf, jit)
|
||||
, polyfill_options(GenPolyfillOptions(block_of_code))
|
||||
|
|
@ -257,8 +256,8 @@ private:
|
|||
return GetBlock(A64::LocationDescriptor{GetCurrentLocation()}.SetSingleStepping(true));
|
||||
}
|
||||
|
||||
CodePtr GetBlock(IR::LocationDescriptor current_location) {
|
||||
if (auto block = emitter.GetBasicBlock(current_location))
|
||||
CodePtr GetBlock(IR::LocationDescriptor descriptor) {
|
||||
if (auto block = emitter.GetBasicBlock(descriptor))
|
||||
return block->entrypoint;
|
||||
|
||||
constexpr size_t MINIMUM_REMAINING_CODESIZE = 1 * 1024 * 1024;
|
||||
|
|
@ -271,8 +270,10 @@ private:
|
|||
|
||||
// JIT Compile
|
||||
const auto get_code = [this](u64 vaddr) { return conf.callbacks->MemoryReadCode(vaddr); };
|
||||
ir_block.Reset(current_location);
|
||||
A64::Translate(ir_block, A64::LocationDescriptor{current_location}, get_code, {conf.define_unpredictable_behaviour, conf.wall_clock_cntpct});
|
||||
// LocationDescriptor ctor() does important ops (like tflags) do not skip
|
||||
auto const arch_descriptor = A64::LocationDescriptor{descriptor};
|
||||
ir_block.Reset(arch_descriptor);
|
||||
A64::Translate(ir_block, arch_descriptor, get_code, {conf.define_unpredictable_behaviour, conf.wall_clock_cntpct});
|
||||
Optimization::Optimize(ir_block, conf, polyfill_options);
|
||||
return emitter.Emit(ir_block).entrypoint;
|
||||
}
|
||||
|
|
@ -299,7 +300,7 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
IR::Block ir_block;
|
||||
IR::Block ir_block = {LocationDescriptor(0, FP::FPCR(0), false)};
|
||||
const UserConfig conf;
|
||||
A64JitState jit_state;
|
||||
BlockOfCode block_of_code;
|
||||
|
|
|
|||
|
|
@ -22,13 +22,10 @@
|
|||
|
||||
namespace Dynarmic::IR {
|
||||
|
||||
Block::Block(const LocationDescriptor& location)
|
||||
: location{location},
|
||||
end_location{location},
|
||||
cond{Cond::AL}
|
||||
{
|
||||
|
||||
}
|
||||
Block::Block(LocationDescriptor location) noexcept
|
||||
: location{location}
|
||||
, end_location{location}
|
||||
{}
|
||||
|
||||
/// Prepends a new instruction to this basic block before the insertion point,
|
||||
/// handling any allocations necessary to do so.
|
||||
|
|
@ -60,6 +57,21 @@ Block::iterator Block::PrependNewInst(iterator insertion_point, Opcode opcode, s
|
|||
return instructions.insert_before(insertion_point, inst);
|
||||
}
|
||||
|
||||
void Block::Reset(LocationDescriptor location_) noexcept {
|
||||
mcl::intrusive_list<IR::Inst> tmp = {};
|
||||
instructions.swap(tmp);
|
||||
inlined_inst.clear();
|
||||
pooled_inst.clear();
|
||||
cond_failed.reset();
|
||||
location = location_;
|
||||
end_location = location_;
|
||||
cond = Cond::AL;
|
||||
terminal = Term::Invalid{};
|
||||
cond_failed_cycle_count = 0;
|
||||
cycle_count = 0;
|
||||
ASSERT(instructions.size() == 0);
|
||||
}
|
||||
|
||||
static std::string TerminalToString(const Terminal& terminal_variant) noexcept {
|
||||
struct : boost::static_visitor<std::string> {
|
||||
std::string operator()(const Term::Invalid&) const {
|
||||
|
|
@ -123,11 +135,11 @@ std::string DumpBlock(const IR::Block& block) noexcept {
|
|||
case Type::A32ExtReg: return A32::ExtRegToString(arg.GetA32ExtRegRef());
|
||||
case Type::A64Reg: return A64::RegToString(arg.GetA64RegRef());
|
||||
case Type::A64Vec: return A64::VecToString(arg.GetA64VecRef());
|
||||
case Type::CoprocInfo: return fmt::format("#<coproc>");
|
||||
case Type::NZCVFlags: return fmt::format("#<NZCV flags>");
|
||||
case Type::Cond: return fmt::format("#<cond={}>", A32::CondToString(arg.GetCond()));
|
||||
case Type::Table: return fmt::format("#<table>");
|
||||
case Type::AccType: return fmt::format("#<acc-type={}>", u32(arg.GetAccType()));
|
||||
case Type::CoprocInfo: return fmt::format("$coproc{}", arg.GetCoprocInfo()[0]);
|
||||
case Type::NZCVFlags: return fmt::format("$nzcv");
|
||||
case Type::Cond: return fmt::format("$cond={}", A32::CondToString(arg.GetCond()));
|
||||
case Type::Table: return fmt::format("$table");
|
||||
case Type::AccType: return fmt::format("$acc-type={}", u32(arg.GetAccType()));
|
||||
default: return fmt::format("<unknown immediate type {}>", arg.GetType());
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ public:
|
|||
using reverse_iterator = instruction_list_type::reverse_iterator;
|
||||
using const_reverse_iterator = instruction_list_type::const_reverse_iterator;
|
||||
|
||||
explicit Block(const LocationDescriptor& location);
|
||||
Block(LocationDescriptor location) noexcept;
|
||||
~Block() = default;
|
||||
Block(const Block&) = delete;
|
||||
Block& operator=(const Block&) = delete;
|
||||
|
|
@ -58,6 +58,7 @@ public:
|
|||
return PrependNewInst(instructions.end(), opcode, args);
|
||||
}
|
||||
iterator PrependNewInst(iterator insertion_point, Opcode op, std::initializer_list<Value> args) noexcept;
|
||||
void Reset(LocationDescriptor location_) noexcept;
|
||||
|
||||
/// Gets a mutable reference to the instruction list for this basic block.
|
||||
inline instruction_list_type& Instructions() noexcept {
|
||||
|
|
@ -140,18 +141,6 @@ public:
|
|||
return cycle_count;
|
||||
}
|
||||
|
||||
inline void Reset(LocationDescriptor location_) noexcept {
|
||||
inlined_inst.clear();
|
||||
pooled_inst.clear();
|
||||
cond_failed.reset();
|
||||
location = location_;
|
||||
terminal = Term::Invalid{};
|
||||
cond_failed_cycle_count = 0;
|
||||
cycle_count = 0;
|
||||
instruction_list_type tmp{};
|
||||
instructions.swap(tmp);
|
||||
}
|
||||
|
||||
/// "Hot cache" for small blocks so we don't call global allocator
|
||||
boost::container::static_vector<Inst, 30> inlined_inst;
|
||||
/// List of instructions in this block.
|
||||
|
|
@ -165,7 +154,7 @@ public:
|
|||
/// Description of the end location of this block
|
||||
LocationDescriptor end_location;
|
||||
/// Conditional to pass in order to execute this block
|
||||
Cond cond;
|
||||
Cond cond = Cond::AL;
|
||||
/// Terminal instruction of this block.
|
||||
Terminal terminal = Term::Invalid{};
|
||||
/// Number of cycles this block takes to execute if the conditional fails.
|
||||
|
|
|
|||
Loading…
Reference in New Issue