mirror of
https://github.com/ARMSX2/ARMSX2.git
synced 2026-08-24 16:50:16 -07:00
Core: ARM64 compatibility
This commit is contained in:
committed by
Connor McLaughlin
parent
7d098674f2
commit
71036c95a4
@@ -954,7 +954,6 @@ set(pcsx2x86Sources
|
||||
x86/ix86-32/iR5900Templates.cpp
|
||||
x86/ix86-32/recVTLB.cpp
|
||||
x86/newVif_Dynarec.cpp
|
||||
x86/newVif_Unpack.cpp
|
||||
x86/newVif_UnpackSSE.cpp
|
||||
)
|
||||
|
||||
@@ -995,7 +994,6 @@ set(pcsx2x86Headers
|
||||
x86/microVU_Tables.inl
|
||||
x86/microVU_Upper.inl
|
||||
x86/newVif.h
|
||||
x86/newVif_HashBucket.h
|
||||
x86/newVif_UnpackSSE.h
|
||||
x86/R5900_Profiler.h
|
||||
)
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include "GS.h"
|
||||
#include "Gif_Unit.h"
|
||||
#include "Vif_Dma.h"
|
||||
#include "x86/iR5900.h"
|
||||
|
||||
// A three-way toggle used to determine if the GIF is stalling (transferring) or done (finished).
|
||||
// Should be a gifstate_t rather then int, but I don't feel like possibly interfering with savestates right now.
|
||||
|
||||
@@ -118,6 +118,22 @@ struct Gif_Tag
|
||||
|
||||
// write out unpacked registers
|
||||
_mm_storeu_si128(reinterpret_cast<__m128i*>(regs), vregs);
|
||||
#elif defined(_M_ARM64)
|
||||
// zero out bits for registers which shouldn't be tested
|
||||
u64 REGS64;
|
||||
std::memcpy(®S64, tag.REGS, sizeof(u64));
|
||||
REGS64 &= (0xFFFFFFFFFFFFFFFFULL >> (64 - nRegs * 4));
|
||||
uint8x16_t vregs = vsetq_lane_u64(REGS64, vdupq_n_u64(0), 0);
|
||||
|
||||
// get upper nibbles, interleave with lower nibbles, clear upper bits from low nibbles
|
||||
vregs = vandq_u8(vzip1q_u8(vregs, vshrq_n_u8(vregs, 4)), vdupq_n_u8(0x0F));
|
||||
|
||||
// compare with GIF_REG_A_D, set hasAD if any lanes passed
|
||||
const uint8x16_t comp = vceqq_u8(vregs, vdupq_n_u8(GIF_REG_A_D));
|
||||
hasAD = vmaxvq_u8(comp) & 1;
|
||||
|
||||
// write out unpacked registers
|
||||
vst1q_u8(regs, vregs);
|
||||
#else
|
||||
// Reference C implementation.
|
||||
hasAD = false;
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include "R3000A.h"
|
||||
#include "R5900.h"
|
||||
#include "ps2/BiosTools.h"
|
||||
#include "x86/iR3000A.h"
|
||||
#include "VMManager.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include "IopHw.h"
|
||||
#include "Mdec.h"
|
||||
#include "R3000A.h"
|
||||
#include "x86/iR5900.h"
|
||||
|
||||
// NOTE: Any modifications to read/write fns should also go into their const counterparts
|
||||
// found in iPsxHw.cpp.
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ const uptr *psxMemRLUT = nullptr;
|
||||
|
||||
IopVM_MemoryAllocMess* iopMem = nullptr;
|
||||
|
||||
alignas(__pagesize) u8 iopHw[Ps2MemSize::IopHardware];
|
||||
alignas(__pagealignsize) u8 iopHw[Ps2MemSize::IopHardware];
|
||||
|
||||
void iopMemAlloc()
|
||||
{
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
#include "Gif_Unit.h"
|
||||
#include "MTVU.h"
|
||||
#include "VMManager.h"
|
||||
#include "x86/newVif.h"
|
||||
#include "Vif_Dynarec.h"
|
||||
|
||||
#include <thread>
|
||||
|
||||
|
||||
+8
-3
@@ -98,7 +98,7 @@ u8* SysMemory::TryAllocateVirtualMemory(const char* name, void* file_handle, upt
|
||||
if (!baseptr)
|
||||
return nullptr;
|
||||
|
||||
if ((uptr)baseptr != base)
|
||||
if (base != 0 && (uptr)baseptr != base)
|
||||
{
|
||||
if (file_handle)
|
||||
{
|
||||
@@ -122,6 +122,8 @@ u8* SysMemory::TryAllocateVirtualMemory(const char* name, void* file_handle, upt
|
||||
|
||||
u8* SysMemory::AllocateVirtualMemory(const char* name, void* file_handle, size_t size, size_t offset_from_base)
|
||||
{
|
||||
// ARM64 does not need the rec areas to be in +/- 2GB.
|
||||
#ifdef _M_X86
|
||||
pxAssertRel(Common::IsAlignedPow2(size, __pagesize), "Virtual memory size is page aligned");
|
||||
|
||||
// Everything looks nicer when the start of all the sections is a nice round looking number.
|
||||
@@ -148,6 +150,9 @@ u8* SysMemory::AllocateVirtualMemory(const char* name, void* file_handle, size_t
|
||||
DevCon.Warning("%s: host memory @ 0x%016" PRIXPTR " -> 0x%016" PRIXPTR " is unavailable; attempting to map elsewhere...", name,
|
||||
base, base + size);
|
||||
}
|
||||
#else
|
||||
return TryAllocateVirtualMemory(name, file_handle, 0, size);
|
||||
#endif
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
@@ -986,8 +991,8 @@ void memClearPageAddr(u32 vaddr)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// PS2 Memory Init / Reset / Shutdown
|
||||
|
||||
EEVM_MemoryAllocMess* eeMem = NULL;
|
||||
alignas(__pagesize) u8 eeHw[Ps2MemSize::Hardware];
|
||||
EEVM_MemoryAllocMess* eeMem = nullptr;
|
||||
alignas(__pagealignsize) u8 eeHw[Ps2MemSize::Hardware];
|
||||
|
||||
|
||||
void memBindConditionalHandlers()
|
||||
|
||||
+2
-2
@@ -59,8 +59,8 @@ struct IopVM_MemoryAllocMess
|
||||
// order to allow for simpler macros and reference handles to be defined (we can safely use
|
||||
// compile-time references to registers instead of having to use instance variables).
|
||||
|
||||
alignas(__pagesize) extern u8 eeHw[Ps2MemSize::Hardware];
|
||||
alignas(__pagesize) extern u8 iopHw[Ps2MemSize::IopHardware];
|
||||
alignas(__pagealignsize) extern u8 eeHw[Ps2MemSize::Hardware];
|
||||
alignas(__pagealignsize) extern u8 iopHw[Ps2MemSize::IopHardware];
|
||||
|
||||
|
||||
extern EEVM_MemoryAllocMess* eeMem;
|
||||
|
||||
+1
-2
@@ -34,8 +34,7 @@ using namespace R5900; // for R5900 disasm tools
|
||||
s32 EEsCycle; // used to sync the IOP to the EE
|
||||
u32 EEoCycle;
|
||||
|
||||
alignas(16) cpuRegisters cpuRegs;
|
||||
alignas(16) fpuRegisters fpuRegs;
|
||||
alignas(16) cpuRegistersPack _cpuRegistersPack;
|
||||
alignas(16) tlbs tlb[48];
|
||||
R5900cpu *Cpu = NULL;
|
||||
|
||||
|
||||
+10
-2
@@ -202,10 +202,18 @@ struct tlbs
|
||||
|
||||
#endif
|
||||
|
||||
alignas(16) extern cpuRegisters cpuRegs;
|
||||
alignas(16) extern fpuRegisters fpuRegs;
|
||||
struct cpuRegistersPack
|
||||
{
|
||||
alignas(16) cpuRegisters cpuRegs;
|
||||
alignas(16) fpuRegisters fpuRegs;
|
||||
};
|
||||
|
||||
alignas(16) extern cpuRegistersPack _cpuRegistersPack;
|
||||
alignas(16) extern tlbs tlb[48];
|
||||
|
||||
static cpuRegisters& cpuRegs = _cpuRegistersPack.cpuRegs;
|
||||
static fpuRegisters& fpuRegs = _cpuRegistersPack.fpuRegs;
|
||||
|
||||
extern bool eeEventTestIsActive;
|
||||
|
||||
void intUpdateCPUCycles();
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@
|
||||
|
||||
#include "DebugTools/Debug.h"
|
||||
#include "R3000A.h"
|
||||
#include "x86/iR5900.h"
|
||||
#include "R5900.h"
|
||||
|
||||
#include "fmt/core.h"
|
||||
|
||||
|
||||
+34
-4
@@ -38,6 +38,7 @@
|
||||
#include "SIO/Sio2.h"
|
||||
#include "SPU2/spu2.h"
|
||||
#include "USB/USB.h"
|
||||
#include "Vif_Dynarec.h"
|
||||
#include "VMManager.h"
|
||||
#include "ps2/BiosTools.h"
|
||||
#include "svnrev.h"
|
||||
@@ -76,10 +77,6 @@
|
||||
#include "common/Darwin/DarwinMisc.h"
|
||||
#endif
|
||||
|
||||
#ifdef _M_X86
|
||||
#include "x86/newVif.h"
|
||||
#endif
|
||||
|
||||
namespace VMManager
|
||||
{
|
||||
static void SetDefaultLoggingSettings(SettingsInterface& si);
|
||||
@@ -230,6 +227,14 @@ bool VMManager::PerformEarlyHardwareChecks(const char** error)
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
#elif defined(_M_ARM64)
|
||||
// Check page size. If it doesn't match, it is a fatal error.
|
||||
const size_t runtime_host_page_size = HostSys::GetRuntimePageSize();
|
||||
if (__pagesize != runtime_host_page_size)
|
||||
{
|
||||
*error = "Page size mismatch. This build cannot run on your Mac.\n\n" COMMON_DOWNLOAD_MESSAGE;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef COMMON_DOWNLOAD_MESSAGE
|
||||
@@ -2502,6 +2507,7 @@ void VMManager::LogCPUCapabilities()
|
||||
LogUserPowerPlan();
|
||||
#endif
|
||||
|
||||
#ifdef _M_X86
|
||||
std::string features;
|
||||
if (cpuinfo_has_x86_avx())
|
||||
features += "AVX ";
|
||||
@@ -2513,6 +2519,18 @@ void VMManager::LogCPUCapabilities()
|
||||
Console.WriteLn(Color_StrongBlack, "x86 Features Detected:");
|
||||
Console.WriteLnFmt(" {}", features);
|
||||
Console.WriteLn();
|
||||
#endif
|
||||
|
||||
#ifdef _M_ARM64
|
||||
const size_t runtime_cache_line_size = HostSys::GetRuntimeCacheLineSize();
|
||||
if (__cachelinesize != runtime_cache_line_size)
|
||||
{
|
||||
// Not fatal, but does have performance implications.
|
||||
WARNING_LOG(
|
||||
"Cache line size mismatch. This build was compiled with {} byte lines, but the system has {} byte lines.",
|
||||
__cachelinesize, runtime_cache_line_size);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
LogGPUCapabilities();
|
||||
@@ -3197,6 +3215,8 @@ void VMManager::WarnAboutUnsafeSettings()
|
||||
append(ICON_FA_EXCLAMATION_CIRCLE,
|
||||
TRANSLATE_SV("VMManager", "INTC Spin Detection is not enabled, this may reduce performance."));
|
||||
}
|
||||
if (!EmuConfig.Cpu.Recompiler.EnableFastmem)
|
||||
append(ICON_FA_EXCLAMATION_CIRCLE, TRANSLATE_SV("VMManager", "Fastmem is not enabled, this will reduce performance."));
|
||||
if (!EmuConfig.Speedhacks.vu1Instant)
|
||||
{
|
||||
append(ICON_FA_EXCLAMATION_CIRCLE,
|
||||
@@ -3322,6 +3342,12 @@ static u32 GetProcessorIdForProcessor(const cpuinfo_processor* proc)
|
||||
|
||||
static void InitializeProcessorList()
|
||||
{
|
||||
if (!cpuinfo_initialize())
|
||||
{
|
||||
Console.Error("cpuinfo_initialize() failed");
|
||||
return;
|
||||
}
|
||||
|
||||
const u32 cluster_count = cpuinfo_get_clusters_count();
|
||||
if (cluster_count == 0)
|
||||
{
|
||||
@@ -3448,6 +3474,10 @@ static void InitializeProcessorList()
|
||||
|
||||
static void SetMTVUAndAffinityControlDefault(SettingsInterface& si)
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
// Everything we support Mac-wise has enough cores for MTVU.
|
||||
si.SetBoolValue("EmuCore/Speedhacks", "vuThread", true);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -29,6 +29,8 @@ static __fi void vu0SetMicroFlags(u32* flags, u32 value)
|
||||
{
|
||||
#ifdef _M_X86
|
||||
_mm_store_si128(reinterpret_cast<__m128i*>(flags), _mm_set1_epi32(value));
|
||||
#elif defined(_M_ARM64)
|
||||
vst1q_u32(flags, vdupq_n_u32(value));
|
||||
#else
|
||||
flags[0] = flags[1] = flags[2] = flags[3] = value;
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@
|
||||
#include "MTVU.h"
|
||||
#include "Vif.h"
|
||||
#include "Vif_Dma.h"
|
||||
#include "x86/newVif.h"
|
||||
#include "Vif_Dynarec.h"
|
||||
|
||||
alignas(16) vifStruct vif0, vif1;
|
||||
|
||||
|
||||
+1
-1
@@ -3,8 +3,8 @@
|
||||
|
||||
#include "Common.h"
|
||||
#include "Vif_Dma.h"
|
||||
#include "Vif_Dynarec.h"
|
||||
#include "VUmicro.h"
|
||||
#include "x86/newVif.h"
|
||||
|
||||
u32 g_vif0Cycles = 0;
|
||||
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
#include "MTVU.h"
|
||||
#include "VUmicro.h"
|
||||
#include "Vif_Dma.h"
|
||||
#include "x86/newVif.h"
|
||||
#include "Vif_Dynarec.h"
|
||||
|
||||
u32 g_vif1Cycles = 0;
|
||||
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
#include "MTVU.h"
|
||||
#include "VUmicro.h"
|
||||
#include "Vif_Dma.h"
|
||||
#include "x86/newVif.h"
|
||||
#include "Vif_Dynarec.h"
|
||||
|
||||
#define vifOp(vifCodeName) _vifT int vifCodeName(int pass, const u32* data)
|
||||
#define pass1 if (pass == 0)
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
// SPDX-FileCopyrightText: 2002-2023 PCSX2 Dev Team
|
||||
// SPDX-License-Identifier: LGPL-3.0+
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Vif.h"
|
||||
#include "Vif_HashBucket.h"
|
||||
#include "VU.h"
|
||||
|
||||
typedef u32 (*nVifCall)(void*, const void*);
|
||||
typedef void (*nVifrecCall)(uptr dest, uptr src);
|
||||
|
||||
extern void _nVifUnpack(int idx, const u8* data, uint mode, bool isFill);
|
||||
extern void dVifReset(int idx);
|
||||
extern void dVifRelease(int idx);
|
||||
extern void VifUnpackSSE_Init();
|
||||
|
||||
_vifT extern void dVifUnpack(const u8* data, bool isFill);
|
||||
|
||||
struct nVifStruct
|
||||
{
|
||||
// Buffer for partial transfers (should always be first to ensure alignment)
|
||||
// Maximum buffer size is 256 (vifRegs.Num max range) * 16 (quadword)
|
||||
alignas(16) u8 buffer[256*16];
|
||||
u32 bSize; // Size of 'buffer'
|
||||
|
||||
// VIF0 or VIF1 - provided for debugging helpfulness only, and is generally unused.
|
||||
// (templates are used for most or all VIF indexing)
|
||||
u32 idx;
|
||||
|
||||
u8* recWritePtr; // current write pos into the reserve
|
||||
u8* recEndPtr;
|
||||
|
||||
HashBucket vifBlocks; // Vif Blocks
|
||||
|
||||
|
||||
nVifStruct() = default;
|
||||
};
|
||||
|
||||
extern void resetNewVif(int idx);
|
||||
|
||||
alignas(16) extern nVifStruct nVif[2];
|
||||
alignas(16) extern nVifCall nVifUpk[(2 * 2 * 16) * 4]; // ([USN][Masking][Unpack Type]) [curCycle]
|
||||
alignas(16) extern u32 nVifMask[3][4][4]; // [MaskNumber][CycleNumber][Vector]
|
||||
|
||||
static constexpr bool newVifDynaRec = 1; // Use code in newVif_Dynarec.inl
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user