From ae1ffbb909d9f93c88c41830deb539f7feef5ed2 Mon Sep 17 00:00:00 2001 From: Garrett Smith Date: Tue, 26 May 2026 21:53:50 -0700 Subject: [PATCH] support args >= 4 via the stack in _arg template (#138) * support args >= 4 via the stack * fix offset --- librecomp/include/librecomp/helpers.hpp | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/librecomp/include/librecomp/helpers.hpp b/librecomp/include/librecomp/helpers.hpp index d8f5afd..eb9f86f 100644 --- a/librecomp/include/librecomp/helpers.hpp +++ b/librecomp/include/librecomp/helpers.hpp @@ -7,8 +7,7 @@ #include template -T _arg(uint8_t* rdram, recomp_context* ctx) { - static_assert(index < 4, "Only args 0 through 3 supported"); +T _arg(uint8_t* rdram, recomp_context* ctx) requires(index < 4) { gpr raw_arg = (&ctx->r4)[index]; if constexpr (std::is_same_v) { if constexpr (index < 2) { @@ -38,6 +37,25 @@ T _arg(uint8_t* rdram, recomp_context* ctx) { } } +template +T _arg(uint8_t* rdram, recomp_context* ctx) requires(index >= 4) { + const auto raw_arg = MEM_W(index * 4, ctx->r29); + if constexpr (std::is_pointer_v) { + static_assert (!std::is_pointer_v>, "Double pointers not supported"); + return TO_PTR(std::remove_pointer_t, raw_arg); + } + else if constexpr (std::is_integral_v) { + static_assert(sizeof(T) <= 4, "64-bit args not supported"); + return static_cast(raw_arg); + } + else { + // static_assert in else workaround + [] () { + static_assert(flag, "Unsupported type"); + }(); + } +} + inline float _arg_float_a1(uint8_t* rdram, recomp_context* ctx) { (void)rdram; union {