From b7e8e8ac3e06e78cae91727551980be10c4903c0 Mon Sep 17 00:00:00 2001 From: Eladash Date: Mon, 13 Apr 2020 13:29:01 +0300 Subject: [PATCH] PPU: Merge reservations store functions into one --- rpcs3/Emu/Cell/PPUThread.cpp | 105 +++++++++-------------------------- 1 file changed, 25 insertions(+), 80 deletions(-) diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index 805b4008fd48..69c9b750ec86 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -1081,7 +1081,7 @@ extern u64 ppu_ldarx(ppu_thread& ppu, u32 addr) return ppu_load_acquire_reservation(ppu, addr); } -const auto ppu_stwcx_tx = build_function_asm([](asmjit::X86Assembler& c, auto& args) +const auto ppu_stwcx_tx = build_function_asm([](asmjit::X86Assembler& c, auto& args) { using namespace asmjit; @@ -1127,76 +1127,6 @@ const auto ppu_stwcx_tx = build_function_asm>(addr & -4); - const u32 old_data = static_cast(ppu.rdata << ((addr & 7) * 8) >> 32); - - if (ppu.raddr != addr || addr & 3 || old_data != data.load() || ppu.rtime != (vm::reservation_acquire(addr, sizeof(u32)) & -128)) - { - ppu.raddr = 0; - return false; - } - - if (g_use_rtm) [[likely]] - { - switch (ppu_stwcx_tx(addr, ppu.rtime, old_data, reg_value)) - { - case 0: - { - // Reservation lost - ppu.raddr = 0; - return false; - } - case 1: - { - vm::reservation_notifier(addr, sizeof(u32)).notify_all(); - ppu.raddr = 0; - return true; - } - } - - auto& res = vm::reservation_acquire(addr, sizeof(u32)); - - ppu.raddr = 0; - - if (res == ppu.rtime && res.compare_and_swap_test(ppu.rtime, ppu.rtime | 1)) - { - if (data.compare_and_swap_test(old_data, reg_value)) - { - res += 127; - vm::reservation_notifier(addr, sizeof(u32)).notify_all(); - return true; - } - - res -= 1; - } - - return false; - } - - vm::passive_unlock(ppu); - - auto& res = vm::reservation_lock(addr, sizeof(u32)); - const u64 old_time = res.load() & -128; - - const bool result = ppu.rtime == old_time && data.compare_and_swap_test(old_data, reg_value); - - if (result) - { - res.release(old_time + 128); - vm::reservation_notifier(addr, sizeof(u32)).notify_all(); - } - else - { - res.release(old_time); - } - - vm::passive_lock(ppu); - ppu.raddr = 0; - return result; -} - const auto ppu_stdcx_tx = build_function_asm([](asmjit::X86Assembler& c, auto& args) { using namespace asmjit; @@ -1243,12 +1173,15 @@ const auto ppu_stdcx_tx = build_function_asm +static bool ppu_store_reservation(ppu_thread& ppu, u32 addr, T reg_value) { - auto& data = vm::_ref>(addr & -8); - const u64 old_data = ppu.rdata << ((addr & 7) * 8); + auto& data = vm::_ref>(addr & (0 - sizeof(T))); + constexpr u64 size_off = (sizeof(T) * 8) & 63; + + const T old_data = static_cast(ppu.rdata << ((addr & 7) * 8) >> size_off); - if (ppu.raddr != addr || addr & 7 || old_data != data.load() || ppu.rtime != (vm::reservation_acquire(addr, sizeof(u64)) & -128)) + if (ppu.raddr != addr || addr % sizeof(T) || old_data != data.load() || ppu.rtime != (vm::reservation_acquire(addr, sizeof(T)) & -128)) { ppu.raddr = 0; return false; @@ -1256,7 +1189,9 @@ extern bool ppu_stdcx(ppu_thread& ppu, u32 addr, u64 reg_value) if (g_use_rtm) [[likely]] { - switch (ppu_stdcx_tx(addr, ppu.rtime, old_data, reg_value)) + constexpr auto& ppu_store_tx = sizeof(T) == 8 ? ppu_stdcx_tx : ppu_stwcx_tx; + + switch (ppu_store_tx(addr, ppu.rtime, old_data, reg_value)) { case 0: { @@ -1266,13 +1201,13 @@ extern bool ppu_stdcx(ppu_thread& ppu, u32 addr, u64 reg_value) } case 1: { - vm::reservation_notifier(addr, sizeof(u64)).notify_all(); + vm::reservation_notifier(addr, sizeof(T)).notify_all(); ppu.raddr = 0; return true; } } - auto& res = vm::reservation_acquire(addr, sizeof(u64)); + auto& res = vm::reservation_acquire(addr, sizeof(T)); ppu.raddr = 0; @@ -1281,7 +1216,7 @@ extern bool ppu_stdcx(ppu_thread& ppu, u32 addr, u64 reg_value) if (data.compare_and_swap_test(old_data, reg_value)) { res += 127; - vm::reservation_notifier(addr, sizeof(u64)).notify_all(); + vm::reservation_notifier(addr, sizeof(T)).notify_all(); return true; } @@ -1293,7 +1228,7 @@ extern bool ppu_stdcx(ppu_thread& ppu, u32 addr, u64 reg_value) vm::passive_unlock(ppu); - auto& res = vm::reservation_lock(addr, sizeof(u64)); + auto& res = vm::reservation_lock(addr, sizeof(T)); const u64 old_time = res.load() & -128; const bool result = ppu.rtime == old_time && data.compare_and_swap_test(old_data, reg_value); @@ -1313,6 +1248,16 @@ extern bool ppu_stdcx(ppu_thread& ppu, u32 addr, u64 reg_value) return result; } +extern bool ppu_stwcx(ppu_thread& ppu, u32 addr, u32 reg_value) +{ + return ppu_store_reservation(ppu, addr, reg_value); +} + +extern bool ppu_stdcx(ppu_thread& ppu, u32 addr, u64 reg_value) +{ + return ppu_store_reservation(ppu, addr, reg_value); +} + extern void ppu_initialize() { const auto _main = g_fxo->get();