PPCCoreCallback: Add support for stack args if GPR limit is reached

This commit is contained in:
GaryOderNichts 2024-05-04 14:46:12 +02:00
parent 13b90874f9
commit 84e78088fb

View File

@ -5,8 +5,28 @@ struct PPCCoreCallbackData_t
{ {
sint32 gprCount = 0; sint32 gprCount = 0;
sint32 floatCount = 0; sint32 floatCount = 0;
sint32 stackCount = 0;
}; };
inline void _PPCCoreCallback_writeGPRArg(PPCCoreCallbackData_t& data, PPCInterpreter_t* hCPU, uint32 value)
{
if (data.gprCount < 8)
{
hCPU->gpr[3 + data.gprCount] = value;
data.gprCount++;
}
else
{
uint32 stackOffset = 8 + data.stackCount * 4;
// PPCCore_executeCallbackInternal does -16*4 to save the current stack area
stackOffset -= 16 * 4;
memory_writeU32(hCPU->gpr[1] + stackOffset, value);
data.stackCount++;
}
}
// callback functions // callback functions
inline uint32 PPCCoreCallback(MPTR function, const PPCCoreCallbackData_t& data) inline uint32 PPCCoreCallback(MPTR function, const PPCCoreCallbackData_t& data)
{ {
@ -16,23 +36,21 @@ inline uint32 PPCCoreCallback(MPTR function, const PPCCoreCallbackData_t& data)
template <typename T, typename... TArgs> template <typename T, typename... TArgs>
uint32 PPCCoreCallback(MPTR function, PPCCoreCallbackData_t& data, T currentArg, TArgs... args) uint32 PPCCoreCallback(MPTR function, PPCCoreCallbackData_t& data, T currentArg, TArgs... args)
{ {
cemu_assert_debug(data.gprCount <= 8); // TODO float arguments on stack
cemu_assert_debug(data.floatCount <= 8); cemu_assert_debug(data.floatCount < 8);
PPCInterpreter_t* hCPU = PPCInterpreter_getCurrentInstance(); PPCInterpreter_t* hCPU = PPCInterpreter_getCurrentInstance();
if constexpr (std::is_pointer_v<T>) if constexpr (std::is_pointer_v<T>)
{ {
hCPU->gpr[3 + data.gprCount] = MEMPTR(currentArg).GetMPTR(); _PPCCoreCallback_writeGPRArg(data, hCPU, MEMPTR(currentArg).GetMPTR());
data.gprCount++;
} }
else if constexpr (std::is_base_of_v<MEMPTRBase, std::remove_reference_t<T>>) else if constexpr (std::is_base_of_v<MEMPTRBase, std::remove_reference_t<T>>)
{ {
hCPU->gpr[3 + data.gprCount] = currentArg.GetMPTR(); _PPCCoreCallback_writeGPRArg(data, hCPU, currentArg.GetMPTR());
data.gprCount++;
} }
else if constexpr (std::is_reference_v<T>) else if constexpr (std::is_reference_v<T>)
{ {
hCPU->gpr[3 + data.gprCount] = MEMPTR(&currentArg).GetMPTR(); _PPCCoreCallback_writeGPRArg(data, hCPU, MEMPTR(&currentArg).GetMPTR());
data.gprCount++;
} }
else if constexpr(std::is_enum_v<T>) else if constexpr(std::is_enum_v<T>)
{ {
@ -53,8 +71,7 @@ uint32 PPCCoreCallback(MPTR function, PPCCoreCallbackData_t& data, T currentArg,
} }
else else
{ {
hCPU->gpr[3 + data.gprCount] = (uint32)currentArg; _PPCCoreCallback_writeGPRArg(data, hCPU, (uint32)currentArg);
data.gprCount++;
} }
return PPCCoreCallback(function, data, args...); return PPCCoreCallback(function, data, args...);