From 8ce0819b42921b9de7cbb699e2f3dcce52748002 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Thu, 29 Oct 2020 05:01:45 +0300 Subject: [PATCH] SPU: add stx/ftx counters Just count pure transaction successes and failures. --- Utilities/JIT.cpp | 23 ----------------------- Utilities/JIT.h | 27 ++++++++++++++++++++++++++- rpcs3/Emu/Cell/PPUThread.cpp | 4 ++-- rpcs3/Emu/Cell/SPUThread.cpp | 35 ++++++++++++++++++++++++++++++----- rpcs3/Emu/Cell/SPUThread.h | 3 +++ 5 files changed, 61 insertions(+), 31 deletions(-) diff --git a/Utilities/JIT.cpp b/Utilities/JIT.cpp index 0cfb1e16d4..e4e58f2429 100644 --- a/Utilities/JIT.cpp +++ b/Utilities/JIT.cpp @@ -266,29 +266,6 @@ asmjit::Runtime& asmjit::get_global_runtime() return g_rt; } -asmjit::Label asmjit::build_transaction_enter(asmjit::X86Assembler& c, asmjit::Label fallback, const asmjit::X86Gp& ctr, uint less_than) -{ - Label fall = c.newLabel(); - Label begin = c.newLabel(); - c.jmp(begin); - c.bind(fall); - c.add(ctr, 1); - - // Don't repeat on zero status (may indicate syscall or interrupt) - c.test(x86::eax, x86::eax); - c.jz(fallback); - - // Other bad statuses are ignored regardless of repeat flag (TODO) - c.cmp(ctr, less_than); - c.jae(fallback); - c.align(kAlignCode, 16); - c.bind(begin); - return fall; - - // xbegin should be issued manually, allows to add more check before entering transaction - //c.xbegin(fall); -} - #ifdef LLVM_AVAILABLE #include diff --git a/Utilities/JIT.h b/Utilities/JIT.h index 6085e2cf8e..17be332d07 100644 --- a/Utilities/JIT.h +++ b/Utilities/JIT.h @@ -56,7 +56,32 @@ namespace asmjit asmjit::Runtime& get_global_runtime(); // Emit xbegin and adjacent loop, return label at xbegin (don't use xabort please) - [[nodiscard]] asmjit::Label build_transaction_enter(X86Assembler& c, Label fallback, const X86Gp& ctr, uint less_than); + template + [[nodiscard]] inline asmjit::Label build_transaction_enter(asmjit::X86Assembler& c, asmjit::Label fallback, const asmjit::X86Gp& ctr, uint less_than, F func) + { + Label fall = c.newLabel(); + Label begin = c.newLabel(); + c.jmp(begin); + c.bind(fall); + + // First invoked after failure + func(); + + c.add(ctr, 1); + + // Don't repeat on zero status (may indicate syscall or interrupt) + c.test(x86::eax, x86::eax); + c.jz(fallback); + + // Other bad statuses are ignored regardless of repeat flag (TODO) + c.cmp(ctr, less_than); + c.jae(fallback); + c.align(kAlignCode, 16); + c.bind(begin); + return fall; + + // xbegin should be issued manually, allows to add more check before entering transaction + } } // Build runtime function with asmjit::X86Assembler diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index 2d3f26b559..312078f589 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -1377,7 +1377,7 @@ const auto ppu_stcx_accurate_tx = build_function_asm(cpu_flag::pause)); c.mov(x86::eax, _XABORT_EXPLICIT); c.jc(fall); @@ -1489,7 +1489,7 @@ const auto ppu_stcx_accurate_tx = build_function_asm(cpu_flag::pause)); c.mov(x86::eax, _XABORT_EXPLICIT); c.jc(fall); @@ -463,6 +466,7 @@ const auto spu_putllc_tx = build_function_asm(cpu_flag::pause)); @@ -916,6 +940,7 @@ const extern auto spu_getllar_tx = build_function_asm stack_mirror; // Return address information const char* current_func{}; // Current STOP or RDCH blocking function