diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index a6720815f..4d60f8e0c 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -26,6 +26,8 @@ add_library(core
cpu_core_private.h
cpu_disasm.cpp
cpu_disasm.h
+ cpu_pgxp.cpp
+ cpu_pgxp.h
cpu_types.cpp
cpu_types.h
digital_controller.cpp
@@ -85,8 +87,6 @@ add_library(core
pad.h
pcdrv.cpp
pcdrv.h
- pgxp.cpp
- pgxp.h
playstation_mouse.cpp
playstation_mouse.h
psf_loader.cpp
diff --git a/src/core/core.vcxproj b/src/core/core.vcxproj
index 0add7b900..529e23a12 100644
--- a/src/core/core.vcxproj
+++ b/src/core/core.vcxproj
@@ -77,7 +77,7 @@
Create
-
+
@@ -161,7 +161,7 @@
-
+
diff --git a/src/core/core.vcxproj.filters b/src/core/core.vcxproj.filters
index d7f0469fd..945af6b54 100644
--- a/src/core/core.vcxproj.filters
+++ b/src/core/core.vcxproj.filters
@@ -41,7 +41,7 @@
-
+
@@ -107,7 +107,7 @@
-
+
diff --git a/src/core/cpu_core.cpp b/src/core/cpu_core.cpp
index 92b5e78d2..2f399feb5 100644
--- a/src/core/cpu_core.cpp
+++ b/src/core/cpu_core.cpp
@@ -14,7 +14,7 @@
#include "gte.h"
#include "host.h"
#include "pcdrv.h"
-#include "pgxp.h"
+#include "cpu_pgxp.h"
#include "settings.h"
#include "system.h"
#include "timing_event.h"
@@ -191,6 +191,9 @@ void CPU::Reset()
GTE::Reset();
+ if (g_settings.gpu_pgxp_enable)
+ PGXP::Reset();
+
// TODO: This consumes cycles...
SetPC(RESET_VECTOR);
}
diff --git a/src/core/cpu_core.h b/src/core/cpu_core.h
index 87fda6ec9..8055c53a0 100644
--- a/src/core/cpu_core.h
+++ b/src/core/cpu_core.h
@@ -47,6 +47,20 @@ union CacheControl
BitField icache_enable;
};
+struct PGXP_value
+{
+ float x;
+ float y;
+ float z;
+ union
+ {
+ u32 flags;
+ u8 compFlags[4];
+ u16 halfFlags[2];
+ };
+ u32 value;
+};
+
struct State
{
// ticks the CPU has executed
@@ -93,6 +107,12 @@ struct State
std::array scratchpad = {};
+ PGXP_value pgxp_gpr[32];
+ PGXP_value pgxp_hi;
+ PGXP_value pgxp_lo;
+ PGXP_value pgxp_cop0[32];
+ PGXP_value pgxp_gte[64];
+
static constexpr u32 GPRRegisterOffset(u32 index) { return offsetof(State, regs.r) + (sizeof(u32) * index); }
static constexpr u32 GTERegisterOffset(u32 index) { return offsetof(State, gte_regs.r32) + (sizeof(u32) * index); }
};
diff --git a/src/core/cpu_newrec_compiler.cpp b/src/core/cpu_newrec_compiler.cpp
index 9e62bd3b9..4bb6c82fe 100644
--- a/src/core/cpu_newrec_compiler.cpp
+++ b/src/core/cpu_newrec_compiler.cpp
@@ -8,7 +8,7 @@
#include "cpu_code_cache.h"
#include "cpu_core_private.h"
#include "cpu_disasm.h"
-#include "pgxp.h"
+#include "cpu_pgxp.h"
#include "settings.h"
#include
#include
@@ -1274,7 +1274,7 @@ void CPU::NewRec::Compiler::CompileInstruction()
{
switch (inst->cop.CommonOp())
{
- case CopCommonInstruction::mfcn: if (inst->r.rt != Reg::zero) { CompileTemplate(nullptr, &Compiler::Compile_mfc0, nullptr, TF_WRITES_T | TF_LOAD_DELAY); } SpecExec_mfc0(); break;
+ case CopCommonInstruction::mfcn: if (inst->r.rt != Reg::zero) { CompileTemplate(nullptr, &Compiler::Compile_mfc0, PGXPFN(CPU_MFC0), TF_WRITES_T | TF_LOAD_DELAY); } SpecExec_mfc0(); break;
case CopCommonInstruction::mtcn: CompileTemplate(nullptr, &Compiler::Compile_mtc0, PGXPFN(CPU_MTC0), TF_READS_T); SpecExec_mtc0(); break;
default: Compile_Fallback(); break;
}
@@ -2122,6 +2122,9 @@ void CPU::NewRec::Compiler::Compile_lui()
return;
SetConstantReg(inst->i.rt, inst->i.imm_zext32() << 16);
+
+ if (g_settings.UsingPGXPCPUMode())
+ GeneratePGXPCallWithMIPSRegs(reinterpret_cast(&PGXP::CPU_LUI), inst->bits);
}
static constexpr const std::array, 16> s_cop0_table = {
diff --git a/src/core/cpu_newrec_compiler_aarch32.cpp b/src/core/cpu_newrec_compiler_aarch32.cpp
index 10a009f43..b85a41b1a 100644
--- a/src/core/cpu_newrec_compiler_aarch32.cpp
+++ b/src/core/cpu_newrec_compiler_aarch32.cpp
@@ -7,10 +7,10 @@
#include "common/log.h"
#include "common/string_util.h"
#include "cpu_core_private.h"
+#include "cpu_pgxp.h"
#include "cpu_recompiler_thunks.h"
#include "cpu_recompiler_types.h"
#include "gte.h"
-#include "pgxp.h"
#include "settings.h"
#include "timing_event.h"
#include
diff --git a/src/core/cpu_newrec_compiler_aarch64.cpp b/src/core/cpu_newrec_compiler_aarch64.cpp
index a30d9133f..a9820cb3b 100644
--- a/src/core/cpu_newrec_compiler_aarch64.cpp
+++ b/src/core/cpu_newrec_compiler_aarch64.cpp
@@ -7,10 +7,10 @@
#include "common/log.h"
#include "common/string_util.h"
#include "cpu_core_private.h"
+#include "cpu_pgxp.h"
#include "cpu_recompiler_thunks.h"
#include "cpu_recompiler_types.h"
#include "gte.h"
-#include "pgxp.h"
#include "settings.h"
#include "timing_event.h"
#include
diff --git a/src/core/cpu_newrec_compiler_x64.cpp b/src/core/cpu_newrec_compiler_x64.cpp
index 0b96f8eef..d476c28d4 100644
--- a/src/core/cpu_newrec_compiler_x64.cpp
+++ b/src/core/cpu_newrec_compiler_x64.cpp
@@ -8,10 +8,10 @@
#include "common/string_util.h"
#include "cpu_code_cache_private.h"
#include "cpu_core_private.h"
+#include "cpu_pgxp.h"
#include "cpu_recompiler_thunks.h"
#include "cpu_recompiler_types.h"
#include "gte.h"
-#include "pgxp.h"
#include "settings.h"
#include "timing_event.h"
#include
diff --git a/src/core/pgxp.cpp b/src/core/cpu_pgxp.cpp
similarity index 54%
rename from src/core/pgxp.cpp
rename to src/core/cpu_pgxp.cpp
index 809173d05..5125c52ca 100644
--- a/src/core/pgxp.cpp
+++ b/src/core/cpu_pgxp.cpp
@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2016 iCatButler, 2019-2023 Connor McLaughlin
// SPDX-License-Identifier: GPL-2.0+
-#include "pgxp.h"
+#include "cpu_pgxp.h"
#include "bus.h"
#include "cpu_core.h"
#include "settings.h"
@@ -12,9 +12,9 @@
#include
#include
-Log_SetChannel(PGXP);
+Log_SetChannel(CPU::PGXP);
-namespace PGXP {
+namespace CPU::PGXP {
namespace {
enum : u32
@@ -38,21 +38,7 @@ enum : u32
#define VALID_ALL (VALID_0 | VALID_1 | VALID_2 | VALID_3)
#define INV_VALID_ALL (ALL ^ VALID_ALL)
-struct PGXP_value
-{
- float x;
- float y;
- float z;
- union
- {
- u32 flags;
- u8 compFlags[4];
- u16 halfFlags[2];
- };
- u32 value;
-};
-
-typedef union
+union psx_value
{
struct
{
@@ -72,7 +58,7 @@ typedef union
} sw;
u32 d;
s32 sd;
-} psx_value;
+};
} // namespace
static void PGXP_CacheVertex(s16 sx, s16 sy, const PGXP_value& vertex);
@@ -82,6 +68,7 @@ static float TruncateVertexPosition(float p);
static bool IsWithinTolerance(float precise_x, float precise_y, int int_x, int int_y);
static void MakeValid(PGXP_value* pV, u32 psxV);
+
static void Validate(PGXP_value* pV, u32 psxV);
static void MaskValidate(PGXP_value* pV, u32 psxV, u32 mask, u32 validMask);
@@ -90,26 +77,106 @@ static double f16Unsign(double in);
static double f16Overflow(double in);
static PGXP_value* GetPtr(u32 addr);
-static PGXP_value* ReadMem(u32 addr);
-static void PGXP_MTC2_int(const PGXP_value& value, u32 reg);
+static void ValidateAndCopyMem(PGXP_value* dest, u32 addr, u32 value);
+static void ValidateAndCopyMem16(PGXP_value* dest, u32 addr, u32 value, bool sign);
+
+static void CPU_MTC2_int(const PGXP_value& value, u32 reg);
static void CPU_BITWISE(u32 instr, u32 rdVal, u32 rsVal, u32 rtVal);
+static void WriteMem(const PGXP_value* value, u32 addr);
+static void WriteMem16(const PGXP_value* src, u32 addr);
+
static const PGXP_value PGXP_value_invalid = {0.f, 0.f, 0.f, {0}, 0};
static const PGXP_value PGXP_value_zero = {0.f, 0.f, 0.f, {VALID_ALL}, 0};
-static PGXP_value CPU_reg[34];
-static PGXP_value CP0_reg[32];
-#define CPU_Hi CPU_reg[32]
-#define CPU_Lo CPU_reg[33]
-
-// GTE registers
-static PGXP_value GTE_regs[64];
-
static PGXP_value* Mem = nullptr;
static PGXP_value* vertexCache = nullptr;
+} // namespace CPU::PGXP
-ALWAYS_INLINE_RELEASE void MakeValid(PGXP_value* pV, u32 psxV)
+void CPU::PGXP::Initialize()
+{
+ std::memset(g_state.pgxp_gpr, 0, sizeof(g_state.pgxp_gpr));
+ std::memset(g_state.pgxp_cop0, 0, sizeof(g_state.pgxp_cop0));
+
+ std::memset(g_state.pgxp_gte, 0, sizeof(g_state.pgxp_gte));
+
+ if (!Mem)
+ {
+ Mem = static_cast(std::calloc(PGXP_MEM_SIZE, sizeof(PGXP_value)));
+ if (!Mem)
+ Panic("Failed to allocate PGXP memory");
+ }
+
+ if (g_settings.gpu_pgxp_vertex_cache && !vertexCache)
+ {
+ vertexCache = static_cast(std::calloc(VERTEX_CACHE_SIZE, sizeof(PGXP_value)));
+ if (!vertexCache)
+ {
+ Log_ErrorPrint("Failed to allocate memory for vertex cache, disabling.");
+ g_settings.gpu_pgxp_vertex_cache = false;
+ }
+ }
+
+ if (vertexCache)
+ std::memset(vertexCache, 0, sizeof(PGXP_value) * VERTEX_CACHE_SIZE);
+}
+
+void CPU::PGXP::Reset()
+{
+ std::memset(g_state.pgxp_gpr, 0, sizeof(g_state.pgxp_gpr));
+ std::memset(g_state.pgxp_cop0, 0, sizeof(g_state.pgxp_cop0));
+ std::memset(g_state.pgxp_gte, 0, sizeof(g_state.pgxp_gte));
+
+ if (Mem)
+ std::memset(Mem, 0, sizeof(PGXP_value) * PGXP_MEM_SIZE);
+
+ if (vertexCache)
+ std::memset(vertexCache, 0, sizeof(PGXP_value) * VERTEX_CACHE_SIZE);
+}
+
+void CPU::PGXP::Shutdown()
+{
+ if (vertexCache)
+ {
+ std::free(vertexCache);
+ vertexCache = nullptr;
+ }
+ if (Mem)
+ {
+ std::free(Mem);
+ Mem = nullptr;
+ }
+
+ std::memset(g_state.pgxp_gte, 0, sizeof(g_state.pgxp_gte));
+
+ std::memset(g_state.pgxp_gpr, 0, sizeof(g_state.pgxp_gpr));
+ std::memset(g_state.pgxp_cop0, 0, sizeof(g_state.pgxp_cop0));
+}
+
+// Instruction register decoding
+#define op(_instr) (_instr >> 26) // The op part of the instruction register
+#define func(_instr) ((_instr)&0x3F) // The funct part of the instruction register
+#define sa(_instr) ((_instr >> 6) & 0x1F) // The sa part of the instruction register
+#define rd(_instr) ((_instr >> 11) & 0x1F) // The rd part of the instruction register
+#define rt(_instr) ((_instr >> 16) & 0x1F) // The rt part of the instruction register
+#define rs(_instr) ((_instr >> 21) & 0x1F) // The rs part of the instruction register
+#define imm(_instr) (_instr & 0xFFFF) // The immediate part of the instruction register
+#define cop2idx(_instr) (((_instr >> 11) & 0x1F) | ((_instr >> 17) & 0x20))
+
+#define SX0 (g_state.pgxp_gte[12].x)
+#define SY0 (g_state.pgxp_gte[12].y)
+#define SX1 (g_state.pgxp_gte[13].x)
+#define SY1 (g_state.pgxp_gte[13].y)
+#define SX2 (g_state.pgxp_gte[14].x)
+#define SY2 (g_state.pgxp_gte[14].y)
+
+#define SXY0 (g_state.pgxp_gte[12])
+#define SXY1 (g_state.pgxp_gte[13])
+#define SXY2 (g_state.pgxp_gte[14])
+#define SXYP (g_state.pgxp_gte[15])
+
+ALWAYS_INLINE_RELEASE void CPU::PGXP::MakeValid(PGXP_value* pV, u32 psxV)
{
if (VALID_01 != (pV->flags & VALID_01))
{
@@ -121,28 +188,28 @@ ALWAYS_INLINE_RELEASE void MakeValid(PGXP_value* pV, u32 psxV)
}
}
-ALWAYS_INLINE_RELEASE void Validate(PGXP_value* pV, u32 psxV)
+ALWAYS_INLINE_RELEASE void CPU::PGXP::Validate(PGXP_value* pV, u32 psxV)
{
// assume pV is not NULL
pV->flags &= (pV->value == psxV) ? ALL : INV_VALID_ALL;
}
-ALWAYS_INLINE_RELEASE void MaskValidate(PGXP_value* pV, u32 psxV, u32 mask, u32 validMask)
+ALWAYS_INLINE_RELEASE void CPU::PGXP::MaskValidate(PGXP_value* pV, u32 psxV, u32 mask, u32 validMask)
{
// assume pV is not NULL
pV->flags &= ((pV->value & mask) == (psxV & mask)) ? ALL : (ALL ^ (validMask));
}
-ALWAYS_INLINE_RELEASE double f16Sign(double in)
+ALWAYS_INLINE_RELEASE double CPU::PGXP::f16Sign(double in)
{
const s32 s = static_cast(static_cast(in * (USHRT_MAX + 1)));
return static_cast(s) / static_cast(USHRT_MAX + 1);
}
-ALWAYS_INLINE_RELEASE double f16Unsign(double in)
+ALWAYS_INLINE_RELEASE double CPU::PGXP::f16Unsign(double in)
{
return (in >= 0) ? in : (in + (USHRT_MAX + 1));
}
-ALWAYS_INLINE_RELEASE double f16Overflow(double in)
+ALWAYS_INLINE_RELEASE double CPU::PGXP::f16Overflow(double in)
{
double out = 0;
s64 v = ((s64)in) >> 16;
@@ -150,24 +217,19 @@ ALWAYS_INLINE_RELEASE double f16Overflow(double in)
return out;
}
-ALWAYS_INLINE_RELEASE PGXP_value* GetPtr(u32 addr)
+ALWAYS_INLINE_RELEASE CPU::PGXP_value* CPU::PGXP::GetPtr(u32 addr)
{
- if ((addr & CPU::SCRATCHPAD_ADDR_MASK) == CPU::SCRATCHPAD_ADDR)
- return &Mem[PGXP_MEM_SCRATCH_OFFSET + ((addr & CPU::SCRATCHPAD_OFFSET_MASK) >> 2)];
+ if ((addr & SCRATCHPAD_ADDR_MASK) == SCRATCHPAD_ADDR)
+ return &Mem[PGXP_MEM_SCRATCH_OFFSET + ((addr & SCRATCHPAD_OFFSET_MASK) >> 2)];
- const u32 paddr = (addr & CPU::PHYSICAL_MEMORY_ADDRESS_MASK);
+ const u32 paddr = (addr & PHYSICAL_MEMORY_ADDRESS_MASK);
if (paddr < Bus::RAM_MIRROR_END)
return &Mem[(paddr & Bus::g_ram_mask) >> 2];
else
return nullptr;
}
-ALWAYS_INLINE_RELEASE PGXP_value* ReadMem(u32 addr)
-{
- return GetPtr(addr);
-}
-
-ALWAYS_INLINE_RELEASE void ValidateAndCopyMem(PGXP_value* dest, u32 addr, u32 value)
+ALWAYS_INLINE_RELEASE void CPU::PGXP::ValidateAndCopyMem(PGXP_value* dest, u32 addr, u32 value)
{
PGXP_value* pMem = GetPtr(addr);
if (pMem)
@@ -180,7 +242,7 @@ ALWAYS_INLINE_RELEASE void ValidateAndCopyMem(PGXP_value* dest, u32 addr, u32 va
*dest = PGXP_value_invalid;
}
-ALWAYS_INLINE_RELEASE static void ValidateAndCopyMem16(PGXP_value* dest, u32 addr, u32 value, bool sign)
+ALWAYS_INLINE_RELEASE void CPU::PGXP::ValidateAndCopyMem16(PGXP_value* dest, u32 addr, u32 value, bool sign)
{
u32 validMask = 0;
psx_value val, mask;
@@ -223,7 +285,7 @@ ALWAYS_INLINE_RELEASE static void ValidateAndCopyMem16(PGXP_value* dest, u32 add
*dest = PGXP_value_invalid;
}
-ALWAYS_INLINE_RELEASE void WriteMem(const PGXP_value* value, u32 addr)
+ALWAYS_INLINE_RELEASE void CPU::PGXP::WriteMem(const PGXP_value* value, u32 addr)
{
PGXP_value* pMem = GetPtr(addr);
@@ -231,7 +293,7 @@ ALWAYS_INLINE_RELEASE void WriteMem(const PGXP_value* value, u32 addr)
*pMem = *value;
}
-ALWAYS_INLINE_RELEASE static void WriteMem16(const PGXP_value* src, u32 addr)
+ALWAYS_INLINE_RELEASE void CPU::PGXP::WriteMem16(const PGXP_value* src, u32 addr)
{
PGXP_value* dest = GetPtr(addr);
psx_value* pVal = nullptr;
@@ -264,92 +326,7 @@ ALWAYS_INLINE_RELEASE static void WriteMem16(const PGXP_value* src, u32 addr)
}
}
-} // namespace PGXP
-
-void PGXP::Initialize()
-{
- std::memset(CPU_reg, 0, sizeof(CPU_reg));
- std::memset(CP0_reg, 0, sizeof(CP0_reg));
-
- std::memset(GTE_regs, 0, sizeof(GTE_regs));
-
- if (!Mem)
- {
- Mem = static_cast(std::calloc(PGXP_MEM_SIZE, sizeof(PGXP_value)));
- if (!Mem)
- Panic("Failed to allocate PGXP memory");
- }
-
- if (g_settings.gpu_pgxp_vertex_cache && !vertexCache)
- {
- vertexCache = static_cast(std::calloc(VERTEX_CACHE_SIZE, sizeof(PGXP_value)));
- if (!vertexCache)
- {
- Log_ErrorPrint("Failed to allocate memory for vertex cache, disabling.");
- g_settings.gpu_pgxp_vertex_cache = false;
- }
- }
-
- if (vertexCache)
- std::memset(vertexCache, 0, sizeof(PGXP_value) * VERTEX_CACHE_SIZE);
-}
-
-void PGXP::Reset()
-{
- std::memset(CPU_reg, 0, sizeof(CPU_reg));
- std::memset(CP0_reg, 0, sizeof(CP0_reg));
-
- std::memset(GTE_regs, 0, sizeof(GTE_regs));
-
- if (Mem)
- std::memset(Mem, 0, sizeof(PGXP_value) * PGXP_MEM_SIZE);
-
- if (vertexCache)
- std::memset(vertexCache, 0, sizeof(PGXP_value) * VERTEX_CACHE_SIZE);
-}
-
-void PGXP::Shutdown()
-{
- if (vertexCache)
- {
- std::free(vertexCache);
- vertexCache = nullptr;
- }
- if (Mem)
- {
- std::free(Mem);
- Mem = nullptr;
- }
-
- std::memset(GTE_regs, 0, sizeof(GTE_regs));
-
- std::memset(CPU_reg, 0, sizeof(CPU_reg));
- std::memset(CP0_reg, 0, sizeof(CP0_reg));
-}
-
-// Instruction register decoding
-#define op(_instr) (_instr >> 26) // The op part of the instruction register
-#define func(_instr) ((_instr)&0x3F) // The funct part of the instruction register
-#define sa(_instr) ((_instr >> 6) & 0x1F) // The sa part of the instruction register
-#define rd(_instr) ((_instr >> 11) & 0x1F) // The rd part of the instruction register
-#define rt(_instr) ((_instr >> 16) & 0x1F) // The rt part of the instruction register
-#define rs(_instr) ((_instr >> 21) & 0x1F) // The rs part of the instruction register
-#define imm(_instr) (_instr & 0xFFFF) // The immediate part of the instruction register
-#define cop2idx(_instr) (((_instr >> 11) & 0x1F) | ((_instr >> 17) & 0x20))
-
-#define SX0 (GTE_regs[12].x)
-#define SY0 (GTE_regs[12].y)
-#define SX1 (GTE_regs[13].x)
-#define SY1 (GTE_regs[13].y)
-#define SX2 (GTE_regs[14].x)
-#define SY2 (GTE_regs[14].y)
-
-#define SXY0 (GTE_regs[12])
-#define SXY1 (GTE_regs[13])
-#define SXY2 (GTE_regs[14])
-#define SXYP (GTE_regs[15])
-
-void PGXP::GTE_PushSXYZ2f(float x, float y, float z, u32 v)
+void CPU::PGXP::GTE_PushSXYZ2f(float x, float y, float z, u32 v)
{
// push values down FIFO
SXY0 = SXY1;
@@ -369,23 +346,17 @@ void PGXP::GTE_PushSXYZ2f(float x, float y, float z, u32 v)
#define VY(n) (psxRegs.CP2D.p[n << 1].sw.h)
#define VZ(n) (psxRegs.CP2D.p[(n << 1) + 1].sw.l)
-int PGXP::GTE_NCLIP_valid(u32 sxy0, u32 sxy1, u32 sxy2)
+int CPU::PGXP::GTE_NCLIP_valid(u32 sxy0, u32 sxy1, u32 sxy2)
{
Validate(&SXY0, sxy0);
Validate(&SXY1, sxy1);
Validate(&SXY2, sxy2);
- if (((SXY0.flags & SXY1.flags & SXY2.flags & VALID_01) == VALID_01)) // && Config.PGXP_GTE && (Config.PGXP_Mode > 0))
- {
- // Don't use accurate clipping for game-constructed values, which don't have a valid Z.
- if ((SXY0.flags & SXY1.flags & SXY2.flags & VALID_2) == 0)
- return 0;
- return 1;
- }
- return 0;
+ // Don't use accurate clipping for game-constructed values, which don't have a valid Z.
+ return (((SXY0.flags & SXY1.flags & SXY2.flags & VALID_012) == VALID_012));
}
-float PGXP::GTE_NCLIP()
+float CPU::PGXP::GTE_NCLIP()
{
float nclip = ((SX0 * SY1) + (SX1 * SY2) + (SX2 * SY0) - (SX0 * SY2) - (SX1 * SY0) - (SX2 * SY1));
@@ -410,7 +381,7 @@ float PGXP::GTE_NCLIP()
return nclip;
}
-ALWAYS_INLINE_RELEASE void PGXP::PGXP_MTC2_int(const PGXP_value& value, u32 reg)
+ALWAYS_INLINE_RELEASE void CPU::PGXP::CPU_MTC2_int(const PGXP_value& value, u32 reg)
{
switch (reg)
{
@@ -426,50 +397,50 @@ ALWAYS_INLINE_RELEASE void PGXP::PGXP_MTC2_int(const PGXP_value& value, u32 reg)
return;
}
- GTE_regs[reg] = value;
+ g_state.pgxp_gte[reg] = value;
}
////////////////////////////////////
// Data transfer tracking
////////////////////////////////////
-void PGXP::CPU_MFC2(u32 instr, u32 rdVal)
+void CPU::PGXP::CPU_MFC2(u32 instr, u32 rdVal)
{
// CPU[Rt] = GTE_D[Rd]
const u32 idx = cop2idx(instr);
- Validate(>E_regs[idx], rdVal);
- CPU_reg[rt(instr)] = GTE_regs[idx];
- CPU_reg[rt(instr)].value = rdVal;
+ Validate(&g_state.pgxp_gte[idx], rdVal);
+ g_state.pgxp_gpr[rt(instr)] = g_state.pgxp_gte[idx];
+ g_state.pgxp_gpr[rt(instr)].value = rdVal;
}
-void PGXP::CPU_MTC2(u32 instr, u32 rtVal)
+void CPU::PGXP::CPU_MTC2(u32 instr, u32 rtVal)
{
// GTE_D[Rd] = CPU[Rt]
const u32 idx = cop2idx(instr);
- Validate(&CPU_reg[rt(instr)], rtVal);
- PGXP_MTC2_int(CPU_reg[rt(instr)], idx);
- GTE_regs[idx].value = rtVal;
+ Validate(&g_state.pgxp_gpr[rt(instr)], rtVal);
+ CPU_MTC2_int(g_state.pgxp_gpr[rt(instr)], idx);
+ g_state.pgxp_gte[idx].value = rtVal;
}
////////////////////////////////////
// Memory Access
////////////////////////////////////
-void PGXP::CPU_LWC2(u32 instr, u32 addr, u32 rtVal)
+void CPU::PGXP::CPU_LWC2(u32 instr, u32 addr, u32 rtVal)
{
// GTE_D[Rt] = Mem[addr]
PGXP_value val;
ValidateAndCopyMem(&val, addr, rtVal);
- PGXP_MTC2_int(val, rt(instr));
+ CPU_MTC2_int(val, rt(instr));
}
-void PGXP::CPU_SWC2(u32 instr, u32 addr, u32 rtVal)
+void CPU::PGXP::CPU_SWC2(u32 instr, u32 addr, u32 rtVal)
{
// Mem[addr] = GTE_D[Rt]
- Validate(>E_regs[rt(instr)], rtVal);
- WriteMem(>E_regs[rt(instr)], addr);
+ Validate(&g_state.pgxp_gte[rt(instr)], rtVal);
+ WriteMem(&g_state.pgxp_gte[rt(instr)], addr);
}
-ALWAYS_INLINE_RELEASE void PGXP::PGXP_CacheVertex(s16 sx, s16 sy, const PGXP_value& vertex)
+ALWAYS_INLINE_RELEASE void CPU::PGXP::PGXP_CacheVertex(s16 sx, s16 sy, const PGXP_value& vertex)
{
if (sx >= -0x800 && sx <= 0x7ff && sy >= -0x800 && sy <= 0x7ff)
{
@@ -478,7 +449,7 @@ ALWAYS_INLINE_RELEASE void PGXP::PGXP_CacheVertex(s16 sx, s16 sy, const PGXP_val
}
}
-ALWAYS_INLINE_RELEASE PGXP::PGXP_value* PGXP::PGXP_GetCachedVertex(short sx, short sy)
+ALWAYS_INLINE_RELEASE CPU::PGXP_value* CPU::PGXP::PGXP_GetCachedVertex(short sx, short sy)
{
if (sx >= -0x800 && sx <= 0x7ff && sy >= -0x800 && sy <= 0x7ff)
{
@@ -489,14 +460,14 @@ ALWAYS_INLINE_RELEASE PGXP::PGXP_value* PGXP::PGXP_GetCachedVertex(short sx, sho
return nullptr;
}
-ALWAYS_INLINE_RELEASE float PGXP::TruncateVertexPosition(float p)
+ALWAYS_INLINE_RELEASE float CPU::PGXP::TruncateVertexPosition(float p)
{
const s32 int_part = static_cast(p);
const float int_part_f = static_cast(int_part);
return static_cast(static_cast(int_part << 5) >> 5) + (p - int_part_f);
}
-ALWAYS_INLINE_RELEASE bool PGXP::IsWithinTolerance(float precise_x, float precise_y, int int_x, int int_y)
+ALWAYS_INLINE_RELEASE bool CPU::PGXP::IsWithinTolerance(float precise_x, float precise_y, int int_x, int int_y)
{
const float tolerance = g_settings.gpu_pgxp_tolerance;
if (tolerance < 0.0f)
@@ -506,10 +477,10 @@ ALWAYS_INLINE_RELEASE bool PGXP::IsWithinTolerance(float precise_x, float precis
std::abs(precise_y - static_cast(int_y)) <= tolerance);
}
-bool PGXP::GetPreciseVertex(u32 addr, u32 value, int x, int y, int xOffs, int yOffs, float* out_x, float* out_y,
- float* out_w)
+bool CPU::PGXP::GetPreciseVertex(u32 addr, u32 value, int x, int y, int xOffs, int yOffs, float* out_x, float* out_y,
+ float* out_w)
{
- const PGXP_value* vert = ReadMem(addr);
+ const PGXP_value* vert = GetPtr(addr);
if (vert && ((vert->flags & VALID_01) == VALID_01) && (vert->value == value))
{
// There is a value here with valid X and Y coordinates
@@ -560,63 +531,63 @@ bool PGXP::GetPreciseVertex(u32 addr, u32 value, int x, int y, int xOffs, int yO
#define imm_sext(_instr) \
static_cast(static_cast(_instr & 0xFFFF)) // The immediate part of the instruction register
-void PGXP::CPU_LW(u32 instr, u32 addr, u32 rtVal)
+void CPU::PGXP::CPU_LW(u32 instr, u32 addr, u32 rtVal)
{
// Rt = Mem[Rs + Im]
- ValidateAndCopyMem(&CPU_reg[rt(instr)], addr, rtVal);
+ ValidateAndCopyMem(&g_state.pgxp_gpr[rt(instr)], addr, rtVal);
}
-void PGXP::CPU_LBx(u32 instr, u32 addr, u32 rtVal)
+void CPU::PGXP::CPU_LBx(u32 instr, u32 addr, u32 rtVal)
{
- CPU_reg[rt(instr)] = PGXP_value_invalid;
+ g_state.pgxp_gpr[rt(instr)] = PGXP_value_invalid;
}
-void PGXP::CPU_LH(u32 instr, u32 addr, u32 rtVal)
+void CPU::PGXP::CPU_LH(u32 instr, u32 addr, u32 rtVal)
{
// Rt = Mem[Rs + Im] (sign extended)
- ValidateAndCopyMem16(&CPU_reg[rt(instr)], addr, rtVal, true);
+ ValidateAndCopyMem16(&g_state.pgxp_gpr[rt(instr)], addr, rtVal, true);
}
-void PGXP::CPU_LHU(u32 instr, u32 addr, u32 rtVal)
+void CPU::PGXP::CPU_LHU(u32 instr, u32 addr, u32 rtVal)
{
// Rt = Mem[Rs + Im] (zero extended)
- ValidateAndCopyMem16(&CPU_reg[rt(instr)], addr, rtVal, false);
+ ValidateAndCopyMem16(&g_state.pgxp_gpr[rt(instr)], addr, rtVal, false);
}
-void PGXP::CPU_SB(u32 instr, u32 addr, u32 rtVal)
+void CPU::PGXP::CPU_SB(u32 instr, u32 addr, u32 rtVal)
{
WriteMem(&PGXP_value_invalid, addr);
}
-void PGXP::CPU_SH(u32 instr, u32 addr, u32 rtVal)
+void CPU::PGXP::CPU_SH(u32 instr, u32 addr, u32 rtVal)
{
- PGXP_value* val = &CPU_reg[rt(instr)];
+ PGXP_value* val = &g_state.pgxp_gpr[rt(instr)];
// validate and copy half value
MaskValidate(val, rtVal, 0xFFFF, VALID_0);
WriteMem16(val, addr);
}
-void PGXP::CPU_SW(u32 instr, u32 addr, u32 rtVal)
+void CPU::PGXP::CPU_SW(u32 instr, u32 addr, u32 rtVal)
{
// Mem[Rs + Im] = Rt
- PGXP_value* val = &CPU_reg[rt(instr)];
+ PGXP_value* val = &g_state.pgxp_gpr[rt(instr)];
Validate(val, rtVal);
WriteMem(val, addr);
}
-void PGXP::CPU_MOVE(u32 rd_and_rs, u32 rsVal)
+void CPU::PGXP::CPU_MOVE(u32 rd_and_rs, u32 rsVal)
{
const u32 Rs = (rd_and_rs & 0xFFu);
- Validate(&CPU_reg[Rs], rsVal);
- CPU_reg[(rd_and_rs >> 8)] = CPU_reg[Rs];
+ Validate(&g_state.pgxp_gpr[Rs], rsVal);
+ g_state.pgxp_gpr[(rd_and_rs >> 8)] = g_state.pgxp_gpr[Rs];
}
-void PGXP::CPU_ADDI(u32 instr, u32 rsVal)
+void CPU::PGXP::CPU_ADDI(u32 instr, u32 rsVal)
{
// Rt = Rs + Imm (signed)
- Validate(&CPU_reg[rs(instr)], rsVal);
- PGXP_value ret = CPU_reg[rs(instr)];
+ Validate(&g_state.pgxp_gpr[rs(instr)], rsVal);
+ PGXP_value ret = g_state.pgxp_gpr[rs(instr)];
psx_value tempImm;
tempImm.d = SignExtend32(static_cast(imm(instr)));
@@ -636,19 +607,19 @@ void PGXP::CPU_ADDI(u32 instr, u32 rsVal)
ret.y += (ret.y > SHRT_MAX) ? -(USHRT_MAX + 1) : (ret.y < SHRT_MIN) ? USHRT_MAX + 1 : 0.f;
}
- CPU_reg[rt(instr)] = ret;
- CPU_reg[rt(instr)].value = rsVal + imm_sext(instr);
+ g_state.pgxp_gpr[rt(instr)] = ret;
+ g_state.pgxp_gpr[rt(instr)].value = rsVal + imm_sext(instr);
}
-void PGXP::CPU_ANDI(u32 instr, u32 rsVal)
+void CPU::PGXP::CPU_ANDI(u32 instr, u32 rsVal)
{
// Rt = Rs & Imm
const u32 rtVal = rsVal & imm(instr);
psx_value vRt;
PGXP_value ret;
- Validate(&CPU_reg[rs(instr)], rsVal);
- ret = CPU_reg[rs(instr)];
+ Validate(&g_state.pgxp_gpr[rs(instr)], rsVal);
+ ret = g_state.pgxp_gpr[rs(instr)];
vRt.d = rtVal;
@@ -671,19 +642,19 @@ void PGXP::CPU_ANDI(u32 instr, u32 rsVal)
ret.flags |= VALID_1;
- CPU_reg[rt(instr)] = ret;
- CPU_reg[rt(instr)].value = rtVal;
+ g_state.pgxp_gpr[rt(instr)] = ret;
+ g_state.pgxp_gpr[rt(instr)].value = rtVal;
}
-void PGXP::CPU_ORI(u32 instr, u32 rsVal)
+void CPU::PGXP::CPU_ORI(u32 instr, u32 rsVal)
{
// Rt = Rs | Imm
const u32 rtVal = rsVal | imm(instr);
psx_value vRt;
PGXP_value ret;
- Validate(&CPU_reg[rs(instr)], rsVal);
- ret = CPU_reg[rs(instr)];
+ Validate(&g_state.pgxp_gpr[rs(instr)], rsVal);
+ ret = g_state.pgxp_gpr[rs(instr)];
vRt.d = rtVal;
@@ -699,18 +670,18 @@ void PGXP::CPU_ORI(u32 instr, u32 rsVal)
}
ret.value = rtVal;
- CPU_reg[rt(instr)] = ret;
+ g_state.pgxp_gpr[rt(instr)] = ret;
}
-void PGXP::CPU_XORI(u32 instr, u32 rsVal)
+void CPU::PGXP::CPU_XORI(u32 instr, u32 rsVal)
{
// Rt = Rs ^ Imm
const u32 rtVal = rsVal ^ imm(instr);
psx_value vRt;
PGXP_value ret;
- Validate(&CPU_reg[rs(instr)], rsVal);
- ret = CPU_reg[rs(instr)];
+ Validate(&g_state.pgxp_gpr[rs(instr)], rsVal);
+ ret = g_state.pgxp_gpr[rs(instr)];
vRt.d = rtVal;
@@ -726,170 +697,173 @@ void PGXP::CPU_XORI(u32 instr, u32 rsVal)
}
ret.value = rtVal;
- CPU_reg[rt(instr)] = ret;
+ g_state.pgxp_gpr[rt(instr)] = ret;
}
-void PGXP::CPU_SLTI(u32 instr, u32 rsVal)
+void CPU::PGXP::CPU_SLTI(u32 instr, u32 rsVal)
{
// Rt = Rs < Imm (signed)
psx_value tempImm;
PGXP_value ret;
- Validate(&CPU_reg[rs(instr)], rsVal);
- ret = CPU_reg[rs(instr)];
+ Validate(&g_state.pgxp_gpr[rs(instr)], rsVal);
+ ret = g_state.pgxp_gpr[rs(instr)];
tempImm.w.h = imm(instr);
ret.y = 0.f;
- ret.x = (CPU_reg[rs(instr)].x < tempImm.sw.h) ? 1.f : 0.f;
+ ret.x = (g_state.pgxp_gpr[rs(instr)].x < tempImm.sw.h) ? 1.f : 0.f;
ret.flags |= VALID_1;
ret.value = BoolToUInt32(static_cast(rsVal) < imm_sext(instr));
- CPU_reg[rt(instr)] = ret;
+ g_state.pgxp_gpr[rt(instr)] = ret;
}
-void PGXP::CPU_SLTIU(u32 instr, u32 rsVal)
+void CPU::PGXP::CPU_SLTIU(u32 instr, u32 rsVal)
{
// Rt = Rs < Imm (Unsigned)
psx_value tempImm;
PGXP_value ret;
- Validate(&CPU_reg[rs(instr)], rsVal);
- ret = CPU_reg[rs(instr)];
+ Validate(&g_state.pgxp_gpr[rs(instr)], rsVal);
+ ret = g_state.pgxp_gpr[rs(instr)];
tempImm.w.h = imm(instr);
ret.y = 0.f;
- ret.x = (f16Unsign(CPU_reg[rs(instr)].x) < tempImm.w.h) ? 1.f : 0.f;
+ ret.x = (f16Unsign(g_state.pgxp_gpr[rs(instr)].x) < tempImm.w.h) ? 1.f : 0.f;
ret.flags |= VALID_1;
ret.value = BoolToUInt32(rsVal < imm(instr));
- CPU_reg[rt(instr)] = ret;
+ g_state.pgxp_gpr[rt(instr)] = ret;
}
////////////////////////////////////
// Load Upper
////////////////////////////////////
-void PGXP::CPU_LUI(u32 instr)
+void CPU::PGXP::CPU_LUI(u32 instr)
{
// Rt = Imm << 16
- CPU_reg[rt(instr)] = PGXP_value_zero;
- CPU_reg[rt(instr)].y = (float)(s16)imm(instr);
- CPU_reg[rt(instr)].value = static_cast(imm(instr)) << 16;
- CPU_reg[rt(instr)].flags = VALID_01;
+ g_state.pgxp_gpr[rt(instr)] = PGXP_value_zero;
+ g_state.pgxp_gpr[rt(instr)].y = (float)(s16)imm(instr);
+ g_state.pgxp_gpr[rt(instr)].value = static_cast(imm(instr)) << 16;
+ g_state.pgxp_gpr[rt(instr)].flags = VALID_01;
}
////////////////////////////////////
// Register Arithmetic
////////////////////////////////////
-void PGXP::CPU_ADD(u32 instr, u32 rsVal, u32 rtVal)
+void CPU::PGXP::CPU_ADD(u32 instr, u32 rsVal, u32 rtVal)
{
// Rd = Rs + Rt (signed)
PGXP_value ret;
- Validate(&CPU_reg[rs(instr)], rsVal);
- Validate(&CPU_reg[rt(instr)], rtVal);
+ Validate(&g_state.pgxp_gpr[rs(instr)], rsVal);
+ Validate(&g_state.pgxp_gpr[rt(instr)], rtVal);
if (rtVal == 0)
{
- ret = CPU_reg[rs(instr)];
+ ret = g_state.pgxp_gpr[rs(instr)];
}
else if (rsVal == 0)
{
- ret = CPU_reg[rt(instr)];
+ ret = g_state.pgxp_gpr[rt(instr)];
}
else
{
// iCB: Only require one valid input
- if (((CPU_reg[rt(instr)].flags & VALID_01) != VALID_01) != ((CPU_reg[rs(instr)].flags & VALID_01) != VALID_01))
+ if (((g_state.pgxp_gpr[rt(instr)].flags & VALID_01) != VALID_01) !=
+ ((g_state.pgxp_gpr[rs(instr)].flags & VALID_01) != VALID_01))
{
- MakeValid(&CPU_reg[rs(instr)], rsVal);
- MakeValid(&CPU_reg[rt(instr)], rtVal);
+ MakeValid(&g_state.pgxp_gpr[rs(instr)], rsVal);
+ MakeValid(&g_state.pgxp_gpr[rt(instr)], rtVal);
}
- ret = CPU_reg[rs(instr)];
+ ret = g_state.pgxp_gpr[rs(instr)];
ret.x = (float)f16Unsign(ret.x);
- ret.x += (float)f16Unsign(CPU_reg[rt(instr)].x);
+ ret.x += (float)f16Unsign(g_state.pgxp_gpr[rt(instr)].x);
// carry on over/underflow
float of = (ret.x > USHRT_MAX) ? 1.f : (ret.x < 0) ? -1.f : 0.f;
ret.x = (float)f16Sign(ret.x);
// ret.x -= of * (USHRT_MAX + 1);
- ret.y += CPU_reg[rt(instr)].y + of;
+ ret.y += g_state.pgxp_gpr[rt(instr)].y + of;
// truncate on overflow/underflow
ret.y += (ret.y > SHRT_MAX) ? -(USHRT_MAX + 1) : (ret.y < SHRT_MIN) ? USHRT_MAX + 1 : 0.f;
// TODO: decide which "z/w" component to use
- ret.halfFlags[0] &= CPU_reg[rt(instr)].halfFlags[0];
+ ret.halfFlags[0] &= g_state.pgxp_gpr[rt(instr)].halfFlags[0];
}
- if (!(ret.flags & VALID_2) && (CPU_reg[rt(instr)].flags & VALID_2))
+ if (!(ret.flags & VALID_2) && (g_state.pgxp_gpr[rt(instr)].flags & VALID_2))
{
- ret.z = CPU_reg[rt(instr)].z;
+ ret.z = g_state.pgxp_gpr[rt(instr)].z;
ret.flags |= VALID_2;
}
ret.value = rsVal + rtVal;
- CPU_reg[rd(instr)] = ret;
+ g_state.pgxp_gpr[rd(instr)] = ret;
}
-void PGXP::CPU_SUB(u32 instr, u32 rsVal, u32 rtVal)
+void CPU::PGXP::CPU_SUB(u32 instr, u32 rsVal, u32 rtVal)
{
// Rd = Rs - Rt (signed)
PGXP_value ret;
- Validate(&CPU_reg[rs(instr)], rsVal);
- Validate(&CPU_reg[rt(instr)], rtVal);
+ Validate(&g_state.pgxp_gpr[rs(instr)], rsVal);
+ Validate(&g_state.pgxp_gpr[rt(instr)], rtVal);
// iCB: Only require one valid input
- if (((CPU_reg[rt(instr)].flags & VALID_01) != VALID_01) != ((CPU_reg[rs(instr)].flags & VALID_01) != VALID_01))
+ if (((g_state.pgxp_gpr[rt(instr)].flags & VALID_01) != VALID_01) !=
+ ((g_state.pgxp_gpr[rs(instr)].flags & VALID_01) != VALID_01))
{
- MakeValid(&CPU_reg[rs(instr)], rsVal);
- MakeValid(&CPU_reg[rt(instr)], rtVal);
+ MakeValid(&g_state.pgxp_gpr[rs(instr)], rsVal);
+ MakeValid(&g_state.pgxp_gpr[rt(instr)], rtVal);
}
- ret = CPU_reg[rs(instr)];
+ ret = g_state.pgxp_gpr[rs(instr)];
ret.x = (float)f16Unsign(ret.x);
- ret.x -= (float)f16Unsign(CPU_reg[rt(instr)].x);
+ ret.x -= (float)f16Unsign(g_state.pgxp_gpr[rt(instr)].x);
// carry on over/underflow
float of = (ret.x > USHRT_MAX) ? 1.f : (ret.x < 0) ? -1.f : 0.f;
ret.x = (float)f16Sign(ret.x);
// ret.x -= of * (USHRT_MAX + 1);
- ret.y -= CPU_reg[rt(instr)].y - of;
+ ret.y -= g_state.pgxp_gpr[rt(instr)].y - of;
// truncate on overflow/underflow
ret.y += (ret.y > SHRT_MAX) ? -(USHRT_MAX + 1) : (ret.y < SHRT_MIN) ? USHRT_MAX + 1 : 0.f;
- ret.halfFlags[0] &= CPU_reg[rt(instr)].halfFlags[0];
+ ret.halfFlags[0] &= g_state.pgxp_gpr[rt(instr)].halfFlags[0];
ret.value = rsVal - rtVal;
- if (!(ret.flags & VALID_2) && (CPU_reg[rt(instr)].flags & VALID_2))
+ if (!(ret.flags & VALID_2) && (g_state.pgxp_gpr[rt(instr)].flags & VALID_2))
{
- ret.z = CPU_reg[rt(instr)].z;
+ ret.z = g_state.pgxp_gpr[rt(instr)].z;
ret.flags |= VALID_2;
}
- CPU_reg[rd(instr)] = ret;
+ g_state.pgxp_gpr[rd(instr)] = ret;
}
-ALWAYS_INLINE_RELEASE void PGXP::CPU_BITWISE(u32 instr, u32 rdVal, u32 rsVal, u32 rtVal)
+ALWAYS_INLINE_RELEASE void CPU::PGXP::CPU_BITWISE(u32 instr, u32 rdVal, u32 rsVal, u32 rtVal)
{
// Rd = Rs & Rt
psx_value vald, vals, valt;
PGXP_value ret;
- Validate(&CPU_reg[rs(instr)], rsVal);
- Validate(&CPU_reg[rt(instr)], rtVal);
+ Validate(&g_state.pgxp_gpr[rs(instr)], rsVal);
+ Validate(&g_state.pgxp_gpr[rt(instr)], rtVal);
// iCB: Only require one valid input
- if (((CPU_reg[rt(instr)].flags & VALID_01) != VALID_01) != ((CPU_reg[rs(instr)].flags & VALID_01) != VALID_01))
+ if (((g_state.pgxp_gpr[rt(instr)].flags & VALID_01) != VALID_01) !=
+ ((g_state.pgxp_gpr[rs(instr)].flags & VALID_01) != VALID_01))
{
- MakeValid(&CPU_reg[rs(instr)], rsVal);
- MakeValid(&CPU_reg[rt(instr)], rtVal);
+ MakeValid(&g_state.pgxp_gpr[rs(instr)], rsVal);
+ MakeValid(&g_state.pgxp_gpr[rt(instr)], rtVal);
}
vald.d = rdVal;
@@ -905,13 +879,13 @@ ALWAYS_INLINE_RELEASE void PGXP::CPU_BITWISE(u32 instr, u32 rdVal, u32 rsVal, u3
}
else if (vald.w.l == vals.w.l)
{
- ret.x = CPU_reg[rs(instr)].x;
- ret.compFlags[0] = CPU_reg[rs(instr)].compFlags[0];
+ ret.x = g_state.pgxp_gpr[rs(instr)].x;
+ ret.compFlags[0] = g_state.pgxp_gpr[rs(instr)].compFlags[0];
}
else if (vald.w.l == valt.w.l)
{
- ret.x = CPU_reg[rt(instr)].x;
- ret.compFlags[0] = CPU_reg[rt(instr)].compFlags[0];
+ ret.x = g_state.pgxp_gpr[rt(instr)].x;
+ ret.compFlags[0] = g_state.pgxp_gpr[rt(instr)].compFlags[0];
}
else
{
@@ -925,13 +899,13 @@ ALWAYS_INLINE_RELEASE void PGXP::CPU_BITWISE(u32 instr, u32 rdVal, u32 rsVal, u3
}
else if (vald.w.h == vals.w.h)
{
- ret.y = CPU_reg[rs(instr)].y;
- ret.compFlags[1] &= CPU_reg[rs(instr)].compFlags[1];
+ ret.y = g_state.pgxp_gpr[rs(instr)].y;
+ ret.compFlags[1] &= g_state.pgxp_gpr[rs(instr)].compFlags[1];
}
else if (vald.w.h == valt.w.h)
{
- ret.y = CPU_reg[rt(instr)].y;
- ret.compFlags[1] &= CPU_reg[rt(instr)].compFlags[1];
+ ret.y = g_state.pgxp_gpr[rt(instr)].y;
+ ret.compFlags[1] &= g_state.pgxp_gpr[rt(instr)].compFlags[1];
}
else
{
@@ -945,15 +919,15 @@ ALWAYS_INLINE_RELEASE void PGXP::CPU_BITWISE(u32 instr, u32 rdVal, u32 rsVal, u3
// /iCB Hack
// Get a valid W
- if ((CPU_reg[rs(instr)].flags & VALID_2) == VALID_2)
+ if ((g_state.pgxp_gpr[rs(instr)].flags & VALID_2) == VALID_2)
{
- ret.z = CPU_reg[rs(instr)].z;
- ret.compFlags[2] = CPU_reg[rs(instr)].compFlags[2];
+ ret.z = g_state.pgxp_gpr[rs(instr)].z;
+ ret.compFlags[2] = g_state.pgxp_gpr[rs(instr)].compFlags[2];
}
- else if ((CPU_reg[rt(instr)].flags & VALID_2) == VALID_2)
+ else if ((g_state.pgxp_gpr[rt(instr)].flags & VALID_2) == VALID_2)
{
- ret.z = CPU_reg[rt(instr)].z;
- ret.compFlags[2] = CPU_reg[rt(instr)].compFlags[2];
+ ret.z = g_state.pgxp_gpr[rt(instr)].z;
+ ret.compFlags[2] = g_state.pgxp_gpr[rt(instr)].compFlags[2];
}
else
{
@@ -962,118 +936,122 @@ ALWAYS_INLINE_RELEASE void PGXP::CPU_BITWISE(u32 instr, u32 rdVal, u32 rsVal, u3
}
ret.value = rdVal;
- CPU_reg[rd(instr)] = ret;
+ g_state.pgxp_gpr[rd(instr)] = ret;
}
-void PGXP::CPU_AND_(u32 instr, u32 rsVal, u32 rtVal)
+void CPU::PGXP::CPU_AND_(u32 instr, u32 rsVal, u32 rtVal)
{
// Rd = Rs & Rt
const u32 rdVal = rsVal & rtVal;
CPU_BITWISE(instr, rdVal, rsVal, rtVal);
}
-void PGXP::CPU_OR_(u32 instr, u32 rsVal, u32 rtVal)
+void CPU::PGXP::CPU_OR_(u32 instr, u32 rsVal, u32 rtVal)
{
// Rd = Rs | Rt
const u32 rdVal = rsVal | rtVal;
CPU_BITWISE(instr, rdVal, rsVal, rtVal);
}
-void PGXP::CPU_XOR_(u32 instr, u32 rsVal, u32 rtVal)
+void CPU::PGXP::CPU_XOR_(u32 instr, u32 rsVal, u32 rtVal)
{
// Rd = Rs ^ Rt
const u32 rdVal = rsVal ^ rtVal;
CPU_BITWISE(instr, rdVal, rsVal, rtVal);
}
-void PGXP::CPU_NOR(u32 instr, u32 rsVal, u32 rtVal)
+void CPU::PGXP::CPU_NOR(u32 instr, u32 rsVal, u32 rtVal)
{
// Rd = Rs NOR Rt
const u32 rdVal = ~(rsVal | rtVal);
CPU_BITWISE(instr, rdVal, rsVal, rtVal);
}
-void PGXP::CPU_SLT(u32 instr, u32 rsVal, u32 rtVal)
+void CPU::PGXP::CPU_SLT(u32 instr, u32 rsVal, u32 rtVal)
{
// Rd = Rs < Rt (signed)
PGXP_value ret;
- Validate(&CPU_reg[rs(instr)], rsVal);
- Validate(&CPU_reg[rt(instr)], rtVal);
+ Validate(&g_state.pgxp_gpr[rs(instr)], rsVal);
+ Validate(&g_state.pgxp_gpr[rt(instr)], rtVal);
// iCB: Only require one valid input
- if (((CPU_reg[rt(instr)].flags & VALID_01) != VALID_01) != ((CPU_reg[rs(instr)].flags & VALID_01) != VALID_01))
+ if (((g_state.pgxp_gpr[rt(instr)].flags & VALID_01) != VALID_01) !=
+ ((g_state.pgxp_gpr[rs(instr)].flags & VALID_01) != VALID_01))
{
- MakeValid(&CPU_reg[rs(instr)], rsVal);
- MakeValid(&CPU_reg[rt(instr)], rtVal);
+ MakeValid(&g_state.pgxp_gpr[rs(instr)], rsVal);
+ MakeValid(&g_state.pgxp_gpr[rt(instr)], rtVal);
}
- ret = CPU_reg[rs(instr)];
+ ret = g_state.pgxp_gpr[rs(instr)];
ret.y = 0.f;
ret.compFlags[1] = VALID;
- ret.x = (CPU_reg[rs(instr)].y < CPU_reg[rt(instr)].y) ? 1.f :
- (f16Unsign(CPU_reg[rs(instr)].x) < f16Unsign(CPU_reg[rt(instr)].x)) ? 1.f :
- 0.f;
+ ret.x = (g_state.pgxp_gpr[rs(instr)].y < g_state.pgxp_gpr[rt(instr)].y) ? 1.f :
+ (f16Unsign(g_state.pgxp_gpr[rs(instr)].x) < f16Unsign(g_state.pgxp_gpr[rt(instr)].x)) ? 1.f :
+ 0.f;
ret.value = BoolToUInt32(static_cast(rsVal) < static_cast(rtVal));
- CPU_reg[rd(instr)] = ret;
+ g_state.pgxp_gpr[rd(instr)] = ret;
}
-void PGXP::CPU_SLTU(u32 instr, u32 rsVal, u32 rtVal)
+void CPU::PGXP::CPU_SLTU(u32 instr, u32 rsVal, u32 rtVal)
{
// Rd = Rs < Rt (unsigned)
PGXP_value ret;
- Validate(&CPU_reg[rs(instr)], rsVal);
- Validate(&CPU_reg[rt(instr)], rtVal);
+ Validate(&g_state.pgxp_gpr[rs(instr)], rsVal);
+ Validate(&g_state.pgxp_gpr[rt(instr)], rtVal);
// iCB: Only require one valid input
- if (((CPU_reg[rt(instr)].flags & VALID_01) != VALID_01) != ((CPU_reg[rs(instr)].flags & VALID_01) != VALID_01))
+ if (((g_state.pgxp_gpr[rt(instr)].flags & VALID_01) != VALID_01) !=
+ ((g_state.pgxp_gpr[rs(instr)].flags & VALID_01) != VALID_01))
{
- MakeValid(&CPU_reg[rs(instr)], rsVal);
- MakeValid(&CPU_reg[rt(instr)], rtVal);
+ MakeValid(&g_state.pgxp_gpr[rs(instr)], rsVal);
+ MakeValid(&g_state.pgxp_gpr[rt(instr)], rtVal);
}
- ret = CPU_reg[rs(instr)];
+ ret = g_state.pgxp_gpr[rs(instr)];
ret.y = 0.f;
ret.compFlags[1] = VALID;
- ret.x = (f16Unsign(CPU_reg[rs(instr)].y) < f16Unsign(CPU_reg[rt(instr)].y)) ? 1.f :
- (f16Unsign(CPU_reg[rs(instr)].x) < f16Unsign(CPU_reg[rt(instr)].x)) ? 1.f :
- 0.f;
+ ret.x = (f16Unsign(g_state.pgxp_gpr[rs(instr)].y) < f16Unsign(g_state.pgxp_gpr[rt(instr)].y)) ? 1.f :
+ (f16Unsign(g_state.pgxp_gpr[rs(instr)].x) < f16Unsign(g_state.pgxp_gpr[rt(instr)].x)) ? 1.f :
+ 0.f;
ret.value = BoolToUInt32(rsVal < rtVal);
- CPU_reg[rd(instr)] = ret;
+ g_state.pgxp_gpr[rd(instr)] = ret;
}
////////////////////////////////////
// Register mult/div
////////////////////////////////////
-void PGXP::CPU_MULT(u32 instr, u32 rsVal, u32 rtVal)
+void CPU::PGXP::CPU_MULT(u32 instr, u32 rsVal, u32 rtVal)
{
// Hi/Lo = Rs * Rt (signed)
- Validate(&CPU_reg[rs(instr)], rsVal);
- Validate(&CPU_reg[rt(instr)], rtVal);
+ Validate(&g_state.pgxp_gpr[rs(instr)], rsVal);
+ Validate(&g_state.pgxp_gpr[rt(instr)], rtVal);
// iCB: Only require one valid input
- if (((CPU_reg[rt(instr)].flags & VALID_01) != VALID_01) != ((CPU_reg[rs(instr)].flags & VALID_01) != VALID_01))
+ if (((g_state.pgxp_gpr[rt(instr)].flags & VALID_01) != VALID_01) !=
+ ((g_state.pgxp_gpr[rs(instr)].flags & VALID_01) != VALID_01))
{
- MakeValid(&CPU_reg[rs(instr)], rsVal);
- MakeValid(&CPU_reg[rt(instr)], rtVal);
+ MakeValid(&g_state.pgxp_gpr[rs(instr)], rsVal);
+ MakeValid(&g_state.pgxp_gpr[rt(instr)], rtVal);
}
- CPU_Lo = CPU_Hi = CPU_reg[rs(instr)];
+ g_state.pgxp_lo = g_state.pgxp_hi = g_state.pgxp_gpr[rs(instr)];
- CPU_Lo.halfFlags[0] = CPU_Hi.halfFlags[0] = (CPU_reg[rs(instr)].halfFlags[0] & CPU_reg[rt(instr)].halfFlags[0]);
+ g_state.pgxp_lo.halfFlags[0] = g_state.pgxp_hi.halfFlags[0] =
+ (g_state.pgxp_gpr[rs(instr)].halfFlags[0] & g_state.pgxp_gpr[rt(instr)].halfFlags[0]);
double xx, xy, yx, yy;
double lx = 0, ly = 0, hx = 0, hy = 0;
// Multiply out components
- xx = f16Unsign(CPU_reg[rs(instr)].x) * f16Unsign(CPU_reg[rt(instr)].x);
- xy = f16Unsign(CPU_reg[rs(instr)].x) * (CPU_reg[rt(instr)].y);
- yx = (CPU_reg[rs(instr)].y) * f16Unsign(CPU_reg[rt(instr)].x);
- yy = (CPU_reg[rs(instr)].y) * (CPU_reg[rt(instr)].y);
+ xx = f16Unsign(g_state.pgxp_gpr[rs(instr)].x) * f16Unsign(g_state.pgxp_gpr[rt(instr)].x);
+ xy = f16Unsign(g_state.pgxp_gpr[rs(instr)].x) * (g_state.pgxp_gpr[rt(instr)].y);
+ yx = (g_state.pgxp_gpr[rs(instr)].y) * f16Unsign(g_state.pgxp_gpr[rt(instr)].x);
+ yy = (g_state.pgxp_gpr[rs(instr)].y) * (g_state.pgxp_gpr[rt(instr)].y);
// Split values into outputs
lx = xx;
@@ -1086,42 +1064,44 @@ void PGXP::CPU_MULT(u32 instr, u32 rsVal, u32 rtVal)
hy = f16Overflow(hx);
- CPU_Lo.x = (float)f16Sign(lx);
- CPU_Lo.y = (float)f16Sign(ly);
- CPU_Hi.x = (float)f16Sign(hx);
- CPU_Hi.y = (float)f16Sign(hy);
+ g_state.pgxp_lo.x = (float)f16Sign(lx);
+ g_state.pgxp_lo.y = (float)f16Sign(ly);
+ g_state.pgxp_hi.x = (float)f16Sign(hx);
+ g_state.pgxp_hi.y = (float)f16Sign(hy);
// compute PSX value
const u64 result = static_cast(static_cast(SignExtend64(rsVal)) * static_cast(SignExtend64(rtVal)));
- CPU_Hi.value = Truncate32(result >> 32);
- CPU_Lo.value = Truncate32(result);
+ g_state.pgxp_hi.value = Truncate32(result >> 32);
+ g_state.pgxp_lo.value = Truncate32(result);
}
-void PGXP::CPU_MULTU(u32 instr, u32 rsVal, u32 rtVal)
+void CPU::PGXP::CPU_MULTU(u32 instr, u32 rsVal, u32 rtVal)
{
// Hi/Lo = Rs * Rt (unsigned)
- Validate(&CPU_reg[rs(instr)], rsVal);
- Validate(&CPU_reg[rt(instr)], rtVal);
+ Validate(&g_state.pgxp_gpr[rs(instr)], rsVal);
+ Validate(&g_state.pgxp_gpr[rt(instr)], rtVal);
// iCB: Only require one valid input
- if (((CPU_reg[rt(instr)].flags & VALID_01) != VALID_01) != ((CPU_reg[rs(instr)].flags & VALID_01) != VALID_01))
+ if (((g_state.pgxp_gpr[rt(instr)].flags & VALID_01) != VALID_01) !=
+ ((g_state.pgxp_gpr[rs(instr)].flags & VALID_01) != VALID_01))
{
- MakeValid(&CPU_reg[rs(instr)], rsVal);
- MakeValid(&CPU_reg[rt(instr)], rtVal);
+ MakeValid(&g_state.pgxp_gpr[rs(instr)], rsVal);
+ MakeValid(&g_state.pgxp_gpr[rt(instr)], rtVal);
}
- CPU_Lo = CPU_Hi = CPU_reg[rs(instr)];
+ g_state.pgxp_lo = g_state.pgxp_hi = g_state.pgxp_gpr[rs(instr)];
- CPU_Lo.halfFlags[0] = CPU_Hi.halfFlags[0] = (CPU_reg[rs(instr)].halfFlags[0] & CPU_reg[rt(instr)].halfFlags[0]);
+ g_state.pgxp_lo.halfFlags[0] = g_state.pgxp_hi.halfFlags[0] =
+ (g_state.pgxp_gpr[rs(instr)].halfFlags[0] & g_state.pgxp_gpr[rt(instr)].halfFlags[0]);
double xx, xy, yx, yy;
double lx = 0, ly = 0, hx = 0, hy = 0;
// Multiply out components
- xx = f16Unsign(CPU_reg[rs(instr)].x) * f16Unsign(CPU_reg[rt(instr)].x);
- xy = f16Unsign(CPU_reg[rs(instr)].x) * f16Unsign(CPU_reg[rt(instr)].y);
- yx = f16Unsign(CPU_reg[rs(instr)].y) * f16Unsign(CPU_reg[rt(instr)].x);
- yy = f16Unsign(CPU_reg[rs(instr)].y) * f16Unsign(CPU_reg[rt(instr)].y);
+ xx = f16Unsign(g_state.pgxp_gpr[rs(instr)].x) * f16Unsign(g_state.pgxp_gpr[rt(instr)].x);
+ xy = f16Unsign(g_state.pgxp_gpr[rs(instr)].x) * f16Unsign(g_state.pgxp_gpr[rt(instr)].y);
+ yx = f16Unsign(g_state.pgxp_gpr[rs(instr)].y) * f16Unsign(g_state.pgxp_gpr[rt(instr)].x);
+ yy = f16Unsign(g_state.pgxp_gpr[rs(instr)].y) * f16Unsign(g_state.pgxp_gpr[rt(instr)].y);
// Split values into outputs
lx = xx;
@@ -1134,124 +1114,128 @@ void PGXP::CPU_MULTU(u32 instr, u32 rsVal, u32 rtVal)
hy = f16Overflow(hx);
- CPU_Lo.x = (float)f16Sign(lx);
- CPU_Lo.y = (float)f16Sign(ly);
- CPU_Hi.x = (float)f16Sign(hx);
- CPU_Hi.y = (float)f16Sign(hy);
+ g_state.pgxp_lo.x = (float)f16Sign(lx);
+ g_state.pgxp_lo.y = (float)f16Sign(ly);
+ g_state.pgxp_hi.x = (float)f16Sign(hx);
+ g_state.pgxp_hi.y = (float)f16Sign(hy);
// compute PSX value
const u64 result = ZeroExtend64(rsVal) * ZeroExtend64(rtVal);
- CPU_Hi.value = Truncate32(result >> 32);
- CPU_Lo.value = Truncate32(result);
+ g_state.pgxp_hi.value = Truncate32(result >> 32);
+ g_state.pgxp_lo.value = Truncate32(result);
}
-void PGXP::CPU_DIV(u32 instr, u32 rsVal, u32 rtVal)
+void CPU::PGXP::CPU_DIV(u32 instr, u32 rsVal, u32 rtVal)
{
// Lo = Rs / Rt (signed)
// Hi = Rs % Rt (signed)
- Validate(&CPU_reg[rs(instr)], rsVal);
- Validate(&CPU_reg[rt(instr)], rtVal);
+ Validate(&g_state.pgxp_gpr[rs(instr)], rsVal);
+ Validate(&g_state.pgxp_gpr[rt(instr)], rtVal);
//// iCB: Only require one valid input
- if (((CPU_reg[rt(instr)].flags & VALID_01) != VALID_01) != ((CPU_reg[rs(instr)].flags & VALID_01) != VALID_01))
+ if (((g_state.pgxp_gpr[rt(instr)].flags & VALID_01) != VALID_01) !=
+ ((g_state.pgxp_gpr[rs(instr)].flags & VALID_01) != VALID_01))
{
- MakeValid(&CPU_reg[rs(instr)], rsVal);
- MakeValid(&CPU_reg[rt(instr)], rtVal);
+ MakeValid(&g_state.pgxp_gpr[rs(instr)], rsVal);
+ MakeValid(&g_state.pgxp_gpr[rt(instr)], rtVal);
}
- CPU_Lo = CPU_Hi = CPU_reg[rs(instr)];
+ g_state.pgxp_lo = g_state.pgxp_hi = g_state.pgxp_gpr[rs(instr)];
- CPU_Lo.halfFlags[0] = CPU_Hi.halfFlags[0] = (CPU_reg[rs(instr)].halfFlags[0] & CPU_reg[rt(instr)].halfFlags[0]);
+ g_state.pgxp_lo.halfFlags[0] = g_state.pgxp_hi.halfFlags[0] =
+ (g_state.pgxp_gpr[rs(instr)].halfFlags[0] & g_state.pgxp_gpr[rt(instr)].halfFlags[0]);
- double vs = f16Unsign(CPU_reg[rs(instr)].x) + (CPU_reg[rs(instr)].y) * (double)(1 << 16);
- double vt = f16Unsign(CPU_reg[rt(instr)].x) + (CPU_reg[rt(instr)].y) * (double)(1 << 16);
+ double vs = f16Unsign(g_state.pgxp_gpr[rs(instr)].x) + (g_state.pgxp_gpr[rs(instr)].y) * (double)(1 << 16);
+ double vt = f16Unsign(g_state.pgxp_gpr[rt(instr)].x) + (g_state.pgxp_gpr[rt(instr)].y) * (double)(1 << 16);
double lo = vs / vt;
- CPU_Lo.y = (float)f16Sign(f16Overflow(lo));
- CPU_Lo.x = (float)f16Sign(lo);
+ g_state.pgxp_lo.y = (float)f16Sign(f16Overflow(lo));
+ g_state.pgxp_lo.x = (float)f16Sign(lo);
double hi = fmod(vs, vt);
- CPU_Hi.y = (float)f16Sign(f16Overflow(hi));
- CPU_Hi.x = (float)f16Sign(hi);
+ g_state.pgxp_hi.y = (float)f16Sign(f16Overflow(hi));
+ g_state.pgxp_hi.x = (float)f16Sign(hi);
// compute PSX value
if (static_cast(rtVal) == 0)
{
// divide by zero
- CPU_Lo.value = (static_cast(rsVal) >= 0) ? UINT32_C(0xFFFFFFFF) : UINT32_C(1);
- CPU_Hi.value = static_cast(static_cast(rsVal));
+ g_state.pgxp_lo.value = (static_cast(rsVal) >= 0) ? UINT32_C(0xFFFFFFFF) : UINT32_C(1);
+ g_state.pgxp_hi.value = static_cast(static_cast(rsVal));
}
else if (rsVal == UINT32_C(0x80000000) && static_cast(rtVal) == -1)
{
// unrepresentable
- CPU_Lo.value = UINT32_C(0x80000000);
- CPU_Hi.value = 0;
+ g_state.pgxp_lo.value = UINT32_C(0x80000000);
+ g_state.pgxp_hi.value = 0;
}
else
{
- CPU_Lo.value = static_cast(static_cast(rsVal) / static_cast(rtVal));
- CPU_Hi.value = static_cast(static_cast(rsVal) % static_cast(rtVal));
+ g_state.pgxp_lo.value = static_cast(static_cast(rsVal) / static_cast(rtVal));
+ g_state.pgxp_hi.value = static_cast(static_cast(rsVal) % static_cast(rtVal));
}
}
-void PGXP::CPU_DIVU(u32 instr, u32 rsVal, u32 rtVal)
+void CPU::PGXP::CPU_DIVU(u32 instr, u32 rsVal, u32 rtVal)
{
// Lo = Rs / Rt (unsigned)
// Hi = Rs % Rt (unsigned)
- Validate(&CPU_reg[rs(instr)], rsVal);
- Validate(&CPU_reg[rt(instr)], rtVal);
+ Validate(&g_state.pgxp_gpr[rs(instr)], rsVal);
+ Validate(&g_state.pgxp_gpr[rt(instr)], rtVal);
//// iCB: Only require one valid input
- if (((CPU_reg[rt(instr)].flags & VALID_01) != VALID_01) != ((CPU_reg[rs(instr)].flags & VALID_01) != VALID_01))
+ if (((g_state.pgxp_gpr[rt(instr)].flags & VALID_01) != VALID_01) !=
+ ((g_state.pgxp_gpr[rs(instr)].flags & VALID_01) != VALID_01))
{
- MakeValid(&CPU_reg[rs(instr)], rsVal);
- MakeValid(&CPU_reg[rt(instr)], rtVal);
+ MakeValid(&g_state.pgxp_gpr[rs(instr)], rsVal);
+ MakeValid(&g_state.pgxp_gpr[rt(instr)], rtVal);
}
- CPU_Lo = CPU_Hi = CPU_reg[rs(instr)];
+ g_state.pgxp_lo = g_state.pgxp_hi = g_state.pgxp_gpr[rs(instr)];
- CPU_Lo.halfFlags[0] = CPU_Hi.halfFlags[0] = (CPU_reg[rs(instr)].halfFlags[0] & CPU_reg[rt(instr)].halfFlags[0]);
+ g_state.pgxp_lo.halfFlags[0] = g_state.pgxp_hi.halfFlags[0] =
+ (g_state.pgxp_gpr[rs(instr)].halfFlags[0] & g_state.pgxp_gpr[rt(instr)].halfFlags[0]);
- double vs = f16Unsign(CPU_reg[rs(instr)].x) + f16Unsign(CPU_reg[rs(instr)].y) * (double)(1 << 16);
- double vt = f16Unsign(CPU_reg[rt(instr)].x) + f16Unsign(CPU_reg[rt(instr)].y) * (double)(1 << 16);
+ double vs = f16Unsign(g_state.pgxp_gpr[rs(instr)].x) + f16Unsign(g_state.pgxp_gpr[rs(instr)].y) * (double)(1 << 16);
+ double vt = f16Unsign(g_state.pgxp_gpr[rt(instr)].x) + f16Unsign(g_state.pgxp_gpr[rt(instr)].y) * (double)(1 << 16);
double lo = vs / vt;
- CPU_Lo.y = (float)f16Sign(f16Overflow(lo));
- CPU_Lo.x = (float)f16Sign(lo);
+ g_state.pgxp_lo.y = (float)f16Sign(f16Overflow(lo));
+ g_state.pgxp_lo.x = (float)f16Sign(lo);
double hi = fmod(vs, vt);
- CPU_Hi.y = (float)f16Sign(f16Overflow(hi));
- CPU_Hi.x = (float)f16Sign(hi);
+ g_state.pgxp_hi.y = (float)f16Sign(f16Overflow(hi));
+ g_state.pgxp_hi.x = (float)f16Sign(hi);
if (rtVal == 0)
{
// divide by zero
- CPU_Lo.value = UINT32_C(0xFFFFFFFF);
- CPU_Hi.value = rsVal;
+ g_state.pgxp_lo.value = UINT32_C(0xFFFFFFFF);
+ g_state.pgxp_hi.value = rsVal;
}
else
{
- CPU_Lo.value = rsVal / rtVal;
- CPU_Hi.value = rsVal % rtVal;
+ g_state.pgxp_lo.value = rsVal / rtVal;
+ g_state.pgxp_hi.value = rsVal % rtVal;
}
}
////////////////////////////////////
// Shift operations (sa)
////////////////////////////////////
-void PGXP::CPU_SLL(u32 instr, u32 rtVal)
+void CPU::PGXP::CPU_SLL(u32 instr, u32 rtVal)
{
// Rd = Rt << Sa
const u32 rdVal = rtVal << sa(instr);
PGXP_value ret;
u32 sh = sa(instr);
- Validate(&CPU_reg[rt(instr)], rtVal);
+ Validate(&g_state.pgxp_gpr[rt(instr)], rtVal);
- ret = CPU_reg[rt(instr)];
+ ret = g_state.pgxp_gpr[rt(instr)];
// TODO: Shift flags
- double x = f16Unsign(CPU_reg[rt(instr)].x);
- double y = f16Unsign(CPU_reg[rt(instr)].y);
+ double x = f16Unsign(g_state.pgxp_gpr[rt(instr)].x);
+ double y = f16Unsign(g_state.pgxp_gpr[rt(instr)].y);
if (sh >= 32)
{
x = 0.f;
@@ -1281,20 +1265,20 @@ void PGXP::CPU_SLL(u32 instr, u32 rtVal)
ret.y = (float)y;
ret.value = rdVal;
- CPU_reg[rd(instr)] = ret;
+ g_state.pgxp_gpr[rd(instr)] = ret;
}
-void PGXP::CPU_SRL(u32 instr, u32 rtVal)
+void CPU::PGXP::CPU_SRL(u32 instr, u32 rtVal)
{
// Rd = Rt >> Sa
const u32 rdVal = rtVal >> sa(instr);
PGXP_value ret;
u32 sh = sa(instr);
- Validate(&CPU_reg[rt(instr)], rtVal);
+ Validate(&g_state.pgxp_gpr[rt(instr)], rtVal);
- ret = CPU_reg[rt(instr)];
+ ret = g_state.pgxp_gpr[rt(instr)];
- double x = CPU_reg[rt(instr)].x, y = f16Unsign(CPU_reg[rt(instr)].y);
+ double x = g_state.pgxp_gpr[rt(instr)].x, y = f16Unsign(g_state.pgxp_gpr[rt(instr)].y);
psx_value iX;
iX.d = rtVal;
@@ -1324,7 +1308,7 @@ void PGXP::CPU_SRL(u32 instr, u32 rtVal)
else if (sh < 16)
{
x += y * (1 << (16 - sh));
- if (CPU_reg[rt(instr)].x < 0)
+ if (g_state.pgxp_gpr[rt(instr)].x < 0)
x += 1 << (16 - sh);
}
else
@@ -1345,19 +1329,19 @@ void PGXP::CPU_SRL(u32 instr, u32 rtVal)
ret.y = (float)y;
ret.value = rdVal;
- CPU_reg[rd(instr)] = ret;
+ g_state.pgxp_gpr[rd(instr)] = ret;
}
-void PGXP::CPU_SRA(u32 instr, u32 rtVal)
+void CPU::PGXP::CPU_SRA(u32 instr, u32 rtVal)
{
// Rd = Rt >> Sa
const u32 rdVal = static_cast(static_cast(rtVal) >> sa(instr));
PGXP_value ret;
u32 sh = sa(instr);
- Validate(&CPU_reg[rt(instr)], rtVal);
- ret = CPU_reg[rt(instr)];
+ Validate(&g_state.pgxp_gpr[rt(instr)], rtVal);
+ ret = g_state.pgxp_gpr[rt(instr)];
- double x = CPU_reg[rt(instr)].x, y = CPU_reg[rt(instr)].y;
+ double x = g_state.pgxp_gpr[rt(instr)].x, y = g_state.pgxp_gpr[rt(instr)].y;
psx_value iX;
iX.d = rtVal;
@@ -1387,7 +1371,7 @@ void PGXP::CPU_SRA(u32 instr, u32 rtVal)
else if (sh < 16)
{
x += y * (1 << (16 - sh));
- if (CPU_reg[rt(instr)].x < 0)
+ if (g_state.pgxp_gpr[rt(instr)].x < 0)
x += 1 << (16 - sh);
}
else
@@ -1408,25 +1392,25 @@ void PGXP::CPU_SRA(u32 instr, u32 rtVal)
ret.y = (float)y;
ret.value = rdVal;
- CPU_reg[rd(instr)] = ret;
+ g_state.pgxp_gpr[rd(instr)] = ret;
}
////////////////////////////////////
// Shift operations variable
////////////////////////////////////
-void PGXP::CPU_SLLV(u32 instr, u32 rtVal, u32 rsVal)
+void CPU::PGXP::CPU_SLLV(u32 instr, u32 rtVal, u32 rsVal)
{
// Rd = Rt << Rs
const u32 rdVal = rtVal << rsVal;
PGXP_value ret;
u32 sh = rsVal & 0x1F;
- Validate(&CPU_reg[rt(instr)], rtVal);
- Validate(&CPU_reg[rs(instr)], rsVal);
+ Validate(&g_state.pgxp_gpr[rt(instr)], rtVal);
+ Validate(&g_state.pgxp_gpr[rs(instr)], rsVal);
- ret = CPU_reg[rt(instr)];
+ ret = g_state.pgxp_gpr[rt(instr)];
- double x = f16Unsign(CPU_reg[rt(instr)].x);
- double y = f16Unsign(CPU_reg[rt(instr)].y);
+ double x = f16Unsign(g_state.pgxp_gpr[rt(instr)].x);
+ double y = f16Unsign(g_state.pgxp_gpr[rt(instr)].y);
if (sh >= 32)
{
x = 0.f;
@@ -1456,21 +1440,21 @@ void PGXP::CPU_SLLV(u32 instr, u32 rtVal, u32 rsVal)
ret.y = (float)y;
ret.value = rdVal;
- CPU_reg[rd(instr)] = ret;
+ g_state.pgxp_gpr[rd(instr)] = ret;
}
-void PGXP::CPU_SRLV(u32 instr, u32 rtVal, u32 rsVal)
+void CPU::PGXP::CPU_SRLV(u32 instr, u32 rtVal, u32 rsVal)
{
// Rd = Rt >> Sa
const u32 rdVal = rtVal >> rsVal;
PGXP_value ret;
u32 sh = rsVal & 0x1F;
- Validate(&CPU_reg[rt(instr)], rtVal);
- Validate(&CPU_reg[rs(instr)], rsVal);
+ Validate(&g_state.pgxp_gpr[rt(instr)], rtVal);
+ Validate(&g_state.pgxp_gpr[rs(instr)], rsVal);
- ret = CPU_reg[rt(instr)];
+ ret = g_state.pgxp_gpr[rt(instr)];
- double x = CPU_reg[rt(instr)].x, y = f16Unsign(CPU_reg[rt(instr)].y);
+ double x = g_state.pgxp_gpr[rt(instr)].x, y = f16Unsign(g_state.pgxp_gpr[rt(instr)].y);
psx_value iX;
iX.d = rtVal;
@@ -1500,7 +1484,7 @@ void PGXP::CPU_SRLV(u32 instr, u32 rtVal, u32 rsVal)
else if (sh < 16)
{
x += y * (1 << (16 - sh));
- if (CPU_reg[rt(instr)].x < 0)
+ if (g_state.pgxp_gpr[rt(instr)].x < 0)
x += 1 << (16 - sh);
}
else
@@ -1521,21 +1505,21 @@ void PGXP::CPU_SRLV(u32 instr, u32 rtVal, u32 rsVal)
ret.y = (float)y;
ret.value = rdVal;
- CPU_reg[rd(instr)] = ret;
+ g_state.pgxp_gpr[rd(instr)] = ret;
}
-void PGXP::CPU_SRAV(u32 instr, u32 rtVal, u32 rsVal)
+void CPU::PGXP::CPU_SRAV(u32 instr, u32 rtVal, u32 rsVal)
{
// Rd = Rt >> Sa
const u32 rdVal = static_cast(static_cast(rtVal) >> rsVal);
PGXP_value ret;
u32 sh = rsVal & 0x1F;
- Validate(&CPU_reg[rt(instr)], rtVal);
- Validate(&CPU_reg[rs(instr)], rsVal);
+ Validate(&g_state.pgxp_gpr[rt(instr)], rtVal);
+ Validate(&g_state.pgxp_gpr[rs(instr)], rsVal);
- ret = CPU_reg[rt(instr)];
+ ret = g_state.pgxp_gpr[rt(instr)];
- double x = CPU_reg[rt(instr)].x, y = CPU_reg[rt(instr)].y;
+ double x = g_state.pgxp_gpr[rt(instr)].x, y = g_state.pgxp_gpr[rt(instr)].y;
psx_value iX;
iX.d = rtVal;
@@ -1565,7 +1549,7 @@ void PGXP::CPU_SRAV(u32 instr, u32 rtVal, u32 rsVal)
else if (sh < 16)
{
x += y * (1 << (16 - sh));
- if (CPU_reg[rt(instr)].x < 0)
+ if (g_state.pgxp_gpr[rt(instr)].x < 0)
x += 1 << (16 - sh);
}
else
@@ -1586,53 +1570,53 @@ void PGXP::CPU_SRAV(u32 instr, u32 rtVal, u32 rsVal)
ret.y = (float)y;
ret.value = rdVal;
- CPU_reg[rd(instr)] = ret;
+ g_state.pgxp_gpr[rd(instr)] = ret;
}
-void PGXP::CPU_MFHI(u32 instr, u32 hiVal)
+void CPU::PGXP::CPU_MFHI(u32 instr, u32 hiVal)
{
// Rd = Hi
- Validate(&CPU_Hi, hiVal);
+ Validate(&g_state.pgxp_hi, hiVal);
- CPU_reg[rd(instr)] = CPU_Hi;
+ g_state.pgxp_gpr[rd(instr)] = g_state.pgxp_hi;
}
-void PGXP::CPU_MTHI(u32 instr, u32 rsVal)
+void CPU::PGXP::CPU_MTHI(u32 instr, u32 rsVal)
{
// Hi = Rd
- Validate(&CPU_reg[rs(instr)], rsVal);
+ Validate(&g_state.pgxp_gpr[rs(instr)], rsVal);
- CPU_Hi = CPU_reg[rd(instr)];
+ g_state.pgxp_hi = g_state.pgxp_gpr[rd(instr)];
}
-void PGXP::CPU_MFLO(u32 instr, u32 loVal)
+void CPU::PGXP::CPU_MFLO(u32 instr, u32 loVal)
{
// Rd = Lo
- Validate(&CPU_Lo, loVal);
+ Validate(&g_state.pgxp_lo, loVal);
- CPU_reg[rd(instr)] = CPU_Lo;
+ g_state.pgxp_gpr[rd(instr)] = g_state.pgxp_lo;
}
-void PGXP::CPU_MTLO(u32 instr, u32 rsVal)
+void CPU::PGXP::CPU_MTLO(u32 instr, u32 rsVal)
{
// Lo = Rd
- Validate(&CPU_reg[rs(instr)], rsVal);
+ Validate(&g_state.pgxp_gpr[rs(instr)], rsVal);
- CPU_Lo = CPU_reg[rd(instr)];
+ g_state.pgxp_lo = g_state.pgxp_gpr[rd(instr)];
}
-void PGXP::CPU_MFC0(u32 instr, u32 rdVal)
+void CPU::PGXP::CPU_MFC0(u32 instr, u32 rdVal)
{
// CPU[Rt] = CP0[Rd]
- Validate(&CP0_reg[rd(instr)], rdVal);
- CPU_reg[rt(instr)] = CP0_reg[rd(instr)];
- CPU_reg[rt(instr)].value = rdVal;
+ Validate(&g_state.pgxp_cop0[rd(instr)], rdVal);
+ g_state.pgxp_gpr[rt(instr)] = g_state.pgxp_cop0[rd(instr)];
+ g_state.pgxp_gpr[rt(instr)].value = rdVal;
}
-void PGXP::CPU_MTC0(u32 instr, u32 rdVal, u32 rtVal)
+void CPU::PGXP::CPU_MTC0(u32 instr, u32 rdVal, u32 rtVal)
{
// CP0[Rd] = CPU[Rt]
- Validate(&CPU_reg[rt(instr)], rtVal);
- CP0_reg[rd(instr)] = CPU_reg[rt(instr)];
- CP0_reg[rd(instr)].value = rdVal;
+ Validate(&g_state.pgxp_gpr[rt(instr)], rtVal);
+ g_state.pgxp_cop0[rd(instr)] = g_state.pgxp_gpr[rt(instr)];
+ g_state.pgxp_cop0[rd(instr)].value = rdVal;
}
diff --git a/src/core/pgxp.h b/src/core/cpu_pgxp.h
similarity index 99%
rename from src/core/pgxp.h
rename to src/core/cpu_pgxp.h
index f7774e46d..39d315058 100644
--- a/src/core/pgxp.h
+++ b/src/core/cpu_pgxp.h
@@ -4,7 +4,7 @@
#pragma once
#include "types.h"
-namespace PGXP {
+namespace CPU::PGXP {
void Initialize();
void Reset();
diff --git a/src/core/cpu_recompiler_code_generator.cpp b/src/core/cpu_recompiler_code_generator.cpp
index 3ed3d5efd..5c6743047 100644
--- a/src/core/cpu_recompiler_code_generator.cpp
+++ b/src/core/cpu_recompiler_code_generator.cpp
@@ -7,7 +7,7 @@
#include "cpu_core_private.h"
#include "cpu_disasm.h"
#include "gte.h"
-#include "pgxp.h"
+#include "cpu_pgxp.h"
#include "settings.h"
Log_SetChannel(CPU::Recompiler);
diff --git a/src/core/gpu_hw.cpp b/src/core/gpu_hw.cpp
index 8e74bcb2e..0833ece74 100644
--- a/src/core/gpu_hw.cpp
+++ b/src/core/gpu_hw.cpp
@@ -6,7 +6,7 @@
#include "gpu_hw_shadergen.h"
#include "gpu_sw_backend.h"
#include "host.h"
-#include "pgxp.h"
+#include "cpu_pgxp.h"
#include "settings.h"
#include "system.h"
@@ -1671,9 +1671,9 @@ void GPU_HW::LoadVertices()
if (pgxp)
{
- valid_w &=
- PGXP::GetPreciseVertex(Truncate32(maddr_and_pos >> 32), vp.bits, native_x, native_y, m_drawing_offset.x,
- m_drawing_offset.y, &vertices[i].x, &vertices[i].y, &vertices[i].w);
+ valid_w &= CPU::PGXP::GetPreciseVertex(Truncate32(maddr_and_pos >> 32), vp.bits, native_x, native_y,
+ m_drawing_offset.x, m_drawing_offset.y, &vertices[i].x, &vertices[i].y,
+ &vertices[i].w);
}
}
if (pgxp)
diff --git a/src/core/gte.cpp b/src/core/gte.cpp
index 7bcf69253..3582429dd 100644
--- a/src/core/gte.cpp
+++ b/src/core/gte.cpp
@@ -5,7 +5,7 @@
#include "cpu_core.h"
#include "cpu_core_private.h"
-#include "pgxp.h"
+#include "cpu_pgxp.h"
#include "settings.h"
#include "timing_event.h"
@@ -794,7 +794,7 @@ void GTE::RTPS(const s16 V[3], u8 shift, bool lm, bool last)
precise_x = std::clamp(precise_x, -1024.0f, 1023.0f);
precise_y = std::clamp(precise_y, -1024.0f, 1023.0f);
- PGXP::GTE_PushSXYZ2f(precise_x, precise_y, precise_z, REGS.dr32[14]);
+ CPU::PGXP::GTE_PushSXYZ2f(precise_x, precise_y, precise_z, REGS.dr32[14]);
}
if (last)
@@ -842,10 +842,10 @@ void GTE::Execute_NCLIP(Instruction inst)
void GTE::Execute_NCLIP_PGXP(Instruction inst)
{
- if (PGXP::GTE_NCLIP_valid(REGS.dr32[12], REGS.dr32[13], REGS.dr32[14]))
+ if (CPU::PGXP::GTE_NCLIP_valid(REGS.dr32[12], REGS.dr32[13], REGS.dr32[14]))
{
REGS.FLAG.Clear();
- REGS.MAC0 = static_cast(PGXP::GTE_NCLIP());
+ REGS.MAC0 = static_cast(CPU::PGXP::GTE_NCLIP());
}
else
{
diff --git a/src/core/hotkeys.cpp b/src/core/hotkeys.cpp
index 458c66918..6f7d760ae 100644
--- a/src/core/hotkeys.cpp
+++ b/src/core/hotkeys.cpp
@@ -8,7 +8,7 @@
#include "gpu.h"
#include "host.h"
#include "imgui_overlays.h"
-#include "pgxp.h"
+#include "cpu_pgxp.h"
#include "settings.h"
#include "spu.h"
#include "system.h"
@@ -341,9 +341,9 @@ DEFINE_HOTKEY("TogglePGXP", TRANSLATE_NOOP("Hotkeys", "Graphics"), TRANSLATE_NOO
5.0f);
if (g_settings.gpu_pgxp_enable)
- PGXP::Initialize();
+ CPU::PGXP::Initialize();
else
- PGXP::Shutdown();
+ CPU::PGXP::Shutdown();
// we need to recompile all blocks if pgxp is toggled on/off
CPU::CodeCache::Reset();
@@ -433,8 +433,8 @@ DEFINE_HOTKEY("TogglePGXPCPU", TRANSLATE_NOOP("Hotkeys", "Graphics"), TRANSLATE_
TRANSLATE_STR("OSDMessage", "PGXP CPU mode is now disabled."),
5.0f);
- PGXP::Shutdown();
- PGXP::Initialize();
+ CPU::PGXP::Shutdown();
+ CPU::PGXP::Initialize();
// we need to recompile all blocks if pgxp is toggled on/off
CPU::CodeCache::Reset();
diff --git a/src/core/system.cpp b/src/core/system.cpp
index fc08df79d..1f731bd39 100644
--- a/src/core/system.cpp
+++ b/src/core/system.cpp
@@ -26,7 +26,7 @@
#include "multitap.h"
#include "pad.h"
#include "pcdrv.h"
-#include "pgxp.h"
+#include "cpu_pgxp.h"
#include "psf_loader.h"
#include "save_state_version.h"
#include "sio.h"
@@ -1561,7 +1561,7 @@ bool System::Initialize(bool force_software_renderer)
GTE::UpdateAspectRatio();
if (g_settings.gpu_pgxp_enable)
- PGXP::Initialize();
+ CPU::PGXP::Initialize();
// Was startup cancelled? (e.g. shading compilers took too long and the user closed the application)
if (IsStartupCancelled())
@@ -1573,7 +1573,7 @@ bool System::Initialize(bool force_software_renderer)
Host::ReleaseRenderWindow();
}
if (g_settings.gpu_pgxp_enable)
- PGXP::Shutdown();
+ CPU::PGXP::Shutdown();
CPU::Shutdown();
Bus::Shutdown();
return false;
@@ -1666,7 +1666,7 @@ void System::DestroySystem()
g_gpu.reset();
InterruptController::Shutdown();
DMA::Shutdown();
- PGXP::Shutdown();
+ CPU::PGXP::Shutdown();
CPU::CodeCache::Shutdown();
Bus::Shutdown();
CPU::Shutdown();
@@ -2086,7 +2086,7 @@ bool System::DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_di
// only reset pgxp if we're not runahead-rollbacking. the value checks will save us from broken rendering, and it
// saves using imprecise values for a frame in 30fps games.
if (sw.IsReading() && g_settings.gpu_pgxp_enable && !is_memory_state)
- PGXP::Reset();
+ CPU::PGXP::Reset();
if (!sw.DoMarker("Bus") || !Bus::DoState(sw))
return false;
@@ -2201,7 +2201,7 @@ void System::InternalReset()
CPU::Reset();
CPU::CodeCache::Reset();
if (g_settings.gpu_pgxp_enable)
- PGXP::Initialize();
+ CPU::PGXP::Initialize();
Bus::Reset();
DMA::Reset();
@@ -3670,10 +3670,10 @@ void System::CheckForSettingsChanges(const Settings& old_settings)
g_settings.gpu_pgxp_cpu != old_settings.gpu_pgxp_cpu)))
{
if (old_settings.gpu_pgxp_enable)
- PGXP::Shutdown();
+ CPU::PGXP::Shutdown();
if (g_settings.gpu_pgxp_enable)
- PGXP::Initialize();
+ CPU::PGXP::Initialize();
CPU::CodeCache::Reset();
}