diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp index a4a6d62a83..f9d80d396c 100644 --- a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp @@ -33,7 +33,6 @@ void JitArm64::Init() code_block.m_stats = &js.st; code_block.m_gpa = &js.gpa; code_block.m_fpa = &js.fpa; - InitBackpatch(); analyzer.SetOption(PPCAnalyst::PPCAnalyzer::OPTION_CONDITIONAL_CONTINUE); } diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.h b/Source/Core/Core/PowerPC/JitArm64/Jit.h index 6271589ed2..7199fb38e4 100644 --- a/Source/Core/Core/PowerPC/JitArm64/Jit.h +++ b/Source/Core/Core/PowerPC/JitArm64/Jit.h @@ -200,8 +200,14 @@ private: } }; + struct FastmemArea + { + u32 length; + const u8* slowmem_code; + }; + // - std::map> m_fault_to_handler; + std::map m_fault_to_handler; std::map m_handler_to_loc; Arm64GPRCache gpr; Arm64FPRCache fpr; @@ -232,13 +238,9 @@ private: // Dump a memory range of code void DumpCode(const u8* start, const u8* end); - // The key is the backpatch flags - std::map m_backpatch_info; - // Backpatching routines bool DisasmLoadStore(const u8* ptr, u32* flags, Arm64Gen::ARM64Reg* reg); - void InitBackpatch(); - u32 EmitBackpatchRoutine(u32 flags, bool fastmem, bool do_farcode, + void EmitBackpatchRoutine(u32 flags, bool fastmem, bool do_farcode, Arm64Gen::ARM64Reg RS, Arm64Gen::ARM64Reg addr, BitSet32 gprs_to_push = BitSet32(0), BitSet32 fprs_to_push = BitSet32(0)); // Loadstore routines diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_BackPatch.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_BackPatch.cpp index e0b8ada73f..a71944479c 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_BackPatch.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_BackPatch.cpp @@ -127,14 +127,12 @@ bool JitArm64::DisasmLoadStore(const u8* ptr, u32* flags, ARM64Reg* reg) return false; } -u32 JitArm64::EmitBackpatchRoutine(u32 flags, bool fastmem, bool do_farcode, +void JitArm64::EmitBackpatchRoutine(u32 flags, bool fastmem, bool do_farcode, ARM64Reg RS, ARM64Reg addr, BitSet32 gprs_to_push, BitSet32 fprs_to_push) { bool in_far_code = false; - u32 trouble_offset = 0; - const u8* trouble_location = nullptr; - const u8* code_base = GetCodePtr(); + const u8* fastmem_start = GetCodePtr(); if (fastmem) { @@ -148,23 +146,17 @@ u32 JitArm64::EmitBackpatchRoutine(u32 flags, bool fastmem, bool do_farcode, { m_float_emit.FCVT(32, 64, D0, RS); m_float_emit.REV32(8, D0, D0); - trouble_offset = (GetCodePtr() - code_base) / 4; - trouble_location = GetCodePtr(); m_float_emit.STR(32, INDEX_UNSIGNED, D0, addr, 0); } else { m_float_emit.REV64(8, Q0, RS); - trouble_offset = (GetCodePtr() - code_base) / 4; - trouble_location = GetCodePtr(); m_float_emit.STR(64, INDEX_UNSIGNED, Q0, addr, 0); } } else if (flags & BackPatchInfo::FLAG_LOAD && flags & (BackPatchInfo::FLAG_SIZE_F32 | BackPatchInfo::FLAG_SIZE_F64)) { - trouble_offset = (GetCodePtr() - code_base) / 4; - trouble_location = GetCodePtr(); if (flags & BackPatchInfo::FLAG_SIZE_F32) { m_float_emit.LD1R(32, EncodeRegToDouble(RS), addr); @@ -186,9 +178,6 @@ u32 JitArm64::EmitBackpatchRoutine(u32 flags, bool fastmem, bool do_farcode, else if (flags & BackPatchInfo::FLAG_SIZE_16) REV16(temp, RS); - trouble_offset = (GetCodePtr() - code_base) / 4; - trouble_location = GetCodePtr(); - if (flags & BackPatchInfo::FLAG_SIZE_32) STR(INDEX_UNSIGNED, temp, addr, 0); else if (flags & BackPatchInfo::FLAG_SIZE_16) @@ -198,9 +187,6 @@ u32 JitArm64::EmitBackpatchRoutine(u32 flags, bool fastmem, bool do_farcode, } else { - trouble_offset = (GetCodePtr() - code_base) / 4; - trouble_location = GetCodePtr(); - if (flags & BackPatchInfo::FLAG_SIZE_32) LDR(INDEX_UNSIGNED, RS, addr, 0); else if (flags & BackPatchInfo::FLAG_SIZE_16) @@ -220,6 +206,7 @@ u32 JitArm64::EmitBackpatchRoutine(u32 flags, bool fastmem, bool do_farcode, SXTH(RS, RS); } } + const u8* fastmem_end = GetCodePtr(); if (!fastmem || do_farcode) { @@ -232,8 +219,8 @@ u32 JitArm64::EmitBackpatchRoutine(u32 flags, bool fastmem, bool do_farcode, handler.fprs = fprs_to_push; handler.flags = flags; - std::map::iterator handler_loc_iter; - handler_loc_iter = m_handler_to_loc.find(handler); + FastmemArea* fastmem_area = &m_fault_to_handler[fastmem_start]; + auto handler_loc_iter = m_handler_to_loc.find(handler); if (handler_loc_iter == m_handler_to_loc.end()) { @@ -241,13 +228,15 @@ u32 JitArm64::EmitBackpatchRoutine(u32 flags, bool fastmem, bool do_farcode, SwitchToFarCode(); const u8* handler_loc = GetCodePtr(); m_handler_to_loc[handler] = handler_loc; - m_fault_to_handler[trouble_location] = std::make_pair(handler, handler_loc); + fastmem_area->slowmem_code = handler_loc; + fastmem_area->length = fastmem_end - fastmem_start; } else { const u8* handler_loc = handler_loc_iter->second; - m_fault_to_handler[trouble_location] = std::make_pair(handler, handler_loc); - return trouble_offset; + fastmem_area->slowmem_code = handler_loc; + fastmem_area->length = fastmem_end - fastmem_start; + return; } } @@ -338,8 +327,6 @@ u32 JitArm64::EmitBackpatchRoutine(u32 flags, bool fastmem, bool do_farcode, RET(X30); SwitchToNearCode(); } - - return trouble_offset; } bool JitArm64::HandleFault(uintptr_t access_address, SContext* ctx) @@ -372,28 +359,29 @@ bool JitArm64::HandleFault(uintptr_t access_address, SContext* ctx) return false; } - std::map>::iterator slow_handler_iter = m_fault_to_handler.find((const u8*)ctx->CTX_PC); + auto slow_handler_iter = m_fault_to_handler.upper_bound((const u8*)ctx->CTX_PC); + slow_handler_iter--; + // no fastmem area found if (slow_handler_iter == m_fault_to_handler.end()) return false; - BackPatchInfo& info = m_backpatch_info[flags]; - ARM64XEmitter emitter((u8*)(ctx->CTX_PC - info.m_fastmem_trouble_inst_offset * 4)); - u64 new_pc = (u64)emitter.GetCodePtr(); + // no overlapping fastmem area found + if ((const u8*)ctx->CTX_PC - slow_handler_iter->first > slow_handler_iter->second.length) + return false; - { - u32 num_insts_max = info.m_fastmem_size - 1; + ARM64XEmitter emitter((u8*) slow_handler_iter->first); - for (u32 i = 0; i < num_insts_max; ++i) - emitter.HINT(HINT_NOP); + emitter.BL(slow_handler_iter->second.slowmem_code); - emitter.BL(slow_handler_iter->second.second); + u32 num_insts_max = slow_handler_iter->second.length / 4 - 1; + for (u32 i = 0; i < num_insts_max; ++i) + emitter.HINT(HINT_NOP); - m_fault_to_handler.erase(slow_handler_iter); - } + m_fault_to_handler.erase(slow_handler_iter); emitter.FlushIcache(); - ctx->CTX_PC = new_pc; + ctx->CTX_PC = (u64)slow_handler_iter->first; // Wipe the top bits of the addr_register if (flags & BackPatchInfo::FLAG_STORE && @@ -403,283 +391,3 @@ bool JitArm64::HandleFault(uintptr_t access_address, SContext* ctx) ctx->CTX_REG(0) &= 0xFFFFFFFFUll; return true; } - -void JitArm64::InitBackpatch() -{ - u32 flags = 0; - BackPatchInfo info; - u8* code_base = GetWritableCodePtr(); - u8* code_end; - - // Loads - { - // 8bit - { - flags = - BackPatchInfo::FLAG_LOAD | - BackPatchInfo::FLAG_SIZE_8; - EmitBackpatchRoutine(flags, false, false, W0, X1); - code_end = GetWritableCodePtr(); - info.m_slowmem_size = (code_end - code_base) / 4; - - SetCodePtr(code_base); - - info.m_fastmem_trouble_inst_offset = - EmitBackpatchRoutine(flags, true, false, W0, X1); - code_end = GetWritableCodePtr(); - info.m_fastmem_size = (code_end - code_base) / 4; - - SetCodePtr(code_base); - - m_backpatch_info[flags] = info; - } - // 16bit - { - flags = - BackPatchInfo::FLAG_LOAD | - BackPatchInfo::FLAG_SIZE_16; - EmitBackpatchRoutine(flags, false, false, W0, X1); - code_end = GetWritableCodePtr(); - info.m_slowmem_size = (code_end - code_base) / 4; - - SetCodePtr(code_base); - - info.m_fastmem_trouble_inst_offset = - EmitBackpatchRoutine(flags, true, false, W0, X1); - code_end = GetWritableCodePtr(); - info.m_fastmem_size = (code_end - code_base) / 4; - - SetCodePtr(code_base); - - m_backpatch_info[flags] = info; - } - // 32bit - { - flags = - BackPatchInfo::FLAG_LOAD | - BackPatchInfo::FLAG_SIZE_32; - EmitBackpatchRoutine(flags, false, false, W0, X1); - code_end = GetWritableCodePtr(); - info.m_slowmem_size = (code_end - code_base) / 4; - - SetCodePtr(code_base); - - info.m_fastmem_trouble_inst_offset = - EmitBackpatchRoutine(flags, true, false, W0, X1); - code_end = GetWritableCodePtr(); - info.m_fastmem_size = (code_end - code_base) / 4; - - SetCodePtr(code_base); - - m_backpatch_info[flags] = info; - } - // 16bit - Extend - { - flags = - BackPatchInfo::FLAG_LOAD | - BackPatchInfo::FLAG_SIZE_16 | - BackPatchInfo::FLAG_EXTEND; - EmitBackpatchRoutine(flags, false, false, W0, X1); - code_end = GetWritableCodePtr(); - info.m_slowmem_size = (code_end - code_base) / 4; - - SetCodePtr(code_base); - - info.m_fastmem_trouble_inst_offset = - EmitBackpatchRoutine(flags, true, false, W0, X1); - code_end = GetWritableCodePtr(); - info.m_fastmem_size = (code_end - code_base) / 4; - - SetCodePtr(code_base); - - m_backpatch_info[flags] = info; - } - // 16bit - Reverse - { - flags = - BackPatchInfo::FLAG_LOAD | - BackPatchInfo::FLAG_SIZE_16 | - BackPatchInfo::FLAG_REVERSE; - EmitBackpatchRoutine(flags, false, false, W0, X1); - code_end = GetWritableCodePtr(); - info.m_slowmem_size = (code_end - code_base) / 4; - - SetCodePtr(code_base); - - info.m_fastmem_trouble_inst_offset = - EmitBackpatchRoutine(flags, true, false, W0, X1); - code_end = GetWritableCodePtr(); - info.m_fastmem_size = (code_end - code_base) / 4; - - SetCodePtr(code_base); - - m_backpatch_info[flags] = info; - } - // 32bit - Reverse - { - flags = - BackPatchInfo::FLAG_LOAD | - BackPatchInfo::FLAG_SIZE_32 | - BackPatchInfo::FLAG_REVERSE; - EmitBackpatchRoutine(flags, false, false, W0, X1); - code_end = GetWritableCodePtr(); - info.m_slowmem_size = (code_end - code_base) / 4; - - SetCodePtr(code_base); - - info.m_fastmem_trouble_inst_offset = - EmitBackpatchRoutine(flags, true, false, W0, X1); - code_end = GetWritableCodePtr(); - info.m_fastmem_size = (code_end - code_base) / 4; - - SetCodePtr(code_base); - - m_backpatch_info[flags] = info; - } - // 32bit float - { - flags = - BackPatchInfo::FLAG_LOAD | - BackPatchInfo::FLAG_SIZE_F32; - EmitBackpatchRoutine(flags, false, false, Q0, X1); - code_end = GetWritableCodePtr(); - info.m_slowmem_size = (code_end - code_base) / 4; - - SetCodePtr(code_base); - - info.m_fastmem_trouble_inst_offset = - EmitBackpatchRoutine(flags, true, false, Q0, X1); - code_end = GetWritableCodePtr(); - info.m_fastmem_size = (code_end - code_base) / 4; - - SetCodePtr(code_base); - - m_backpatch_info[flags] = info; - } - // 64bit float - { - flags = - BackPatchInfo::FLAG_LOAD | - BackPatchInfo::FLAG_SIZE_F64; - EmitBackpatchRoutine(flags, false, false, Q0, X1); - code_end = GetWritableCodePtr(); - info.m_slowmem_size = (code_end - code_base) / 4; - - SetCodePtr(code_base); - - info.m_fastmem_trouble_inst_offset = - EmitBackpatchRoutine(flags, true, false, Q0, X1); - code_end = GetWritableCodePtr(); - info.m_fastmem_size = (code_end - code_base) / 4; - - SetCodePtr(code_base); - - m_backpatch_info[flags] = info; - } - } - - // Stores - { - // 8bit - { - flags = - BackPatchInfo::FLAG_STORE | - BackPatchInfo::FLAG_SIZE_8; - EmitBackpatchRoutine(flags, false, false, W0, X1); - code_end = GetWritableCodePtr(); - info.m_slowmem_size = (code_end - code_base) / 4; - - SetCodePtr(code_base); - - info.m_fastmem_trouble_inst_offset = - EmitBackpatchRoutine(flags, true, false, W0, X1); - code_end = GetWritableCodePtr(); - info.m_fastmem_size = (code_end - code_base) / 4; - - SetCodePtr(code_base); - - m_backpatch_info[flags] = info; - } - // 16bit - { - flags = - BackPatchInfo::FLAG_STORE | - BackPatchInfo::FLAG_SIZE_16; - EmitBackpatchRoutine(flags, false, false, W0, X1); - code_end = GetWritableCodePtr(); - info.m_slowmem_size = (code_end - code_base) / 4; - - SetCodePtr(code_base); - - info.m_fastmem_trouble_inst_offset = - EmitBackpatchRoutine(flags, true, false, W0, X1); - code_end = GetWritableCodePtr(); - info.m_fastmem_size = (code_end - code_base) / 4; - - SetCodePtr(code_base); - - m_backpatch_info[flags] = info; - } - // 32bit - { - flags = - BackPatchInfo::FLAG_STORE | - BackPatchInfo::FLAG_SIZE_32; - EmitBackpatchRoutine(flags, false, false, W0, X1); - code_end = GetWritableCodePtr(); - info.m_slowmem_size = (code_end - code_base) / 4; - - SetCodePtr(code_base); - - info.m_fastmem_trouble_inst_offset = - EmitBackpatchRoutine(flags, true, false, W0, X1); - code_end = GetWritableCodePtr(); - info.m_fastmem_size = (code_end - code_base) / 4; - - SetCodePtr(code_base); - - m_backpatch_info[flags] = info; - } - // 32bit float - { - flags = - BackPatchInfo::FLAG_STORE | - BackPatchInfo::FLAG_SIZE_F32; - EmitBackpatchRoutine(flags, false, false, Q0, X1); - code_end = GetWritableCodePtr(); - info.m_slowmem_size = (code_end - code_base) / 4; - - SetCodePtr(code_base); - - info.m_fastmem_trouble_inst_offset = - EmitBackpatchRoutine(flags, true, false, Q0, X1); - code_end = GetWritableCodePtr(); - info.m_fastmem_size = (code_end - code_base) / 4; - - SetCodePtr(code_base); - - m_backpatch_info[flags] = info; - } - // 64bit float - { - flags = - BackPatchInfo::FLAG_STORE | - BackPatchInfo::FLAG_SIZE_F64; - EmitBackpatchRoutine(flags, false, false, Q0, X1); - code_end = GetWritableCodePtr(); - info.m_slowmem_size = (code_end - code_base) / 4; - - SetCodePtr(code_base); - - info.m_fastmem_trouble_inst_offset = - EmitBackpatchRoutine(flags, true, false, Q0, X1); - code_end = GetWritableCodePtr(); - info.m_fastmem_size = (code_end - code_base) / 4; - - SetCodePtr(code_base); - - m_backpatch_info[flags] = info; - } - } -} - diff --git a/Source/Core/Core/PowerPC/JitArmCommon/BackPatch.h b/Source/Core/Core/PowerPC/JitArmCommon/BackPatch.h index 369854a621..fc8f96ad26 100644 --- a/Source/Core/Core/PowerPC/JitArmCommon/BackPatch.h +++ b/Source/Core/Core/PowerPC/JitArmCommon/BackPatch.h @@ -34,8 +34,4 @@ struct BackPatchInfo return 64; return 0; } - - u32 m_fastmem_size; - u32 m_fastmem_trouble_inst_offset; - u32 m_slowmem_size; };