mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 18:53:28 +01:00
CALL_FUNC macro fixed
Now it can call any HLE function, possibly using LLE if available.
This commit is contained in:
parent
da4bf43fb2
commit
093ecc0a02
@ -125,33 +125,36 @@ void hook_ppu_funcs(vm::ptr<u32> base, u32 size);
|
||||
|
||||
bool patch_ppu_import(u32 addr, u32 index);
|
||||
|
||||
// call specified function directly if LLE is not available, call LLE equivalent in callback style otherwise
|
||||
template<typename T, typename... Args> inline auto hle_call_func(PPUThread& CPU, T func, u32 index, Args&&... args) -> decltype(func(std::forward<Args>(args)...))
|
||||
// Variable associated with registered HLE function
|
||||
template<typename T, T Func> struct ppu_func_by_func { static u32 index; };
|
||||
|
||||
template<typename T, T Func> u32 ppu_func_by_func<T, Func>::index = 0xffffffffu;
|
||||
|
||||
template<typename T, T Func, typename... Args, typename RT = std::result_of_t<T(Args...)>> inline RT call_ppu_func(PPUThread& ppu, Args&&... args)
|
||||
{
|
||||
const auto mfunc = get_ppu_func_by_index(index);
|
||||
const auto mfunc = get_ppu_func_by_index(ppu_func_by_func<T, Func>::index);
|
||||
|
||||
if (mfunc && mfunc->lle_func && (mfunc->flags & MFF_FORCED_HLE) == 0 && (mfunc->flags & MFF_NO_RETURN) == 0)
|
||||
{
|
||||
const u32 pc = vm::read32(mfunc->lle_func.addr());
|
||||
const u32 rtoc = vm::read32(mfunc->lle_func.addr() + 4);
|
||||
|
||||
return cb_call<decltype(func(std::forward<Args>(args)...)), Args...>(CPU, pc, rtoc, std::forward<Args>(args)...);
|
||||
return cb_call<RT, Args...>(ppu, pc, rtoc, std::forward<Args>(args)...);
|
||||
}
|
||||
else
|
||||
{
|
||||
return func(std::forward<Args>(args)...);
|
||||
return Func(std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
|
||||
#define CALL_FUNC(cpu, func, ...) hle_call_func(cpu, func, g_ppu_func_index__##func, __VA_ARGS__)
|
||||
// call specified function directly if LLE is not available, call LLE equivalent in callback style otherwise
|
||||
#define CALL_FUNC(ppu, func, ...) call_ppu_func<decltype(&func), &func>(ppu, __VA_ARGS__)
|
||||
|
||||
#define REG_FUNC(module, name) add_ppu_func(ModuleFunc(get_function_id(#name), 0, &module, #name, bind_func(name)))
|
||||
#define REG_FUNC_FH(module, name) add_ppu_func(ModuleFunc(get_function_id(#name), MFF_FORCED_HLE, &module, #name, bind_func(name)))
|
||||
#define REG_FUNC_NR(module, name) add_ppu_func(ModuleFunc(get_function_id(#name), MFF_NO_RETURN, &module, #name, bind_func(name)))
|
||||
#define REG_FNID(module, nid, func, ...) (ppu_func_by_func<decltype(&func), &func>::index = add_ppu_func(ModuleFunc(nid, { __VA_ARGS__ }, &module, #func, BIND_FUNC(func))))
|
||||
|
||||
#define REG_UNNAMED(module, nid) add_ppu_func(ModuleFunc(0x##nid, 0, &module, "_nid_"#nid, bind_func(_nid_##nid)))
|
||||
#define REG_FUNC(module, func, ...) REG_FNID(module, get_function_id(#func), func, __VA_ARGS__)
|
||||
|
||||
#define REG_SUB(module, ns, name, ...) add_ppu_func_sub({ __VA_ARGS__ }, #name, &module, bind_func(ns::name))
|
||||
#define REG_SUB(module, ns, name, ...) add_ppu_func_sub({ __VA_ARGS__ }, #name, &module, BIND_FUNC(ns::name))
|
||||
|
||||
#define SP_OP(type, op, sup) []() { s32 XXX = 0; SearchPatternEntry res = { (type), (op), 0, (sup) }; XXX = -1; res.mask = (op) ^ ~res.data; return res; }()
|
||||
#define SP_I(op) SP_OP(SPET_MASKED_OPCODE, op, 0)
|
||||
|
@ -293,57 +293,57 @@ s32 cellFiberPpuUtilWorkerControlInitializeWithAttribute()
|
||||
|
||||
Module cellFiber("cellFiber", []()
|
||||
{
|
||||
REG_FUNC_NR(cellFiber, _cellFiberPpuInitialize);
|
||||
REG_FUNC(cellFiber, _cellFiberPpuInitialize, MFF_NO_RETURN);
|
||||
|
||||
REG_FUNC_NR(cellFiber, _cellFiberPpuSchedulerAttributeInitialize);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuInitializeScheduler);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuFinalizeScheduler);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuRunFibers);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuCheckFlags);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuHasRunnableFiber);
|
||||
REG_FUNC(cellFiber, _cellFiberPpuSchedulerAttributeInitialize, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuInitializeScheduler, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuFinalizeScheduler, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuRunFibers, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuCheckFlags, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuHasRunnableFiber, MFF_NO_RETURN);
|
||||
|
||||
REG_FUNC_NR(cellFiber, _cellFiberPpuAttributeInitialize);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuCreateFiber);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuExit);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuYield);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuJoinFiber);
|
||||
REG_FUNC(cellFiber, _cellFiberPpuAttributeInitialize, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuCreateFiber, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuExit, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuYield, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuJoinFiber, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuSelf);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuSendSignal);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuWaitSignal);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuWaitFlag);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuGetScheduler);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuSetPriority);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuCheckStackLimit);
|
||||
REG_FUNC(cellFiber, cellFiberPpuSendSignal, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuWaitSignal, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuWaitFlag, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuGetScheduler, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuSetPriority, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuCheckStackLimit, MFF_NO_RETURN);
|
||||
|
||||
REG_FUNC_NR(cellFiber, _cellFiberPpuContextAttributeInitialize);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuContextInitialize);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuContextFinalize);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuContextRun);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuContextSwitch);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuContextSelf);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuContextReturnToThread);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuContextCheckStackLimit);
|
||||
REG_FUNC(cellFiber, _cellFiberPpuContextAttributeInitialize, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuContextInitialize, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuContextFinalize, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuContextRun, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuContextSwitch, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuContextSelf, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuContextReturnToThread, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuContextCheckStackLimit, MFF_NO_RETURN);
|
||||
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuContextRunScheduler);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuContextEnterScheduler);
|
||||
REG_FUNC(cellFiber, cellFiberPpuContextRunScheduler, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuContextEnterScheduler, MFF_NO_RETURN);
|
||||
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuSchedulerTraceInitialize);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuSchedulerTraceFinalize);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuSchedulerTraceStart);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuSchedulerTraceStop);
|
||||
REG_FUNC(cellFiber, cellFiberPpuSchedulerTraceInitialize, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuSchedulerTraceFinalize, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuSchedulerTraceStart, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuSchedulerTraceStop, MFF_NO_RETURN);
|
||||
|
||||
REG_FUNC_NR(cellFiber, _cellFiberPpuUtilWorkerControlAttributeInitialize);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuUtilWorkerControlRunFibers);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuUtilWorkerControlInitialize);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuUtilWorkerControlSetPollingMode);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuUtilWorkerControlJoinFiber);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuUtilWorkerControlDisconnectEventQueue);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuUtilWorkerControlSendSignal);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuUtilWorkerControlConnectEventQueueToSpurs);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuUtilWorkerControlFinalize);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuUtilWorkerControlWakeup);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuUtilWorkerControlCreateFiber);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuUtilWorkerControlShutdown);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuUtilWorkerControlCheckFlags);
|
||||
REG_FUNC_NR(cellFiber, cellFiberPpuUtilWorkerControlInitializeWithAttribute);
|
||||
REG_FUNC(cellFiber, _cellFiberPpuUtilWorkerControlAttributeInitialize, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuUtilWorkerControlRunFibers, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuUtilWorkerControlInitialize, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuUtilWorkerControlSetPollingMode, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuUtilWorkerControlJoinFiber, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuUtilWorkerControlDisconnectEventQueue, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuUtilWorkerControlSendSignal, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuUtilWorkerControlConnectEventQueueToSpurs, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuUtilWorkerControlFinalize, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuUtilWorkerControlWakeup, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuUtilWorkerControlCreateFiber, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuUtilWorkerControlShutdown, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuUtilWorkerControlCheckFlags, MFF_NO_RETURN);
|
||||
REG_FUNC(cellFiber, cellFiberPpuUtilWorkerControlInitializeWithAttribute, MFF_NO_RETURN);
|
||||
});
|
||||
|
@ -422,8 +422,6 @@ void spursHandlerWaitReady(PPUThread& ppu, vm::ptr<CellSpurs> spurs)
|
||||
|
||||
if (spurs->handlerExiting.load())
|
||||
{
|
||||
extern u32 g_ppu_func_index__sys_lwmutex_unlock; // test
|
||||
|
||||
if (s32 rc = CALL_FUNC(ppu, sys_lwmutex_unlock, ppu, spurs.ptr(&CellSpurs::mutex)))
|
||||
{
|
||||
throw EXCEPTION("sys_lwmutex_unlock() failed (0x%x)", rc);
|
||||
|
@ -276,13 +276,11 @@ s32 sys_lwmutex_unlock(PPUThread& ppu, vm::ptr<sys_lwmutex_t> lwmutex)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
u32 g_ppu_func_index__sys_lwmutex_unlock; // test
|
||||
|
||||
void sysPrxForUser_sys_lwmutex_init()
|
||||
{
|
||||
REG_FUNC(sysPrxForUser, sys_lwmutex_create);
|
||||
REG_FUNC(sysPrxForUser, sys_lwmutex_destroy);
|
||||
REG_FUNC(sysPrxForUser, sys_lwmutex_lock);
|
||||
REG_FUNC(sysPrxForUser, sys_lwmutex_trylock);
|
||||
g_ppu_func_index__sys_lwmutex_unlock = REG_FUNC(sysPrxForUser, sys_lwmutex_unlock); // test
|
||||
REG_FUNC(sysPrxForUser, sys_lwmutex_unlock);
|
||||
}
|
||||
|
@ -614,7 +614,7 @@ namespace sys_net
|
||||
}
|
||||
|
||||
// define additional macro for specific namespace
|
||||
#define REG_FUNC_(name) add_ppu_func(ModuleFunc(get_function_id(#name), 0, &libnet, #name, bind_func(sys_net::name)))
|
||||
#define REG_FUNC_(name) add_ppu_func(ModuleFunc(get_function_id(#name), 0, &libnet, #name, BIND_FUNC(sys_net::name)))
|
||||
|
||||
Module libnet("sys_net", []()
|
||||
{
|
||||
|
@ -228,11 +228,11 @@ namespace ppu_func_detail
|
||||
bind_result<RT, result_type<RT>::value>::put_result(ppu, call<T...>(ppu, func, arg_info_pack_t<>{}));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename RT, typename... T> force_inline void do_call(PPUThread& ppu, RT(*func)(T...))
|
||||
{
|
||||
func_binder<RT, T...>::do_call(ppu, func);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename RT, typename... T> force_inline void call_ppu_func(PPUThread& ppu, RT(*func)(T...))
|
||||
{
|
||||
ppu_func_detail::func_binder<RT, T...>::do_call(ppu, func);
|
||||
}
|
||||
|
||||
#define bind_func(func) [](PPUThread& ppu){ call_ppu_func(ppu, func); }
|
||||
#define BIND_FUNC(func) [](PPUThread& ppu){ ppu_func_detail::do_call(ppu, func); }
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user