From dc8252bb9fd9c3ea3929533a4c50f1947d475ed9 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Tue, 20 Oct 2020 08:22:25 +0300 Subject: [PATCH] Remove XABORT in PPU/SPU transactions. It's expensive for unknown reason. Simply XEND is usually much cheaper. Add some minor improvements. Use g_sudo_addr. --- Utilities/JIT.cpp | 37 ++--------- Utilities/JIT.h | 5 +- rpcs3/Emu/Cell/PPUThread.cpp | 94 +++++++++++++++++++-------- rpcs3/Emu/Cell/SPUThread.cpp | 121 +++++++++++++++++++++++------------ rpcs3/util/atomic2.cpp | 8 ++- 5 files changed, 161 insertions(+), 104 deletions(-) diff --git a/Utilities/JIT.cpp b/Utilities/JIT.cpp index 01e92a7241..0cfb1e16d4 100644 --- a/Utilities/JIT.cpp +++ b/Utilities/JIT.cpp @@ -272,33 +272,13 @@ asmjit::Label asmjit::build_transaction_enter(asmjit::X86Assembler& c, asmjit::L Label begin = c.newLabel(); c.jmp(begin); c.bind(fall); + c.add(ctr, 1); - if (less_than < 65) - { - c.add(ctr, 1); - c.test(x86::eax, _XABORT_RETRY); - c.jz(fallback); - } - else - { - // Don't repeat on explicit XABORT instruction (workaround) - c.test(x86::eax, _XABORT_EXPLICIT); - c.jnz(fallback); - - // Don't repeat on weird zero status - c.test(x86::eax, x86::eax); - c.jz(fallback); - - // Count an attempt without RETRY flag as 65 normal attempts and continue - c.push(x86::rax); - c.not_(x86::eax); - c.and_(x86::eax, _XABORT_RETRY); - c.shl(x86::eax, 5); - c.add(x86::eax, 1); // eax = RETRY ? 1 : 65 - c.add(ctr, x86::rax); - c.pop(x86::rax); - } + // 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); @@ -309,13 +289,6 @@ asmjit::Label asmjit::build_transaction_enter(asmjit::X86Assembler& c, asmjit::L //c.xbegin(fall); } -void asmjit::build_transaction_abort(asmjit::X86Assembler& c, unsigned char code) -{ - c.db(0xc6); - c.db(0xf8); - c.db(code); -} - #ifdef LLVM_AVAILABLE #include diff --git a/Utilities/JIT.h b/Utilities/JIT.h index fafcae8d1b..6085e2cf8e 100644 --- a/Utilities/JIT.h +++ b/Utilities/JIT.h @@ -55,11 +55,8 @@ namespace asmjit // Should only be used to build global functions asmjit::Runtime& get_global_runtime(); - // Emit xbegin and adjacent loop, return label at xbegin + // 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); - - // Emit xabort - void build_transaction_abort(X86Assembler& c, unsigned char code); } // Build runtime function with asmjit::X86Assembler diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index 7945681f51..c4f22b9969 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -1340,7 +1340,7 @@ const auto ppu_stcx_accurate_tx = build_function_asm(cpu_flag::pause)); - c.jc(fail3); + c.jc(fall2); c.mov(x86::rax, x86::qword_ptr(x86::rbx)); c.and_(x86::rax, -128); c.cmp(x86::rax, x86::r13); @@ -1504,30 +1529,47 @@ const auto ppu_stcx_accurate_tx = build_function_asm([](asmjit::X86Assembler& c, auto& args) +const auto spu_putllc_tx = build_function_asm([](asmjit::X86Assembler& c, auto& args) { using namespace asmjit; @@ -352,7 +352,7 @@ const auto spu_putllc_tx = build_function_asm(cpu_flag::pause)); - c.jc(fail3); + c.jc(fall2); c.mov(x86::rax, x86::qword_ptr(x86::rbx)); c.and_(x86::rax, -128); c.cmp(x86::rax, x86::r13); @@ -539,7 +564,7 @@ const auto spu_putllc_tx = build_function_asm(cpu_flag::pause)); diff --git a/rpcs3/util/atomic2.cpp b/rpcs3/util/atomic2.cpp index fdec8df1df..7702079a2e 100644 --- a/rpcs3/util/atomic2.cpp +++ b/rpcs3/util/atomic2.cpp @@ -211,11 +211,15 @@ static const auto commit_tx = build_function_asm