Android project - New files related to vuRegistersPack

This commit is contained in:
k2154
2025-07-31 06:18:19 +09:00
parent dcd29b383e
commit 3dd21a4d82
8 changed files with 706 additions and 113 deletions
+125
View File
@@ -0,0 +1,125 @@
//
// Created by k2154 on 2025-07-29.
//
#ifndef PCSX2_R3000ADEF_H
#define PCSX2_R3000ADEF_H
#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;
#endif //PCSX2_R3000ADEF_H
+1 -1
View File
@@ -34,7 +34,7 @@ using namespace R5900; // for R5900 disasm tools
s32 EEsCycle; // used to sync the IOP to the EE
u32 EEoCycle;
alignas(16) cpuRegistersPack _cpuRegistersPack;
alignas(16) cpuRegistersPack g_cpuRegistersPack;
alignas(16) tlbs tlb[48];
cachedTlbs_t cachedTlbs;
+143
View File
@@ -0,0 +1,143 @@
//
// Created by k2154 on 2025-07-30.
//
#ifndef PCSX2_R5900DEF_H
#define PCSX2_R5900DEF_H
#include "common/Pcsx2Defs.h"
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];
};
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
};
#endif //PCSX2_R5900DEF_H
+173
View File
@@ -0,0 +1,173 @@
//
// Created by k2154 on 2025-07-30.
//
#ifndef PCSX2_VUDEF_H
#define PCSX2_VUDEF_H
#include "VifDef.h"
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)
};
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;
}
};
#endif //PCSX2_VUDEF_H
+125
View File
@@ -0,0 +1,125 @@
//
// Created by k2154 on 2025-07-30.
//
#ifndef PCSX2_VIFDEF_H
#define PCSX2_VIFDEF_H
#include "common/Pcsx2Defs.h"
#include "common/StringUtil.h"
#include "MemoryTypes.h"
//
// 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); }
};
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;
};
static VIFregisters& vif0Regs = (VIFregisters&)eeHw[0x3800];
static VIFregisters& vif1Regs = (VIFregisters&)eeHw[0x3C00];
#endif //PCSX2_VIFDEF_H
+27
View File
@@ -0,0 +1,27 @@
//
// Created by k2154 on 2025-07-30.
//
#ifndef PCSX2_CPUREGISTERSPACK_H
#define PCSX2_CPUREGISTERSPACK_H
#include "R5900Def.h"
#include "R3000ADef.h"
#include "VUDef.h"
struct cpuRegistersPack
{
alignas(16) cpuRegisters cpuRegs{};
alignas(16) fpuRegisters fpuRegs{};
alignas(16) psxRegisters psxRegs{};
alignas(16) VURegs vuRegs[2];
};
alignas(16) 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];
#endif //PCSX2_CPUREGISTERSPACK_H
+38 -38
View File
@@ -173,7 +173,7 @@ static const void* _DynGen_JITCompile()
u8* retval = armGetCurrentCodePointer();
// xFastCall((void*)iopRecRecompile, ptr32[&psxRegs.pc]);
armLoad(EAX, PTR_PSX(pc));
armLoad(EAX, PTR_CPU(psxRegs.pc));
armEmitCall(reinterpret_cast<void*>(iopRecRecompile));
// xMOV(eax, ptr[&psxRegs.pc]);
@@ -182,7 +182,7 @@ static const void* _DynGen_JITCompile()
// xMOV(rcx, ptrNative[xComplexAddress(rcx, psxRecLUT, rax * wordsize)]);
// xJMP(ptrNative[rbx * (wordsize / 4) + rcx]);
armLoad(EAX, PTR_PSX(pc));
armLoad(EAX, PTR_CPU(psxRegs.pc));
armMoveAddressToReg(RDX, &psxRecLUT);
armAsm->Lsr(ECX, EAX, 16);
armAsm->Lsr(EAX, EAX, 2);
@@ -206,7 +206,7 @@ static const void* _DynGen_DispatcherReg()
// xMOV(rcx, ptrNative[xComplexAddress(rcx, psxRecLUT, rax * wordsize)]);
// xJMP(ptrNative[rbx * (wordsize / 4) + rcx]);
armLoad(EAX, PTR_PSX(pc));
armLoad(EAX, PTR_CPU(psxRegs.pc));
armMoveAddressToReg(RDX, &psxRecLUT);
armAsm->Lsr(ECX, EAX, 16);
armAsm->Lsr(EAX, EAX, 2);
@@ -281,7 +281,7 @@ void _psxFlushConstReg(int reg)
if (PSX_IS_CONST1(reg) && !(g_psxFlushedConstReg & (1 << reg)))
{
// xMOV(ptr32[&psxRegs.GPR.r[reg]], g_psxConstRegs[reg]);
armStore(PTR_PSX(GPR.r[reg]), g_psxConstRegs[reg]);
armStore(PTR_CPU(psxRegs.GPR.r[reg]), g_psxConstRegs[reg]);
g_psxFlushedConstReg |= (1 << reg);
}
}
@@ -303,7 +303,7 @@ void _psxFlushConstRegs()
if (!(g_psxFlushedConstReg & (1 << i)))
{
// xMOV(ptr32[&psxRegs.GPR.r[i]], g_psxConstRegs[i]);
armStore(PTR_PSX(GPR.r[i]), g_psxConstRegs[i]);
armStore(PTR_CPU(psxRegs.GPR.r[i]), g_psxConstRegs[i]);
g_psxFlushedConstReg |= 1 << i;
}
@@ -340,7 +340,7 @@ void _psxMoveGPRtoR(const a64::Register& to, int fromgpr)
}
else {
// xMOV(to, ptr[&psxRegs.GPR.r[fromgpr]]);
armLoad(to, PTR_PSX(GPR.r[fromgpr]));
armLoad(to, PTR_CPU(psxRegs.GPR.r[fromgpr]));
}
}
}
@@ -363,7 +363,7 @@ void _psxMoveGPRtoM(uptr to, int fromgpr)
else
{
// xMOV(eax, ptr[&psxRegs.GPR.r[fromgpr]]);
armLoad(EAX, PTR_PSX(GPR.r[fromgpr]));
armLoad(EAX, PTR_CPU(psxRegs.GPR.r[fromgpr]));
// xMOV(ptr32[(u32*)(to)], eax);
armAsm->Str(EAX, armMemOperandPtr((u32*)(to)));
}
@@ -395,7 +395,7 @@ void _psxFlushCall(int flushtype)
if ((flushtype & FLUSH_PC) /*&& !g_cpuFlushedPC*/)
{
// xMOV(ptr32[&psxRegs.pc], psxpc);
armStore(PTR_PSX(pc), psxpc);
armStore(PTR_CPU(psxRegs.pc), psxpc);
//g_cpuFlushedPC = true;
}
}
@@ -699,9 +699,9 @@ static void psxRecompileIrxImport()
return;
// xMOV(ptr32[&psxRegs.code], psxRegs.code);
armStore(PTR_PSX(code), psxRegs.code);
armStore(PTR_CPU(psxRegs.code), psxRegs.code);
// xMOV(ptr32[&psxRegs.pc], psxpc);
armStore(PTR_PSX(pc), psxpc);
armStore(PTR_CPU(psxRegs.pc), psxpc);
_psxFlushCall(FLUSH_NODESTROY);
if (TraceActive(IOP.Bios))
@@ -1128,15 +1128,15 @@ void psxSetBranchReg(u32 reg)
if (x86regs[wbreg].inuse && x86regs[wbreg].type == X86TYPE_PCWRITEBACK)
{
// xMOV(ptr32[&psxRegs.pc], xRegister32(wbreg));
armStore(PTR_PSX(pc), a64::WRegister(wbreg));
armStore(PTR_CPU(psxRegs.pc), a64::WRegister(wbreg));
x86regs[wbreg].inuse = 0;
}
else
{
// xMOV(eax, ptr32[&psxRegs.pcWriteback]);
armLoad(EAX, PTR_PSX(pcWriteback));
armLoad(EAX, PTR_CPU(psxRegs.pcWriteback));
// xMOV(ptr32[&psxRegs.pc], eax);
armStore(PTR_PSX(pc), EAX);
armStore(PTR_CPU(psxRegs.pc), EAX);
}
}
else
@@ -1145,7 +1145,7 @@ void psxSetBranchReg(u32 reg)
{
const int x86reg = _allocX86reg(X86TYPE_PSX, reg, MODE_READ);
// xMOV(ptr32[&psxRegs.pc], xRegister32(x86reg));
armStore(PTR_PSX(pc), a64::WRegister(x86reg));
armStore(PTR_CPU(psxRegs.pc), a64::WRegister(x86reg));
}
else
{
@@ -1168,7 +1168,7 @@ void psxSetBranchImm(u32 imm)
// end the current block
// xMOV(ptr32[&psxRegs.pc], imm);
armStore(PTR_PSX(pc), imm);
armStore(PTR_CPU(psxRegs.pc), imm);
_psxFlushCall(FLUSH_EVERYTHING);
iPsxBranchTest(imm, imm <= psxpc);
@@ -1188,11 +1188,11 @@ static void iPsxAddEECycles(u32 blockCycles)
{
if (blockCycles != 0xFFFFFFFF) {
// xSUB(ptr32[&psxRegs.iopCycleEE], blockCycles * 8);
armSub(PTR_PSX(iopCycleEE), blockCycles * 8, true);
armSub(PTR_CPU(psxRegs.iopCycleEE), blockCycles * 8, true);
}
else {
// xSUB(ptr32[&psxRegs.iopCycleEE], eax);
armSub(PTR_PSX(iopCycleEE), EAX, true);
armSub(PTR_CPU(psxRegs.iopCycleEE), EAX, true);
}
return;
}
@@ -1206,7 +1206,7 @@ static void iPsxAddEECycles(u32 blockCycles)
armAsm->Mov(EAX, blockCycles * cnum);
}
// xADD(eax, ptr32[&psxRegs.iopCycleEECarry]);
armAsm->Add(EAX, EAX, armLoad(PTR_PSX(iopCycleEECarry)));
armAsm->Add(EAX, EAX, armLoad(PTR_CPU(psxRegs.iopCycleEECarry)));
// xMOV(ecx, cdenom);
armAsm->Mov(ECX, cdenom);
armAsm->Mov(EEX, EAX);
@@ -1216,9 +1216,9 @@ static void iPsxAddEECycles(u32 blockCycles)
armAsm->Udiv(EAX, EEX, ECX);
armAsm->Msub(EDX, EAX, ECX, EEX);
// xMOV(ptr32[&psxRegs.iopCycleEECarry], edx);
armStore(PTR_PSX(iopCycleEECarry), EDX);
armStore(PTR_CPU(psxRegs.iopCycleEECarry), EDX);
// xSUB(ptr32[&psxRegs.iopCycleEE], eax);
armSub(PTR_PSX(iopCycleEE), EAX, true);
armSub(PTR_CPU(psxRegs.iopCycleEE), EAX, true);
}
static void iPsxBranchTest(u32 newpc, u32 cpuBranch)
@@ -1228,11 +1228,11 @@ static void iPsxBranchTest(u32 newpc, u32 cpuBranch)
if (EmuConfig.Speedhacks.WaitLoop && s_nBlockFF && newpc == s_branchTo)
{
// xMOV(eax, ptr32[&psxRegs.cycle]);
armLoad(EAX, PTR_PSX(cycle));
armLoad(EAX, PTR_CPU(psxRegs.cycle));
// xMOV(ecx, eax);
armAsm->Mov(ECX, EAX);
// xMOV(edx, ptr32[&psxRegs.iopCycleEE]);
armLoadsw(EDX, PTR_PSX(iopCycleEE));
armLoadsw(EDX, PTR_CPU(psxRegs.iopCycleEE));
// xADD(edx, 7);
armAsm->Add(EDX, EDX, 7);
// xSHR(edx, 3);
@@ -1240,12 +1240,12 @@ static void iPsxBranchTest(u32 newpc, u32 cpuBranch)
// xADD(eax, edx);
armAsm->Add(EAX, EAX, EDX);
// xCMP(eax, ptr32[&psxRegs.iopNextEventCycle]);
armLoad(EEX, PTR_PSX(iopNextEventCycle));
armLoad(EEX, PTR_CPU(psxRegs.iopNextEventCycle));
armAsm->Cmp(EAX, EEX);
// xCMOVNS(eax, ptr32[&psxRegs.iopNextEventCycle]);
armAsm->Csel(EAX, EEX, EAX, a64::Condition::pl);
// xMOV(ptr32[&psxRegs.cycle], eax);
armStore(PTR_PSX(cycle), EAX);
armStore(PTR_CPU(psxRegs.cycle), EAX);
// xSUB(eax, ecx);
armAsm->Sub(EAX, EAX, ECX);
// xSHL(eax, 3);
@@ -1260,7 +1260,7 @@ static void iPsxBranchTest(u32 newpc, u32 cpuBranch)
if (newpc != 0xffffffff)
{
// xCMP(ptr32[&psxRegs.pc], newpc);
armAsm->Cmp(armLoad(PTR_PSX(pc)), newpc);
armAsm->Cmp(armLoad(PTR_CPU(psxRegs.pc)), newpc);
// xJNE(iopDispatcherReg);
armEmitCondBranch(a64::Condition::ne, iopDispatcherReg);
}
@@ -1270,7 +1270,7 @@ static void iPsxBranchTest(u32 newpc, u32 cpuBranch)
// xMOV(ebx, ptr32[&psxRegs.cycle]);
// xADD(ebx, blockCycles);
// xMOV(ptr32[&psxRegs.cycle], ebx); // update cycles
armAdd(EBX, PTR_PSX(cycle), blockCycles);
armAdd(EBX, PTR_CPU(psxRegs.cycle), blockCycles);
// jump if iopCycleEE <= 0 (iop's timeslice timed out, so time to return control to the EE)
iPsxAddEECycles(blockCycles);
@@ -1279,7 +1279,7 @@ static void iPsxBranchTest(u32 newpc, u32 cpuBranch)
// check if an event is pending
// xSUB(ebx, ptr32[&psxRegs.iopNextEventCycle]);
armAsm->Subs(EBX, EBX, armLoad(PTR_PSX(iopNextEventCycle)));
armAsm->Subs(EBX, EBX, armLoad(PTR_CPU(psxRegs.iopNextEventCycle)));
// xForwardJS<u8> nointerruptpending;
a64::Label nointerruptpending;
armAsm->B(&nointerruptpending, a64::Condition::mi);
@@ -1290,7 +1290,7 @@ static void iPsxBranchTest(u32 newpc, u32 cpuBranch)
if (newpc != 0xffffffff)
{
// xCMP(ptr32[&psxRegs.pc], newpc);
armAsm->Cmp(armLoad(PTR_PSX(pc)), newpc);
armAsm->Cmp(armLoad(PTR_CPU(psxRegs.pc)), newpc);
// xJNE(iopDispatcherReg);
armEmitCondBranch(a64::Condition::ne, iopDispatcherReg);
}
@@ -1321,9 +1321,9 @@ static void checkcodefn()
void rpsxSYSCALL()
{
// xMOV(ptr32[&psxRegs.code], psxRegs.code);
armStore(PTR_PSX(code), psxRegs.code);
armStore(PTR_CPU(psxRegs.code), psxRegs.code);
// xMOV(ptr32[&psxRegs.pc], psxpc - 4);
armStore(PTR_PSX(pc), psxpc - 4);
armStore(PTR_CPU(psxRegs.pc), psxpc - 4);
_psxFlushCall(FLUSH_NODESTROY);
//xMOV( ecx, 0x20 ); // exception code
@@ -1334,13 +1334,13 @@ void rpsxSYSCALL()
armEmitCall(reinterpret_cast<const void*>(psxException));
// xCMP(ptr32[&psxRegs.pc], psxpc - 4);
armAsm->Cmp(armLoad(PTR_PSX(pc)), psxpc - 4);
armAsm->Cmp(armLoad(PTR_CPU(psxRegs.pc)), psxpc - 4);
// j8Ptr[0] = JE8(0);
a64::Label j8Ptr0;
armAsm->B(&j8Ptr0, a64::Condition::eq);
// xADD(ptr32[&psxRegs.cycle], psxScaleBlockCycles());
armAdd(PTR_PSX(cycle), psxScaleBlockCycles());
armAdd(PTR_CPU(psxRegs.cycle), psxScaleBlockCycles());
iPsxAddEECycles(psxScaleBlockCycles());
// JMP32((uptr)iopDispatcherReg - ((uptr)x86Ptr + 5));
armEmitJmp(iopDispatcherReg);
@@ -1355,9 +1355,9 @@ void rpsxSYSCALL()
void rpsxBREAK()
{
// xMOV(ptr32[&psxRegs.code], psxRegs.code);
armStore(PTR_PSX(code), psxRegs.code);
armStore(PTR_CPU(psxRegs.code), psxRegs.code);
// xMOV(ptr32[&psxRegs.pc], psxpc - 4);
armStore(PTR_PSX(pc), psxpc - 4);
armStore(PTR_CPU(psxRegs.pc), psxpc - 4);
_psxFlushCall(FLUSH_NODESTROY);
//xMOV( ecx, 0x24 ); // exception code
@@ -1368,12 +1368,12 @@ void rpsxBREAK()
armEmitCall(reinterpret_cast<const void*>(psxException));
// xCMP(ptr32[&psxRegs.pc], psxpc - 4);
armAsm->Cmp(armLoad(PTR_PSX(pc)), psxpc - 4);
armAsm->Cmp(armLoad(PTR_CPU(psxRegs.pc)), psxpc - 4);
// j8Ptr[0] = JE8(0);
a64::Label j8Ptr0;
armAsm->B(&j8Ptr0, a64::Condition::eq);
// xADD(ptr32[&psxRegs.cycle], psxScaleBlockCycles());
armAdd(PTR_PSX(cycle), psxScaleBlockCycles());
armAdd(PTR_CPU(psxRegs.cycle), psxScaleBlockCycles());
iPsxAddEECycles(psxScaleBlockCycles());
// JMP32((uptr)iopDispatcherReg - ((uptr)x86Ptr + 5));
armEmitJmp(iopDispatcherReg);
@@ -1875,7 +1875,7 @@ StartRecomp:
else
{
// xADD(ptr32[&psxRegs.cycle], psxScaleBlockCycles());
armAdd(PTR_PSX(cycle), psxScaleBlockCycles());
armAdd(PTR_CPU(psxRegs.cycle), psxScaleBlockCycles());
iPsxAddEECycles(psxScaleBlockCycles());
}
@@ -1884,7 +1884,7 @@ StartRecomp:
pxAssert(psxpc == s_nEndBlock);
_psxFlushCall(FLUSH_EVERYTHING);
// xMOV(ptr32[&psxRegs.pc], psxpc);
armStore(PTR_PSX(pc), psxpc);
armStore(PTR_CPU(psxRegs.pc), psxpc);
// recBlocks.Link(HWADDR(s_nEndBlock), xJcc32());
armAsm->Nop();
recBlocks.Link(HWADDR(s_nEndBlock), (s32*)armGetCurrentCodePointer()-1);
File diff suppressed because it is too large Load Diff