From fae9a7ad71a5673c4ff5c2f088237647be9c9867 Mon Sep 17 00:00:00 2001 From: Ran-j Date: Sat, 29 Nov 2025 02:28:05 -0300 Subject: [PATCH] feat: update ps2 CPU context --- ps2xRecomp/src/code_generator.cpp | 22 ++++++++--- ps2xRuntime/include/ps2_runtime.h | 62 +++++++++++++++++++++++-------- 2 files changed, 63 insertions(+), 21 deletions(-) diff --git a/ps2xRecomp/src/code_generator.cpp b/ps2xRecomp/src/code_generator.cpp index 3d2c312..f9973f1 100644 --- a/ps2xRecomp/src/code_generator.cpp +++ b/ps2xRecomp/src/code_generator.cpp @@ -607,8 +607,18 @@ namespace ps2recomp case OPCODE_SDC2: // was OPCODE_SQC2 need to check return fmt::format("WRITE128(ADD32(GPR_U32(ctx, {}), {}), (__m128i)ctx->vu0_vf[{}]);", inst.rs, inst.simmediate, inst.rt); case OPCODE_DADDI: + return fmt::format( + "{{ int64_t src = (int64_t)GPR_S64(ctx, {}); " + "int64_t imm = (int64_t){}; " + "int64_t res = src + imm; " + "if (((src ^ imm) >= 0) && ((src ^ res) < 0)) " + " runtime->SignalException(ctx, EXCEPTION_INTEGER_OVERFLOW); " + "else SET_GPR_S64(ctx, {}, res); }}", + inst.rs, inst.simmediate, inst.rt); case OPCODE_DADDIU: - return fmt::format("SET_GPR_U64(ctx, {}, GPR_U64(ctx, {}) + (uint64_t)(int64_t){});", inst.rt, inst.rs, inst.simmediate); + return fmt::format( + "SET_GPR_S64(ctx, {}, (int64_t)GPR_S64(ctx, {}) + (int64_t){});", + inst.rt, inst.rs, inst.simmediate); case OPCODE_J: return fmt::format("// JAL 0x{:X} - Handled by branch logic", (inst.address & 0xF0000000) | (inst.target << 2)); case OPCODE_JAL: @@ -1516,18 +1526,18 @@ namespace ps2recomp return fmt::format("SET_GPR_U32(ctx, {}, ctx->vu0_fbrst4);", rt); case VU0_CR_ACC: return fmt::format("SET_GPR_VEC(ctx, {}, (__m128i)ctx->vu0_acc);", rt); - case VU0_CR_INFO: + case VU0_CR_INFO: // I dd found on offical docs but ok return fmt::format("SET_GPR_U32(ctx, {}, ctx->vu0_info);", rt); case VU0_CR_CLIP2: return fmt::format("SET_GPR_U32(ctx, {}, ctx->vu0_clip_flags2);", rt); case VU0_CR_P: return fmt::format("SET_GPR_U32(ctx, {}, *(uint32_t*)&ctx->vu0_p);", rt); - case VU0_CR_XITOP: + case VU0_CR_XITOP: // Maybe this does not exist, maybe we handle to vu0_itop return fmt::format("SET_GPR_U32(ctx, {}, ctx->vu0_xitop);", rt); case VU0_CR_ITOP: return fmt::format("SET_GPR_U32(ctx, {}, ctx->vu0_itop);", rt); case VU0_CR_TOP: - return fmt::format("SET_GPR_U32(ctx, {}, ctx->vu0_top);", rt); + return fmt::format("SET_GPR_U32(ctx, {}, ctx->vu0_vpu_stat);", rt); default: return fmt::format("// Unimplemented CFC2 VU CReg: {}", rt); } @@ -1589,7 +1599,7 @@ namespace ps2recomp case VU0_CR_ITOP: return fmt::format("ctx->vu0_itop = GPR_U32(ctx, {}) & 0x3FF;", rt); case VU0_CR_TOP: - return fmt::format("ctx->vu0_top = GPR_U32(ctx, {}) & 0x3FF;", rt); + return fmt::format("ctx->vu0_vpu_stat = GPR_U32(ctx, {}) & 0x3FF;", rt); default: return fmt::format("// Unimplemented CTC2 VU CReg: {}", rd); } @@ -2420,7 +2430,7 @@ namespace ps2recomp ss << "#include \"ps2_runtime.h\"\n"; ss << "#include \"ps2_recompiled_functions.h\"\n"; ss << "#include \"ps2_stubs.h\"\n"; - ss << "#include \"ps2_syscalls.h\"\n\n"; + ss << "#include \"ps2_syscalls.h\"\n\n"; // Registration function ss << "void registerAllFunctions(PS2Runtime& runtime) {\n"; diff --git a/ps2xRuntime/include/ps2_runtime.h b/ps2xRuntime/include/ps2_runtime.h index 3f9fc2d..5537d67 100644 --- a/ps2xRuntime/include/ps2_runtime.h +++ b/ps2xRuntime/include/ps2_runtime.h @@ -56,7 +56,7 @@ enum PS2Exception }; // PS2 CPU context (R5900) -struct R5900Context +struct alignas(16) R5900Context { // General Purpose Registers (128-bit) __m128i r[32]; // Main registers @@ -64,23 +64,39 @@ struct R5900Context // Control registers uint32_t pc; // Program counter uint64_t insn_count; // Instruction counter - uint32_t hi, lo; // HI/LO registers for mult/div results - uint32_t hi1, lo1; // Secondary HI/LO registers for MULT1/DIV1 + uint64_t hi, lo; // HI/LO registers for mult/div results + uint64_t hi1, lo1; // Secondary HI/LO registers for MULT1/DIV1 uint32_t sa; // Shift amount register // VU0 registers (when used in macro mode) - __m128 vu0_vf[32]; // VU0 vector float registers - uint16_t vi[16]; // VU0 vector integer registers - float vu0_q; // VU0 Q register (quotient) - float vu0_p; // VU0 P register (EFU result) - float vu0_i; // VU0 I register (integer value) - __m128 vu0_r; // VU0 R register - uint16_t vu0_status; // VU0 status register - uint32_t vu0_mac_flags; // VU0 MAC flags - uint32_t vu0_clip_flags; // VU0 clipping flags - uint32_t vu0_cmsar0; // VU0 microprogram start address - uint32_t vu0_fbrst; // VIF/VU reset register - float vu0_cf[4]; // VU0 FMAC control floating-point registers + __m128 vu0_vf[32]; // VU0 vector float registers + uint16_t vi[16]; // VU0 vector integer registers + float vu0_q; // VU0 Q register (quotient) + float vu0_p; // VU0 P register (EFU result) + float vu0_i; // VU0 I register (integer value) + __m128 vu0_r; // VU0 R register + __m128 vu0_acc; // VU0 ACC accumulator register + uint16_t vu0_status; // VU0 status register + uint32_t vu0_mac_flags; // VU0 MAC flags + uint32_t vu0_clip_flags; // VU0 clipping flags + uint32_t vu0_clip_flags2; // VU0 clipping flags + uint32_t vu0_cmsar0; // VU0 microprogram start address + uint32_t vu0_cmsar1; // VU0 microprogram start address + uint32_t vu0_cmsar2; // VU0 microprogram start address + uint32_t vu0_cmsar3; // VU0 microprogram start address + uint32_t vu0_vpu_stat; + uint32_t vu0_vpu_stat2; // extra VPU status (used by CR_VPU_STAT2) + uint32_t vu0_vpu_stat3; // extra VPU status 3 + uint32_t vu0_vpu_stat4; // extra VPU status 4 + uint32_t vu0_tpc; // TPC (VU0 PC) + uint32_t vu0_tpc2; // second TPC + uint32_t vu0_fbrst; // VIF/VU reset register + uint32_t vu0_fbrst2; // FBRST2 + uint32_t vu0_fbrst3; // FBRST3 + uint32_t vu0_itop; + uint32_t vu0_info; + + float vu0_cf[4]; // VU0 FMAC control floating-point registers // COP0 System control registers uint32_t cop0_index; @@ -106,6 +122,9 @@ struct R5900Context uint32_t cop0_taghi; uint32_t cop0_errorepc; + // COP2 control registers (VU0 integer + control) + uint32_t cop2_ccr[32]; + // FPU registers (COP1) float f[32]; uint32_t fcr31; // Control/status register @@ -139,6 +158,7 @@ struct R5900Context vu0_p = 0.0f; vu0_i = 0.0f; vu0_r = _mm_setzero_ps(); + vu0_acc = _mm_setzero_ps(); vu0_status = 0; vu0_mac_flags = 0; vu0_clip_flags = 0; @@ -169,6 +189,18 @@ struct R5900Context cop0_taghi = 0; cop0_errorepc = 0; + vu0_tpc = 0; + vu0_vpu_stat2 = 0; + vu0_tpc2 = 0; + vu0_cmsar1 = 0; + vu0_fbrst2 = 0; + vu0_vpu_stat3 = 0; + vu0_cmsar2 = 0; + vu0_fbrst3 = 0; + vu0_vpu_stat4 = 0; + vu0_itop = 0; + vu0_info = 0; + // Reset COP1 state fcr31 = 0; }