diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt index 65ac044e45..4704b340b2 100644 --- a/Source/Core/Core/CMakeLists.txt +++ b/Source/Core/Core/CMakeLists.txt @@ -653,11 +653,6 @@ PRIVATE ZLIB::ZLIB ) -if ((DEFINED CMAKE_ANDROID_ARCH_ABI AND CMAKE_ANDROID_ARCH_ABI MATCHES "x86|x86_64") OR - (NOT DEFINED CMAKE_ANDROID_ARCH_ABI AND _M_X86_64)) - target_link_libraries(core PRIVATE bdisasm) -endif() - if (APPLE) target_link_libraries(core PRIVATE diff --git a/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp b/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp index a8a9f99ed3..dd012ce88f 100644 --- a/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp +++ b/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp @@ -3,7 +3,15 @@ #include "Core/PowerPC/CachedInterpreter/CachedInterpreter.h" +#include +#include +#include + +#include +#include + #include "Common/CommonTypes.h" +#include "Common/GekkoDisassembler.h" #include "Common/Logging/Log.h" #include "Core/ConfigManager.h" #include "Core/Core.h" @@ -290,14 +298,16 @@ void CachedInterpreter::Jit(u32 em_address, bool clear_cache_and_retry_on_failur b->near_end = GetWritableCodePtr(); b->far_begin = b->far_end = nullptr; - b->codeSize = static_cast(b->near_end - b->normalEntry); - // Mark the memory region that this code block uses in the RangeSizeSet. if (b->near_begin != b->near_end) m_free_ranges.erase(b->near_begin, b->near_end); m_block_cache.FinalizeBlock(*b, jo.enableBlocklink, code_block, m_code_buffer); +#ifdef JIT_LOG_GENERATED_CODE + LogGeneratedCode(); +#endif + return; } } @@ -434,3 +444,22 @@ void CachedInterpreter::ClearCache() RefreshConfig(); Host_JitCacheCleared(); } + +void CachedInterpreter::LogGeneratedCode() const +{ + std::ostringstream stream; + + stream << "\nPPC Code Buffer:\n"; + for (const PPCAnalyst::CodeOp& op : + std::span{m_code_buffer.data(), code_block.m_num_instructions}) + { + fmt::print(stream, "0x{:08x}\t\t{}\n", op.address, + Common::GekkoDisassembler::Disassemble(op.inst.hex, op.address)); + } + + stream << "\nHost Code:\n"; + Disassemble(*js.curBlock, stream); + + // TODO C++20: std::ostringstream::view() + DEBUG_LOG_FMT(DYNA_REC, "{}", std::move(stream).str()); +} diff --git a/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.h b/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.h index 4096c7b3a8..a29cf53758 100644 --- a/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.h +++ b/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.h @@ -71,6 +71,8 @@ private: void FreeRanges(); void ResetFreeMemoryRanges(); + void LogGeneratedCode() const; + struct StartProfiledBlockOperands; template struct EndBlockOperands; diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/PowerPC/Jit64/Jit.cpp index 7d26ab76af..cc88868fee 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit.cpp @@ -4,10 +4,10 @@ #include "Core/PowerPC/Jit64/Jit.h" #include +#include #include #include -#include #include #include @@ -833,6 +833,10 @@ void Jit64::Jit(u32 em_address, bool clear_cache_and_retry_on_failure) b->far_end = far_end; blocks.FinalizeBlock(*b, jo.enableBlocklink, code_block, m_code_buffer); + +#ifdef JIT_LOG_GENERATED_CODE + LogGeneratedCode(); +#endif return; } } @@ -1198,12 +1202,6 @@ bool Jit64::DoJit(u32 em_address, JitBlock* b, u32 nextPC) return false; } - b->codeSize = static_cast(GetCodePtr() - b->normalEntry); - -#ifdef JIT_LOG_GENERATED_CODE - LogGeneratedX86(code_block.m_num_instructions, m_code_buffer, start, b); -#endif - return true; } @@ -1330,39 +1328,24 @@ bool Jit64::HandleFunctionHooking(u32 address) return true; } -void LogGeneratedX86(size_t size, const PPCAnalyst::CodeBuffer& code_buffer, const u8* normalEntry, - const JitBlock* b) +void Jit64::LogGeneratedCode() const { - for (size_t i = 0; i < size; i++) + std::ostringstream stream; + + stream << "\nPPC Code Buffer:\n"; + for (const PPCAnalyst::CodeOp& op : + std::span{m_code_buffer.data(), code_block.m_num_instructions}) { - const PPCAnalyst::CodeOp& op = code_buffer[i]; - const std::string disasm = Common::GekkoDisassembler::Disassemble(op.inst.hex, op.address); - DEBUG_LOG_FMT(DYNA_REC, "IR_X86 PPC: {:08x} {}\n", op.address, disasm); + fmt::print(stream, "0x{:08x}\t\t{}\n", op.address, + Common::GekkoDisassembler::Disassemble(op.inst.hex, op.address)); } - disassembler x64disasm; - x64disasm.set_syntax_intel(); + const JitBlock* const block = js.curBlock; + stream << "\nHost Near Code:\n"; + m_disassembler->Disassemble(block->normalEntry, block->near_end, stream); + stream << "\nHost Far Code:\n"; + m_disassembler->Disassemble(block->far_begin, block->far_end, stream); - u64 disasmPtr = reinterpret_cast(normalEntry); - const u8* end = normalEntry + b->codeSize; - - while (reinterpret_cast(disasmPtr) < end) - { - char sptr[1000] = ""; - disasmPtr += x64disasm.disasm64(disasmPtr, disasmPtr, reinterpret_cast(disasmPtr), sptr); - DEBUG_LOG_FMT(DYNA_REC, "IR_X86 x86: {}", sptr); - } - - if (b->codeSize <= 250) - { - std::ostringstream ss; - ss << std::hex; - for (u8 i = 0; i <= b->codeSize; i++) - { - ss.width(2); - ss.fill('0'); - ss << static_cast(*(normalEntry + i)); - } - DEBUG_LOG_FMT(DYNA_REC, "IR_X86 bin: {}\n\n\n", ss.str()); - } + // TODO C++20: std::ostringstream::view() + DEBUG_LOG_FMT(DYNA_REC, "{}", std::move(stream).str()); } diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.h b/Source/Core/Core/PowerPC/Jit64/Jit.h index b1969704b3..0e98981a46 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit.h +++ b/Source/Core/Core/PowerPC/Jit64/Jit.h @@ -276,6 +276,8 @@ private: void FreeRanges(); void ResetFreeMemoryRanges(); + void LogGeneratedCode() const; + static void ImHere(Jit64& jit); JitBlockCache blocks{*this}; @@ -294,6 +296,3 @@ private: std::map m_been_here; std::unique_ptr m_disassembler; }; - -void LogGeneratedX86(size_t size, const PPCAnalyst::CodeBuffer& code_buffer, const u8* normalEntry, - const JitBlock* b); diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp index d2dfbc605b..c5c6f9b075 100644 --- a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp @@ -5,10 +5,16 @@ #include #include +#include +#include + +#include +#include #include "Common/Arm64Emitter.h" #include "Common/CommonTypes.h" #include "Common/EnumUtils.h" +#include "Common/GekkoDisassembler.h" #include "Common/HostDisassembler.h" #include "Common/Logging/Log.h" #include "Common/MathUtil.h" @@ -1021,6 +1027,10 @@ void JitArm64::Jit(u32 em_address, bool clear_cache_and_retry_on_failure) b->far_end = far_end; blocks.FinalizeBlock(*b, jo.enableBlocklink, code_block, m_code_buffer); + +#ifdef JIT_LOG_GENERATED_CODE + LogGeneratedCode(); +#endif return; } } @@ -1381,10 +1391,30 @@ bool JitArm64::DoJit(u32 em_address, JitBlock* b, u32 nextPC) return false; } - b->codeSize = static_cast(GetCodePtr() - b->normalEntry); - FlushIcache(); m_far_code.FlushIcache(); return true; } + +void JitArm64::LogGeneratedCode() const +{ + std::ostringstream stream; + + stream << "\nPPC Code Buffer:\n"; + for (const PPCAnalyst::CodeOp& op : + std::span{m_code_buffer.data(), code_block.m_num_instructions}) + { + fmt::print(stream, "0x{:08x}\t\t{}\n", op.address, + Common::GekkoDisassembler::Disassemble(op.inst.hex, op.address)); + } + + const JitBlock* const block = js.curBlock; + stream << "\nHost Near Code:\n"; + m_disassembler->Disassemble(block->normalEntry, block->near_end, stream); + stream << "\nHost Far Code:\n"; + m_disassembler->Disassemble(block->far_begin, block->far_end, stream); + + // TODO C++20: std::ostringstream::view() + DEBUG_LOG_FMT(DYNA_REC, "{}", std::move(stream).str()); +} diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.h b/Source/Core/Core/PowerPC/JitArm64/Jit.h index e27392b3e5..0c1ea0d647 100644 --- a/Source/Core/Core/PowerPC/JitArm64/Jit.h +++ b/Source/Core/Core/PowerPC/JitArm64/Jit.h @@ -308,6 +308,8 @@ protected: void IntializeSpeculativeConstants(); + void LogGeneratedCode() const; + // AsmRoutines void GenerateAsm(); void GenerateCommonAsm(); diff --git a/Source/Core/Core/PowerPC/JitCommon/JitCache.h b/Source/Core/Core/PowerPC/JitCommon/JitCache.h index fb9b330097..9d227d62b0 100644 --- a/Source/Core/Core/PowerPC/JitCommon/JitCache.h +++ b/Source/Core/Core/PowerPC/JitCommon/JitCache.h @@ -45,9 +45,6 @@ struct JitBlockData // and valid_block in particular). This is useful because of // of the way the instruction cache works on PowerPC. u32 physicalAddress; - // The number of bytes of JIT'ed code contained in this block. Mostly - // useful for logging. - u32 codeSize; // The number of PPC instructions represented by this block. Mostly // useful for logging. u32 originalSize;