Files
PSPRecomp/profiles/vcs/host/vcs_native_fast_paths.cpp
Jessica_Natalia 98d6b05477 mais otimizaçoes
mais otimizaçoes
2026-08-13 11:20:36 -03:00

135 lines
5.9 KiB
C++

#include "vcs_native_fast_paths.hpp"
#include "vcs_collision_fast_paths.hpp"
#include "vcs_fast_paths.hpp"
#include "psprecomp/common.hpp"
#include "psprecomp/runtime.hpp"
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <sstream>
namespace vcs {
namespace {
constexpr std::uint32_t kCollisionFastPath = 0x088B1554u;
constexpr std::uint32_t kVfpuFastPath = 0x088B1780u;
bool truthy(const char *text) {
return text != nullptr && *text != '\0' && std::strcmp(text, "0") != 0;
}
std::uint64_t validation_limit(const char *name) {
const char *text = std::getenv(name);
if (text == nullptr || *text == '\0') return 0u;
char *end = nullptr;
const unsigned long long value = std::strtoull(text, &end, 0);
return end != text && *end == '\0' ? static_cast<std::uint64_t>(value) : 0u;
}
void collision_fast_path(psprecomp::Runtime &runtime, psprecomp::AllegrexContext &ctx) {
static const bool enabled = [] {
if (truthy(std::getenv("PSPRECOMP_NO_FAST_088B1554"))) return false;
if (truthy(std::getenv("PSPRECOMP_VALIDATE_FAST_088B1554"))) return true;
// This leaf has already matched the generated AOT reference across
// real gameplay validation runs. Keep it on in production; the NO_
// switch remains available for an immediate A/B or compatibility bisect.
return true;
}();
if (!enabled) {
if (!runtime.invoke_isolated_aot(kCollisionFastPath, ctx))
throw psprecomp::Error("Missing AOT reference for VCS native fast path 0x088B1554");
return;
}
static const std::uint64_t limit = validation_limit("PSPRECOMP_VALIDATE_FAST_088B1554");
static std::uint64_t count = 0u;
if (count < limit) {
const psprecomp::AllegrexContext input = ctx;
const std::uint32_t point = input.gpr[6];
const std::uint32_t mindist = input.gpr[7];
std::uint8_t point_before[32]{};
for (std::uint32_t i = 0; i < 32u; ++i)
point_before[i] = runtime.memory().aot_load8(point + i);
const std::uint32_t mindist_before = runtime.memory().aot_load32(mindist);
constexpr std::uint32_t validation_return = 0xFFFFFFFFu;
psprecomp::AllegrexContext reference = input;
reference.gpr[31] = validation_return;
if (!runtime.invoke_isolated_aot(kCollisionFastPath, reference))
throw psprecomp::Error("Missing AOT reference for VCS native fast path 0x088B1554");
if (reference.pc != validation_return)
throw psprecomp::Error("VCS native reference 0x088B1554 escaped validation return sentinel");
reference.gpr[31] = input.gpr[31];
reference.pc = input.gpr[31];
std::uint8_t point_expected[32]{};
for (std::uint32_t i = 0; i < 32u; ++i)
point_expected[i] = runtime.memory().aot_load8(point + i);
const std::uint32_t mindist_expected = runtime.memory().aot_load32(mindist);
for (std::uint32_t i = 0; i < 32u; ++i)
runtime.memory().aot_store8(point + i, point_before[i]);
runtime.memory().aot_store32(mindist, mindist_before);
ctx = input;
psprecomp::vcs_fast_088B1554(runtime, ctx);
ctx.gpr[0] = 0u;
bool memory_matches = runtime.memory().aot_load32(mindist) == mindist_expected;
for (std::uint32_t i = 0; i < 32u && memory_matches; ++i)
memory_matches = runtime.memory().aot_load8(point + i) == point_expected[i];
const bool abi_matches = ctx.pc == reference.pc && ctx.gpr[2] == reference.gpr[2] &&
ctx.gpr[29] == reference.gpr[29] && ctx.gpr[31] == reference.gpr[31];
if (!memory_matches || !abi_matches) {
std::ostringstream message;
message << "VCS native fast path 0x088B1554 diverged at validation call " << count
<< " reference_v0=" << psprecomp::hex32(reference.gpr[2])
<< " fast_v0=" << psprecomp::hex32(ctx.gpr[2])
<< " reference_dist=" << psprecomp::hex32(mindist_expected)
<< " fast_dist=" << psprecomp::hex32(runtime.memory().aot_load32(mindist));
throw psprecomp::Error(message.str());
}
++count;
if (count == limit)
std::cerr << "[fast-validate] 0x088B1554 matched " << count << " consecutive real calls\n";
return;
}
psprecomp::vcs_fast_088B1554(runtime, ctx);
}
void vfpu_fast_path(psprecomp::Runtime &runtime, psprecomp::AllegrexContext &ctx) {
static const std::uint64_t limit = validation_limit("PSPRECOMP_VALIDATE_FAST_088B1780");
static std::uint64_t count = 0u;
if (count < limit) {
psprecomp::AllegrexContext reference = ctx;
if (!runtime.invoke_isolated_aot(kVfpuFastPath, reference))
throw psprecomp::Error("Missing AOT reference for VCS native fast path 0x088B1780");
psprecomp::vcs_fast_088B1780(runtime, ctx);
ctx.gpr[0] = 0u;
if (std::memcmp(&reference, &ctx, sizeof(psprecomp::AllegrexContext)) != 0) {
std::ostringstream message;
message << "VCS native fast path 0x088B1780 diverged at validation call " << count
<< " reference_pc=" << psprecomp::hex32(reference.pc)
<< " fast_pc=" << psprecomp::hex32(ctx.pc)
<< " reference_v0=" << psprecomp::hex32(reference.gpr[2])
<< " fast_v0=" << psprecomp::hex32(ctx.gpr[2]);
throw psprecomp::Error(message.str());
}
++count;
if (count == limit)
std::cerr << "[fast-validate] 0x088B1780 matched " << count << " consecutive real calls\n";
return;
}
psprecomp::vcs_fast_088B1780(runtime, ctx);
}
} // namespace
void install_native_fast_paths(psprecomp::Runtime &runtime) {
runtime.register_native_fast_path(kCollisionFastPath, &collision_fast_path);
runtime.register_native_fast_path(kVfpuFastPath, &vfpu_fast_path);
}
} // namespace vcs