mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-23 03:02:53 +01:00
Basic stack argument support for callbacks
This commit is contained in:
parent
4243558319
commit
201f0f3a9f
@ -11,6 +11,11 @@ namespace cb_detail
|
||||
ARG_STACK,
|
||||
};
|
||||
|
||||
// Current implementation can handle only fixed amount of stack arguments.
|
||||
// This constant can be increased if necessary.
|
||||
// It's possible to calculate suitable stack frame size in template, but too complicated.
|
||||
static const auto FIXED_STACK_FRAME_SIZE = 0x100;
|
||||
|
||||
template<typename T, _func_arg_type type, int g_count, int f_count, int v_count>
|
||||
struct _func_arg;
|
||||
|
||||
@ -50,25 +55,29 @@ namespace cb_detail
|
||||
template<typename T, int g_count, int f_count, int v_count>
|
||||
struct _func_arg<T, ARG_STACK, g_count, f_count, v_count>
|
||||
{
|
||||
static_assert(g_count <= 8, "TODO: Unsupported stack argument type (general)");
|
||||
static_assert(f_count <= 12, "TODO: Unsupported stack argument type (float)");
|
||||
static_assert(v_count <= 12, "TODO: Unsupported stack argument type (vector)");
|
||||
static_assert(sizeof(T) <= 8, "Invalid callback argument type for ARG_STACK");
|
||||
|
||||
__forceinline static void set_value(PPUThread& CPU, const T arg)
|
||||
{
|
||||
// TODO
|
||||
const int stack_pos = 0x70 + (g_count - 9) * 8 - FIXED_STACK_FRAME_SIZE;
|
||||
static_assert(stack_pos < 0, "TODO: Increase fixed stack frame size (arg count limit broken)");
|
||||
u64 value = 0;
|
||||
(T&)value = arg;
|
||||
vm::write64(CPU.GPR[1] + stack_pos, value);
|
||||
}
|
||||
};
|
||||
|
||||
template<int g_count, int f_count, int v_count>
|
||||
__forceinline static void _bind_func_args(PPUThread& CPU)
|
||||
__forceinline static bool _bind_func_args(PPUThread& CPU)
|
||||
{
|
||||
// terminator
|
||||
return false;
|
||||
}
|
||||
|
||||
template<int g_count, int f_count, int v_count, typename T1, typename... T>
|
||||
__forceinline static void _bind_func_args(PPUThread& CPU, T1 arg1, T... args)
|
||||
__forceinline static bool _bind_func_args(PPUThread& CPU, T1 arg1, T... args)
|
||||
{
|
||||
static_assert(!std::is_pointer<T1>::value, "Invalid callback argument type (pointer)");
|
||||
static_assert(!std::is_reference<T1>::value, "Invalid callback argument type (reference)");
|
||||
@ -82,7 +91,8 @@ namespace cb_detail
|
||||
const int v = v_count + (is_vector ? 1 : 0);
|
||||
|
||||
_func_arg<T1, t, g, f, v>::set_value(CPU, arg1);
|
||||
_bind_func_args<g, f, v>(CPU, args...);
|
||||
// return true if stack was used
|
||||
return _bind_func_args<g, f, v>(CPU, args...) || (t == ARG_STACK);
|
||||
}
|
||||
|
||||
template<typename RT>
|
||||
@ -136,8 +146,10 @@ namespace cb_detail
|
||||
{
|
||||
__forceinline static RT call(PPUThread& CPU, u32 pc, u32 rtoc, T... args)
|
||||
{
|
||||
_bind_func_args<0, 0, 0>(CPU, args...);
|
||||
const bool stack = _bind_func_args<0, 0, 0>(CPU, args...);
|
||||
if (stack) CPU.GPR[1] -= FIXED_STACK_FRAME_SIZE;
|
||||
CPU.FastCall2(pc, rtoc);
|
||||
if (stack) CPU.GPR[1] += FIXED_STACK_FRAME_SIZE;
|
||||
return _func_res<RT>::get_value(CPU);
|
||||
}
|
||||
};
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "Emu/SysCalls/Modules.h"
|
||||
#include "Emu/SysCalls/Callback.h"
|
||||
|
||||
#include "Emu/Cell/SPURSManager.h"
|
||||
#include "cellSpurs.h"
|
||||
@ -12,17 +13,127 @@ extern u32 libsre;
|
||||
extern u32 libsre_rtoc;
|
||||
#endif
|
||||
|
||||
s64 spursInit(
|
||||
vm::ptr<CellSpurs2> spurs,
|
||||
u32 arg2,
|
||||
u64 arg3,
|
||||
s32 nSpus,
|
||||
s32 spuPriority,
|
||||
s32 ppuPriority,
|
||||
u32 flags,
|
||||
u32 arg8,
|
||||
u32 arg9,
|
||||
u32 arg10,
|
||||
u32 arg11,
|
||||
u32 arg12,
|
||||
u32 arg13)
|
||||
{
|
||||
// internal function
|
||||
#ifdef PRX_DEBUG
|
||||
return cb_caller<s32,vm::ptr<CellSpurs2>, u32, u64, s32, s32, s32, u32, u32, u32, u32, u32, u32, u32>::call(GetCurrentPPUThread(), libsre + 0x74E4, libsre_rtoc,
|
||||
spurs, arg2, arg3, nSpus, spuPriority, ppuPriority, flags, arg8, arg9, arg10, arg11, arg12, arg13);
|
||||
#else
|
||||
//spurs->spurs = new SPURSManager(attr);
|
||||
return CELL_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
s64 cellSpursInitialize(vm::ptr<CellSpurs> spurs, s32 nSpus, s32 spuPriority, s32 ppuPriority, bool exitIfNoWork)
|
||||
{
|
||||
cellSpurs->Warning("cellSpursInitialize(spurs_addr=0x%x, nSpus=%d, spuPriority=%d, ppuPriority=%d, exitIfNoWork=%d)", spurs.addr(), nSpus, spuPriority, ppuPriority, exitIfNoWork);
|
||||
cellSpurs->Warning("cellSpursInitialize(spurs_addr=0x%x, nSpus=%d, spuPriority=%d, ppuPriority=%d, exitIfNoWork=%d)",
|
||||
spurs.addr(), nSpus, spuPriority, ppuPriority, exitIfNoWork ? 1 : 0);
|
||||
|
||||
#ifdef PRX_DEBUG
|
||||
#ifdef PRX_DEBUG_XXX
|
||||
return GetCurrentPPUThread().FastCall2(libsre + 0x8480, libsre_rtoc);
|
||||
#else
|
||||
SPURSManagerAttribute *attr = new SPURSManagerAttribute(nSpus, spuPriority, ppuPriority, exitIfNoWork);
|
||||
spurs->spurs = new SPURSManager(attr);
|
||||
return spursInit(
|
||||
vm::ptr<CellSpurs2>::make(spurs.addr()),
|
||||
0,
|
||||
0,
|
||||
nSpus,
|
||||
spuPriority,
|
||||
ppuPriority,
|
||||
exitIfNoWork ? 1 : 0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
#endif
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
s64 cellSpursInitializeWithAttribute(vm::ptr<CellSpurs> spurs, vm::ptr<const CellSpursAttribute> attr)
|
||||
{
|
||||
cellSpurs->Warning("cellSpursInitializeWithAttribute(spurs_addr=0x%x, attr_addr=0x%x)", spurs.addr(), attr.addr());
|
||||
|
||||
#ifdef PRX_DEBUG_XXX
|
||||
return GetCurrentPPUThread().FastCall2(libsre + 0x839C, libsre_rtoc);
|
||||
#else
|
||||
if (!attr)
|
||||
{
|
||||
return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
||||
}
|
||||
if (attr.addr() % 8)
|
||||
{
|
||||
return CELL_SPURS_CORE_ERROR_ALIGN;
|
||||
}
|
||||
if (attr->m.arg1 > 2)
|
||||
{
|
||||
return CELL_SPURS_CORE_ERROR_INVAL;
|
||||
}
|
||||
|
||||
return spursInit(
|
||||
vm::ptr<CellSpurs2>::make(spurs.addr()),
|
||||
attr->m.arg1,
|
||||
attr->m.arg2,
|
||||
attr->m.nSpus,
|
||||
attr->m.spuPriority,
|
||||
attr->m.ppuPriority,
|
||||
(u32)attr->_u32.raw[10] | (u32)attr->_u8[20],
|
||||
attr.addr() + 0x15,
|
||||
attr->_u32.raw[9],
|
||||
attr->_u32.raw[11],
|
||||
attr.addr() + 0x38,
|
||||
attr->_u32.raw[16],
|
||||
attr->_u32.raw[17]);
|
||||
#endif
|
||||
}
|
||||
|
||||
s64 cellSpursInitializeWithAttribute2(vm::ptr<CellSpurs2> spurs, vm::ptr<const CellSpursAttribute> attr)
|
||||
{
|
||||
cellSpurs->Warning("cellSpursInitializeWithAttribute2(spurs_addr=0x%x, attr_addr=0x%x)", spurs.addr(), attr.addr());
|
||||
|
||||
#ifdef PRX_DEBUG_XXX
|
||||
return GetCurrentPPUThread().FastCall2(libsre + 0x82B4, libsre_rtoc);
|
||||
#else
|
||||
if (!attr)
|
||||
{
|
||||
return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
||||
}
|
||||
if (attr.addr() % 8)
|
||||
{
|
||||
return CELL_SPURS_CORE_ERROR_ALIGN;
|
||||
}
|
||||
if (attr->m.arg1 > 2)
|
||||
{
|
||||
return CELL_SPURS_CORE_ERROR_INVAL;
|
||||
}
|
||||
|
||||
return spursInit(
|
||||
spurs,
|
||||
attr->m.arg1,
|
||||
attr->m.arg2,
|
||||
attr->m.nSpus,
|
||||
attr->m.spuPriority,
|
||||
attr->m.ppuPriority,
|
||||
(u32)attr->_u32.raw[10] | (u32)attr->_u8[20] | 4,
|
||||
attr.addr() + 0x15,
|
||||
attr->_u32.raw[9],
|
||||
attr->_u32.raw[11],
|
||||
attr.addr() + 0x38,
|
||||
attr->_u32.raw[16],
|
||||
attr->_u32.raw[17]);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -39,32 +150,6 @@ s64 cellSpursFinalize(vm::ptr<CellSpurs> spurs)
|
||||
#endif
|
||||
}
|
||||
|
||||
s64 cellSpursInitializeWithAttribute(vm::ptr<CellSpurs> spurs, vm::ptr<const CellSpursAttribute> attr)
|
||||
{
|
||||
cellSpurs->Warning("cellSpursInitializeWithAttribute(spurs_addr=0x%x, spurs_addr=0x%x)", spurs.addr(), attr.addr());
|
||||
|
||||
#ifdef PRX_DEBUG
|
||||
return GetCurrentPPUThread().FastCall2(libsre + 0x839C, libsre_rtoc);
|
||||
#else
|
||||
spurs->spurs = new SPURSManager(attr->attr);
|
||||
|
||||
return CELL_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
s64 cellSpursInitializeWithAttribute2(vm::ptr<CellSpurs2> spurs, vm::ptr<const CellSpursAttribute> attr)
|
||||
{
|
||||
cellSpurs->Warning("cellSpursInitializeWithAttribute2(spurs_addr=0x%x, spurs_addr=0x%x)", spurs.addr(), attr.addr());
|
||||
|
||||
#ifdef PRX_DEBUG
|
||||
return GetCurrentPPUThread().FastCall2(libsre + 0x82B4, libsre_rtoc);
|
||||
#else
|
||||
spurs->spurs = new SPURSManager(attr->attr);
|
||||
|
||||
return CELL_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
s64 _cellSpursAttributeInitialize(vm::ptr<CellSpursAttribute> attr, s32 nSpus, s32 spuPriority, s32 ppuPriority, bool exitIfNoWork)
|
||||
{
|
||||
cellSpurs->Warning("_cellSpursAttributeInitialize(attr_addr=0x%x, nSpus=%d, spuPriority=%d, ppuPriority=%d, exitIfNoWork=%d)",
|
||||
|
@ -94,7 +94,35 @@ struct CellSpurs2
|
||||
|
||||
struct CellSpursAttribute
|
||||
{
|
||||
SPURSManagerAttribute *attr;
|
||||
static const auto align = 8;
|
||||
static const auto size = 512;
|
||||
|
||||
union
|
||||
{
|
||||
// raw data
|
||||
u8 _u8[size / sizeof(u8)];
|
||||
|
||||
struct
|
||||
{
|
||||
be_t<u32> raw[size / sizeof(u32)];
|
||||
} _u32;
|
||||
|
||||
// real structure
|
||||
struct
|
||||
{
|
||||
be_t<u32> arg1;
|
||||
be_t<u32> arg2;
|
||||
be_t<u32> nSpus;
|
||||
be_t<s32> spuPriority;
|
||||
be_t<s32> ppuPriority;
|
||||
} m;
|
||||
|
||||
// alternative implementation
|
||||
struct
|
||||
{
|
||||
SPURSManagerAttribute *attr;
|
||||
} c;
|
||||
};
|
||||
};
|
||||
|
||||
struct CellSpursEventFlag
|
||||
|
@ -227,7 +227,7 @@ s32 cellFsClosedir(u32 fd)
|
||||
|
||||
s32 cellFsStat(vm::ptr<const char> path, vm::ptr<CellFsStat> sb)
|
||||
{
|
||||
sys_fs->Warning("cellFsStat(path=\"%s\", sb_addr: 0x%x)", path.get_ptr(), sb.addr());
|
||||
sys_fs->Warning("cellFsStat(path=\"%s\", sb_addr=0x%x)", path.get_ptr(), sb.addr());
|
||||
|
||||
LV2_LOCK(0);
|
||||
|
||||
@ -270,7 +270,7 @@ s32 cellFsStat(vm::ptr<const char> path, vm::ptr<CellFsStat> sb)
|
||||
|
||||
s32 cellFsFstat(u32 fd, vm::ptr<CellFsStat> sb)
|
||||
{
|
||||
sys_fs->Warning("cellFsFstat(fd=%d, sb_addr: 0x%x)", fd, sb.addr());
|
||||
sys_fs->Warning("cellFsFstat(fd=%d, sb_addr=0x%x)", fd, sb.addr());
|
||||
|
||||
LV2_LOCK(0);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user