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(); }