emit_arm64: Add BlockRelocationType::MoveToScratch0

This commit is contained in:
Merry 2023-02-15 11:42:22 +00:00
parent a179e2f2bb
commit 15e889fbe3
5 changed files with 45 additions and 15 deletions

View file

@ -124,13 +124,27 @@ static void LinkBlockLinks(const CodePtr entry_point, const CodePtr target_ptr,
using namespace oaknut; using namespace oaknut;
using namespace oaknut::util; using namespace oaknut::util;
for (auto [ptr_offset] : block_relocations_list) { for (auto [ptr_offset, type] : block_relocations_list) {
CodeGenerator c{reinterpret_cast<u32*>(entry_point + ptr_offset)}; CodeGenerator c{reinterpret_cast<u32*>(entry_point + ptr_offset)};
if (target_ptr) { switch (type) {
c.B((void*)target_ptr); case BlockRelocationType::Branch:
} else { if (target_ptr) {
c.NOP(); c.B((void*)target_ptr);
} else {
c.NOP();
}
break;
case BlockRelocationType::MoveToScratch0:
if (target_ptr) {
c.ADRL(Xscratch0, (void*)target_ptr);
} else {
c.NOP();
c.NOP();
}
break;
default:
ASSERT_FALSE("Invalid BlockRelocationType");
} }
} }
} }

View file

@ -256,9 +256,19 @@ void EmitRelocation(oaknut::CodeGenerator& code, EmitContext& ctx, LinkTarget li
code.NOP(); code.NOP();
} }
void EmitBlockLinkRelocation(oaknut::CodeGenerator& code, EmitContext& ctx, const IR::LocationDescriptor& descriptor) { void EmitBlockLinkRelocation(oaknut::CodeGenerator& code, EmitContext& ctx, const IR::LocationDescriptor& descriptor, BlockRelocationType type) {
ctx.ebi.block_relocations[descriptor].emplace_back(BlockRelocation{code.ptr<CodePtr>() - ctx.ebi.entry_point}); ctx.ebi.block_relocations[descriptor].emplace_back(BlockRelocation{code.ptr<CodePtr>() - ctx.ebi.entry_point, type});
code.NOP(); switch (type) {
case BlockRelocationType::Branch:
code.NOP();
break;
case BlockRelocationType::MoveToScratch0:
code.NOP();
code.NOP();
break;
default:
UNREACHABLE();
}
} }
} // namespace Dynarmic::Backend::Arm64 } // namespace Dynarmic::Backend::Arm64

View file

@ -91,8 +91,14 @@ struct Relocation {
LinkTarget target; LinkTarget target;
}; };
enum class BlockRelocationType {
Branch,
MoveToScratch0,
};
struct BlockRelocation { struct BlockRelocation {
std::ptrdiff_t code_offset; std::ptrdiff_t code_offset;
BlockRelocationType type;
}; };
struct EmittedBlockInfo { struct EmittedBlockInfo {
@ -165,7 +171,7 @@ EmittedBlockInfo EmitArm64(oaknut::CodeGenerator& code, IR::Block block, const E
template<IR::Opcode op> template<IR::Opcode op>
void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst); void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
void EmitRelocation(oaknut::CodeGenerator& code, EmitContext& ctx, LinkTarget link_target); void EmitRelocation(oaknut::CodeGenerator& code, EmitContext& ctx, LinkTarget link_target);
void EmitBlockLinkRelocation(oaknut::CodeGenerator& code, EmitContext& ctx, const IR::LocationDescriptor& descriptor); void EmitBlockLinkRelocation(oaknut::CodeGenerator& code, EmitContext& ctx, const IR::LocationDescriptor& descriptor, BlockRelocationType type);
oaknut::Label EmitA32Cond(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Cond cond); oaknut::Label EmitA32Cond(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Cond cond);
oaknut::Label EmitA64Cond(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Cond cond); oaknut::Label EmitA64Cond(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Cond cond);
void EmitA32Terminal(oaknut::CodeGenerator& code, EmitContext& ctx); void EmitA32Terminal(oaknut::CodeGenerator& code, EmitContext& ctx);

View file

@ -67,11 +67,11 @@ void EmitA32Terminal(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Term::Li
if (ctx.conf.enable_cycle_counting) { if (ctx.conf.enable_cycle_counting) {
code.CMP(Xticks, 0); code.CMP(Xticks, 0);
code.B(LE, fail); code.B(LE, fail);
EmitBlockLinkRelocation(code, ctx, terminal.next); EmitBlockLinkRelocation(code, ctx, terminal.next, BlockRelocationType::Branch);
} else { } else {
code.LDAR(Wscratch0, Xhalt); code.LDAR(Wscratch0, Xhalt);
code.CBNZ(Wscratch0, fail); code.CBNZ(Wscratch0, fail);
EmitBlockLinkRelocation(code, ctx, terminal.next); EmitBlockLinkRelocation(code, ctx, terminal.next, BlockRelocationType::Branch);
} }
} }
@ -85,7 +85,7 @@ void EmitA32Terminal(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Term::Li
EmitSetUpperLocationDescriptor(code, ctx, terminal.next, initial_location); EmitSetUpperLocationDescriptor(code, ctx, terminal.next, initial_location);
if (ctx.conf.HasOptimization(OptimizationFlag::BlockLinking) && !is_single_step) { if (ctx.conf.HasOptimization(OptimizationFlag::BlockLinking) && !is_single_step) {
EmitBlockLinkRelocation(code, ctx, terminal.next); EmitBlockLinkRelocation(code, ctx, terminal.next, BlockRelocationType::Branch);
} }
code.MOV(Wscratch0, A32::LocationDescriptor{terminal.next}.PC()); code.MOV(Wscratch0, A32::LocationDescriptor{terminal.next}.PC());

View file

@ -46,11 +46,11 @@ void EmitA64Terminal(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Term::Li
if (ctx.conf.enable_cycle_counting) { if (ctx.conf.enable_cycle_counting) {
code.CMP(Xticks, 0); code.CMP(Xticks, 0);
code.B(LE, fail); code.B(LE, fail);
EmitBlockLinkRelocation(code, ctx, terminal.next); EmitBlockLinkRelocation(code, ctx, terminal.next, BlockRelocationType::Branch);
} else { } else {
code.LDAR(Wscratch0, Xhalt); code.LDAR(Wscratch0, Xhalt);
code.CBNZ(Wscratch0, fail); code.CBNZ(Wscratch0, fail);
EmitBlockLinkRelocation(code, ctx, terminal.next); EmitBlockLinkRelocation(code, ctx, terminal.next, BlockRelocationType::Branch);
} }
} }
@ -62,7 +62,7 @@ void EmitA64Terminal(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Term::Li
void EmitA64Terminal(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Term::LinkBlockFast terminal, IR::LocationDescriptor, bool is_single_step) { void EmitA64Terminal(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Term::LinkBlockFast terminal, IR::LocationDescriptor, bool is_single_step) {
if (ctx.conf.HasOptimization(OptimizationFlag::BlockLinking) && !is_single_step) { if (ctx.conf.HasOptimization(OptimizationFlag::BlockLinking) && !is_single_step) {
EmitBlockLinkRelocation(code, ctx, terminal.next); EmitBlockLinkRelocation(code, ctx, terminal.next, BlockRelocationType::Branch);
} }
code.MOV(Xscratch0, A64::LocationDescriptor{terminal.next}.PC()); code.MOV(Xscratch0, A64::LocationDescriptor{terminal.next}.PC());