Android project - Added vuRegistersPack for microVU

This commit is contained in:
k2154
2025-07-31 06:03:23 +09:00
parent c2644ed27c
commit dcd29b383e
26 changed files with 319 additions and 850 deletions
+6 -10
View File
@@ -55,22 +55,18 @@ namespace a64 = vixl::aarch64;
#define RSTATE_x23 a64::x23
#define RSTATE_x24 a64::x24
// fastmem
#define RFASTMEMBASE a64::x25
// microVU
#define RSTATE_MVU a64::x27
#define RSTATE_VU1 a64::x28
#define RSTATE_VUR a64::x26
#define PTR_MVU(field) a64::MemOperand(RSTATE_MVU, offsetof(microVU, field))
#define PTR_VU1(field) a64::MemOperand(RSTATE_VU1, offsetof(VURegs, field))
#define PTR_VUR(field) a64::MemOperand(RSTATE_VUR, offsetof(VURegs, field))
// CPU(iR5900), PSX(iR3000A), FPU(iFPU, iFPUd)
#define RSTATE_CPU a64::x27
#define RSTATE_PSX a64::x28
#define RSTATE_CPU a64::x29
#define PTR_PSX(field) a64::MemOperand(RSTATE_PSX, offsetof(psxRegisters, field))
#define PTR_CPU(field) a64::MemOperand(RSTATE_CPU, offsetof(cpuRegistersPack, field))
// microVU
#define RSTATE_MVU a64::x28
#define PTR_MVU(field) a64::MemOperand(RSTATE_MVU, offsetof(vuRegistersPack, field))
static inline s64 GetPCDisplacement(const void* current, const void* target)
{
+1 -1
View File
@@ -32,7 +32,7 @@ static constexpr uint iopWaitCycles = 384; // Keep inline with EE wait cycle max
bool iopEventTestIsActive = false;
alignas(16) psxRegisters psxRegs;
//alignas(16) psxRegisters psxRegs;
void psxReset()
{
+1 -116
View File
@@ -3,122 +3,7 @@
#pragma once
#include "common/Pcsx2Defs.h"
union GPRRegs {
struct {
u32 r0, at, v0, v1, a0, a1, a2, a3,
t0, t1, t2, t3, t4, t5, t6, t7,
s0, s1, s2, s3, s4, s5, s6, s7,
t8, t9, k0, k1, gp, sp, s8, ra, hi, lo; // hi needs to be at index 32! don't change
} n;
u32 r[34]; /* Lo, Hi in r[33] and r[32] */
};
union CP0Regs {
struct {
u32 Index, Random, EntryLo0, EntryLo1,
Context, PageMask, Wired, Reserved0,
BadVAddr, Count, EntryHi, Compare,
Status, Cause, EPC, PRid,
Config, LLAddr, WatchLO, WatchHI,
XContext, Reserved1, Reserved2, Reserved3,
Reserved4, Reserved5, ECC, CacheErr,
TagLo, TagHi, ErrorEPC, Reserved6;
} n;
u32 r[32];
};
struct SVector2D {
short x, y;
};
struct SVector2Dz {
short z, pad;
};
struct SVector3D {
short x, y, z, pad;
};
struct LVector3D {
short x, y, z, pad;
};
struct CBGR {
unsigned char r, g, b, c;
};
struct SMatrix3D {
short m11, m12, m13, m21, m22, m23, m31, m32, m33, pad;
};
union CP2Data {
struct {
SVector3D v0, v1, v2;
CBGR rgb;
s32 otz;
s32 ir0, ir1, ir2, ir3;
SVector2D sxy0, sxy1, sxy2, sxyp;
SVector2Dz sz0, sz1, sz2, sz3;
CBGR rgb0, rgb1, rgb2;
s32 reserved;
s32 mac0, mac1, mac2, mac3;
u32 irgb, orgb;
s32 lzcs, lzcr;
} n;
u32 r[32];
};
union CP2Ctrl {
struct {
SMatrix3D rMatrix;
s32 trX, trY, trZ;
SMatrix3D lMatrix;
s32 rbk, gbk, bbk;
SMatrix3D cMatrix;
s32 rfc, gfc, bfc;
s32 ofx, ofy;
s32 h;
s32 dqa, dqb;
s32 zsf3, zsf4;
s32 flag;
} n;
u32 r[32];
};
struct psxRegisters {
GPRRegs GPR; /* General Purpose Registers */
CP0Regs CP0; /* Coprocessor0 Registers */
CP2Data CP2D; /* Cop2 data registers */
CP2Ctrl CP2C; /* Cop2 control registers */
u32 pc; /* Program counter */
u32 code; /* The instruction */
u32 cycle;
u32 interrupt;
u32 pcWriteback;
// Controls when branch tests are performed.
u32 iopNextEventCycle;
// This value is used when the IOP execution is broken to return control to the EE.
// (which happens when the IOP throws EE-bound interrupts). It holds the value of
// iopCycleEE (which is set to zero to facilitate the code break), so that the unrun
// cycles can be accounted for later.
s32 iopBreak;
// Tracks current number of cycles IOP can run in EE cycles. When it dips below zero,
// control is returned to the EE.
s32 iopCycleEE;
u32 iopCycleEECarry;
u32 sCycle[32]; // start cycle for signaled ints
s32 eCycle[32]; // cycle delta for signaled ints (sCycle + eCycle == branch cycle)
//u32 _msflag[32];
//u32 _smflag[32];
};
alignas(16) extern psxRegisters psxRegs;
#include "cpuRegistersPack.h"
#ifndef _PC_
+1 -146
View File
@@ -3,8 +3,7 @@
#pragma once
#include "common/Pcsx2Defs.h"
#include "cpuRegistersPack.h"
#include <array>
// --------------------------------------------------------------------------------------
@@ -17,126 +16,6 @@ extern const char* const bios[256];
extern s32 EEsCycle;
extern u32 EEoCycle;
union GPR_reg { // Declare union type GPR register
u128 UQ;
s128 SQ;
u64 UD[2]; //128 bits
s64 SD[2];
u32 UL[4];
s32 SL[4];
u16 US[8];
s16 SS[8];
u8 UC[16];
s8 SC[16];
};
union GPRregs {
struct {
GPR_reg r0, at, v0, v1, a0, a1, a2, a3,
t0, t1, t2, t3, t4, t5, t6, t7,
s0, s1, s2, s3, s4, s5, s6, s7,
t8, t9, k0, k1, gp, sp, s8, ra;
} n;
GPR_reg r[32];
};
union PERFregs {
struct
{
union
{
struct
{
u32 pad0:1; // LSB should always be zero (or undefined)
u32 EXL0:1; // enable PCR0 during Level 1 exception handling
u32 K0:1; // enable PCR0 during Kernel Mode execution
u32 S0:1; // enable PCR0 during Supervisor mode execution
u32 U0:1; // enable PCR0 during User-mode execution
u32 Event0:5; // PCR0 event counter (all values except 1 ignored at this time)
u32 pad1:1; // more zero/undefined padding [bit 10]
u32 EXL1:1; // enable PCR1 during Level 1 exception handling
u32 K1:1; // enable PCR1 during Kernel Mode execution
u32 S1:1; // enable PCR1 during Supervisor mode execution
u32 U1:1; // enable PCR1 during User-mode execution
u32 Event1:5; // PCR1 event counter (all values except 1 ignored at this time)
u32 Reserved:11;
u32 CTE:1; // Counter enable bit, no counting if set to zero.
} b;
u32 val;
} pccr;
u32 pcr0, pcr1, pad;
} n;
u32 r[4];
};
union CP0regs {
struct {
u32 Index, Random, EntryLo0, EntryLo1,
Context, PageMask, Wired, Reserved0,
BadVAddr, Count, EntryHi, Compare;
union {
struct {
u32 IE:1; // Bit 0: Interrupt Enable flag.
u32 EXL:1; // Bit 1: Exception Level, set on any exception not covered by ERL.
u32 ERL:1; // Bit 2: Error level, set on Resetm NMI, perf/debug exceptions.
u32 KSU:2; // Bits 3-4: Kernel [clear] / Supervisor [set] mode
u32 unused0:3;
u32 IM:8; // Bits 10-15: Interrupt mask (bits 12,13,14 are unused)
u32 EIE:1; // Bit 16: IE bit enabler. When cleared, ints are disabled regardless of IE status.
u32 _EDI:1; // Bit 17: Interrupt Enable (set enables ints in all modes, clear enables ints in kernel mode only)
u32 CH:1; // Bit 18: Status of most recent cache instruction (set for hit, clear for miss)
u32 unused1:3;
u32 BEV:1; // Bit 22: if set, use bootstrap for TLB/general exceptions
u32 DEV:1; // Bit 23: if set, use bootstrap for perf/debug exceptions
u32 unused2:2;
u32 FR:1; // (?)
u32 unused3:1;
u32 CU:4; // Bits 28-31: Co-processor Usable flag
} b;
u32 val;
} Status;
u32 Cause, EPC, PRid,
Config, LLAddr, WatchLO, WatchHI,
XContext, Reserved1, Reserved2, Debug,
DEPC, PerfCnt, ErrCtl, CacheErr,
TagLo, TagHi, ErrorEPC, DESAVE;
} n;
u32 r[32];
};
struct cpuRegisters {
GPRregs GPR; // GPR regs
// NOTE: don't change order since recompiler uses it
GPR_reg HI;
GPR_reg LO; // hi & log 128bit wide
CP0regs CP0; // is COP0 32bit?
u32 sa; // shift amount (32bit), needs to be 16 byte aligned
u32 IsDelaySlot; // set true when the current instruction is a delay slot.
u32 pc; // Program counter, when changing offset in struct, check iR5900-X.S to make sure offset is correct
u32 code; // current instruction
PERFregs PERF;
u32 eCycle[32];
u32 sCycle[32]; // for internal counters
u32 cycle; // calculate cpucycles..
u32 interrupt;
int branch;
int opmode; // operating mode
u32 tempcycles;
u32 dmastall;
u32 pcWriteback;
// if cpuRegs.cycle is greater than this cycle, should check cpuEventTest for updates
u32 nextEventCycle;
u32 lastEventCycle;
u32 lastCOP0Cycle;
u32 lastPERFCycle[2];
};
// used for optimization
union GPR_reg64 {
u64 UD[1]; //64 bits
@@ -149,19 +28,6 @@ union GPR_reg64 {
s8 SC[8];
};
union FPRreg {
float f;
u32 UL;
s32 SL; // signed 32bit used for sign extension in interpreters.
};
struct fpuRegisters {
FPRreg fpr[32]; // 32bit floating point registers
u32 fprc[32]; // 32bit floating point control registers
FPRreg ACC; // 32 bit accumulator
u32 ACCflag; // an internal accumulator overflow flag
};
union PageMask_t
{
struct
@@ -255,13 +121,6 @@ struct tlbs
#endif
struct cpuRegistersPack
{
alignas(16) cpuRegisters cpuRegs;
alignas(16) fpuRegisters fpuRegs;
};
alignas(16) extern cpuRegistersPack _cpuRegistersPack;
alignas(16) extern tlbs tlb[48];
struct cachedTlbs_t
@@ -276,10 +135,6 @@ struct cachedTlbs_t
};
extern cachedTlbs_t cachedTlbs;
static cpuRegisters& cpuRegs = _cpuRegistersPack.cpuRegs;
static fpuRegisters& fpuRegs = _cpuRegistersPack.fpuRegs;
extern bool eeEventTestIsActive;
void intUpdateCPUCycles();
+4 -4
View File
@@ -575,7 +575,7 @@ public:
~SavestateEntry_VU0mem() = default;
const char* GetFilename() const override { return "vu0Memory.bin"; }
u8* GetDataPtr() const override { return vuRegs[0].Mem; }
u8* GetDataPtr() const override { return g_cpuRegistersPack.vuRegs[0].Mem; }
uint GetDataSize() const override { return VU0_MEMSIZE; }
};
@@ -585,7 +585,7 @@ public:
~SavestateEntry_VU1mem() = default;
const char* GetFilename() const override { return "vu1Memory.bin"; }
u8* GetDataPtr() const override { return vuRegs[1].Mem; }
u8* GetDataPtr() const override { return g_cpuRegistersPack.vuRegs[1].Mem; }
uint GetDataSize() const override { return VU1_MEMSIZE; }
};
@@ -595,7 +595,7 @@ public:
~SavestateEntry_VU0prog() = default;
const char* GetFilename() const override { return "vu0MicroMem.bin"; }
u8* GetDataPtr() const override { return vuRegs[0].Micro; }
u8* GetDataPtr() const override { return g_cpuRegistersPack.vuRegs[0].Micro; }
uint GetDataSize() const override { return VU0_PROGSIZE; }
};
@@ -605,7 +605,7 @@ public:
~SavestateEntry_VU1prog() = default;
const char* GetFilename() const override { return "vu1MicroMem.bin"; }
u8* GetDataPtr() const override { return vuRegs[1].Micro; }
u8* GetDataPtr() const override { return g_cpuRegistersPack.vuRegs[1].Micro; }
uint GetDataSize() const override { return VU1_PROGSIZE; }
};
+2 -168
View File
@@ -33,171 +33,9 @@ enum VUStatus
VU_Stop = 2,
};
union VECTOR
{
struct
{
float x, y, z, w;
} f;
struct
{
u32 x, y, z, w;
} i;
float F[4];
u128 UQ;
s128 SQ;
u64 UD[2]; //128 bits
s64 SD[2];
u32 UL[4];
s32 SL[4];
u16 US[8];
s16 SS[8];
u8 UC[16];
s8 SC[16];
};
struct REG_VI
{
union
{
float F;
s32 SL;
u32 UL;
s16 SS[2];
u16 US[2];
s8 SC[4];
u8 UC[4];
};
u32 padding[3]; // needs padding to make them 128bit; VU0 maps VU1's VI regs as 128bits to addr 0x4xx0 in
// VU0 mem, with only lower 16 bits valid, and the upper 112bits are hardwired to 0 (cottonvibes)
};
//#define VUFLAG_BREAKONMFLAG 0x00000001
#define VUFLAG_MFLAGSET 0x00000002
#define VUFLAG_INTCINTERRUPT 0x00000004
struct fdivPipe
{
int enable;
REG_VI reg;
u32 sCycle;
u32 Cycle;
u32 statusflag;
};
struct efuPipe
{
int enable;
REG_VI reg;
u32 sCycle;
u32 Cycle;
};
struct fmacPipe
{
u32 regupper;
u32 reglower;
int flagreg;
u32 xyzwupper;
u32 xyzwlower;
u32 sCycle;
u32 Cycle;
u32 macflag;
u32 statusflag;
u32 clipflag;
};
struct ialuPipe
{
int reg;
u32 sCycle;
u32 Cycle;
};
struct alignas(16) VURegs
{
VECTOR VF[32]; // VF and VI need to be first in this struct for proper mapping
REG_VI VI[32]; // needs to be 128bit x 32 (cottonvibes)
VECTOR ACC;
REG_VI q;
REG_VI p;
uint idx; // VU index (0 or 1)
// flags/cycle are needed by VIF dma code, so they have to be here (for now)
// We may replace these by accessors in the future, if merited.
u32 cycle;
u32 flags;
// Current opcode being interpreted or recompiled (this var is used by Interps
// but not microVU. Would like to have it local to their respective classes... someday)
u32 code;
u32 start_pc;
// branch/branchpc are used by interpreter only, but making them local to the interpreter
// classes requires considerable code refactoring. Maybe later. >_<
u32 branch;
u32 branchpc;
u32 delaybranchpc;
bool takedelaybranch;
u32 ebit;
u32 pending_q;
u32 pending_p;
alignas(16) u32 micro_macflags[4];
alignas(16) u32 micro_clipflags[4];
alignas(16) u32 micro_statusflags[4];
// MAC/Status flags -- these are used by interpreters but are kind of hacky
// and shouldn't be relied on for any useful/valid info. Would like to move them out of
// this struct eventually.
u32 macflag;
u32 statusflag;
u32 clipflag;
s32 nextBlockCycles;
u8* Mem;
u8* Micro;
u32 xgkickaddr;
u32 xgkickdiff;
u32 xgkicksizeremaining;
u32 xgkicklastcycle;
u32 xgkickcyclecount;
u32 xgkickenable;
u32 xgkickendpacket;
u8 VIBackupCycles;
u32 VIOldValue;
u32 VIRegNumber;
fmacPipe fmac[4];
u32 fmacreadpos;
u32 fmacwritepos;
u32 fmaccount;
fdivPipe fdiv;
efuPipe efu;
ialuPipe ialu[4];
u32 ialureadpos;
u32 ialuwritepos;
u32 ialucount;
VURegs()
{
Mem = NULL;
Micro = NULL;
}
bool IsVU1() const;
bool IsVU0() const;
VIFregisters& GetVifRegs() const
{
return IsVU1() ? vif1Regs : vif0Regs;
}
};
enum VUPipeState
{
@@ -210,16 +48,12 @@ enum VUPipeState
VUPIPE_XGKICK
};
extern VURegs vuRegs[2];
// Obsolete(?) -- I think I'd rather use vu0Regs/vu1Regs or actually have these explicit to any
// CPP file that needs them only. --air
static VURegs& VU0 = vuRegs[0];
static VURegs& VU1 = vuRegs[1];
// Do not use __fi here because it fires 'multiple definition' error in GCC
inline bool VURegs::IsVU1() const { return this == &vuRegs[1]; }
inline bool VURegs::IsVU0() const { return this == &vuRegs[0]; }
inline bool VURegs::IsVU1() const { return this == &g_cpuRegistersPack.vuRegs[1]; }
inline bool VURegs::IsVU0() const { return this == &g_cpuRegistersPack.vuRegs[0]; }
extern void vuMemAllocate();
extern void vuMemReset();
+1 -1
View File
@@ -5,7 +5,7 @@
#include "VUmicro.h"
#include "MTVU.h"
alignas(16) VURegs vuRegs[2];
//alignas(16) VURegs vuRegs[2];
void vuMemAllocate()
{
+7 -7
View File
@@ -1134,12 +1134,12 @@ static __fi void _vuMR32(VURegs* VU)
__fi u32* GET_VU_MEM(VURegs* VU, u32 addr) // non-static, also used by sVU for now.
{
if (VU == &vuRegs[1])
return (u32*)(vuRegs[1].Mem + (addr & 0x3fff));
if (VU == &g_cpuRegistersPack.vuRegs[1])
return (u32*)(g_cpuRegistersPack.vuRegs[1].Mem + (addr & 0x3fff));
else if (addr & 0x4000)
return (u32*)((u8*)vuRegs[1].VF + (addr & 0x3ff)); // get VF and VI regs (they're mapped to 0x4xx0 in VU0 mem!)
return (u32*)((u8*)g_cpuRegistersPack.vuRegs[1].VF + (addr & 0x3ff)); // get VF and VI regs (they're mapped to 0x4xx0 in VU0 mem!)
else
return (u32*)(vuRegs[0].Mem + (addr & 0xfff)); // for addr 0x0000 to 0x4000 just wrap around
return (u32*)(g_cpuRegistersPack.vuRegs[0].Mem + (addr & 0xfff)); // for addr 0x0000 to 0x4000 just wrap around
}
static __ri void _vuLQ(VURegs* VU)
@@ -1832,7 +1832,7 @@ void _vuXGKICKTransfer(s32 cycles, bool flush)
if (VU1.xgkicksizeremaining == 0)
{
VUM_LOG("XGKICK reading new tag from %x", VU1.xgkickaddr);
u32 size = gifUnit.GetGSPacketSize(GIF_PATH_1, vuRegs[1].Mem, VU1.xgkickaddr, ~0u, flush);
u32 size = gifUnit.GetGSPacketSize(GIF_PATH_1, g_cpuRegistersPack.vuRegs[1].Mem, VU1.xgkickaddr, ~0u, flush);
VU1.xgkicksizeremaining = size & 0xFFFF;
VU1.xgkickendpacket = size >> 31;
VU1.xgkickdiff = 0x4000 - VU1.xgkickaddr;
@@ -1867,11 +1867,11 @@ void _vuXGKICKTransfer(s32 cycles, bool flush)
if ((transfersize * 0x10) < VU1.xgkicksizeremaining)
gifUnit.gifPath[GIF_PATH_1].CopyGSPacketData(&VU1.Mem[VU1.xgkickaddr], transfersize * 0x10, true);
else
gifUnit.TransferGSPacketData(GIF_TRANS_XGKICK, &vuRegs[1].Mem[VU1.xgkickaddr], transfersize * 0x10, true);
gifUnit.TransferGSPacketData(GIF_TRANS_XGKICK, &g_cpuRegistersPack.vuRegs[1].Mem[VU1.xgkickaddr], transfersize * 0x10, true);
}
else*/
//{
gifUnit.TransferGSPacketData(GIF_TRANS_XGKICK, &vuRegs[1].Mem[VU1.xgkickaddr], transfersize * 0x10, true);
gifUnit.TransferGSPacketData(GIF_TRANS_XGKICK, &g_cpuRegistersPack.vuRegs[1].Mem[VU1.xgkickaddr], transfersize * 0x10, true);
//}
if ((VU0.VI[REG_VPU_STAT].UL & 0x100) && flush)
-113
View File
@@ -79,38 +79,6 @@ enum vif_stallreasons
VIF_IRQ_STALL = 2
};
//
// Bitfield Structure
//
union tVIF_STAT {
struct {
u32 VPS : 2; // Vif(0/1) status; 00 - idle, 01 - waiting for data following vifcode, 10 - decoding vifcode, 11 - decompressing/trasferring data follwing vifcode.
u32 VEW : 1; // E-bit wait (1 - wait, 0 - don't wait)
u32 VGW : 1; // Status waiting for the end of gif transfer (Vif1 only)
u32 _reserved : 2;
u32 MRK : 1; // Mark Detect
u32 DBF : 1; // Double Buffer Flag
u32 VSS : 1; // Stopped by STOP
u32 VFS : 1; // Stopped by ForceBreak
u32 VIS : 1; // Vif Interrupt Stall
u32 INT : 1; // Intereupt by the i bit.
u32 ER0 : 1; // DmaTag Mismatch error.
u32 ER1 : 1; // VifCode error
u32 _reserved2 : 9;
u32 FDR : 1; // VIF/FIFO transfer direction. (false - memory -> Vif, true - Vif -> memory)
u32 FQC : 5; // Amount of data. Up to 8 qwords on Vif0, 16 on Vif1.
};
u32 _u32;
tVIF_STAT() = default;
tVIF_STAT(u32 val) { _u32 = val; }
bool test(u32 flags) const { return !!(_u32 & flags); }
void set_flags (u32 flags) { _u32 |= flags; }
void clear_flags(u32 flags) { _u32 &= ~flags; }
void reset() { _u32 = 0; }
std::string desc() const { return StringUtil::StdStringFromFormat("Stat: 0x%x", _u32); }
};
#define VIF_STAT(value) ((tVIF_STAT)(value))
union tVIF_FBRST {
@@ -134,84 +102,6 @@ union tVIF_FBRST {
#define FBRST(value) ((tVIF_FBRST)(value))
union tVIF_ERR {
struct {
u32 MII : 1; // Masks Stat INT.
u32 ME0 : 1; // Masks Stat Err0.
u32 ME1 : 1; // Masks Stat Err1.
u32 _reserved : 29;
};
u32 _u32;
tVIF_ERR() = default;
tVIF_ERR (u32 val) { _u32 = val; }
void write(u32 val) { _u32 = val; }
bool test (u32 flags) const { return !!(_u32 & flags); }
void set_flags (u32 flags) { _u32 |= flags; }
void clear_flags(u32 flags) { _u32 &= ~flags; }
void reset() { _u32 = 0; }
std::string desc() const { return StringUtil::StdStringFromFormat("Err: 0x%x", _u32); }
};
struct vifCycle
{
u8 cl, wl;
u8 pad[2];
};
struct VIFregisters {
tVIF_STAT stat;
u32 _pad0[3];
u32 fbrst;
u32 _pad1[3];
tVIF_ERR err;
u32 _pad2[3];
u32 mark;
u32 _pad3[3];
vifCycle cycle; //data write cycle
u32 _pad4[3];
u32 mode;
u32 _pad5[3];
u32 num;
u32 _pad6[3];
u32 mask;
u32 _pad7[3];
u32 code;
u32 _pad8[3];
u32 itops;
u32 _pad9[3];
u32 base; // Not used in VIF0
u32 _pad10[3];
u32 ofst; // Not used in VIF0
u32 _pad11[3];
u32 tops; // Not used in VIF0
u32 _pad12[3];
u32 itop;
u32 _pad13[3];
u32 top; // Not used in VIF0
u32 _pad14[3];
u32 mskpath3;
u32 _pad15[3];
u32 r0; // row0 register
u32 _pad16[3];
u32 r1; // row1 register
u32 _pad17[3];
u32 r2; // row2 register
u32 _pad18[3];
u32 r3; // row3 register
u32 _pad19[3];
u32 c0; // col0 register
u32 _pad20[3];
u32 c1; // col1 register
u32 _pad21[3];
u32 c2; // col2 register
u32 _pad22[3];
u32 c3; // col3 register
u32 _pad23[3];
u32 offset; // internal UNPACK offset
u32 addr;
};
struct VIFregistersMTVU {
vifCycle cycle; //data write cycle
u32 mode;
@@ -221,9 +111,6 @@ struct VIFregistersMTVU {
u32 top; // Not used in VIF0
};
static VIFregisters& vif0Regs = (VIFregisters&)eeHw[0x3800];
static VIFregisters& vif1Regs = (VIFregisters&)eeHw[0x3C00];
#define _vifT template <int idx>
#define GetVifX (idx ? (vif1) : (vif0))
#define vifXch (idx ? (vif1ch) : (vif0ch))
+1 -1
View File
@@ -317,7 +317,7 @@ void releaseNewVif(int idx)
static __fi u8* getVUptr(uint idx, int offset)
{
return (u8*)(vuRegs[idx].Mem + (offset & (idx ? 0x3ff0 : 0xff0)));
return (u8*)(g_cpuRegistersPack.vuRegs[idx].Mem + (offset & (idx ? 0x3ff0 : 0xff0)));
}
+1 -1
View File
@@ -543,7 +543,7 @@ _vifT __fi void dVifUnpack(const u8* data, bool isFill)
}
{ // Execute the block
const VURegs& VU = vuRegs[idx];
const VURegs& VU = g_cpuRegistersPack.vuRegs[idx];
const uint vuMemLimit = idx ? 0x4000 : 0x1000;
u8* startmem = VU.Mem + (vif.tag.addr & (vuMemLimit - 0x10));
+1 -1
View File
@@ -492,7 +492,7 @@ _vifT __fi void dVifUnpack(const u8* data, bool isFill)
b = dVifCompile<idx>(block, isFill);
{ // Execute the block
const VURegs& VU = vuRegs[idx];
const VURegs& VU = g_cpuRegistersPack.vuRegs[idx];
constexpr uint vuMemLimit = idx ? 0x4000 : 0x1000;
u8* startmem = VU.Mem + (vif.tag.addr & (vuMemLimit - 0x10));
+7 -7
View File
@@ -640,7 +640,7 @@ void _deletePSXtoX86reg(int reg, int flush)
{
pxAssert(reg != 0);
// xMOV(ptr32[&psxRegs.GPR.r[reg]], xRegister32(i));
armStore(PTR_PSX(GPR.r[reg]), a64::WRegister(i));
armStore(PTR_CPU(psxRegs.GPR.r[reg]), a64::WRegister(i));
// get rid of MODE_WRITE since don't want to flush again
x86regs[i].mode &= ~MODE_WRITE;
@@ -748,15 +748,15 @@ void _writebackXMMreg(int xmmreg)
{
if (xmmregs[xmmreg].reg == 33) {
// xMOVSS(ptr[&VU0.VI[REG_I].F], xRegisterSSE(xmmreg));
armAsm->Str(a64::QRegister(xmmreg).S(), PTR_VUR(VI[REG_I].F));
armAsm->Str(a64::QRegister(xmmreg).S(), PTR_CPU(vuRegs[0].VI[REG_I].F));
}
else if (xmmregs[xmmreg].reg == 32) {
// xMOVAPS(ptr[VU0.ACC.F], xRegisterSSE(xmmreg));
armAsm->Str(a64::QRegister(xmmreg).Q(), PTR_VUR(ACC.F));
armAsm->Str(a64::QRegister(xmmreg).Q(), PTR_CPU(vuRegs[0].ACC.F));
}
else if (xmmregs[xmmreg].reg > 0) {
// xMOVAPS(ptr[VU0.VF[xmmregs[xmmreg].reg].F], xRegisterSSE(xmmreg));
armAsm->Str(a64::QRegister(xmmreg).Q(), PTR_VUR(VF[xmmregs[xmmreg].reg].F));
armAsm->Str(a64::QRegister(xmmreg).Q(), PTR_CPU(vuRegs[0].VF[xmmregs[xmmreg].reg].F));
}
}
break;
@@ -845,15 +845,15 @@ int _allocVFtoXMMreg(int vfreg, int mode)
{
if (vfreg == 33) {
// xMOVSSZX(xRegisterSSE(xmmreg), ptr[&VU0.VI[REG_I].F]);
armAsm->Ldr(a64::QRegister(xmmreg).S(), PTR_VUR(VI[REG_I].F));
armAsm->Ldr(a64::QRegister(xmmreg).S(), PTR_CPU(vuRegs[0].VI[REG_I].F));
}
else if (vfreg == 32) {
// xMOVAPS(xRegisterSSE(xmmreg), ptr[VU0.ACC.F]);
armAsm->Ldr(a64::QRegister(xmmreg).Q(), PTR_VUR(ACC.F));
armAsm->Ldr(a64::QRegister(xmmreg).Q(), PTR_CPU(vuRegs[0].ACC.F));
}
else {
// xMOVAPS(xRegisterSSE(xmmreg), ptr[VU0.VF[xmmregs[xmmreg].reg].F]);
armAsm->Ldr(a64::QRegister(xmmreg).Q(), PTR_VUR(VF[xmmregs[xmmreg].reg].F));
armAsm->Ldr(a64::QRegister(xmmreg).Q(), PTR_CPU(vuRegs[0].VF[xmmregs[xmmreg].reg].F));
}
}
+5 -5
View File
@@ -409,7 +409,7 @@ int _allocX86reg(int type, int reg, int mode)
{
RALOG("Loading guest PSX reg %d to GPR %d\n", reg, regnum);
// xMOV(new_reg32, ptr32[&psxRegs.GPR.r[reg]]);
armLoad(new_reg32, PTR_PSX(GPR.r[reg]));
armLoad(new_reg32, PTR_CPU(psxRegs.GPR.r[reg]));
}
}
}
@@ -419,7 +419,7 @@ int _allocX86reg(int type, int reg, int mode)
{
RALOG("Loading guest VI reg %d to GPR %d", reg, regnum);
// xMOVZX(xRegister32(regnum), ptr16[&VU0.VI[reg].US[0]]);
armAsm->Ldrh(a64::WRegister(regnum), PTR_VUR(VI[reg].US[0]));
armAsm->Ldrh(a64::WRegister(regnum), PTR_CPU(vuRegs[0].VI[reg].US[0]));
}
break;
@@ -475,7 +475,7 @@ void _writebackX86Reg(int x86reg)
case X86TYPE_VIREG:
RALOG("Writing back VI reg %d for guest reg %d P2\n", x86reg, x86regs[x86reg].reg);
// xMOV(ptr16[&VU0.VI[x86regs[x86reg].reg].UL], xRegister16(x86reg));
armAsm->Strh(a64::WRegister(x86reg), PTR_VUR(VI[x86regs[x86reg].reg].UL));
armAsm->Strh(a64::WRegister(x86reg), PTR_CPU(vuRegs[0].VI[x86regs[x86reg].reg].UL));
break;
case X86TYPE_PCWRITEBACK:
@@ -487,13 +487,13 @@ void _writebackX86Reg(int x86reg)
case X86TYPE_PSX:
RALOG("Writing back PSX GPR reg %d for guest reg %d P2\n", x86reg, x86regs[x86reg].reg);
// xMOV(ptr32[&psxRegs.GPR.r[x86regs[x86reg].reg]], xRegister32(x86reg));
armStore(PTR_PSX(GPR.r[x86regs[x86reg].reg]), a64::WRegister(x86reg));
armStore(PTR_CPU(psxRegs.GPR.r[x86regs[x86reg].reg]), a64::WRegister(x86reg));
break;
case X86TYPE_PSX_PCWRITEBACK:
RALOG("Writing back PSX PC writeback in host reg %d\n", x86reg);
// xMOV(ptr32[&psxRegs.pcWriteback], xRegister32(x86reg));
armStore(PTR_PSX(pcWriteback), a64::WRegister(x86reg));
armStore(PTR_CPU(psxRegs.pcWriteback), a64::WRegister(x86reg));
break;
default:
@@ -490,7 +490,7 @@ static const void* _DynGen_EnterRecompiledCode()
static constexpr u32 stack_size = 32 + 8;
#else
// Stack still needs to be aligned
// static constexpr u32 stack_size = 8;
// static constexpr u32 stack_size = 16;
#endif
// We never return through this function, instead we fastjmp() out.
@@ -501,8 +501,7 @@ static const void* _DynGen_EnterRecompiledCode()
// From memory to registry
armMoveAddressToReg(RSTATE_PSX, &psxRegs);
armMoveAddressToReg(RSTATE_CPU, &_cpuRegistersPack);
armMoveAddressToReg(RSTATE_VUR, &VU0);
armMoveAddressToReg(RSTATE_CPU, &g_cpuRegistersPack);
if (CHECK_FASTMEM) {
// xMOV(RFASTMEMBASE, ptrNative[&vtlb_private::vtlbdata.fastmem_base]);
+3 -1
View File
@@ -7,6 +7,8 @@
#include "common/Perf.h"
#include "common/StringUtil.h"
alignas(16) vuRegistersPack g_vuRegistersPack;
//------------------------------------------------------------------
// Micro VU - Main Functions
//------------------------------------------------------------------
@@ -438,7 +440,7 @@ bool SaveStateBase::vuJITFreeze()
void DumpVUState(u32 n, u32 pc)
{
const VURegs& r = vuRegs[n];
const VURegs& r = g_cpuRegistersPack.vuRegs[n];
const microVU& mVU = (n == 0) ? microVU0 : microVU1;
static FILE* fp = nullptr;
static bool fp_opened = false;
+13 -3
View File
@@ -123,7 +123,8 @@ struct microVU
u32 totalCycles; // Total Cycles that mVU is expected to run for
s32 cycles; // Cycles Counter
VURegs& regs() const { return ::vuRegs[index]; }
// VURegs& regs() const { return ::vuRegs[index]; }
VURegs& regs() const { return ::g_cpuRegistersPack.vuRegs[index]; }
__fi REG_VI& getVI(uint reg) const { return regs().VI[reg]; }
__fi VECTOR& getVF(uint reg) const { return regs().VF[reg]; }
@@ -268,8 +269,17 @@ public:
};
// microVU rec structs
alignas(16) microVU microVU0;
alignas(16) microVU microVU1;
//alignas(16) microVU microVU0;
//alignas(16) microVU microVU1;
struct vuRegistersPack
{
alignas(16) microVU microVU[2];
};
alignas(16) extern vuRegistersPack g_vuRegistersPack;
////
static microVU& microVU0 = g_vuRegistersPack.microVU[0];
static microVU& microVU1 = g_vuRegistersPack.microVU[1];
// Debug Helper
int mVUdebugNow = 0;
+10 -10
View File
@@ -75,10 +75,10 @@ __ri void mVUallocSFLAGc(const x32& reg, const x32& regT, int fInstance)
}
// Denormalizes Status Flag; destroys tmp1/tmp2
__ri void mVUallocSFLAGd(u32* memAddr, const x32& reg = EAX, const x32& tmp1 = ECX, const x32& tmp2 = EDX)
__ri void mVUallocSFLAGd(const a64::MemOperand memAddr, const x32& reg = EAX, const x32& tmp1 = ECX, const x32& tmp2 = EDX)
{
// xMOV(tmp2, ptr32[memAddr]);
armAsm->Ldr(tmp2, armMemOperandPtr(memAddr));
armAsm->Ldr(tmp2, memAddr);
// xMOV(reg, tmp2);
armAsm->Mov(reg, tmp2);
// xSHR(reg, 3);
@@ -106,7 +106,7 @@ __ri void mVUallocSFLAGd(u32* memAddr, const x32& reg = EAX, const x32& tmp1 = E
__fi void mVUallocMFLAGa(mV, const x32& reg, int fInstance)
{
// xMOVZX(reg, ptr16[&mVU.macFlag[fInstance]]);
armAsm->Ldrh(reg, PTR_MVU(macFlag[fInstance]));
armAsm->Ldrh(reg, PTR_MVU(microVU[mVU.index].macFlag[fInstance]));
}
__fi void mVUallocMFLAGb(mV, const x32& reg, int fInstance)
@@ -114,11 +114,11 @@ __fi void mVUallocMFLAGb(mV, const x32& reg, int fInstance)
//xAND(reg, 0xffff);
if (fInstance < 4) {
// xMOV(ptr32[&mVU.macFlag[fInstance]], reg); // microVU
armAsm->Str(reg, PTR_MVU(macFlag[fInstance]));
armAsm->Str(reg, PTR_MVU(microVU[mVU.index].macFlag[fInstance]));
}
else {
// xMOV(ptr32[&mVU.regs().VI[REG_MAC_FLAG].UL], reg); // macroVU
armAsm->Str(reg, PTR_VUR(VI[REG_MAC_FLAG].UL));
armAsm->Str(reg, PTR_CPU(vuRegs[mVU.index].VI[REG_MAC_FLAG].UL));
}
}
@@ -126,11 +126,11 @@ __fi void mVUallocCFLAGa(mV, const x32& reg, int fInstance)
{
if (fInstance < 4) {
// xMOV(reg, ptr32[&mVU.clipFlag[fInstance]]); // microVU
armAsm->Ldr(reg, PTR_MVU(clipFlag[fInstance]));
armAsm->Ldr(reg, PTR_MVU(microVU[mVU.index].clipFlag[fInstance]));
}
else {
// xMOV(reg, ptr32[&mVU.regs().VI[REG_CLIP_FLAG].UL]); // macroVU
armAsm->Ldr(reg, PTR_VUR(VI[REG_CLIP_FLAG].UL));
armAsm->Ldr(reg, PTR_CPU(vuRegs[mVU.index].VI[REG_CLIP_FLAG].UL));
}
}
@@ -138,11 +138,11 @@ __fi void mVUallocCFLAGb(mV, const x32& reg, int fInstance)
{
if (fInstance < 4) {
// xMOV(ptr32[&mVU.clipFlag[fInstance]], reg); // microVU
armAsm->Str(reg, PTR_MVU(clipFlag[fInstance]));
armAsm->Str(reg, PTR_MVU(microVU[mVU.index].clipFlag[fInstance]));
}
else {
// xMOV(ptr32[&mVU.regs().VI[REG_CLIP_FLAG].UL], reg); // macroVU
armAsm->Str(reg, PTR_VUR(VI[REG_CLIP_FLAG].UL));
armAsm->Str(reg, PTR_CPU(vuRegs[mVU.index].VI[REG_CLIP_FLAG].UL));
}
}
@@ -154,7 +154,7 @@ void microRegAlloc::writeVIBackup(const a64::Register& reg)
{
microVU& mVU = index ? microVU1 : microVU0;
// xMOV(ptr32[&mVU.VIbackup], xRegister32(reg));
armAsm->Str(a64::WRegister(reg), PTR_MVU(VIbackup));
armAsm->Str(a64::WRegister(reg), PTR_MVU(microVU[mVU.index].VIbackup));
}
//------------------------------------------------------------------
+85 -85
View File
@@ -69,11 +69,11 @@ void mVUDTendProgram(mV, microFlagCycles* mFC, int isEbit)
armPSHUFD(xmmPQ, xmmPQ, 0xe1);
}
// xMOVSS(ptr32[&mVU.regs().VI[REG_Q].UL], xmmPQ);
armAsm->Str(xmmPQ.S(), PTR_VUR(VI[REG_Q].UL));
armAsm->Str(xmmPQ.S(), PTR_CPU(vuRegs[mVU.index].VI[REG_Q].UL));
// xPSHUF.D(xmmPQ, xmmPQ, 0xe1);
armPSHUFD(xmmPQ, xmmPQ, 0xe1);
// xMOVSS(ptr32[&mVU.regs().pending_q], xmmPQ);
armAsm->Str(xmmPQ.S(), PTR_VUR(pending_q));
armAsm->Str(xmmPQ.S(), PTR_CPU(vuRegs[mVU.index].pending_q));
// xPSHUF.D(xmmPQ, xmmPQ, 0xe1);
armPSHUFD(xmmPQ, xmmPQ, 0xe1);
@@ -86,11 +86,11 @@ void mVUDTendProgram(mV, microFlagCycles* mFC, int isEbit)
// xPSHUF.D(xmmPQ, xmmPQ, 0xC6); // 3 0 1 2
armPSHUFD(xmmPQ, xmmPQ, 0xC6);
// xMOVSS(ptr32[&mVU.regs().VI[REG_P].UL], xmmPQ);
armAsm->Str(xmmPQ.S(), PTR_VUR(VI[REG_P].UL));
armAsm->Str(xmmPQ.S(), PTR_CPU(vuRegs[mVU.index].VI[REG_P].UL));
// xPSHUF.D(xmmPQ, xmmPQ, 0x87); // 0 2 1 3
armPSHUFD(xmmPQ, xmmPQ, 0x87);
// xMOVSS(ptr32[&mVU.regs().pending_p], xmmPQ);
armAsm->Str(xmmPQ.S(), PTR_VUR(pending_p));
armAsm->Str(xmmPQ.S(), PTR_CPU(vuRegs[mVU.index].pending_p));
// xPSHUF.D(xmmPQ, xmmPQ, 0x27); // 3 2 1 0
armPSHUFD(xmmPQ, xmmPQ, 0x27);
}
@@ -98,72 +98,72 @@ void mVUDTendProgram(mV, microFlagCycles* mFC, int isEbit)
// Save MAC, Status and CLIP Flag Instances
mVUallocSFLAGc(gprT1, gprT2, fStatus);
// xMOV(ptr32[&mVU.regs().VI[REG_STATUS_FLAG].UL], gprT1);
armAsm->Str(gprT1, PTR_VUR(VI[REG_STATUS_FLAG].UL));
armAsm->Str(gprT1, PTR_CPU(vuRegs[mVU.index].VI[REG_STATUS_FLAG].UL));
mVUallocMFLAGa(mVU, gprT1, fMac);
mVUallocCFLAGa(mVU, gprT2, fClip);
// xMOV(ptr32[&mVU.regs().VI[REG_MAC_FLAG].UL], gprT1);
armAsm->Str(gprT1, PTR_VUR(VI[REG_MAC_FLAG].UL));
armAsm->Str(gprT1, PTR_CPU(vuRegs[mVU.index].VI[REG_MAC_FLAG].UL));
// xMOV(ptr32[&mVU.regs().VI[REG_CLIP_FLAG].UL], gprT2);
armAsm->Str(gprT2, PTR_VUR(VI[REG_CLIP_FLAG].UL));
armAsm->Str(gprT2, PTR_CPU(vuRegs[mVU.index].VI[REG_CLIP_FLAG].UL));
if (!isEbit) // Backup flag instances
{
// xMOVAPS(xmmT1, ptr128[mVU.macFlag]);
armAsm->Ldr(xmmT1.Q(), PTR_MVU(macFlag));
armAsm->Ldr(xmmT1.Q(), PTR_MVU(microVU[mVU.index].macFlag));
// xMOVAPS(ptr128[&mVU.regs().micro_macflags], xmmT1);
armAsm->Str(xmmT1.Q(), PTR_VUR(micro_macflags));
armAsm->Str(xmmT1.Q(), PTR_CPU(vuRegs[mVU.index].micro_macflags));
// xMOVAPS(xmmT1, ptr128[mVU.clipFlag]);
armAsm->Ldr(xmmT1.Q(), PTR_MVU(clipFlag));
armAsm->Ldr(xmmT1.Q(), PTR_MVU(microVU[mVU.index].clipFlag));
// xMOVAPS(ptr128[&mVU.regs().micro_clipflags], xmmT1);
armAsm->Str(xmmT1.Q(), PTR_VUR(micro_clipflags));
armAsm->Str(xmmT1.Q(), PTR_CPU(vuRegs[mVU.index].micro_clipflags));
// xMOV(ptr32[&mVU.regs().micro_statusflags[0]], gprF0);
armAsm->Str(gprF0, PTR_VUR(micro_statusflags[0]));
armAsm->Str(gprF0, PTR_CPU(vuRegs[mVU.index].micro_statusflags[0]));
// xMOV(ptr32[&mVU.regs().micro_statusflags[1]], gprF1);
armAsm->Str(gprF1, PTR_VUR(micro_statusflags[1]));
armAsm->Str(gprF1, PTR_CPU(vuRegs[mVU.index].micro_statusflags[1]));
// xMOV(ptr32[&mVU.regs().micro_statusflags[2]], gprF2);
armAsm->Str(gprF2, PTR_VUR(micro_statusflags[2]));
armAsm->Str(gprF2, PTR_CPU(vuRegs[mVU.index].micro_statusflags[2]));
// xMOV(ptr32[&mVU.regs().micro_statusflags[3]], gprF3);
armAsm->Str(gprF3, PTR_VUR(micro_statusflags[3]));
armAsm->Str(gprF3, PTR_CPU(vuRegs[mVU.index].micro_statusflags[3]));
}
else // Flush flag instances
{
// xMOVDZX(xmmT1, ptr32[&mVU.regs().VI[REG_CLIP_FLAG].UL]);
armAsm->Ldr(xmmT1, PTR_VUR(VI[REG_CLIP_FLAG].UL));
armAsm->Ldr(xmmT1, PTR_CPU(vuRegs[mVU.index].VI[REG_CLIP_FLAG].UL));
// xSHUF.PS(xmmT1, xmmT1, 0);
armSHUFPS(xmmT1, xmmT1, 0);
// xMOVAPS(ptr128[&mVU.regs().micro_clipflags], xmmT1);
armAsm->Str(xmmT1.Q(), PTR_VUR(micro_clipflags));
armAsm->Str(xmmT1.Q(), PTR_CPU(vuRegs[mVU.index].micro_clipflags));
// xMOVDZX(xmmT1, ptr32[&mVU.regs().VI[REG_MAC_FLAG].UL]);
armAsm->Ldr(xmmT1, PTR_VUR(VI[REG_MAC_FLAG].UL));
armAsm->Ldr(xmmT1, PTR_CPU(vuRegs[mVU.index].VI[REG_MAC_FLAG].UL));
// xSHUF.PS(xmmT1, xmmT1, 0);
armSHUFPS(xmmT1, xmmT1, 0);
// xMOVAPS(ptr128[&mVU.regs().micro_macflags], xmmT1);
armAsm->Str(xmmT1.Q(), PTR_VUR(micro_macflags));
armAsm->Str(xmmT1.Q(), PTR_CPU(vuRegs[mVU.index].micro_macflags));
// xMOVDZX(xmmT1, getFlagReg(fStatus));
armAsm->Fmov(xmmT1.S(), getFlagReg(fStatus));
// xSHUF.PS(xmmT1, xmmT1, 0);
armSHUFPS(xmmT1, xmmT1, 0);
// xMOVAPS(ptr128[&mVU.regs().micro_statusflags], xmmT1);
armAsm->Str(xmmT1.Q(), PTR_VUR(micro_statusflags));
armAsm->Str(xmmT1.Q(), PTR_CPU(vuRegs[mVU.index].micro_statusflags));
}
if (EmuConfig.Gamefixes.VUSyncHack || EmuConfig.Gamefixes.FullVU0SyncHack) {
// xMOV(ptr32[&mVU.regs().nextBlockCycles], 0);
armAsm->Str(a64::wzr, PTR_VUR(nextBlockCycles));
armAsm->Str(a64::wzr, PTR_CPU(vuRegs[mVU.index].nextBlockCycles));
}
// xMOV(ptr32[&mVU.regs().VI[REG_TPC].UL], xPC);
armStorePtr(xPC, PTR_VUR(VI[REG_TPC].UL));
armStorePtr(xPC, PTR_CPU(vuRegs[mVU.index].VI[REG_TPC].UL));
if (isEbit) // Clear 'is busy' Flags
{
if (!mVU.index || !THREAD_VU1)
{
// xAND(ptr32[&VU0.VI[REG_VPU_STAT].UL], (isVU1 ? ~0x100 : ~0x001)); // VBS0/VBS1 flag
armAnd(PTR_VUR(VI[REG_VPU_STAT].UL), (isVU1 ? ~0x100 : ~0x001));
armAnd(PTR_CPU(vuRegs[0].VI[REG_VPU_STAT].UL), (isVU1 ? ~0x100 : ~0x001));
}
}
@@ -235,11 +235,11 @@ void mVUendProgram(mV, microFlagCycles* mFC, int isEbit)
armPSHUFD(xmmPQ, xmmPQ, 0xe1);
}
// xMOVSS(ptr32[&mVU.regs().VI[REG_Q].UL], xmmPQ);
armAsm->Str(xmmPQ.S(), PTR_VUR(VI[REG_Q].UL));
armAsm->Str(xmmPQ.S(), PTR_CPU(vuRegs[mVU.index].VI[REG_Q].UL));
// xPSHUF.D(xmmPQ, xmmPQ, 0xe1);
armPSHUFD(xmmPQ, xmmPQ, 0xe1);
// xMOVSS(ptr32[&mVU.regs().pending_q], xmmPQ);
armAsm->Str(xmmPQ.S(), PTR_VUR(pending_q));
armAsm->Str(xmmPQ.S(), PTR_CPU(vuRegs[mVU.index].pending_q));
// xPSHUF.D(xmmPQ, xmmPQ, 0xe1);
armPSHUFD(xmmPQ, xmmPQ, 0xe1);
@@ -252,11 +252,11 @@ void mVUendProgram(mV, microFlagCycles* mFC, int isEbit)
// xPSHUF.D(xmmPQ, xmmPQ, 0xC6); // 3 0 1 2
armPSHUFD(xmmPQ, xmmPQ, 0xC6);
// xMOVSS(ptr32[&mVU.regs().VI[REG_P].UL], xmmPQ);
armAsm->Str(xmmPQ.S(), PTR_VUR(VI[REG_P].UL));
armAsm->Str(xmmPQ.S(), PTR_CPU(vuRegs[mVU.index].VI[REG_P].UL));
// xPSHUF.D(xmmPQ, xmmPQ, 0x87); // 0 2 1 3
armPSHUFD(xmmPQ, xmmPQ, 0x87);
// xMOVSS(ptr32[&mVU.regs().pending_p], xmmPQ);
armAsm->Str(xmmPQ.S(), PTR_VUR(pending_p));
armAsm->Str(xmmPQ.S(), PTR_CPU(vuRegs[mVU.index].pending_p));
// xPSHUF.D(xmmPQ, xmmPQ, 0x27); // 3 2 1 0
armPSHUFD(xmmPQ, xmmPQ, 0x27);
}
@@ -264,78 +264,78 @@ void mVUendProgram(mV, microFlagCycles* mFC, int isEbit)
// Save MAC, Status and CLIP Flag Instances
mVUallocSFLAGc(gprT1, gprT2, fStatus);
// xMOV(ptr32[&mVU.regs().VI[REG_STATUS_FLAG].UL], gprT1);
armAsm->Str(gprT1, PTR_VUR(VI[REG_STATUS_FLAG].UL));
armAsm->Str(gprT1, PTR_CPU(vuRegs[mVU.index].VI[REG_STATUS_FLAG].UL));
mVUallocMFLAGa(mVU, gprT1, fMac);
mVUallocCFLAGa(mVU, gprT2, fClip);
// xMOV(ptr32[&mVU.regs().VI[REG_MAC_FLAG].UL], gprT1);
armAsm->Str(gprT1, PTR_VUR(VI[REG_MAC_FLAG].UL));
armAsm->Str(gprT1, PTR_CPU(vuRegs[mVU.index].VI[REG_MAC_FLAG].UL));
// xMOV(ptr32[&mVU.regs().VI[REG_CLIP_FLAG].UL], gprT2);
armAsm->Str(gprT2, PTR_VUR(VI[REG_CLIP_FLAG].UL));
armAsm->Str(gprT2, PTR_CPU(vuRegs[mVU.index].VI[REG_CLIP_FLAG].UL));
if (!isEbit || isEbit == 3) // Backup flag instances
{
// xMOVAPS(xmmT1, ptr128[mVU.macFlag]);
armAsm->Ldr(xmmT1.Q(), PTR_MVU(macFlag));
armAsm->Ldr(xmmT1.Q(), PTR_MVU(microVU[mVU.index].macFlag));
// xMOVAPS(ptr128[&mVU.regs().micro_macflags], xmmT1);
armAsm->Str(xmmT1.Q(), PTR_VUR(micro_macflags));
armAsm->Str(xmmT1.Q(), PTR_CPU(vuRegs[mVU.index].micro_macflags));
// xMOVAPS(xmmT1, ptr128[mVU.clipFlag]);
armAsm->Ldr(xmmT1.Q(), PTR_MVU(clipFlag));
armAsm->Ldr(xmmT1.Q(), PTR_MVU(microVU[mVU.index].clipFlag));
// xMOVAPS(ptr128[&mVU.regs().micro_clipflags], xmmT1);
armAsm->Str(xmmT1.Q(), PTR_VUR(micro_clipflags));
armAsm->Str(xmmT1.Q(), PTR_CPU(vuRegs[mVU.index].micro_clipflags));
// xMOV(ptr32[&mVU.regs().micro_statusflags[0]], gprF0);
armAsm->Str(gprF0, PTR_VUR(micro_statusflags[0]));
armAsm->Str(gprF0, PTR_CPU(vuRegs[mVU.index].micro_statusflags[0]));
// xMOV(ptr32[&mVU.regs().micro_statusflags[1]], gprF1);
armAsm->Str(gprF1, PTR_VUR(micro_statusflags[1]));
armAsm->Str(gprF1, PTR_CPU(vuRegs[mVU.index].micro_statusflags[1]));
// xMOV(ptr32[&mVU.regs().micro_statusflags[2]], gprF2);
armAsm->Str(gprF2, PTR_VUR(micro_statusflags[2]));
armAsm->Str(gprF2, PTR_CPU(vuRegs[mVU.index].micro_statusflags[2]));
// xMOV(ptr32[&mVU.regs().micro_statusflags[3]], gprF3);
armAsm->Str(gprF3, PTR_VUR(micro_statusflags[3]));
armAsm->Str(gprF3, PTR_CPU(vuRegs[mVU.index].micro_statusflags[3]));
}
else // Flush flag instances
{
// xMOVDZX(xmmT1, ptr32[&mVU.regs().VI[REG_CLIP_FLAG].UL]);
armAsm->Ldr(xmmT1, PTR_VUR(VI[REG_CLIP_FLAG].UL));
armAsm->Ldr(xmmT1, PTR_CPU(vuRegs[mVU.index].VI[REG_CLIP_FLAG].UL));
// xSHUF.PS(xmmT1, xmmT1, 0);
armSHUFPS(xmmT1, xmmT1, 0);
// xMOVAPS(ptr128[&mVU.regs().micro_clipflags], xmmT1);
armAsm->Str(xmmT1.Q(), PTR_VUR(micro_clipflags));
armAsm->Str(xmmT1.Q(), PTR_CPU(vuRegs[mVU.index].micro_clipflags));
// xMOVDZX(xmmT1, ptr32[&mVU.regs().VI[REG_MAC_FLAG].UL]);
armAsm->Ldr(xmmT1, PTR_VUR(VI[REG_MAC_FLAG].UL));
armAsm->Ldr(xmmT1, PTR_CPU(vuRegs[mVU.index].VI[REG_MAC_FLAG].UL));
// xSHUF.PS(xmmT1, xmmT1, 0);
armSHUFPS(xmmT1, xmmT1, 0);
// xMOVAPS(ptr128[&mVU.regs().micro_macflags], xmmT1);
armAsm->Str(xmmT1.Q(), PTR_VUR(micro_macflags));
armAsm->Str(xmmT1.Q(), PTR_CPU(vuRegs[mVU.index].micro_macflags));
// xMOVDZX(xmmT1, getFlagReg(fStatus));
armAsm->Fmov(xmmT1.S(), getFlagReg(fStatus));
// xSHUF.PS(xmmT1, xmmT1, 0);
armSHUFPS(xmmT1, xmmT1, 0);
// xMOVAPS(ptr128[&mVU.regs().micro_statusflags], xmmT1);
armAsm->Str(xmmT1.Q(), PTR_VUR(micro_statusflags));
armAsm->Str(xmmT1.Q(), PTR_CPU(vuRegs[mVU.index].micro_statusflags));
}
// xMOV(ptr32[&mVU.regs().VI[REG_TPC].UL], xPC);
armStorePtr(xPC, PTR_VUR(VI[REG_TPC].UL));
armStorePtr(xPC, PTR_CPU(vuRegs[mVU.index].VI[REG_TPC].UL));
if ((isEbit && isEbit != 3)) // Clear 'is busy' Flags
{
if (EmuConfig.Gamefixes.VUSyncHack || EmuConfig.Gamefixes.FullVU0SyncHack) {
// xMOV(ptr32[&mVU.regs().nextBlockCycles], 0);
armStorePtr(0, PTR_VUR(nextBlockCycles));
armStorePtr(0, PTR_CPU(vuRegs[mVU.index].nextBlockCycles));
}
if (!mVU.index || !THREAD_VU1)
{
// xAND(ptr32[&VU0.VI[REG_VPU_STAT].UL], (isVU1 ? ~0x100 : ~0x001)); // VBS0/VBS1 flag
armAnd(PTR_VUR(VI[REG_VPU_STAT].UL), (isVU1 ? ~0x100 : ~0x001));
armAnd(PTR_CPU(vuRegs[0].VI[REG_VPU_STAT].UL), (isVU1 ? ~0x100 : ~0x001));
}
}
else if (isEbit)
{
if (EmuConfig.Gamefixes.VUSyncHack || EmuConfig.Gamefixes.FullVU0SyncHack) {
// xMOV(ptr32[&mVU.regs().nextBlockCycles], 0);
armStorePtr(0, PTR_VUR(nextBlockCycles));
armStorePtr(0, PTR_CPU(vuRegs[mVU.index].nextBlockCycles));
}
}
@@ -395,16 +395,16 @@ void normJumpCompile(mV, microFlagCycles& mFC, bool isEvilJump)
if (isEvilJump)
{
// xMOV(arg1regd, ptr32[&mVU.evilBranch]);
armAsm->Ldr(EAX, PTR_MVU(evilBranch));
armAsm->Ldr(EAX, PTR_MVU(microVU[mVU.index].evilBranch));
// xMOV(gprT1, ptr32[&mVU.evilevilBranch]);
armAsm->Ldr(EEX, PTR_MVU(evilevilBranch));
armAsm->Ldr(EEX, PTR_MVU(microVU[mVU.index].evilevilBranch));
// xMOV(ptr32[&mVU.evilBranch], gprT1);
armAsm->Str(EEX, PTR_MVU(evilBranch));
armAsm->Str(EEX, PTR_MVU(microVU[mVU.index].evilBranch));
}
else
{
// xMOV(arg1regd, ptr32[&mVU.branch]);
armAsm->Ldr(EAX, PTR_MVU(branch));
armAsm->Ldr(EAX, PTR_MVU(microVU[mVU.index].branch));
}
if (doJumpCaching) {
// xLoadFarAddr(arg2reg, mVUpBlock);
@@ -422,7 +422,7 @@ void normJumpCompile(mV, microFlagCycles& mFC, bool isEvilJump)
//So if it is taken, you need to end the program, else you get infinite loops.
mVUendProgram(mVU, &mFC, 2);
// xMOV(ptr32[&mVU.regs().VI[REG_TPC].UL], arg1regd);
armAsm->Str(EAX, PTR_VUR(VI[REG_TPC].UL));
armAsm->Str(EAX, PTR_CPU(vuRegs[mVU.index].VI[REG_TPC].UL));
if (mVU.index && THREAD_VU1) {
// xFastCall((void *) mVUEBit);
armEmitCall(reinterpret_cast<void*>(mVUEBit));
@@ -460,7 +460,7 @@ void normBranch(mV, microFlagCycles& mFC)
}
else {
// xTEST(ptr32[&VU0.VI[REG_FBRST].UL], (isVU1 ? 0x400 : 0x4));
armAsm->Tst(armLoadPtr(PTR_VUR(VI[REG_FBRST].UL)), (isVU1 ? 0x400 : 0x4));
armAsm->Tst(armLoadPtr(PTR_CPU(vuRegs[0].VI[REG_FBRST].UL)), (isVU1 ? 0x400 : 0x4));
}
// xForwardJump32 eJMP(Jcc_Zero);
a64::Label eJMP;
@@ -468,9 +468,9 @@ void normBranch(mV, microFlagCycles& mFC)
if (!mVU.index || !THREAD_VU1)
{
// xOR(ptr32[&VU0.VI[REG_VPU_STAT].UL], (isVU1 ? 0x200 : 0x2));
armOrr(PTR_VUR(VI[REG_VPU_STAT].UL), (isVU1 ? 0x200 : 0x2));
armOrr(PTR_CPU(vuRegs[0].VI[REG_VPU_STAT].UL), (isVU1 ? 0x200 : 0x2));
// xOR(ptr32[&mVU.regs().flags], VUFLAG_INTCINTERRUPT);
armOrr(PTR_VUR(flags), VUFLAG_INTCINTERRUPT);
armOrr(PTR_CPU(vuRegs[mVU.index].flags), VUFLAG_INTCINTERRUPT);
}
iPC = branchAddr(mVU) >> 2; // branchAddr(mVU) / 4
mVUDTendProgram(mVU, &mFC, 1);
@@ -490,7 +490,7 @@ void normBranch(mV, microFlagCycles& mFC)
}
else {
// xTEST(ptr32[&VU0.VI[REG_FBRST].UL], (isVU1 ? 0x800 : 0x8));
armAsm->Tst(armLoadPtr(PTR_VUR(VI[REG_FBRST].UL)), (isVU1 ? 0x800 : 0x8));
armAsm->Tst(armLoadPtr(PTR_CPU(vuRegs[0].VI[REG_FBRST].UL)), (isVU1 ? 0x800 : 0x8));
}
// xForwardJump32 eJMP(Jcc_Zero);
a64::Label eJMP;
@@ -498,9 +498,9 @@ void normBranch(mV, microFlagCycles& mFC)
if (!mVU.index || !THREAD_VU1)
{
// xOR(ptr32[&VU0.VI[REG_VPU_STAT].UL], (isVU1 ? 0x400 : 0x4));
armOrr(PTR_VUR(VI[REG_VPU_STAT].UL), (isVU1 ? 0x400 : 0x4));
armOrr(PTR_CPU(vuRegs[0].VI[REG_VPU_STAT].UL), (isVU1 ? 0x400 : 0x4));
// xOR(ptr32[&mVU.regs().flags], VUFLAG_INTCINTERRUPT);
armOrr(PTR_VUR(flags), VUFLAG_INTCINTERRUPT);
armOrr(PTR_CPU(vuRegs[mVU.index].flags), VUFLAG_INTCINTERRUPT);
}
iPC = branchAddr(mVU) >> 2; // branchAddr(mVU) / 4
mVUDTendProgram(mVU, &mFC, 1);
@@ -523,7 +523,7 @@ void normBranch(mV, microFlagCycles& mFC)
mVUendProgram(mVU, &mFC, 3);
iPC = branchAddr(mVU) >> 2; // branchAddr(mVU) / 4;
// xMOV(ptr32[&mVU.regs().VI[REG_TPC].UL], xPC);
armStorePtr(xPC, PTR_VUR(VI[REG_TPC].UL));
armStorePtr(xPC, PTR_CPU(vuRegs[mVU.index].VI[REG_TPC].UL));
if (mVU.index && THREAD_VU1) {
// xFastCall((void *) mVUEBit);
armEmitCall(reinterpret_cast<void*>(mVUEBit));
@@ -561,7 +561,7 @@ void condBranch(mV, microFlagCycles& mFC, a64::Condition JMPcc)
}
else {
// xTEST(ptr32[&VU0.VI[REG_FBRST].UL], (isVU1 ? 0x800 : 0x8));
armAsm->Tst(armLoadPtr(PTR_VUR(VI[REG_FBRST].UL)), (isVU1 ? 0x800 : 0x8));
armAsm->Tst(armLoadPtr(PTR_CPU(vuRegs[0].VI[REG_FBRST].UL)), (isVU1 ? 0x800 : 0x8));
}
// xForwardJump32 eJMP(Jcc_Zero);
a64::Label eJMP;
@@ -569,9 +569,9 @@ void condBranch(mV, microFlagCycles& mFC, a64::Condition JMPcc)
if (!mVU.index || !THREAD_VU1)
{
// xOR(ptr32[&VU0.VI[REG_VPU_STAT].UL], (isVU1 ? 0x400 : 0x4));
armOrr(PTR_VUR(VI[REG_VPU_STAT].UL), (isVU1 ? 0x400 : 0x4));
armOrr(PTR_CPU(vuRegs[0].VI[REG_VPU_STAT].UL), (isVU1 ? 0x400 : 0x4));
// xOR(ptr32[&mVU.regs().flags], VUFLAG_INTCINTERRUPT);
armOrr(PTR_VUR(flags), VUFLAG_INTCINTERRUPT);
armOrr(PTR_CPU(vuRegs[mVU.index].flags), VUFLAG_INTCINTERRUPT);
}
mVUDTendProgram(mVU, &mFC, 2);
// xCMP(ptr16[&mVU.branch], 0);
@@ -581,7 +581,7 @@ void condBranch(mV, microFlagCycles& mFC, a64::Condition JMPcc)
armAsm->B(&tJMP, a64::InvertCondition(JMPcc));
incPC(4); // Set PC to First instruction of Non-Taken Side
// xMOV(ptr32[&mVU.regs().VI[REG_TPC].UL], xPC);
armStorePtr(xPC, PTR_VUR(VI[REG_TPC].UL));
armStorePtr(xPC, PTR_CPU(vuRegs[mVU.index].VI[REG_TPC].UL));
if (mVU.index && THREAD_VU1) {
// xFastCall((void *) mVUTBit);
armEmitCall(reinterpret_cast<void*>(mVUTBit));
@@ -593,7 +593,7 @@ void condBranch(mV, microFlagCycles& mFC, a64::Condition JMPcc)
incPC(-4); // Go Back to Branch Opcode to get branchAddr
iPC = branchAddr(mVU) >> 2; // branchAddr(mVU) / 4
// xMOV(ptr32[&mVU.regs().VI[REG_TPC].UL], xPC);
armStorePtr(xPC, PTR_VUR(VI[REG_TPC].UL));
armStorePtr(xPC, PTR_CPU(vuRegs[mVU.index].VI[REG_TPC].UL));
if (mVU.index && THREAD_VU1) {
// xFastCall((void *) mVUTBit);
armEmitCall(reinterpret_cast<void*>(mVUTBit));
@@ -613,7 +613,7 @@ void condBranch(mV, microFlagCycles& mFC, a64::Condition JMPcc)
}
else {
// xTEST(ptr32[&VU0.VI[REG_FBRST].UL], (isVU1 ? 0x400 : 0x4));
armAsm->Tst(armLoadPtr(PTR_VUR(VI[REG_FBRST].UL)), (isVU1 ? 0x400 : 0x4));
armAsm->Tst(armLoadPtr(PTR_CPU(vuRegs[0].VI[REG_FBRST].UL)), (isVU1 ? 0x400 : 0x4));
}
// xForwardJump32 eJMP(Jcc_Zero);
a64::Label eJMP;
@@ -621,9 +621,9 @@ void condBranch(mV, microFlagCycles& mFC, a64::Condition JMPcc)
if (!mVU.index || !THREAD_VU1)
{
// xOR(ptr32[&VU0.VI[REG_VPU_STAT].UL], (isVU1 ? 0x200 : 0x2));
armOrr(PTR_VUR(VI[REG_VPU_STAT].UL), (isVU1 ? 0x200 : 0x2));
armOrr(PTR_CPU(vuRegs[0].VI[REG_VPU_STAT].UL), (isVU1 ? 0x200 : 0x2));
// xOR(ptr32[&mVU.regs().flags], VUFLAG_INTCINTERRUPT);
armOrr(PTR_VUR(flags), VUFLAG_INTCINTERRUPT);
armOrr(PTR_CPU(vuRegs[mVU.index].flags), VUFLAG_INTCINTERRUPT);
}
mVUDTendProgram(mVU, &mFC, 2);
// xCMP(ptr16[&mVU.branch], 0);
@@ -633,7 +633,7 @@ void condBranch(mV, microFlagCycles& mFC, a64::Condition JMPcc)
armAsm->B(&dJMP, a64::InvertCondition(JMPcc));
incPC(4); // Set PC to First instruction of Non-Taken Side
// xMOV(ptr32[&mVU.regs().VI[REG_TPC].UL], xPC);
armStorePtr(xPC, PTR_VUR(VI[REG_TPC].UL));
armStorePtr(xPC, PTR_CPU(vuRegs[mVU.index].VI[REG_TPC].UL));
// xJMP(mVU.exitFunct);
armEmitJmp(mVU.exitFunct);
// dJMP.SetTarget();
@@ -641,7 +641,7 @@ void condBranch(mV, microFlagCycles& mFC, a64::Condition JMPcc)
incPC(-4); // Go Back to Branch Opcode to get branchAddr
iPC = branchAddr(mVU) >> 2; // branchAddr(mVU) / 4
// xMOV(ptr32[&mVU.regs().VI[REG_TPC].UL], xPC);
armStorePtr(xPC, PTR_VUR(VI[REG_TPC].UL));
armStorePtr(xPC, PTR_CPU(vuRegs[mVU.index].VI[REG_TPC].UL));
// xJMP(mVU.exitFunct);
armEmitJmp(mVU.exitFunct);
// eJMP.SetTarget();
@@ -666,7 +666,7 @@ void condBranch(mV, microFlagCycles& mFC, a64::Condition JMPcc)
armAsm->B(&dJMP, JMPcc);
incPC(4); // Set PC to First instruction of Non-Taken Side
// xMOV(ptr32[&mVU.regs().VI[REG_TPC].UL], xPC);
armStorePtr(xPC, PTR_VUR(VI[REG_TPC].UL));
armStorePtr(xPC, PTR_CPU(vuRegs[mVU.index].VI[REG_TPC].UL));
if (mVU.index && THREAD_VU1) {
// xFastCall((void *) mVUEBit);
armEmitCall(reinterpret_cast<void*>(mVUEBit));
@@ -678,7 +678,7 @@ void condBranch(mV, microFlagCycles& mFC, a64::Condition JMPcc)
incPC(-4); // Go Back to Branch Opcode to get branchAddr
iPC = branchAddr(mVU) >> 2; // branchAddr(mVU) / 4
// xMOV(ptr32[&mVU.regs().VI[REG_TPC].UL], xPC);
armStorePtr(xPC, PTR_VUR(VI[REG_TPC].UL));
armStorePtr(xPC, PTR_CPU(vuRegs[mVU.index].VI[REG_TPC].UL));
if (mVU.index && THREAD_VU1) {
// xFastCall((void *) mVUEBit);
armEmitCall(reinterpret_cast<void*>(mVUEBit));
@@ -702,7 +702,7 @@ void condBranch(mV, microFlagCycles& mFC, a64::Condition JMPcc)
armAsm->B(&eJMP, JMPcc);
incPC(1); // Set PC to First instruction of Non-Taken Side
// xMOV(ptr32[&mVU.regs().VI[REG_TPC].UL], xPC);
armStorePtr(xPC, PTR_VUR(VI[REG_TPC].UL));
armStorePtr(xPC, PTR_CPU(vuRegs[mVU.index].VI[REG_TPC].UL));
if (mVU.index && THREAD_VU1) {
// xFastCall((void *) mVUEBit);
armEmitCall(reinterpret_cast<void*>(mVUEBit));
@@ -715,7 +715,7 @@ void condBranch(mV, microFlagCycles& mFC, a64::Condition JMPcc)
iPC = branchAddr(mVU) >> 2; // branchAddr(mVU) / 4
// xMOV(ptr32[&mVU.regs().VI[REG_TPC].UL], xPC);
armStorePtr(xPC, PTR_VUR(VI[REG_TPC].UL));
armStorePtr(xPC, PTR_CPU(vuRegs[mVU.index].VI[REG_TPC].UL));
if (mVU.index && THREAD_VU1) {
// xFastCall((void *) mVUEBit);
armEmitCall(reinterpret_cast<void*>(mVUEBit));
@@ -806,7 +806,7 @@ void normJump(mV, microFlagCycles& mFC)
}
else {
// xTEST(ptr32[&VU0.VI[REG_FBRST].UL], (isVU1 ? 0x400 : 0x4));
armAsm->Tst(armLoadPtr(PTR_VUR(VI[REG_FBRST].UL)), (isVU1 ? 0x400 : 0x4));
armAsm->Tst(armLoadPtr(PTR_CPU(vuRegs[0].VI[REG_FBRST].UL)), (isVU1 ? 0x400 : 0x4));
}
// xForwardJump32 eJMP(Jcc_Zero);
a64::Label eJMP;
@@ -814,15 +814,15 @@ void normJump(mV, microFlagCycles& mFC)
if (!mVU.index || !THREAD_VU1)
{
// xOR(ptr32[&VU0.VI[REG_VPU_STAT].UL], (isVU1 ? 0x200 : 0x2));
armOrr(PTR_VUR(VI[REG_VPU_STAT].UL), (isVU1 ? 0x200 : 0x2));
armOrr(PTR_CPU(vuRegs[0].VI[REG_VPU_STAT].UL), (isVU1 ? 0x200 : 0x2));
// xOR(ptr32[&mVU.regs().flags], VUFLAG_INTCINTERRUPT);
armOrr(PTR_VUR(flags), VUFLAG_INTCINTERRUPT);
armOrr(PTR_CPU(vuRegs[mVU.index].flags), VUFLAG_INTCINTERRUPT);
}
mVUDTendProgram(mVU, &mFC, 2);
// xMOV(gprT1, ptr32[&mVU.branch]);
armAsm->Ldr(gprT1, PTR_MVU(branch));
armAsm->Ldr(gprT1, PTR_MVU(microVU[mVU.index].branch));
// xMOV(ptr32[&mVU.regs().VI[REG_TPC].UL], gprT1);
armAsm->Str(gprT1, PTR_VUR(VI[REG_TPC].UL));
armAsm->Str(gprT1, PTR_CPU(vuRegs[mVU.index].VI[REG_TPC].UL));
// xJMP(mVU.exitFunct);
armEmitJmp(mVU.exitFunct);
// eJMP.SetTarget();
@@ -839,7 +839,7 @@ void normJump(mV, microFlagCycles& mFC)
}
else {
// xTEST(ptr32[&VU0.VI[REG_FBRST].UL], (isVU1 ? 0x800 : 0x8));
armAsm->Tst(armLoadPtr(PTR_VUR(VI[REG_FBRST].UL)), (isVU1 ? 0x800 : 0x8));
armAsm->Tst(armLoadPtr(PTR_CPU(vuRegs[0].VI[REG_FBRST].UL)), (isVU1 ? 0x800 : 0x8));
}
// xForwardJump32 eJMP(Jcc_Zero);
a64::Label eJMP;
@@ -847,15 +847,15 @@ void normJump(mV, microFlagCycles& mFC)
if (!mVU.index || !THREAD_VU1)
{
// xOR(ptr32[&VU0.VI[REG_VPU_STAT].UL], (isVU1 ? 0x400 : 0x4));
armOrr(PTR_VUR(VI[REG_VPU_STAT].UL), (isVU1 ? 0x400 : 0x4));
armOrr(PTR_CPU(vuRegs[0].VI[REG_VPU_STAT].UL), (isVU1 ? 0x400 : 0x4));
// xOR(ptr32[&mVU.regs().flags], VUFLAG_INTCINTERRUPT);
armOrr(PTR_VUR(flags), VUFLAG_INTCINTERRUPT);
armOrr(PTR_CPU(vuRegs[mVU.index].flags), VUFLAG_INTCINTERRUPT);
}
mVUDTendProgram(mVU, &mFC, 2);
// xMOV(gprT1, ptr32[&mVU.branch]);
armAsm->Ldr(gprT1, PTR_MVU(branch));
armAsm->Ldr(gprT1, PTR_MVU(microVU[mVU.index].branch));
// xMOV(ptr32[&mVU.regs().VI[REG_TPC].UL], gprT1);
armAsm->Str(gprT1, PTR_VUR(VI[REG_TPC].UL));
armAsm->Str(gprT1, PTR_CPU(vuRegs[mVU.index].VI[REG_TPC].UL));
if (mVU.index && THREAD_VU1) {
// xFastCall((void *) mVUTBit);
armEmitCall(reinterpret_cast<void*>(mVUTBit));
@@ -869,9 +869,9 @@ void normJump(mV, microFlagCycles& mFC)
{
mVUendProgram(mVU, &mFC, 2);
// xMOV(gprT1, ptr32[&mVU.branch]);
armAsm->Ldr(gprT1, PTR_MVU(branch));
armAsm->Ldr(gprT1, PTR_MVU(microVU[mVU.index].branch));
// xMOV(ptr32[&mVU.regs().VI[REG_TPC].UL], gprT1);
armAsm->Str(gprT1, PTR_VUR(VI[REG_TPC].UL));
armAsm->Str(gprT1, PTR_CPU(vuRegs[mVU.index].VI[REG_TPC].UL));
if (mVU.index && THREAD_VU1) {
// xFastCall((void *) mVUEBit);
armEmitCall(reinterpret_cast<void*>(mVUEBit));
+13 -13
View File
@@ -139,7 +139,7 @@ void doIbit(mV)
// xMOV(gprT1, ptr32[&curI]);
armAsm->Ldr(gprT1, armMemOperandPtr(&curI));
// xMOV(ptr32[&mVU.getVI(REG_I)], gprT1);
armAsm->Str(gprT1, PTR_VUR(VI[REG_I]));
armAsm->Str(gprT1, PTR_CPU(vuRegs[mVU.index].VI[REG_I]));
}
else
{
@@ -153,7 +153,7 @@ void doIbit(mV)
tempI = curI;
// xMOV(ptr32[&mVU.getVI(REG_I)], tempI);
armStorePtr(tempI, PTR_VUR(VI[REG_I]));
armStorePtr(tempI, PTR_CPU(vuRegs[mVU.index].VI[REG_I]));
}
incPC(1);
}
@@ -500,7 +500,7 @@ void mVUtestCycles(microVU& mVU, microFlagCycles& mFC)
}
}
// xMOV(eax, ptr32[&mVU.cycles]);
armAsm->Ldrsw(EAX, PTR_MVU(cycles));
armAsm->Ldrsw(EAX, PTR_MVU(microVU[mVU.index].cycles));
if (EmuConfig.Gamefixes.VUSyncHack) {
// xSUB(eax, mVUcycles); // Running behind, make sure we have time to run the block
armAsm->Subs(EAX, EAX, mVUcycles);
@@ -521,7 +521,7 @@ void mVUtestCycles(microVU& mVU, microFlagCycles& mFC)
if (EmuConfig.Gamefixes.VUSyncHack || EmuConfig.Gamefixes.FullVU0SyncHack) {
// xMOV(ptr32[&mVU.regs().nextBlockCycles], mVUcycles);
armStorePtr(mVUcycles, PTR_VUR(nextBlockCycles));
armStorePtr(mVUcycles, PTR_CPU(vuRegs[mVU.index].nextBlockCycles));
}
mVUendProgram(mVU, &mFC, 0);
@@ -529,7 +529,7 @@ void mVUtestCycles(microVU& mVU, microFlagCycles& mFC)
armBind(&skip);
// xSUB(ptr32[&mVU.cycles], mVUcycles);
armSub(PTR_MVU(cycles), mVUcycles);
armSub(PTR_MVU(microVU[mVU.index].cycles), mVUcycles);
}
//------------------------------------------------------------------
@@ -601,7 +601,7 @@ void mVUDoDBit(microVU& mVU, microFlagCycles* mFC)
}
else {
// xTEST(ptr32[&VU0.VI[REG_FBRST].UL], (isVU1 ? 0x400 : 0x4));
armAsm->Tst(armLoadPtr(PTR_VUR(VI[REG_FBRST].UL)), (isVU1 ? 0x400 : 0x4));
armAsm->Tst(armLoadPtr(PTR_CPU(vuRegs[0].VI[REG_FBRST].UL)), (isVU1 ? 0x400 : 0x4));
}
// xForwardJump32 eJMP(Jcc_Zero);
a64::Label eJMP;
@@ -609,9 +609,9 @@ void mVUDoDBit(microVU& mVU, microFlagCycles* mFC)
if (!isVU1 || !THREAD_VU1)
{
// xOR(ptr32[&VU0.VI[REG_VPU_STAT].UL], (isVU1 ? 0x200 : 0x2));
armOrr(PTR_VUR(VI[REG_VPU_STAT].UL), (isVU1 ? 0x200 : 0x2));
armOrr(PTR_CPU(vuRegs[0].VI[REG_VPU_STAT].UL), (isVU1 ? 0x200 : 0x2));
// xOR(ptr32[&mVU.regs().flags], VUFLAG_INTCINTERRUPT);
armOrr(PTR_VUR(flags), VUFLAG_INTCINTERRUPT);
armOrr(PTR_CPU(vuRegs[mVU.index].flags), VUFLAG_INTCINTERRUPT);
}
incPC(1);
mVUDTendProgram(mVU, mFC, 1);
@@ -628,7 +628,7 @@ void mVUDoTBit(microVU& mVU, microFlagCycles* mFC)
}
else {
// xTEST(ptr32[&VU0.VI[REG_FBRST].UL], (isVU1 ? 0x800 : 0x8));
armAsm->Tst(armLoadPtr(PTR_VUR(VI[REG_FBRST].UL)), (isVU1 ? 0x800 : 0x8));
armAsm->Tst(armLoadPtr(PTR_CPU(vuRegs[0].VI[REG_FBRST].UL)), (isVU1 ? 0x800 : 0x8));
}
// xForwardJump32 eJMP(Jcc_Zero);
a64::Label eJMP;
@@ -636,9 +636,9 @@ void mVUDoTBit(microVU& mVU, microFlagCycles* mFC)
if (!isVU1 || !THREAD_VU1)
{
// xOR(ptr32[&VU0.VI[REG_VPU_STAT].UL], (isVU1 ? 0x400 : 0x4));
armOrr(PTR_VUR(VI[REG_VPU_STAT].UL), (isVU1 ? 0x400 : 0x4));
armOrr(PTR_CPU(vuRegs[0].VI[REG_VPU_STAT].UL), (isVU1 ? 0x400 : 0x4));
// xOR(ptr32[&mVU.regs().flags], VUFLAG_INTCINTERRUPT);
armOrr(PTR_VUR(flags), VUFLAG_INTCINTERRUPT);
armOrr(PTR_CPU(vuRegs[mVU.index].flags), VUFLAG_INTCINTERRUPT);
}
incPC(1);
mVUDTendProgram(mVU, mFC, 1);
@@ -947,7 +947,7 @@ void* mVUcompile(microVU& mVU, u32 startPC, uptr pState)
if (mVUup.mBit)
{
// xOR(ptr32[&mVU.regs().flags], VUFLAG_MFLAGSET);
armOrr(PTR_VUR(flags), VUFLAG_MFLAGSET);
armOrr(PTR_CPU(vuRegs[mVU.index].flags), VUFLAG_MFLAGSET);
}
if (isVU1 && mVUlow.kickcycles && CHECK_XGKICKHACK)
@@ -985,7 +985,7 @@ void* mVUcompile(microVU& mVU, u32 startPC, uptr pState)
mVUsetupRange(mVU, xPC, false);
if (EmuConfig.Gamefixes.VUSyncHack || EmuConfig.Gamefixes.FullVU0SyncHack) {
// xMOV(ptr32[&mVU.regs().nextBlockCycles], 0);
armStorePtr(0, PTR_VUR(nextBlockCycles));
armStorePtr(0, PTR_CPU(vuRegs[mVU.index].nextBlockCycles));
}
mVUendProgram(mVU, &mFC, 0);
normBranchCompile(mVU, xPC);

Some files were not shown because too many files have changed in this diff Show More