1
0
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:
Nekotekina 2015-09-08 14:29:27 +03:00
parent da4bf43fb2
commit 093ecc0a02
7 changed files with 787 additions and 788 deletions

View File

@ -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)

View File

@ -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);
});

View File

@ -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);

View File

@ -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);
}

View File

@ -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", []()
{

View File

@ -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