Initial Linux Aarch64 support

* Update asmjit dependency (aarch64 branch)
* Disable USE_DISCORD_RPC by default
* Dump some JIT objects in rpcs3 cache dir
* Add SIGILL handler for all platforms
* Fix resetting zeroing denormals in thread pool
* Refactor most v128:: utils into global gv_** functions
* Refactor PPU interpreter (incomplete), remove "precise"
* - Instruction specializations with multiple accuracy flags
* - Adjust calling convention for speed
* - Removed precise/fast setting, replaced with static
* - Started refactoring interpreters for building at runtime JIT
*   (I got tired of poor compiler optimizations)
* - Expose some accuracy settings (SAT, NJ, VNAN, FPCC)
* - Add exec_bytes PPU thread variable (akin to cycle count)
* PPU LLVM: fix VCTUXS+VCTSXS instruction NaN results
* SPU interpreter: remove "precise" for now (extremely non-portable)
* - As with PPU, settings changed to static/dynamic for interpreters.
* - Precise options will be implemented later
* Fix termination after fatal error dialog
This commit is contained in:
Nekotekina 2021-12-30 19:39:18 +03:00
parent d6aa834b5f
commit 580bd2b25e
89 changed files with 20360 additions and 5612 deletions

View file

@ -684,7 +684,7 @@ namespace vm
// 1. To simplify range_lock logic
// 2. To make sure it never overlaps with 32-bit addresses
// Also check that it's aligned (lowest 16 bits)
ensure((shm_self & 0xffff'8000'0000'ffff) == range_locked);
ensure((shm_self & 0xffff'0000'0000'ffff) == range_locked);
// Find another mirror and map it as shareable too
for (auto& ploc : g_locations)
@ -714,7 +714,7 @@ namespace vm
u64 shm_self = reinterpret_cast<u64>(shm->get()) ^ range_locked;
// Check (see above)
ensure((shm_self & 0xffff'8000'0000'ffff) == range_locked);
ensure((shm_self & 0xffff'0000'0000'ffff) == range_locked);
// Map range as shareable
for (u32 i = addr / 65536; i < addr / 65536 + size / 65536; i++)
@ -1129,13 +1129,16 @@ namespace vm
{
auto fill64 = [](u8* ptr, u64 data, usz count)
{
#ifdef _MSC_VER
#ifdef _M_X64
__stosq(reinterpret_cast<u64*>(ptr), data, count);
#else
#elif defined(ARCH_X64)
__asm__ ("mov %0, %%rdi; mov %1, %%rax; mov %2, %%rcx; rep stosq;"
:
: "r" (ptr), "r" (data), "r" (count)
: "rdi", "rax", "rcx", "memory");
#else
for (usz i = 0; i < count; i++)
reinterpret_cast<u64*>(ptr)[i] = data;
#endif
};

View file

@ -200,16 +200,10 @@ namespace vm
return {};
}
// Unsafe convert host ptr to PS3 VM address (clamp with 4GiB alignment assumption)
inline vm::addr_t get_addr(const void* ptr)
{
const auto [addr, ok] = try_get_addr(ptr);
if (!ok)
{
fmt::throw_exception("Not a virtual memory pointer (%p)", ptr);
}
return addr;
return vm::addr_t{static_cast<u32>(uptr(ptr))};
}
template<typename T>

View file

@ -3,6 +3,7 @@
#include "vm.h"
#include "vm_locking.h"
#include "util/atomic.hpp"
#include "util/tsc.hpp"
#include <functional>
extern bool g_use_rtm;
@ -11,7 +12,6 @@ extern u64 g_rtm_tx_limit2;
#ifdef _MSC_VER
extern "C"
{
u64 __rdtsc();
u32 _xbegin();
void _xend();
}
@ -19,15 +19,6 @@ extern "C"
namespace vm
{
inline u64 get_tsc()
{
#ifdef _MSC_VER
return __rdtsc();
#else
return __builtin_ia32_rdtsc();
#endif
}
enum : u64
{
rsrv_lock_mask = 127,
@ -108,13 +99,14 @@ namespace vm
auto& res = vm::reservation_acquire(addr);
//_m_prefetchw(&res);
#if defined(ARCH_X64)
if (g_use_rtm)
{
// Stage 1: single optimistic transaction attempt
unsigned status = -1;
u64 _old = 0;
auto stamp0 = get_tsc(), stamp1 = stamp0, stamp2 = stamp0;
auto stamp0 = utils::get_tsc(), stamp1 = stamp0, stamp2 = stamp0;
#ifndef _MSC_VER
__asm__ goto ("xbegin %l[stage2];" ::: "memory" : stage2);
@ -176,16 +168,16 @@ namespace vm
#ifndef _MSC_VER
__asm__ volatile ("mov %%eax, %0;" : "=r" (status) :: "memory");
#endif
stamp1 = get_tsc();
stamp1 = utils::get_tsc();
// Stage 2: try to lock reservation first
_old = res.fetch_add(1);
// Compute stamps excluding memory touch
stamp2 = get_tsc() - (stamp1 - stamp0);
stamp2 = utils::get_tsc() - (stamp1 - stamp0);
// Start lightened transaction
for (; !(_old & vm::rsrv_unique_lock) && stamp2 - stamp0 <= g_rtm_tx_limit2; stamp2 = get_tsc())
for (; !(_old & vm::rsrv_unique_lock) && stamp2 - stamp0 <= g_rtm_tx_limit2; stamp2 = utils::get_tsc())
{
if (cpu.has_pause_flag())
{
@ -285,6 +277,9 @@ namespace vm
return result;
}
}
#else
static_cast<void>(cpu);
#endif /* ARCH_X64 */
// Lock reservation and perform heavyweight lock
reservation_shared_lock_internal(res);