vm: expand reservation lock bit area to 7 bit

This is minor change.
This commit is contained in:
Nekotekina 2019-05-18 20:56:22 +03:00
parent ceaa669494
commit 9abb303569
5 changed files with 36 additions and 35 deletions

View file

@ -975,7 +975,7 @@ static T ppu_load_acquire_reservation(ppu_thread& ppu, u32 addr)
while (LIKELY(g_use_rtm)) while (LIKELY(g_use_rtm))
{ {
ppu.rtime = vm::reservation_acquire(addr, sizeof(T)); ppu.rtime = vm::reservation_acquire(addr, sizeof(T)) & -128;
ppu.rdata = data; ppu.rdata = data;
if (LIKELY(vm::reservation_acquire(addr, sizeof(T)) == ppu.rtime)) if (LIKELY(vm::reservation_acquire(addr, sizeof(T)) == ppu.rtime))
@ -990,7 +990,7 @@ static T ppu_load_acquire_reservation(ppu_thread& ppu, u32 addr)
ppu.rtime = vm::reservation_acquire(addr, sizeof(T)); ppu.rtime = vm::reservation_acquire(addr, sizeof(T));
if (LIKELY((ppu.rtime & 1) == 0)) if (LIKELY((ppu.rtime & 127) == 0))
{ {
ppu.rdata = data; ppu.rdata = data;
@ -1006,7 +1006,7 @@ static T ppu_load_acquire_reservation(ppu_thread& ppu, u32 addr)
{ {
ppu.rtime = vm::reservation_acquire(addr, sizeof(T)); ppu.rtime = vm::reservation_acquire(addr, sizeof(T));
if (LIKELY((ppu.rtime & 1) == 0)) if (LIKELY((ppu.rtime & 127) == 0))
{ {
ppu.rdata = data; ppu.rdata = data;
@ -1066,7 +1066,7 @@ const auto ppu_stwcx_tx = build_function_asm<bool(*)(u32 raddr, u64 rtime, u64 r
c.cmp(x86::dword_ptr(x86::r11), args[2].r32()); c.cmp(x86::dword_ptr(x86::r11), args[2].r32());
c.jne(fail); c.jne(fail);
c.mov(x86::dword_ptr(x86::r11), args[3].r32()); c.mov(x86::dword_ptr(x86::r11), args[3].r32());
c.add(x86::qword_ptr(x86::r10), 2); c.sub(x86::qword_ptr(x86::r10), -128);
c.xend(); c.xend();
c.mov(x86::eax, 1); c.mov(x86::eax, 1);
c.ret(); c.ret();
@ -1096,7 +1096,7 @@ extern bool ppu_stwcx(ppu_thread& ppu, u32 addr, u32 reg_value)
auto& data = vm::_ref<atomic_be_t<u32>>(addr & -4); auto& data = vm::_ref<atomic_be_t<u32>>(addr & -4);
const u32 old_data = static_cast<u32>(ppu.rdata << ((addr & 7) * 8) >> 32); const u32 old_data = static_cast<u32>(ppu.rdata << ((addr & 7) * 8) >> 32);
if (ppu.raddr != addr || addr & 3 || old_data != data.load() || ppu.rtime != (vm::reservation_acquire(addr, sizeof(u32)) & ~1ull)) if (ppu.raddr != addr || addr & 3 || old_data != data.load() || ppu.rtime != (vm::reservation_acquire(addr, sizeof(u32)) & -128))
{ {
ppu.raddr = 0; ppu.raddr = 0;
return false; return false;
@ -1119,13 +1119,13 @@ extern bool ppu_stwcx(ppu_thread& ppu, u32 addr, u32 reg_value)
vm::passive_unlock(ppu); vm::passive_unlock(ppu);
auto& res = vm::reservation_lock(addr, sizeof(u32)); auto& res = vm::reservation_lock(addr, sizeof(u32));
const u64 old_time = res.load() & ~1ull; const u64 old_time = res.load() & -128;
const bool result = ppu.rtime == old_time && data.compare_and_swap_test(old_data, reg_value); const bool result = ppu.rtime == old_time && data.compare_and_swap_test(old_data, reg_value);
if (result) if (result)
{ {
res.release(old_time + 2); res.release(old_time + 128);
vm::reservation_notifier(addr, sizeof(u32)).notify_all(); vm::reservation_notifier(addr, sizeof(u32)).notify_all();
} }
else else
@ -1164,7 +1164,7 @@ const auto ppu_stdcx_tx = build_function_asm<bool(*)(u32 raddr, u64 rtime, u64 r
c.cmp(x86::qword_ptr(x86::r11), args[2]); c.cmp(x86::qword_ptr(x86::r11), args[2]);
c.jne(fail); c.jne(fail);
c.mov(x86::qword_ptr(x86::r11), args[3]); c.mov(x86::qword_ptr(x86::r11), args[3]);
c.add(x86::qword_ptr(x86::r10), 2); c.sub(x86::qword_ptr(x86::r10), -128);
c.xend(); c.xend();
c.mov(x86::eax, 1); c.mov(x86::eax, 1);
c.ret(); c.ret();
@ -1194,7 +1194,7 @@ extern bool ppu_stdcx(ppu_thread& ppu, u32 addr, u64 reg_value)
auto& data = vm::_ref<atomic_be_t<u64>>(addr & -8); auto& data = vm::_ref<atomic_be_t<u64>>(addr & -8);
const u64 old_data = ppu.rdata << ((addr & 7) * 8); const u64 old_data = ppu.rdata << ((addr & 7) * 8);
if (ppu.raddr != addr || addr & 7 || old_data != data.load() || ppu.rtime != (vm::reservation_acquire(addr, sizeof(u64)) & ~1ull)) if (ppu.raddr != addr || addr & 7 || old_data != data.load() || ppu.rtime != (vm::reservation_acquire(addr, sizeof(u64)) & -128))
{ {
ppu.raddr = 0; ppu.raddr = 0;
return false; return false;
@ -1217,13 +1217,13 @@ extern bool ppu_stdcx(ppu_thread& ppu, u32 addr, u64 reg_value)
vm::passive_unlock(ppu); vm::passive_unlock(ppu);
auto& res = vm::reservation_lock(addr, sizeof(u64)); auto& res = vm::reservation_lock(addr, sizeof(u64));
const u64 old_time = res.load() & ~1ull; const u64 old_time = res.load() & -128;
const bool result = ppu.rtime == old_time && data.compare_and_swap_test(old_data, reg_value); const bool result = ppu.rtime == old_time && data.compare_and_swap_test(old_data, reg_value);
if (result) if (result)
{ {
res.release(old_time + 2); res.release(old_time + 128);
vm::reservation_notifier(addr, sizeof(u64)).notify_all(); vm::reservation_notifier(addr, sizeof(u64)).notify_all();
} }
else else

View file

@ -1212,7 +1212,7 @@ void spu_recompiler::get_events()
c->mov(*qw0, imm_ptr(vm::g_reservations)); c->mov(*qw0, imm_ptr(vm::g_reservations));
c->shr(qw1->r32(), 4); c->shr(qw1->r32(), 4);
c->mov(*qw0, x86::qword_ptr(*qw0, *qw1)); c->mov(*qw0, x86::qword_ptr(*qw0, *qw1));
c->and_(qw0->r64(), (u64)(~1ull)); c->and_(qw0->r64(), -128);
c->cmp(*qw0, SPU_OFF_64(rtime)); c->cmp(*qw0, SPU_OFF_64(rtime));
c->jne(fail); c->jne(fail);
c->mov(*qw0, imm_ptr(vm::g_base_addr)); c->mov(*qw0, imm_ptr(vm::g_base_addr));

View file

@ -316,7 +316,7 @@ const auto spu_putllc_tx = build_function_asm<u32(*)(u32 raddr, u64 rtime, const
c.movaps(x86::oword_ptr(x86::r11, 112), x86::xmm15); c.movaps(x86::oword_ptr(x86::r11, 112), x86::xmm15);
} }
c.add(x86::qword_ptr(x86::r10), 2); c.sub(x86::qword_ptr(x86::r10), -128);
c.xend(); c.xend();
c.mov(x86::eax, 1); c.mov(x86::eax, 1);
c.jmp(_ret); c.jmp(_ret);
@ -452,6 +452,7 @@ const auto spu_getll_tx = build_function_asm<u64(*)(u32 raddr, void* rdata)>([](
c.movaps(x86::oword_ptr(args[1], 112), x86::xmm7); c.movaps(x86::oword_ptr(args[1], 112), x86::xmm7);
} }
c.and_(x86::rax, -128);
c.jmp(_ret); c.jmp(_ret);
// Touch memory after transaction failure // Touch memory after transaction failure
@ -561,7 +562,7 @@ const auto spu_putlluc_tx = build_function_asm<bool(*)(u32 raddr, const void* rd
c.movaps(x86::oword_ptr(x86::r11, 112), x86::xmm7); c.movaps(x86::oword_ptr(x86::r11, 112), x86::xmm7);
} }
c.add(x86::qword_ptr(x86::r10), 2); c.sub(x86::qword_ptr(x86::r10), -128);
c.xend(); c.xend();
c.vzeroupper(); c.vzeroupper();
c.mov(x86::eax, 1); c.mov(x86::eax, 1);
@ -1034,28 +1035,28 @@ void spu_thread::do_dma_transfer(const spu_mfc_cmd& args)
{ {
auto& res = vm::reservation_lock(eal, 1); auto& res = vm::reservation_lock(eal, 1);
*reinterpret_cast<u8*>(dst) = *reinterpret_cast<const u8*>(src); *reinterpret_cast<u8*>(dst) = *reinterpret_cast<const u8*>(src);
res.release(res.load() + 1); res.release(res.load() + 127);
break; break;
} }
case 2: case 2:
{ {
auto& res = vm::reservation_lock(eal, 2); auto& res = vm::reservation_lock(eal, 2);
*reinterpret_cast<u16*>(dst) = *reinterpret_cast<const u16*>(src); *reinterpret_cast<u16*>(dst) = *reinterpret_cast<const u16*>(src);
res.release(res.load() + 1); res.release(res.load() + 127);
break; break;
} }
case 4: case 4:
{ {
auto& res = vm::reservation_lock(eal, 4); auto& res = vm::reservation_lock(eal, 4);
*reinterpret_cast<u32*>(dst) = *reinterpret_cast<const u32*>(src); *reinterpret_cast<u32*>(dst) = *reinterpret_cast<const u32*>(src);
res.release(res.load() + 1); res.release(res.load() + 127);
break; break;
} }
case 8: case 8:
{ {
auto& res = vm::reservation_lock(eal, 8); auto& res = vm::reservation_lock(eal, 8);
*reinterpret_cast<u64*>(dst) = *reinterpret_cast<const u64*>(src); *reinterpret_cast<u64*>(dst) = *reinterpret_cast<const u64*>(src);
res.release(res.load() + 1); res.release(res.load() + 127);
break; break;
} }
default: default:
@ -1074,7 +1075,7 @@ void spu_thread::do_dma_transfer(const spu_mfc_cmd& args)
size -= 16; size -= 16;
} }
res.release(res.load() + 1); res.release(res.load() + 127);
break; break;
} }
@ -1271,7 +1272,7 @@ void spu_thread::do_putlluc(const spu_mfc_cmd& args)
if (raddr && addr == raddr) if (raddr && addr == raddr)
{ {
// Last check for event before we clear the reservation // Last check for event before we clear the reservation
if ((vm::reservation_acquire(addr, 128) & ~1ull) != rtime || rdata != vm::_ref<decltype(rdata)>(addr)) if ((vm::reservation_acquire(addr, 128) & -128) != rtime || rdata != vm::_ref<decltype(rdata)>(addr))
{ {
ch_event_stat |= SPU_EVENT_LR; ch_event_stat |= SPU_EVENT_LR;
} }
@ -1310,12 +1311,12 @@ void spu_thread::do_putlluc(const spu_mfc_cmd& args)
// TODO: vm::check_addr // TODO: vm::check_addr
vm::writer_lock lock(addr); vm::writer_lock lock(addr);
mov_rdata(data.data(), to_write.data()); mov_rdata(data.data(), to_write.data());
res.release(res.load() + 1); res.release(res.load() + 127);
} }
else else
{ {
mov_rdata(data.data(), to_write.data()); mov_rdata(data.data(), to_write.data());
res.release(res.load() + 1); res.release(res.load() + 127);
} }
} }
@ -1458,9 +1459,9 @@ bool spu_thread::process_mfc_cmd()
if (is_polling) if (is_polling)
{ {
rtime = vm::reservation_acquire(addr, 128); rtime = vm::reservation_acquire(addr, 128) & -128;
while (rdata == data && vm::reservation_acquire(addr, 128) == rtime) while (rdata == data && (vm::reservation_acquire(addr, 128)) == rtime)
{ {
if (is_stopped()) if (is_stopped())
{ {
@ -1487,7 +1488,7 @@ bool spu_thread::process_mfc_cmd()
{ {
for (;; count++, busy_wait(300)) for (;; count++, busy_wait(300))
{ {
ntime = vm::reservation_acquire(addr, 128); ntime = vm::reservation_acquire(addr, 128) & -128;
dst = data; dst = data;
if (LIKELY(vm::reservation_acquire(addr, 128) == ntime)) if (LIKELY(vm::reservation_acquire(addr, 128) == ntime))
@ -1505,7 +1506,7 @@ bool spu_thread::process_mfc_cmd()
else else
{ {
auto& res = vm::reservation_lock(addr, 128); auto& res = vm::reservation_lock(addr, 128);
const u64 old_time = res.load() & ~1ull; const u64 old_time = res.load() & -128;
if (g_cfg.core.spu_accurate_getllar) if (g_cfg.core.spu_accurate_getllar)
{ {
@ -1530,7 +1531,7 @@ bool spu_thread::process_mfc_cmd()
if (const u32 _addr = raddr) if (const u32 _addr = raddr)
{ {
// Last check for event before we replace the reservation with a new one // Last check for event before we replace the reservation with a new one
if ((vm::reservation_acquire(_addr, 128) & ~1ull) != rtime || rdata != vm::_ref<decltype(rdata)>(_addr)) if ((vm::reservation_acquire(_addr, 128) & -128) != rtime || rdata != vm::_ref<decltype(rdata)>(_addr))
{ {
ch_event_stat |= SPU_EVENT_LR; ch_event_stat |= SPU_EVENT_LR;
@ -1558,7 +1559,7 @@ bool spu_thread::process_mfc_cmd()
const u32 addr = ch_mfc_cmd.eal & -128u; const u32 addr = ch_mfc_cmd.eal & -128u;
u32 result = 0; u32 result = 0;
if (raddr == addr && rtime == (vm::reservation_acquire(raddr, 128) & ~1ull)) if (raddr == addr && rtime == (vm::reservation_acquire(raddr, 128) & -128))
{ {
const auto& to_write = _ref<decltype(rdata)>(ch_mfc_cmd.lsa & 0x3ff80); const auto& to_write = _ref<decltype(rdata)>(ch_mfc_cmd.lsa & 0x3ff80);
@ -1580,7 +1581,7 @@ bool spu_thread::process_mfc_cmd()
else if (auto& data = vm::_ref<decltype(rdata)>(addr); rdata == data) else if (auto& data = vm::_ref<decltype(rdata)>(addr); rdata == data)
{ {
auto& res = vm::reservation_lock(raddr, 128); auto& res = vm::reservation_lock(raddr, 128);
const u64 old_time = res.load() & ~1ull; const u64 old_time = res.load() & -128;
if (rtime == old_time) if (rtime == old_time)
{ {
@ -1593,7 +1594,7 @@ bool spu_thread::process_mfc_cmd()
if (rdata == data) if (rdata == data)
{ {
mov_rdata(data.data(), to_write.data()); mov_rdata(data.data(), to_write.data());
res.release(old_time + 2); res.release(old_time + 128);
result = 1; result = 1;
} }
else else
@ -1618,7 +1619,7 @@ bool spu_thread::process_mfc_cmd()
if (raddr) if (raddr)
{ {
// Last check for event before we clear the reservation // Last check for event before we clear the reservation
if (raddr == addr || rtime != (vm::reservation_acquire(raddr, 128) & ~1ull) || rdata != vm::_ref<decltype(rdata)>(raddr)) if (raddr == addr || rtime != (vm::reservation_acquire(raddr, 128) & -128) || rdata != vm::_ref<decltype(rdata)>(raddr))
{ {
ch_event_stat |= SPU_EVENT_LR; ch_event_stat |= SPU_EVENT_LR;
} }
@ -1770,7 +1771,7 @@ u32 spu_thread::get_events(bool waiting)
} }
// Check reservation status and set SPU_EVENT_LR if lost // Check reservation status and set SPU_EVENT_LR if lost
if (raddr && ((vm::reservation_acquire(raddr, sizeof(rdata)) & ~1ull) != rtime || rdata != vm::_ref<decltype(rdata)>(raddr))) if (raddr && ((vm::reservation_acquire(raddr, sizeof(rdata)) & -128) != rtime || rdata != vm::_ref<decltype(rdata)>(raddr)))
{ {
ch_event_stat |= SPU_EVENT_LR; ch_event_stat |= SPU_EVENT_LR;
raddr = 0; raddr = 0;

View file

@ -98,7 +98,7 @@ namespace vm
inline void reservation_update(u32 addr, u32 size, bool lsb = false) inline void reservation_update(u32 addr, u32 size, bool lsb = false)
{ {
// Update reservation info with new timestamp // Update reservation info with new timestamp
reservation_acquire(addr, size) += 2; reservation_acquire(addr, size) += 128;
} }
// Get reservation sync variable // Get reservation sync variable

View file

@ -123,7 +123,7 @@ namespace rsx
{ {
auto& res = vm::reservation_lock(addr, 4); auto& res = vm::reservation_lock(addr, 4);
vm::write32(addr, arg); vm::write32(addr, arg);
res &= ~1ull; res &= -128;
} }
if (addr >> 28 != 0x4) if (addr >> 28 != 0x4)
@ -1018,7 +1018,7 @@ namespace rsx
{ {
temp1.reset(new u8[in_pitch * (in_h - 1) + (in_bpp * in_w)]); temp1.reset(new u8[in_pitch * (in_h - 1) + (in_bpp * in_w)]);
const s32 stride_y = (scale_y < 0 ? -1 : 1) * in_pitch; const s32 stride_y = (scale_y < 0 ? -1 : 1) * in_pitch;
for (u32 y = 0; y < in_h; ++y) for (u32 y = 0; y < in_h; ++y)
{ {