mirror of
https://github.com/izzy2lost/PCSX2_ARM64.git
synced 2026-06-19 10:16:23 -07:00
Android project - Add vtlbDef.h
This commit is contained in:
@@ -57,7 +57,6 @@ namespace a64 = vixl::aarch64;
|
||||
|
||||
// fastmem
|
||||
#define RFASTMEMBASE a64::x25
|
||||
#define PTR_MBLOCK(field) a64::MemOperand(RFASTMEMBASE, offsetof(microBlock, field))
|
||||
|
||||
#define RSTATE_x26 a64::x26
|
||||
|
||||
@@ -70,9 +69,8 @@ namespace a64 = vixl::aarch64;
|
||||
#define RSTATE_MVU a64::x28
|
||||
#define PTR_MVU(field) a64::MemOperand(RSTATE_MVU, offsetof(vuRegistersPack, field))
|
||||
|
||||
// iopMem->Main, vu1Thread
|
||||
// iopMem->Main
|
||||
#define RSTATE_x29 a64::x29
|
||||
#define PTR_VU1(field) a64::MemOperand(RSTATE_x29, offsetof(VU_Thread, field))
|
||||
|
||||
static inline s64 GetPCDisplacement(const void* current, const void* target)
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
#include <thread>
|
||||
|
||||
VU_Thread vu1Thread;
|
||||
//VU_Thread vu1Thread;
|
||||
|
||||
#define MTVU_ALWAYS_KICK 0
|
||||
#define MTVU_SYNC_MODE 0
|
||||
|
||||
@@ -120,4 +120,4 @@ private:
|
||||
u32 Get_vuCycles();
|
||||
};
|
||||
|
||||
extern VU_Thread vu1Thread;
|
||||
extern VU_Thread& vu1Thread;
|
||||
|
||||
@@ -34,7 +34,7 @@ using namespace R5900; // for R5900 disasm tools
|
||||
s32 EEsCycle; // used to sync the IOP to the EE
|
||||
u32 EEoCycle;
|
||||
|
||||
alignas(32) cpuRegistersPack g_cpuRegistersPack;
|
||||
alignas(64) cpuRegistersPack g_cpuRegistersPack;
|
||||
alignas(16) tlbs tlb[48];
|
||||
cachedTlbs_t cachedTlbs;
|
||||
|
||||
|
||||
@@ -8,25 +8,25 @@
|
||||
#include "R5900Def.h"
|
||||
#include "R3000ADef.h"
|
||||
#include "VUDef.h"
|
||||
#include "vtlbDef.h"
|
||||
|
||||
struct cpuRegistersPack
|
||||
{
|
||||
alignas(16) cpuRegisters cpuRegs{};
|
||||
alignas(16) fpuRegisters fpuRegs{};
|
||||
alignas(16) psxRegisters psxRegs{};
|
||||
alignas(16) VIFregisters vifRegs[2]{};
|
||||
alignas(16) VURegs vuRegs[2];
|
||||
alignas(16) VIFregisters vifRegs[2];
|
||||
alignas(16) mVU_SSE4 mVUss4;
|
||||
alignas(32) mVU_Globals mVUglob;
|
||||
alignas(64) vtlb_private::MapData vtlbdata;
|
||||
};
|
||||
alignas(32) extern cpuRegistersPack g_cpuRegistersPack;
|
||||
alignas(64) extern cpuRegistersPack g_cpuRegistersPack;
|
||||
////
|
||||
static cpuRegisters& cpuRegs = g_cpuRegistersPack.cpuRegs;
|
||||
static fpuRegisters& fpuRegs = g_cpuRegistersPack.fpuRegs;
|
||||
static psxRegisters& psxRegs = g_cpuRegistersPack.psxRegs;
|
||||
static VURegs& VU0 = g_cpuRegistersPack.vuRegs[0];
|
||||
static VURegs& VU1 = g_cpuRegistersPack.vuRegs[1];
|
||||
static mVU_SSE4& mVUClamp = g_cpuRegistersPack.mVUss4;
|
||||
static mVU_Globals& mVUglob = g_cpuRegistersPack.mVUglob;
|
||||
|
||||
#endif //PCSX2_CPUREGISTERSPACK_H
|
||||
|
||||
@@ -44,7 +44,7 @@ using namespace vtlb_private;
|
||||
|
||||
namespace vtlb_private
|
||||
{
|
||||
alignas(64) MapData vtlbdata;
|
||||
MapData& vtlbdata = g_cpuRegistersPack.vtlbdata;
|
||||
} // namespace vtlb_private
|
||||
|
||||
static vtlbHandler vtlbHandlerCount = 0;
|
||||
|
||||
@@ -3,42 +3,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "MemoryTypes.h"
|
||||
|
||||
#include "vtlbDef.h"
|
||||
#include "common/HostSys.h"
|
||||
#include "common/SingleRegisterTypes.h"
|
||||
|
||||
static const uptr VTLB_AllocUpperBounds = _1gb * 2;
|
||||
|
||||
// Specialized function pointers for each read type
|
||||
typedef mem8_t vtlbMemR8FP(u32 addr);
|
||||
typedef mem16_t vtlbMemR16FP(u32 addr);
|
||||
typedef mem32_t vtlbMemR32FP(u32 addr);
|
||||
typedef mem64_t vtlbMemR64FP(u32 addr);
|
||||
typedef RETURNS_R128 vtlbMemR128FP(u32 addr);
|
||||
|
||||
// Specialized function pointers for each write type
|
||||
typedef void vtlbMemW8FP(u32 addr,mem8_t data);
|
||||
typedef void vtlbMemW16FP(u32 addr,mem16_t data);
|
||||
typedef void vtlbMemW32FP(u32 addr,mem32_t data);
|
||||
typedef void vtlbMemW64FP(u32 addr,mem64_t data);
|
||||
typedef void TAKES_R128 vtlbMemW128FP(u32 addr,r128 data);
|
||||
|
||||
template <size_t Width, bool Write> struct vtlbMemFP;
|
||||
|
||||
template<> struct vtlbMemFP< 8, false> { typedef vtlbMemR8FP fn; static const uptr Index = 0; };
|
||||
template<> struct vtlbMemFP< 16, false> { typedef vtlbMemR16FP fn; static const uptr Index = 1; };
|
||||
template<> struct vtlbMemFP< 32, false> { typedef vtlbMemR32FP fn; static const uptr Index = 2; };
|
||||
template<> struct vtlbMemFP< 64, false> { typedef vtlbMemR64FP fn; static const uptr Index = 3; };
|
||||
template<> struct vtlbMemFP<128, false> { typedef vtlbMemR128FP fn; static const uptr Index = 4; };
|
||||
template<> struct vtlbMemFP< 8, true> { typedef vtlbMemW8FP fn; static const uptr Index = 0; };
|
||||
template<> struct vtlbMemFP< 16, true> { typedef vtlbMemW16FP fn; static const uptr Index = 1; };
|
||||
template<> struct vtlbMemFP< 32, true> { typedef vtlbMemW32FP fn; static const uptr Index = 2; };
|
||||
template<> struct vtlbMemFP< 64, true> { typedef vtlbMemW64FP fn; static const uptr Index = 3; };
|
||||
template<> struct vtlbMemFP<128, true> { typedef vtlbMemW128FP fn; static const uptr Index = 4; };
|
||||
|
||||
typedef u32 vtlbHandler;
|
||||
|
||||
extern bool vtlb_Core_Alloc();
|
||||
extern void vtlb_Core_Free();
|
||||
extern void vtlb_Alloc_Ppmap();
|
||||
@@ -115,111 +84,6 @@ extern void vtlb_DynGenWrite_Const(u32 bits, bool xmm, u32 addr_const, int value
|
||||
|
||||
extern void vtlb_DynGenDispatchers();
|
||||
|
||||
namespace vtlb_private
|
||||
{
|
||||
static const uint VTLB_PAGE_BITS = 12;
|
||||
static const uint VTLB_PAGE_MASK = 4095;
|
||||
static const uint VTLB_PAGE_SIZE = 4096;
|
||||
|
||||
static const uint VTLB_PMAP_SZ = _1mb * 512;
|
||||
static const uint VTLB_PMAP_ITEMS = VTLB_PMAP_SZ / VTLB_PAGE_SIZE;
|
||||
static const uint VTLB_VMAP_ITEMS = _4gb / VTLB_PAGE_SIZE;
|
||||
|
||||
static const uint VTLB_HANDLER_ITEMS = 128;
|
||||
|
||||
static const uptr POINTER_SIGN_BIT = 1ULL << (sizeof(uptr) * 8 - 1);
|
||||
|
||||
struct VTLBPhysical
|
||||
{
|
||||
private:
|
||||
sptr value;
|
||||
explicit VTLBPhysical(sptr value): value(value) { }
|
||||
public:
|
||||
VTLBPhysical(): value(0) {}
|
||||
/// Create from a pointer to raw memory
|
||||
static VTLBPhysical fromPointer(void *ptr) { return fromPointer((sptr)ptr); }
|
||||
/// Create from an integer representing a pointer to raw memory
|
||||
static VTLBPhysical fromPointer(sptr ptr);
|
||||
/// Create from a handler and address
|
||||
static VTLBPhysical fromHandler(vtlbHandler handler);
|
||||
|
||||
/// Get the raw value held by the entry
|
||||
uptr raw() const { return value; }
|
||||
/// Returns whether or not this entry is a handler
|
||||
bool isHandler() const { return value < 0; }
|
||||
/// Assumes the entry is a pointer, giving back its value
|
||||
uptr assumePtr() const { return value; }
|
||||
/// Assumes the entry is a handler, and gets the raw handler ID
|
||||
u8 assumeHandler() const { return value; }
|
||||
};
|
||||
|
||||
struct VTLBVirtual
|
||||
{
|
||||
private:
|
||||
uptr value;
|
||||
explicit VTLBVirtual(uptr value): value(value) { }
|
||||
public:
|
||||
VTLBVirtual(): value(0) {}
|
||||
VTLBVirtual(VTLBPhysical phys, u32 paddr, u32 vaddr);
|
||||
static VTLBVirtual fromPointer(uptr ptr, u32 vaddr) {
|
||||
return VTLBVirtual(VTLBPhysical::fromPointer(ptr), 0, vaddr);
|
||||
}
|
||||
|
||||
/// Get the raw value held by the entry
|
||||
uptr raw() const { return value; }
|
||||
/// Returns whether or not this entry is a handler
|
||||
bool isHandler(u32 vaddr) const { return (sptr)(value + vaddr) < 0; }
|
||||
/// Assumes the entry is a pointer, giving back its value
|
||||
uptr assumePtr(u32 vaddr) const { return value + vaddr; }
|
||||
/// Assumes the entry is a handler, and gets the raw handler ID
|
||||
u8 assumeHandlerGetID() const { return value; }
|
||||
/// Assumes the entry is a handler, and gets the physical address
|
||||
u32 assumeHandlerGetPAddr(u32 vaddr) const { return (value + vaddr - assumeHandlerGetID()) & ~POINTER_SIGN_BIT; }
|
||||
/// Assumes the entry is a handler, returning it as a void*
|
||||
void *assumeHandlerGetRaw(int index, bool write) const;
|
||||
/// Assumes the entry is a handler, returning it
|
||||
template <size_t Width, bool Write>
|
||||
typename vtlbMemFP<Width, Write>::fn *assumeHandler() const;
|
||||
};
|
||||
|
||||
struct MapData
|
||||
{
|
||||
// first indexer -- 8/16/32/64/128 bit tables [values 0-4]
|
||||
// second indexer -- read/write [0 or 1]
|
||||
// third indexer -- 128 possible handlers!
|
||||
void* RWFT[5][2][VTLB_HANDLER_ITEMS];
|
||||
|
||||
VTLBPhysical pmap[VTLB_PMAP_ITEMS]; //512KB // PS2 physical to x86 physical
|
||||
|
||||
VTLBVirtual* vmap; //4MB (allocated by vtlb_init) // PS2 virtual to x86 physical
|
||||
|
||||
u32* ppmap; //4MB (allocated by vtlb_init) // PS2 virtual to PS2 physical
|
||||
|
||||
uptr fastmem_base;
|
||||
|
||||
MapData()
|
||||
{
|
||||
vmap = NULL;
|
||||
ppmap = NULL;
|
||||
fastmem_base = 0;
|
||||
}
|
||||
};
|
||||
|
||||
alignas(64) extern MapData vtlbdata;
|
||||
|
||||
inline void *VTLBVirtual::assumeHandlerGetRaw(int index, bool write) const
|
||||
{
|
||||
return vtlbdata.RWFT[index][write][assumeHandlerGetID()];
|
||||
}
|
||||
|
||||
template <size_t Width, bool Write>
|
||||
typename vtlbMemFP<Width, Write>::fn *VTLBVirtual::assumeHandler() const
|
||||
{
|
||||
using FP = vtlbMemFP<Width, Write>;
|
||||
return (typename FP::fn *)assumeHandlerGetRaw(FP::Index, Write);
|
||||
}
|
||||
}
|
||||
|
||||
enum vtlb_ProtectionMode
|
||||
{
|
||||
ProtMode_None = 0, // page is 'unaccounted' -- neither protected nor unprotected
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
//
|
||||
// Created by k2154 on 2025-08-18.
|
||||
//
|
||||
|
||||
#ifndef PCSX2_VTLBDEF_H
|
||||
#define PCSX2_VTLBDEF_H
|
||||
|
||||
#include "MemoryTypes.h"
|
||||
#include "common/SingleRegisterTypes.h"
|
||||
|
||||
// Specialized function pointers for each read type
|
||||
typedef mem8_t vtlbMemR8FP(u32 addr);
|
||||
typedef mem16_t vtlbMemR16FP(u32 addr);
|
||||
typedef mem32_t vtlbMemR32FP(u32 addr);
|
||||
typedef mem64_t vtlbMemR64FP(u32 addr);
|
||||
typedef RETURNS_R128 vtlbMemR128FP(u32 addr);
|
||||
|
||||
// Specialized function pointers for each write type
|
||||
typedef void vtlbMemW8FP(u32 addr,mem8_t data);
|
||||
typedef void vtlbMemW16FP(u32 addr,mem16_t data);
|
||||
typedef void vtlbMemW32FP(u32 addr,mem32_t data);
|
||||
typedef void vtlbMemW64FP(u32 addr,mem64_t data);
|
||||
typedef void TAKES_R128 vtlbMemW128FP(u32 addr,r128 data);
|
||||
|
||||
template <size_t Width, bool Write> struct vtlbMemFP;
|
||||
|
||||
template<> struct vtlbMemFP< 8, false> { typedef vtlbMemR8FP fn; static const uptr Index = 0; };
|
||||
template<> struct vtlbMemFP< 16, false> { typedef vtlbMemR16FP fn; static const uptr Index = 1; };
|
||||
template<> struct vtlbMemFP< 32, false> { typedef vtlbMemR32FP fn; static const uptr Index = 2; };
|
||||
template<> struct vtlbMemFP< 64, false> { typedef vtlbMemR64FP fn; static const uptr Index = 3; };
|
||||
template<> struct vtlbMemFP<128, false> { typedef vtlbMemR128FP fn; static const uptr Index = 4; };
|
||||
template<> struct vtlbMemFP< 8, true> { typedef vtlbMemW8FP fn; static const uptr Index = 0; };
|
||||
template<> struct vtlbMemFP< 16, true> { typedef vtlbMemW16FP fn; static const uptr Index = 1; };
|
||||
template<> struct vtlbMemFP< 32, true> { typedef vtlbMemW32FP fn; static const uptr Index = 2; };
|
||||
template<> struct vtlbMemFP< 64, true> { typedef vtlbMemW64FP fn; static const uptr Index = 3; };
|
||||
template<> struct vtlbMemFP<128, true> { typedef vtlbMemW128FP fn; static const uptr Index = 4; };
|
||||
|
||||
typedef u32 vtlbHandler;
|
||||
|
||||
namespace vtlb_private
|
||||
{
|
||||
static const uint VTLB_PAGE_BITS = 12;
|
||||
static const uint VTLB_PAGE_MASK = 4095;
|
||||
static const uint VTLB_PAGE_SIZE = 4096;
|
||||
|
||||
static const uint VTLB_PMAP_SZ = _1mb * 512;
|
||||
static const uint VTLB_PMAP_ITEMS = VTLB_PMAP_SZ / VTLB_PAGE_SIZE;
|
||||
static const uint VTLB_VMAP_ITEMS = _4gb / VTLB_PAGE_SIZE;
|
||||
|
||||
static const uint VTLB_HANDLER_ITEMS = 128;
|
||||
|
||||
static const uptr POINTER_SIGN_BIT = 1ULL << (sizeof(uptr) * 8 - 1);
|
||||
|
||||
struct VTLBPhysical
|
||||
{
|
||||
private:
|
||||
sptr value;
|
||||
explicit VTLBPhysical(sptr value): value(value) { }
|
||||
public:
|
||||
VTLBPhysical(): value(0) {}
|
||||
/// Create from a pointer to raw memory
|
||||
static VTLBPhysical fromPointer(void *ptr) { return fromPointer((sptr)ptr); }
|
||||
/// Create from an integer representing a pointer to raw memory
|
||||
static VTLBPhysical fromPointer(sptr ptr);
|
||||
/// Create from a handler and address
|
||||
static VTLBPhysical fromHandler(vtlbHandler handler);
|
||||
|
||||
/// Get the raw value held by the entry
|
||||
uptr raw() const { return value; }
|
||||
/// Returns whether or not this entry is a handler
|
||||
bool isHandler() const { return value < 0; }
|
||||
/// Assumes the entry is a pointer, giving back its value
|
||||
uptr assumePtr() const { return value; }
|
||||
/// Assumes the entry is a handler, and gets the raw handler ID
|
||||
u8 assumeHandler() const { return value; }
|
||||
};
|
||||
|
||||
struct VTLBVirtual
|
||||
{
|
||||
public:
|
||||
uptr value;
|
||||
explicit VTLBVirtual(uptr value): value(value) { }
|
||||
public:
|
||||
VTLBVirtual(): value(0) {}
|
||||
VTLBVirtual(VTLBPhysical phys, u32 paddr, u32 vaddr);
|
||||
static VTLBVirtual fromPointer(uptr ptr, u32 vaddr) {
|
||||
return VTLBVirtual(VTLBPhysical::fromPointer(ptr), 0, vaddr);
|
||||
}
|
||||
|
||||
/// Get the raw value held by the entry
|
||||
uptr raw() const { return value; }
|
||||
/// Returns whether or not this entry is a handler
|
||||
bool isHandler(u32 vaddr) const { return (sptr)(value + vaddr) < 0; }
|
||||
/// Assumes the entry is a pointer, giving back its value
|
||||
uptr assumePtr(u32 vaddr) const { return value + vaddr; }
|
||||
/// Assumes the entry is a handler, and gets the raw handler ID
|
||||
u8 assumeHandlerGetID() const { return value; }
|
||||
/// Assumes the entry is a handler, and gets the physical address
|
||||
u32 assumeHandlerGetPAddr(u32 vaddr) const { return (value + vaddr - assumeHandlerGetID()) & ~POINTER_SIGN_BIT; }
|
||||
/// Assumes the entry is a handler, returning it as a void*
|
||||
void *assumeHandlerGetRaw(int index, bool write) const;
|
||||
/// Assumes the entry is a handler, returning it
|
||||
template <size_t Width, bool Write>
|
||||
typename vtlbMemFP<Width, Write>::fn *assumeHandler() const;
|
||||
};
|
||||
|
||||
struct MapData
|
||||
{
|
||||
// first indexer -- 8/16/32/64/128 bit tables [values 0-4]
|
||||
// second indexer -- read/write [0 or 1]
|
||||
// third indexer -- 128 possible handlers!
|
||||
void* RWFT[5][2][VTLB_HANDLER_ITEMS];
|
||||
|
||||
VTLBPhysical pmap[VTLB_PMAP_ITEMS]; //512KB // PS2 physical to x86 physical
|
||||
|
||||
VTLBVirtual* vmap; //4MB (allocated by vtlb_init) // PS2 virtual to x86 physical
|
||||
|
||||
u32* ppmap; //4MB (allocated by vtlb_init) // PS2 virtual to PS2 physical
|
||||
|
||||
uptr fastmem_base;
|
||||
|
||||
MapData()
|
||||
{
|
||||
vmap = NULL;
|
||||
ppmap = NULL;
|
||||
fastmem_base = 0;
|
||||
}
|
||||
};
|
||||
|
||||
extern MapData& vtlbdata;
|
||||
|
||||
inline void *VTLBVirtual::assumeHandlerGetRaw(int index, bool write) const
|
||||
{
|
||||
return vtlbdata.RWFT[index][write][assumeHandlerGetID()];
|
||||
}
|
||||
|
||||
template <size_t Width, bool Write>
|
||||
typename vtlbMemFP<Width, Write>::fn *VTLBVirtual::assumeHandler() const
|
||||
{
|
||||
using FP = vtlbMemFP<Width, Write>;
|
||||
return (typename FP::fn *)assumeHandlerGetRaw(FP::Index, Write);
|
||||
}
|
||||
}
|
||||
|
||||
#endif //PCSX2_VTLBDEF_H
|
||||
@@ -493,7 +493,7 @@ static const void* _DynGen_EnterRecompiledCode()
|
||||
|
||||
if (CHECK_FASTMEM) {
|
||||
// xMOV(RFASTMEMBASE, ptrNative[&vtlb_private::vtlbdata.fastmem_base]);
|
||||
armAsm->Ldr(RFASTMEMBASE, armMemOperandPtr(&vtlb_private::vtlbdata.fastmem_base));
|
||||
armAsm->Ldr(RFASTMEMBASE, PTR_CPU(vtlbdata.fastmem_base));
|
||||
}
|
||||
|
||||
// xJMP(DispatcherReg);
|
||||
|
||||
@@ -166,7 +166,8 @@ namespace vtlb_private
|
||||
// xSHR(eax, VTLB_PAGE_BITS);
|
||||
armAsm->Lsr(EAX, EAX, VTLB_PAGE_BITS);
|
||||
// xMOV(rax, ptrNative[xComplexAddress(arg3reg, vtlbdata.vmap, rax * wordsize)]);
|
||||
armMoveAddressToReg(RXVIXLSCRATCH, vtlbdata.vmap);
|
||||
// armMoveAddressToReg(RXVIXLSCRATCH, vtlbdata.vmap);
|
||||
armAsm->Ldr(RXVIXLSCRATCH, PTR_CPU(vtlbdata.vmap));
|
||||
armAsm->Ldr(RAX, a64::MemOperand(RXVIXLSCRATCH, RAX, a64::LSL, 3));
|
||||
// xADD(arg1reg, rax);
|
||||
armAsm->Adds(RCX, RCX, RAX);
|
||||
@@ -177,49 +178,50 @@ namespace vtlb_private
|
||||
{
|
||||
pxAssert(bits == 8 || bits == 16 || bits == 32 || bits == 64 || bits == 128);
|
||||
|
||||
auto mop = a64::MemOperand(RCX);
|
||||
switch (bits)
|
||||
{
|
||||
case 8:
|
||||
if (sign) {
|
||||
// xMOVSX(rax, ptr8[arg1reg]);
|
||||
armAsm->Ldrsb(RAX, a64::MemOperand(RCX));
|
||||
armAsm->Ldrsb(RAX, mop);
|
||||
}
|
||||
else {
|
||||
// xMOVZX(rax, ptr8[arg1reg]);
|
||||
armAsm->Ldrb(RAX, a64::MemOperand(RCX));
|
||||
armAsm->Ldrb(RAX, mop);
|
||||
}
|
||||
break;
|
||||
|
||||
case 16:
|
||||
if (sign) {
|
||||
// xMOVSX(rax, ptr16[arg1reg]);
|
||||
armAsm->Ldrsh(RAX, a64::MemOperand(RCX));
|
||||
armAsm->Ldrsh(RAX, mop);
|
||||
}
|
||||
else {
|
||||
// xMOVZX(rax, ptr16[arg1reg]);
|
||||
armAsm->Ldrh(RAX, a64::MemOperand(RCX));
|
||||
armAsm->Ldrh(RAX, mop);
|
||||
}
|
||||
break;
|
||||
|
||||
case 32:
|
||||
if (sign) {
|
||||
// xMOVSX(rax, ptr32[arg1reg]);
|
||||
armAsm->Ldrsw(RAX, a64::MemOperand(RCX));
|
||||
armAsm->Ldrsw(RAX, mop);
|
||||
}
|
||||
else {
|
||||
// xMOV(eax, ptr32[arg1reg]);
|
||||
armAsm->Ldr(EAX, a64::MemOperand(RCX));
|
||||
armAsm->Ldr(EAX, mop);
|
||||
}
|
||||
break;
|
||||
|
||||
case 64:
|
||||
// xMOV(rax, ptr64[arg1reg]);
|
||||
armAsm->Ldr(RAX, a64::MemOperand(RCX));
|
||||
armAsm->Ldr(RAX, mop);
|
||||
break;
|
||||
|
||||
case 128:
|
||||
// xMOVAPS(xmm0, ptr128[arg1reg]);
|
||||
armAsm->Ldr(xmm0.Q(), a64::MemOperand(RCX));
|
||||
armAsm->Ldr(xmm0.Q(), mop);
|
||||
break;
|
||||
|
||||
jNO_DEFAULT
|
||||
@@ -229,31 +231,32 @@ namespace vtlb_private
|
||||
// ------------------------------------------------------------------------
|
||||
static void DynGen_DirectWrite(u32 bits)
|
||||
{
|
||||
auto mop = a64::MemOperand(RCX);
|
||||
switch (bits)
|
||||
{
|
||||
case 8:
|
||||
// xMOV(ptr[arg1reg], xRegister8(arg2regd));
|
||||
armAsm->Strb(EDX, a64::MemOperand(RCX));
|
||||
armAsm->Strb(EDX, mop);
|
||||
break;
|
||||
|
||||
case 16:
|
||||
// xMOV(ptr[arg1reg], xRegister16(arg2regd));
|
||||
armAsm->Strh(EDX, a64::MemOperand(RCX));
|
||||
armAsm->Strh(EDX, mop);
|
||||
break;
|
||||
|
||||
case 32:
|
||||
// xMOV(ptr[arg1reg], arg2regd);
|
||||
armAsm->Str(EDX, a64::MemOperand(RCX));
|
||||
armAsm->Str(EDX, mop);
|
||||
break;
|
||||
|
||||
case 64:
|
||||
// xMOV(ptr[arg1reg], arg2reg);
|
||||
armAsm->Str(RDX, a64::MemOperand(RCX));
|
||||
armAsm->Str(RDX, mop);
|
||||
break;
|
||||
|
||||
case 128:
|
||||
// xMOVAPS(ptr[arg1reg], xRegisterSSE::GetArgRegister(1, 0));
|
||||
armAsm->Str(armQRegister(1).Q(), a64::MemOperand(RCX));
|
||||
armAsm->Str(armQRegister(1).Q(), mop);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -425,7 +428,7 @@ void vtlb_DynGenDispatchers()
|
||||
//// copy code
|
||||
memcpy(code_start, m_IndirectDispatchers, INDIRECT_DISPATCHERS_SIZE);
|
||||
////
|
||||
armSetAsmPtr(code_start, INDIRECT_DISPATCHERS_SIZE, nullptr);
|
||||
armSetAsmPtr(code_start + INDIRECT_DISPATCHERS_SIZE, INDIRECT_DISPATCHERS_SIZE, nullptr);
|
||||
armStartBlock();
|
||||
}
|
||||
|
||||
@@ -469,7 +472,7 @@ int vtlb_DynGenReadNonQuad(u32 bits, bool sign, bool xmm, int addr_reg, vtlb_Rea
|
||||
|
||||
const u8* codeStart;
|
||||
// const xAddressReg x86addr(addr_reg);
|
||||
a64::MemOperand baseAddr = a64::MemOperand(RFASTMEMBASE, a64::XRegister(addr_reg));
|
||||
a64::MemOperand x86addr = a64::MemOperand(RFASTMEMBASE, a64::XRegister(addr_reg));
|
||||
|
||||
if (!xmm)
|
||||
{
|
||||
@@ -479,23 +482,24 @@ int vtlb_DynGenReadNonQuad(u32 bits, bool sign, bool xmm, int addr_reg, vtlb_Rea
|
||||
codeStart = armGetCurrentCodePointer();
|
||||
// const xRegister64 x86reg(x86_dest_reg);
|
||||
|
||||
auto x86reg = a64::XRegister(x86_dest_reg);
|
||||
switch (bits)
|
||||
{
|
||||
case 8:
|
||||
// sign ? xMOVSX(x86reg, ptr8[RFASTMEMBASE + x86addr]) : xMOVZX(xRegister32(x86reg), ptr8[RFASTMEMBASE + x86addr]);
|
||||
sign ? armAsm->Ldrsb(a64::XRegister(x86_dest_reg), baseAddr) : armAsm->Ldrb(a64::WRegister(x86_dest_reg), baseAddr);
|
||||
sign ? armAsm->Ldrsb(x86reg, x86addr) : armAsm->Ldrb(x86reg.W(), x86addr);
|
||||
break;
|
||||
case 16:
|
||||
// sign ? xMOVSX(x86reg, ptr16[RFASTMEMBASE + x86addr]) : xMOVZX(xRegister32(x86reg), ptr16[RFASTMEMBASE + x86addr]);
|
||||
sign ? armAsm->Ldrsh(a64::XRegister(x86_dest_reg), baseAddr) : armAsm->Ldrh(a64::WRegister(x86_dest_reg), baseAddr);
|
||||
sign ? armAsm->Ldrsh(x86reg, x86addr) : armAsm->Ldrh(x86reg.W(), x86addr);
|
||||
break;
|
||||
case 32:
|
||||
// sign ? xMOVSX(x86reg, ptr32[RFASTMEMBASE + x86addr]) : xMOV(xRegister32(x86reg), ptr32[RFASTMEMBASE + x86addr]);
|
||||
sign ? armAsm->Ldrsw(a64::XRegister(x86_dest_reg), baseAddr) : armAsm->Ldr(a64::WRegister(x86_dest_reg), baseAddr);
|
||||
sign ? armAsm->Ldrsw(x86reg, x86addr) : armAsm->Ldr(x86reg.W(), x86addr);
|
||||
break;
|
||||
case 64:
|
||||
// xMOV(x86reg, ptr64[RFASTMEMBASE + x86addr]);
|
||||
armAsm->Ldr(a64::XRegister(x86_dest_reg), baseAddr);
|
||||
armAsm->Ldr(x86reg, x86addr);
|
||||
break;
|
||||
|
||||
jNO_DEFAULT
|
||||
@@ -510,7 +514,7 @@ int vtlb_DynGenReadNonQuad(u32 bits, bool sign, bool xmm, int addr_reg, vtlb_Rea
|
||||
// const xRegisterSSE xmmreg(x86_dest_reg);
|
||||
const a64::QRegister xmmreg(x86_dest_reg);
|
||||
// xMOVSSZX(xmmreg, ptr32[RFASTMEMBASE + x86addr]);
|
||||
armAsm->Ldr(xmmreg.S(), baseAddr);
|
||||
armAsm->Ldr(xmmreg.S(), x86addr);
|
||||
}
|
||||
|
||||
// vtlb_AddLoadStoreInfo((uptr)codeStart, static_cast<u32>(x86Ptr - codeStart),
|
||||
@@ -536,31 +540,43 @@ int vtlb_DynGenReadNonQuad_Const(u32 bits, bool sign, bool xmm, u32 addr_const,
|
||||
auto vmv = vtlbdata.vmap[addr_const >> VTLB_PAGE_BITS];
|
||||
if (!vmv.isHandler(addr_const))
|
||||
{
|
||||
auto ppf = vmv.assumePtr(addr_const);
|
||||
// uptr ppf = vmv.assumePtr(addr_const);
|
||||
// auto mop = armMemOperandPtr((u8*)ppf);
|
||||
|
||||
armAsm->Mov(ECX, addr_const);
|
||||
armAsm->Mov(EAX, ECX);
|
||||
armAsm->Lsr(EAX, EAX, VTLB_PAGE_BITS);
|
||||
armAsm->Ldr(RXVIXLSCRATCH, PTR_CPU(vtlbdata.vmap));
|
||||
armAsm->Ldr(RAX, a64::MemOperand(RXVIXLSCRATCH, RAX, a64::LSL, 3));
|
||||
armAsm->Add(RCX, RCX, RAX);
|
||||
auto mop = a64::MemOperand(RCX);
|
||||
|
||||
if (!xmm)
|
||||
{
|
||||
// x86_dest_reg = dest_reg_alloc ? dest_reg_alloc() : (_freeX86reg(eax), eax.GetId());
|
||||
x86_dest_reg = dest_reg_alloc ? dest_reg_alloc() : (_freeX86reg(EAX), EAX.GetCode());
|
||||
|
||||
auto regX = a64::XRegister(x86_dest_reg);
|
||||
switch (bits)
|
||||
{
|
||||
case 8:
|
||||
// sign ? xMOVSX(xRegister64(x86_dest_reg), ptr8[(u8*)ppf]) : xMOVZX(xRegister32(x86_dest_reg), ptr8[(u8*)ppf]);
|
||||
sign ? armAsm->Ldrsb(a64::XRegister(x86_dest_reg), armMemOperandPtr((u8*)ppf)) : armAsm->Ldrb(a64::WRegister(x86_dest_reg), armMemOperandPtr((u8*)ppf));
|
||||
sign ? armAsm->Ldrsb(regX, mop) : armAsm->Ldrb(regX.W(), mop);
|
||||
break;
|
||||
|
||||
case 16:
|
||||
// sign ? xMOVSX(xRegister64(x86_dest_reg), ptr16[(u16*)ppf]) : xMOVZX(xRegister32(x86_dest_reg), ptr16[(u16*)ppf]);
|
||||
sign ? armAsm->Ldrsh(a64::XRegister(x86_dest_reg), armMemOperandPtr((u16*)ppf)) : armAsm->Ldrh(a64::WRegister(x86_dest_reg), armMemOperandPtr((u16*)ppf));
|
||||
sign ? armAsm->Ldrsh(regX, mop) : armAsm->Ldrh(regX.W(), mop);
|
||||
break;
|
||||
|
||||
case 32:
|
||||
// sign ? xMOVSX(xRegister64(x86_dest_reg), ptr32[(u32*)ppf]) : xMOV(xRegister32(x86_dest_reg), ptr32[(u32*)ppf]);
|
||||
sign ? armAsm->Ldrsw(a64::XRegister(x86_dest_reg), armMemOperandPtr((u32*)ppf)) : armAsm->Ldr(a64::WRegister(x86_dest_reg), armMemOperandPtr((u32*)ppf));
|
||||
sign ? armAsm->Ldrsw(regX, mop) : armAsm->Ldr(regX.W(), mop);
|
||||
break;
|
||||
|
||||
case 64:
|
||||
// xMOV(xRegister64(x86_dest_reg), ptr64[(u64*)ppf]);
|
||||
armAsm->Ldr(a64::XRegister(x86_dest_reg), armMemOperandPtr((u64*)ppf));
|
||||
armAsm->Ldr(regX, mop);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -568,7 +584,7 @@ int vtlb_DynGenReadNonQuad_Const(u32 bits, bool sign, bool xmm, u32 addr_const,
|
||||
{
|
||||
x86_dest_reg = dest_reg_alloc ? dest_reg_alloc() : (_freeXMMreg(0), 0);
|
||||
// xMOVSSZX(xRegisterSSE(x86_dest_reg), ptr32[(float*)ppf]);
|
||||
armAsm->Ldr(a64::QRegister(x86_dest_reg).S(), armMemOperandPtr((float*)ppf));
|
||||
armAsm->Ldr(a64::QRegister(x86_dest_reg).S(), mop);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -619,27 +635,29 @@ int vtlb_DynGenReadNonQuad_Const(u32 bits, bool sign, bool xmm, u32 addr_const,
|
||||
{
|
||||
// x86_dest_reg = dest_reg_alloc ? dest_reg_alloc() : (_freeX86reg(eax), eax.GetId());
|
||||
x86_dest_reg = dest_reg_alloc ? dest_reg_alloc() : (_freeX86reg(EAX), EAX.GetCode());
|
||||
|
||||
auto regX = a64::XRegister(x86_dest_reg);
|
||||
switch (bits)
|
||||
{
|
||||
// save REX prefix by using 32bit dest for zext
|
||||
case 8:
|
||||
// sign ? xMOVSX(xRegister64(x86_dest_reg), al) : xMOVZX(xRegister32(x86_dest_reg), al);
|
||||
sign ? armAsm->Sxtb(a64::XRegister(x86_dest_reg), EAX) : armAsm->Uxtb(a64::WRegister(x86_dest_reg), EAX);
|
||||
sign ? armAsm->Sxtb(regX, EAX) : armAsm->Uxtb(regX.W(), EAX);
|
||||
break;
|
||||
|
||||
case 16:
|
||||
// sign ? xMOVSX(xRegister64(x86_dest_reg), ax) : xMOVZX(xRegister32(x86_dest_reg), ax);
|
||||
sign ? armAsm->Sxth(a64::XRegister(x86_dest_reg), EAX) : armAsm->Uxth(a64::WRegister(x86_dest_reg), EAX);
|
||||
sign ? armAsm->Sxth(regX, EAX) : armAsm->Uxth(regX.W(), EAX);
|
||||
break;
|
||||
|
||||
case 32:
|
||||
// sign ? xMOVSX(xRegister64(x86_dest_reg), eax) : xMOV(xRegister32(x86_dest_reg), eax);
|
||||
sign ? armAsm->Sxtw(a64::XRegister(x86_dest_reg), EAX) : armAsm->Mov(a64::WRegister(x86_dest_reg), EAX);
|
||||
sign ? armAsm->Sxtw(regX, EAX) : armAsm->Mov(regX.W(), EAX);
|
||||
break;
|
||||
|
||||
case 64:
|
||||
// xMOV(xRegister64(x86_dest_reg), rax);
|
||||
armAsm->Mov(a64::XRegister(x86_dest_reg) , RAX);
|
||||
armAsm->Mov(regX , RAX);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -704,11 +722,19 @@ int vtlb_DynGenReadQuad_Const(u32 bits, u32 addr_const, vtlb_ReadRegAllocCallbac
|
||||
auto vmv = vtlbdata.vmap[addr_const >> VTLB_PAGE_BITS];
|
||||
if (!vmv.isHandler(addr_const))
|
||||
{
|
||||
void* ppf = reinterpret_cast<void*>(vmv.assumePtr(addr_const));
|
||||
// void* ppf = reinterpret_cast<void*>(vmv.assumePtr(addr_const));
|
||||
reg = dest_reg_alloc ? dest_reg_alloc() : (_freeXMMreg(0), 0);
|
||||
if (reg >= 0) {
|
||||
// xMOVAPS(xRegisterSSE(reg), ptr128[ppf]);
|
||||
armAsm->Ldr(a64::QRegister(reg).Q(), armMemOperandPtr(ppf));
|
||||
// armAsm->Ldr(a64::QRegister(reg).Q(), armMemOperandPtr(ppf));
|
||||
|
||||
armAsm->Mov(ECX, addr_const);
|
||||
armAsm->Mov(EAX, ECX);
|
||||
armAsm->Lsr(EAX, EAX, VTLB_PAGE_BITS);
|
||||
armAsm->Ldr(RXVIXLSCRATCH, PTR_CPU(vtlbdata.vmap));
|
||||
armAsm->Ldr(RAX, a64::MemOperand(RXVIXLSCRATCH, RAX, a64::LSL, 3));
|
||||
armAsm->Add(RCX, RCX, RAX);
|
||||
armAsm->Ldr(a64::QRegister(reg).Q(), a64::MemOperand(RCX));
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -806,23 +832,24 @@ void vtlb_DynGenWrite(u32 sz, bool xmm, int addr_reg, int value_reg)
|
||||
|
||||
if (!xmm)
|
||||
{
|
||||
auto regX = a64::XRegister(value_reg);
|
||||
switch (sz)
|
||||
{
|
||||
case 8:
|
||||
// xMOV(ptr8[RFASTMEMBASE + vaddr_reg], xRegister8(xRegister32(value_reg)));
|
||||
armAsm->Strb(a64::WRegister(value_reg), mop);
|
||||
armAsm->Strb(regX.W(), mop);
|
||||
break;
|
||||
case 16:
|
||||
// xMOV(ptr16[RFASTMEMBASE + vaddr_reg], xRegister16(value_reg));
|
||||
armAsm->Strh(a64::WRegister(value_reg), mop);
|
||||
armAsm->Strh(regX.W(), mop);
|
||||
break;
|
||||
case 32:
|
||||
// xMOV(ptr32[RFASTMEMBASE + vaddr_reg], xRegister32(value_reg));
|
||||
armAsm->Str(a64::WRegister(value_reg), mop);
|
||||
armAsm->Str(regX.W(), mop);
|
||||
break;
|
||||
case 64:
|
||||
// xMOV(ptr64[RFASTMEMBASE + vaddr_reg], xRegister64(value_reg));
|
||||
armAsm->Str(a64::XRegister(value_reg), mop);
|
||||
armAsm->Str(regX, mop);
|
||||
break;
|
||||
|
||||
jNO_DEFAULT
|
||||
@@ -831,15 +858,17 @@ void vtlb_DynGenWrite(u32 sz, bool xmm, int addr_reg, int value_reg)
|
||||
else
|
||||
{
|
||||
pxAssert(sz == 32 || sz == 128);
|
||||
|
||||
auto regQ = a64::QRegister(value_reg);
|
||||
switch (sz)
|
||||
{
|
||||
case 32:
|
||||
// xMOVSS(ptr32[RFASTMEMBASE + vaddr_reg], xRegisterSSE(value_reg));
|
||||
armAsm->Str(a64::QRegister(value_reg).S(), mop);
|
||||
armAsm->Str(regQ.S(), mop);
|
||||
break;
|
||||
case 128:
|
||||
// xMOVAPS(ptr128[RFASTMEMBASE + vaddr_reg], xRegisterSSE(value_reg));
|
||||
armAsm->Str(a64::QRegister(value_reg).Q(), mop);
|
||||
armAsm->Str(regQ.Q(), mop);
|
||||
break;
|
||||
|
||||
jNO_DEFAULT
|
||||
@@ -918,30 +947,40 @@ void vtlb_DynGenWrite_Const(u32 bits, bool xmm, u32 addr_const, int value_reg)
|
||||
auto vmv = vtlbdata.vmap[addr_const >> VTLB_PAGE_BITS];
|
||||
if (!vmv.isHandler(addr_const))
|
||||
{
|
||||
auto ppf = vmv.assumePtr(addr_const);
|
||||
const a64::MemOperand mop = armMemOperandPtr((void*)ppf);
|
||||
// auto ppf = vmv.assumePtr(addr_const);
|
||||
// a64::MemOperand mop = armMemOperandPtr((u8*)ppf);
|
||||
|
||||
armAsm->Mov(ECX, addr_const);
|
||||
armAsm->Mov(EAX, ECX);
|
||||
armAsm->Lsr(EAX, EAX, VTLB_PAGE_BITS);
|
||||
armAsm->Ldr(RXVIXLSCRATCH, PTR_CPU(vtlbdata.vmap));
|
||||
armAsm->Ldr(RAX, a64::MemOperand(RXVIXLSCRATCH, RAX, a64::LSL, 3));
|
||||
armAsm->Add(RCX, RCX, RAX);
|
||||
auto mop = a64::MemOperand(RCX);
|
||||
|
||||
if (!xmm)
|
||||
{
|
||||
auto regX = a64::XRegister(value_reg);
|
||||
switch (bits)
|
||||
{
|
||||
case 8:
|
||||
// xMOV(ptr[(void*)ppf], xRegister8(xRegister32(value_reg)));
|
||||
armAsm->Strb(a64::WRegister(value_reg), mop);
|
||||
armAsm->Strb(regX.W(), mop);
|
||||
break;
|
||||
|
||||
case 16:
|
||||
// xMOV(ptr[(void*)ppf], xRegister16(value_reg));
|
||||
armAsm->Strh(a64::WRegister(value_reg), mop);
|
||||
armAsm->Strh(regX.W(), mop);
|
||||
break;
|
||||
|
||||
case 32:
|
||||
// xMOV(ptr[(void*)ppf], xRegister32(value_reg));
|
||||
armAsm->Str(a64::WRegister(value_reg), mop);
|
||||
armAsm->Str(regX.W(), mop);
|
||||
break;
|
||||
|
||||
case 64:
|
||||
// xMOV(ptr64[(void*)ppf], xRegister64(value_reg));
|
||||
armAsm->Str(a64::XRegister(value_reg), mop);
|
||||
armAsm->Str(regX, mop);
|
||||
break;
|
||||
|
||||
jNO_DEFAULT
|
||||
@@ -949,16 +988,17 @@ void vtlb_DynGenWrite_Const(u32 bits, bool xmm, u32 addr_const, int value_reg)
|
||||
}
|
||||
else
|
||||
{
|
||||
auto regQ = a64::QRegister(value_reg);
|
||||
switch (bits)
|
||||
{
|
||||
case 32:
|
||||
// xMOVSS(ptr[(void*)ppf], xRegisterSSE(value_reg));
|
||||
armAsm->Str(a64::QRegister(value_reg).S(), mop);
|
||||
armAsm->Str(regQ.S(), mop);
|
||||
break;
|
||||
|
||||
case 128:
|
||||
// xMOVAPS(ptr128[(void*)ppf], xRegisterSSE(value_reg));
|
||||
armAsm->Str(a64::QRegister(value_reg).Q(), mop);
|
||||
armAsm->Str(regQ.Q(), mop);
|
||||
break;
|
||||
|
||||
jNO_DEFAULT
|
||||
@@ -1047,8 +1087,9 @@ void vtlb_DynV2P()
|
||||
// xSHR(eax, VTLB_PAGE_BITS);
|
||||
armAsm->Lsr(EAX, EAX, VTLB_PAGE_BITS);
|
||||
// xMOV(eax, ptr[xComplexAddress(rdx, vtlbdata.ppmap, rax * 4)]);
|
||||
armMoveAddressToReg(RDX, vtlbdata.ppmap);
|
||||
armAsm->Ldr(EAX, a64::MemOperand(RDX, RAX, a64::LSL, 2));
|
||||
// armMoveAddressToReg(RDX, vtlbdata.ppmap);
|
||||
armAsm->Ldr(RXVIXLSCRATCH, PTR_CPU(vtlbdata.ppmap));
|
||||
armAsm->Ldr(EAX, a64::MemOperand(RXVIXLSCRATCH, RAX, a64::LSL, 2));
|
||||
|
||||
// xOR(eax, ecx);
|
||||
armAsm->Orr(EAX, EAX, ECX);
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
#include "common/Perf.h"
|
||||
#include "common/StringUtil.h"
|
||||
|
||||
alignas(16) vuRegistersPack g_vuRegistersPack;
|
||||
alignas(64) vuRegistersPack g_vuRegistersPack;
|
||||
VU_Thread& vu1Thread = g_vuRegistersPack.vu1Thread;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Micro VU - Main Functions
|
||||
|
||||
@@ -278,8 +278,9 @@ public:
|
||||
struct vuRegistersPack
|
||||
{
|
||||
alignas(16) microVU microVU[2];
|
||||
alignas(64) VU_Thread vu1Thread;
|
||||
};
|
||||
alignas(16) extern vuRegistersPack g_vuRegistersPack;
|
||||
alignas(64) extern vuRegistersPack g_vuRegistersPack;
|
||||
////
|
||||
static microVU& microVU0 = g_vuRegistersPack.microVU[0];
|
||||
static microVU& microVU1 = g_vuRegistersPack.microVU[1];
|
||||
|
||||
@@ -413,7 +413,9 @@ void normJumpCompile(mV, microFlagCycles& mFC, bool isEvilJump)
|
||||
else
|
||||
{
|
||||
// xLoadFarAddr(arg2reg, &mVUpBlock->pStateEnd);
|
||||
armAsm->Ldr(RCX, PTR_MBLOCK(pStateEnd));
|
||||
armMoveAddressToReg(RCX, &mVUpBlock->pStateEnd);
|
||||
// armAsm->Ldr(RXVIXLSCRATCH, PTR_MVU(microVU[mVU.index].prog.IRinfo.pBlock));
|
||||
// armAsm->Add(RCX, RXVIXLSCRATCH, offsetof(microBlock, pStateEnd));
|
||||
}
|
||||
|
||||
if (mVUup.eBit && isEvilJump) // E-bit EvilJump
|
||||
@@ -442,7 +444,7 @@ void normJumpCompile(mV, microFlagCycles& mFC, bool isEvilJump)
|
||||
|
||||
mVUrestoreRegs(mVU);
|
||||
// xJMP(gprT1q); // Jump to rec-code address
|
||||
armAsm->Br(RAX);
|
||||
armAsm->Br(gprT1q);
|
||||
}
|
||||
|
||||
void normBranch(mV, microFlagCycles& mFC)
|
||||
@@ -456,7 +458,7 @@ void normBranch(mV, microFlagCycles& mFC)
|
||||
u32 tempPC = iPC;
|
||||
if (mVU.index && THREAD_VU1) {
|
||||
// xTEST(ptr32[&vu1Thread.vuFBRST], (isVU1 ? 0x400 : 0x4));
|
||||
armAsm->Tst(armLoadPtr(PTR_VU1(vuFBRST)), (isVU1 ? 0x400 : 0x4));
|
||||
armAsm->Tst(armLoadPtr(PTR_MVU(vu1Thread.vuFBRST)), (isVU1 ? 0x400 : 0x4));
|
||||
}
|
||||
else {
|
||||
// xTEST(ptr32[&VU0.VI[REG_FBRST].UL], (isVU1 ? 0x400 : 0x4));
|
||||
@@ -486,7 +488,7 @@ void normBranch(mV, microFlagCycles& mFC)
|
||||
u32 tempPC = iPC;
|
||||
if (mVU.index && THREAD_VU1) {
|
||||
// xTEST(ptr32[&vu1Thread.vuFBRST], (isVU1 ? 0x800 : 0x8));
|
||||
armAsm->Tst(armLoadPtr(PTR_VU1(vuFBRST)), (isVU1 ? 0x800 : 0x8));
|
||||
armAsm->Tst(armLoadPtr(PTR_MVU(vu1Thread.vuFBRST)), (isVU1 ? 0x800 : 0x8));
|
||||
}
|
||||
else {
|
||||
// xTEST(ptr32[&VU0.VI[REG_FBRST].UL], (isVU1 ? 0x800 : 0x8));
|
||||
@@ -515,7 +517,9 @@ void normBranch(mV, microFlagCycles& mFC)
|
||||
|
||||
memcpy(&mVUpBlock->pStateEnd, &mVUregs, sizeof(microRegInfo));
|
||||
// xLoadFarAddr(rax, &mVUpBlock->pStateEnd);
|
||||
armAsm->Ldr(RAX, PTR_MBLOCK(pStateEnd));
|
||||
armMoveAddressToReg(RAX, &mVUpBlock->pStateEnd);
|
||||
// armAsm->Ldr(RXVIXLSCRATCH, PTR_MVU(microVU[mVU.index].prog.IRinfo.pBlock));
|
||||
// armAsm->Add(RAX, RXVIXLSCRATCH, offsetof(microBlock, pStateEnd));
|
||||
// xCALL((void*)mVU.copyPLState);
|
||||
armEmitCall(mVU.copyPLState);
|
||||
|
||||
@@ -557,7 +561,7 @@ void condBranch(mV, microFlagCycles& mFC, a64::Condition JMPcc)
|
||||
u32 tempPC = iPC;
|
||||
if (mVU.index && THREAD_VU1) {
|
||||
// xTEST(ptr32[&vu1Thread.vuFBRST], (isVU1 ? 0x800 : 0x8));
|
||||
armAsm->Tst(armLoadPtr(PTR_VU1(vuFBRST)), (isVU1 ? 0x800 : 0x8));
|
||||
armAsm->Tst(armLoadPtr(PTR_MVU(vu1Thread.vuFBRST)), (isVU1 ? 0x800 : 0x8));
|
||||
}
|
||||
else {
|
||||
// xTEST(ptr32[&VU0.VI[REG_FBRST].UL], (isVU1 ? 0x800 : 0x8));
|
||||
@@ -609,7 +613,7 @@ void condBranch(mV, microFlagCycles& mFC, a64::Condition JMPcc)
|
||||
u32 tempPC = iPC;
|
||||
if (mVU.index && THREAD_VU1) {
|
||||
// xTEST(ptr32[&vu1Thread.vuFBRST], (isVU1 ? 0x400 : 0x4));
|
||||
armAsm->Tst(armLoadPtr(PTR_VU1(vuFBRST)), (isVU1 ? 0x400 : 0x4));
|
||||
armAsm->Tst(armLoadPtr(PTR_MVU(vu1Thread.vuFBRST)), (isVU1 ? 0x400 : 0x4));
|
||||
}
|
||||
else {
|
||||
// xTEST(ptr32[&VU0.VI[REG_FBRST].UL], (isVU1 ? 0x400 : 0x4));
|
||||
@@ -654,7 +658,9 @@ void condBranch(mV, microFlagCycles& mFC, a64::Condition JMPcc)
|
||||
|
||||
memcpy(&mVUpBlock->pStateEnd, &mVUregs, sizeof(microRegInfo));
|
||||
// xLoadFarAddr(rax, &mVUpBlock->pStateEnd);
|
||||
armAsm->Ldr(RAX, PTR_MBLOCK(pStateEnd));
|
||||
armMoveAddressToReg(RAX, &mVUpBlock->pStateEnd);
|
||||
// armAsm->Ldr(RXVIXLSCRATCH, PTR_MVU(microVU[mVU.index].prog.IRinfo.pBlock));
|
||||
// armAsm->Add(RAX, RXVIXLSCRATCH, offsetof(microBlock, pStateEnd));
|
||||
// xCALL((void*)mVU.copyPLState);
|
||||
armEmitCall(mVU.copyPLState);
|
||||
|
||||
@@ -800,7 +806,7 @@ void normJump(mV, microFlagCycles& mFC)
|
||||
|
||||
if (THREAD_VU1) {
|
||||
// xTEST(ptr32[&vu1Thread.vuFBRST], (isVU1 ? 0x400 : 0x4));
|
||||
armAsm->Tst(armLoadPtr(PTR_VU1(vuFBRST)), (isVU1 ? 0x400 : 0x4));
|
||||
armAsm->Tst(armLoadPtr(PTR_MVU(vu1Thread.vuFBRST)), (isVU1 ? 0x400 : 0x4));
|
||||
}
|
||||
else {
|
||||
// xTEST(ptr32[&VU0.VI[REG_FBRST].UL], (isVU1 ? 0x400 : 0x4));
|
||||
@@ -833,7 +839,7 @@ void normJump(mV, microFlagCycles& mFC)
|
||||
|
||||
if (mVU.index && THREAD_VU1) {
|
||||
// xTEST(ptr32[&vu1Thread.vuFBRST], (isVU1 ? 0x800 : 0x8));
|
||||
armAsm->Tst(armLoadPtr(PTR_VU1(vuFBRST)), (isVU1 ? 0x800 : 0x8));
|
||||
armAsm->Tst(armLoadPtr(PTR_MVU(vu1Thread.vuFBRST)), (isVU1 ? 0x800 : 0x8));
|
||||
}
|
||||
else {
|
||||
// xTEST(ptr32[&VU0.VI[REG_FBRST].UL], (isVU1 ? 0x800 : 0x8));
|
||||
|
||||
@@ -515,7 +515,7 @@ void mVUtestCycles(microVU& mVU, microFlagCycles& mFC)
|
||||
armAsm->B(&skip, a64::Condition::pl);
|
||||
|
||||
// xLoadFarAddr(rax, &mVUpBlock->pState);
|
||||
armAsm->Ldr(RAX, PTR_MBLOCK(pState));
|
||||
armMoveAddressToReg(RAX, &mVUpBlock->pState);
|
||||
// xCALL((void*)mVU.copyPLState);
|
||||
armEmitCall(mVU.copyPLState);
|
||||
|
||||
@@ -597,7 +597,7 @@ void mVUDoDBit(microVU& mVU, microFlagCycles* mFC)
|
||||
{
|
||||
if (mVU.index && THREAD_VU1) {
|
||||
// xTEST(ptr32[&vu1Thread.vuFBRST], (isVU1 ? 0x400 : 0x4));
|
||||
armAsm->Tst(armLoadPtr(PTR_VU1(vuFBRST)), (isVU1 ? 0x400 : 0x4));
|
||||
armAsm->Tst(armLoadPtr(PTR_MVU(vu1Thread.vuFBRST)), (isVU1 ? 0x400 : 0x4));
|
||||
}
|
||||
else {
|
||||
// xTEST(ptr32[&VU0.VI[REG_FBRST].UL], (isVU1 ? 0x400 : 0x4));
|
||||
@@ -624,7 +624,7 @@ void mVUDoTBit(microVU& mVU, microFlagCycles* mFC)
|
||||
{
|
||||
if (mVU.index && THREAD_VU1) {
|
||||
// xTEST(ptr32[&vu1Thread.vuFBRST], (isVU1 ? 0x800 : 0x8));
|
||||
armAsm->Tst(armLoadPtr(PTR_VU1(vuFBRST)), (isVU1 ? 0x800 : 0x8));
|
||||
armAsm->Tst(armLoadPtr(PTR_MVU(vu1Thread.vuFBRST)), (isVU1 ? 0x800 : 0x8));
|
||||
}
|
||||
else {
|
||||
// xTEST(ptr32[&VU0.VI[REG_FBRST].UL], (isVU1 ? 0x800 : 0x8));
|
||||
|
||||
@@ -28,10 +28,8 @@ void mVUdispatcherAB(mV)
|
||||
armBeginStackFrame();
|
||||
|
||||
// From memory to registry
|
||||
armMoveAddressToReg(RSTATE_x29, &vu1Thread);
|
||||
armMoveAddressToReg(RSTATE_MVU, &g_vuRegistersPack);
|
||||
armMoveAddressToReg(RSTATE_CPU, &g_cpuRegistersPack);
|
||||
armMoveAddressToReg(RFASTMEMBASE, &mVUpBlock);
|
||||
|
||||
// = The caller has already put the needed parameters in ecx/edx:
|
||||
if (!isVU1) {
|
||||
|
||||
@@ -388,9 +388,9 @@ mVUop(mVU_EEXP)
|
||||
// xMUL.SS(t1, ptr32[mVUglob.E2]);
|
||||
armAsm->Fmul(t1.S(), t1.S(), armLoadPtrV(PTR_CPU(mVUglob.E2)).S());
|
||||
SSE_ADDSS(mVU, xmmPQ, t1);
|
||||
eexpHelper(&mVUglob.E3);
|
||||
eexpHelper(&mVUglob.E4);
|
||||
eexpHelper(&mVUglob.E5);
|
||||
eexpHelper(PTR_CPU(mVUglob.E3));
|
||||
eexpHelper(PTR_CPU(mVUglob.E4));
|
||||
eexpHelper(PTR_CPU(mVUglob.E5));
|
||||
SSE_MULSS(mVU, t2, Fs);
|
||||
// xMUL.SS(t2, ptr32[mVUglob.E6]);
|
||||
armAsm->Fmul(t2.S(), t2.S(), armLoadPtrV(PTR_CPU(mVUglob.E6)).S());
|
||||
@@ -2069,7 +2069,7 @@ mVUop(mVU_XTOP)
|
||||
const a64::Register& regT = mVU.regAlloc->allocGPR(-1, _It_, mVUlow.backupVI);
|
||||
// xMOVZX(regT, ptr16[&mVU.getVifRegs().top]);
|
||||
if (mVU.index && THREAD_VU1) {
|
||||
armAsm->Ldrh(regT, PTR_VU1(vifRegs.top));
|
||||
armAsm->Ldrh(regT, PTR_MVU(vu1Thread.vifRegs.top));
|
||||
} else {
|
||||
armAsm->Ldrh(regT, PTR_CPU(vifRegs[mVU.index].top));
|
||||
}
|
||||
@@ -2093,7 +2093,7 @@ mVUop(mVU_XITOP)
|
||||
const a64::Register& regT = mVU.regAlloc->allocGPR(-1, _It_, mVUlow.backupVI);
|
||||
// xMOVZX(regT, ptr16[&mVU.getVifRegs().itop]);
|
||||
if (mVU.index && THREAD_VU1) {
|
||||
armAsm->Ldrh(regT, PTR_VU1(vifRegs.itop));
|
||||
armAsm->Ldrh(regT, PTR_MVU(vu1Thread.vifRegs.itop));
|
||||
} else {
|
||||
armAsm->Ldrh(regT, PTR_CPU(vifRegs[mVU.index].itop));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user