mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-30 21:32:50 +00:00
SC_FUNC.h rewritten
Now float arguments should work correctly
This commit is contained in:
parent
9eda0aa245
commit
5d3a612003
@ -754,6 +754,10 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
mem_class_t() : m_addr(0)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T> u32 operator += (T right)
|
||||
{
|
||||
mem_t<T>& m((mem_t<T>&)*this);
|
||||
|
@ -141,7 +141,6 @@ __forceinline void Module::AddFuncSub(const char group[8], const u64 ops[], cons
|
||||
{
|
||||
if (!ops[0]) return;
|
||||
|
||||
//TODO: track down where this is supposed to be deleted
|
||||
SFunc* sf = new SFunc;
|
||||
sf->ptr = (void *)func;
|
||||
sf->func = bind_func(func);
|
||||
|
@ -1,414 +1,159 @@
|
||||
#pragma once
|
||||
#include "Emu/Cell/PPUThread.h"
|
||||
|
||||
#define RESULT(x) CPU.GPR[3] = (x)
|
||||
|
||||
class func_caller
|
||||
{
|
||||
public:
|
||||
virtual void operator()() = 0;
|
||||
};
|
||||
|
||||
|
||||
template<bool is_in_sp, bool is_fp, bool is_ptr, typename T, int i>
|
||||
struct get_arg;
|
||||
|
||||
template<typename T, int i>
|
||||
struct get_arg<false, false, false, T, i> // not fp, not ptr, 1..8
|
||||
namespace detail
|
||||
{
|
||||
static __forceinline T func(PPUThread& CPU) { return (T&)CPU.GPR[i + 2]; }
|
||||
enum bind_arg_type
|
||||
{
|
||||
ARG_GENERAL,
|
||||
ARG_FLOAT,
|
||||
ARG_VECTOR,
|
||||
ARG_STACK,
|
||||
};
|
||||
|
||||
template<bool is_fp, typename T, int i>
|
||||
struct get_arg<false, is_fp, true, T, i> // ptr, 1..8
|
||||
template<typename T, bind_arg_type type, int g_count, int f_count, int v_count>
|
||||
struct bind_arg;
|
||||
|
||||
template<typename T, int g_count, int f_count, int v_count>
|
||||
struct bind_arg<T, ARG_GENERAL, g_count, f_count, v_count>
|
||||
{
|
||||
static_assert(i == 0, "Invalid function argument type: pointer");
|
||||
static __forceinline T func(PPUThread& CPU) { return nullptr; }
|
||||
static __forceinline T func(PPUThread& CPU) { return (T&)CPU.GPR[g_count + 2]; }
|
||||
};
|
||||
|
||||
template<bool is_in_sp, typename T, int i>
|
||||
struct get_arg<is_in_sp, true, false, T, i> // fp, 1..12
|
||||
template<typename T, int g_count, int f_count, int v_count>
|
||||
struct bind_arg<T, ARG_FLOAT, g_count, f_count, v_count>
|
||||
{
|
||||
static __forceinline T func(PPUThread& CPU) { return CPU.FPR[i]; }
|
||||
static __forceinline T func(PPUThread& CPU) { return (T&)CPU.FPR[f_count]; }
|
||||
};
|
||||
|
||||
template<typename T, int i>
|
||||
struct get_arg<true, false, false, T, i> // not fp, not ptr, 9..12
|
||||
template<typename T, int g_count, int f_count, int v_count>
|
||||
struct bind_arg<T, ARG_VECTOR, g_count, f_count, v_count>
|
||||
{
|
||||
static __forceinline T func(PPUThread& CPU) { u64 res = CPU.GetStackArg(i); return (T&)res; }
|
||||
static_assert(v_count == 0, "ARG_VECTOR not supported");
|
||||
static __forceinline T func(PPUThread& CPU) { return T(); }
|
||||
};
|
||||
|
||||
template<bool is_fp, typename T, int i>
|
||||
struct get_arg<true, is_fp, true, T, i> // ptr, 9..12
|
||||
template<typename T, int g_count, int f_count, int v_count>
|
||||
struct bind_arg<T, ARG_STACK, g_count, f_count, v_count>
|
||||
{
|
||||
static_assert(i == 0, "Invalid function argument type: pointer");
|
||||
static __forceinline T func(PPUThread& CPU) { return nullptr; }
|
||||
static __forceinline T func(PPUThread& CPU) { return CPU.GetStackArg(8 + std::max(g_count - 8, 0) + std::max(f_count - 12, 0)); }
|
||||
};
|
||||
|
||||
#define ARG(n) get_arg<((n) > 8), std::is_floating_point<T##n>::value, std::is_pointer<T##n>::value, T##n, n>::func(CPU)
|
||||
|
||||
template<typename TR>
|
||||
class binder_func_0 : public func_caller
|
||||
template<typename T>
|
||||
struct bind_result
|
||||
{
|
||||
typedef TR (*func_t)();
|
||||
const func_t m_call;
|
||||
|
||||
public:
|
||||
binder_func_0(func_t call) : func_caller(), m_call(call) {}
|
||||
virtual void operator()() { declCPU(); RESULT(m_call()); }
|
||||
static __forceinline void func(PPUThread& CPU, T value)
|
||||
{
|
||||
static_assert(!std::is_pointer<T>::value, "Invalid function result type: pointer");
|
||||
if (std::is_floating_point<T>::value)
|
||||
{
|
||||
(T&)CPU.FPR[1] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
(T&)CPU.GPR[3] = value;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
class binder_func_0<void> : public func_caller
|
||||
template <typename RT, typename F, typename Tuple, bool Done, int Total, int... N>
|
||||
struct call_impl
|
||||
{
|
||||
typedef void (*func_t)();
|
||||
const func_t m_call;
|
||||
|
||||
public:
|
||||
binder_func_0(func_t call) : func_caller(), m_call(call) {}
|
||||
virtual void operator()() { declCPU(); m_call(); }
|
||||
static __forceinline RT call(F f, Tuple && t)
|
||||
{
|
||||
return call_impl<RT, F, Tuple, Total == 1 + sizeof...(N), Total, N..., sizeof...(N)>::call(f, std::forward<Tuple>(t));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename TR, typename T1>
|
||||
class binder_func_1 : public func_caller
|
||||
template <typename RT, typename F, typename Tuple, int Total, int... N>
|
||||
struct call_impl<RT, F, Tuple, true, Total, N...>
|
||||
{
|
||||
typedef TR (*func_t)(T1);
|
||||
const func_t m_call;
|
||||
|
||||
public:
|
||||
binder_func_1(func_t call) : func_caller(), m_call(call) {}
|
||||
virtual void operator()() { declCPU(); RESULT(m_call(ARG(1))); }
|
||||
static __forceinline RT call(F f, Tuple && t)
|
||||
{
|
||||
return f(std::get<N>(std::forward<Tuple>(t))...);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T1>
|
||||
class binder_func_1<void, T1> : public func_caller
|
||||
template <typename RT, typename F, typename Tuple>
|
||||
static __forceinline RT call(F f, Tuple && t)
|
||||
{
|
||||
typedef void (*func_t)(T1);
|
||||
const func_t m_call;
|
||||
|
||||
public:
|
||||
binder_func_1(func_t call) : func_caller(), m_call(call) {}
|
||||
virtual void operator()() { declCPU(); m_call(ARG(1)); }
|
||||
};
|
||||
|
||||
template<typename TR, typename T1, typename T2>
|
||||
class binder_func_2 : public func_caller
|
||||
{
|
||||
typedef TR (*func_t)(T1, T2);
|
||||
const func_t m_call;
|
||||
|
||||
public:
|
||||
binder_func_2(func_t call) : func_caller(), m_call(call) {}
|
||||
virtual void operator()() { declCPU(); RESULT(m_call(ARG(1), ARG(2))); }
|
||||
};
|
||||
|
||||
template<typename T1, typename T2>
|
||||
class binder_func_2<void, T1, T2> : public func_caller
|
||||
{
|
||||
typedef void (*func_t)(T1, T2);
|
||||
const func_t m_call;
|
||||
|
||||
public:
|
||||
binder_func_2(func_t call) : func_caller(), m_call(call) {}
|
||||
virtual void operator()() { declCPU(); m_call(ARG(1), ARG(2)); }
|
||||
};
|
||||
|
||||
template<typename TR, typename T1, typename T2, typename T3>
|
||||
class binder_func_3 : public func_caller
|
||||
{
|
||||
typedef TR (*func_t)(T1, T2, T3);
|
||||
const func_t m_call;
|
||||
|
||||
public:
|
||||
binder_func_3(func_t call) : func_caller(), m_call(call) {}
|
||||
virtual void operator()() { declCPU(); RESULT(m_call(ARG(1), ARG(2), ARG(3))); }
|
||||
};
|
||||
|
||||
template<typename T1, typename T2, typename T3>
|
||||
class binder_func_3<void, T1, T2, T3> : public func_caller
|
||||
{
|
||||
typedef void (*func_t)(T1, T2, T3);
|
||||
const func_t m_call;
|
||||
|
||||
public:
|
||||
binder_func_3(func_t call) : func_caller(), m_call(call) {}
|
||||
virtual void operator()() { declCPU(); m_call(ARG(1), ARG(2), ARG(3)); }
|
||||
};
|
||||
|
||||
template<typename TR, typename T1, typename T2, typename T3, typename T4>
|
||||
class binder_func_4 : public func_caller
|
||||
{
|
||||
typedef TR (*func_t)(T1, T2, T3, T4);
|
||||
const func_t m_call;
|
||||
|
||||
public:
|
||||
binder_func_4(func_t call) : func_caller(), m_call(call) {}
|
||||
virtual void operator()() { declCPU(); RESULT(m_call(ARG(1), ARG(2), ARG(3), ARG(4))); }
|
||||
};
|
||||
|
||||
template<typename T1, typename T2, typename T3, typename T4>
|
||||
class binder_func_4<void, T1, T2, T3, T4> : public func_caller
|
||||
{
|
||||
typedef void (*func_t)(T1, T2, T3, T4);
|
||||
const func_t m_call;
|
||||
|
||||
public:
|
||||
binder_func_4(func_t call) : func_caller(), m_call(call) {}
|
||||
virtual void operator()() { declCPU(); m_call(ARG(1), ARG(2), ARG(3), ARG(4)); }
|
||||
};
|
||||
|
||||
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
class binder_func_5 : public func_caller
|
||||
{
|
||||
typedef TR (*func_t)(T1, T2, T3, T4, T5);
|
||||
const func_t m_call;
|
||||
|
||||
public:
|
||||
binder_func_5(func_t call) : func_caller(), m_call(call) {}
|
||||
virtual void operator()() { declCPU(); RESULT(m_call(ARG(1), ARG(2), ARG(3), ARG(4), ARG(5))); }
|
||||
};
|
||||
|
||||
template<typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
class binder_func_5<void, T1, T2, T3, T4, T5> : public func_caller
|
||||
{
|
||||
typedef void (*func_t)(T1, T2, T3, T4, T5);
|
||||
const func_t m_call;
|
||||
|
||||
public:
|
||||
binder_func_5(func_t call) : func_caller(), m_call(call) {}
|
||||
virtual void operator()() { declCPU(); m_call(ARG(1), ARG(2), ARG(3), ARG(4), ARG(5)); }
|
||||
};
|
||||
|
||||
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
|
||||
class binder_func_6 : public func_caller
|
||||
{
|
||||
typedef TR (*func_t)(T1, T2, T3, T4, T5, T6);
|
||||
const func_t m_call;
|
||||
|
||||
public:
|
||||
binder_func_6(func_t call) : func_caller(), m_call(call) {}
|
||||
virtual void operator()() { declCPU(); RESULT(m_call(ARG(1), ARG(2), ARG(3), ARG(4), ARG(5), ARG(6))); }
|
||||
};
|
||||
|
||||
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
|
||||
class binder_func_6<void, T1, T2, T3, T4, T5, T6> : public func_caller
|
||||
{
|
||||
typedef void (*func_t)(T1, T2, T3, T4, T5, T6);
|
||||
const func_t m_call;
|
||||
|
||||
public:
|
||||
binder_func_6(func_t call) : func_caller(), m_call(call) {}
|
||||
virtual void operator()() { declCPU(); m_call(ARG(1), ARG(2), ARG(3), ARG(4), ARG(5), ARG(6)); }
|
||||
};
|
||||
|
||||
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
|
||||
class binder_func_7 : public func_caller
|
||||
{
|
||||
typedef TR (*func_t)(T1, T2, T3, T4, T5, T6, T7);
|
||||
const func_t m_call;
|
||||
|
||||
public:
|
||||
binder_func_7(func_t call) : func_caller(), m_call(call) {}
|
||||
virtual void operator()() { declCPU(); RESULT(m_call(ARG(1), ARG(2), ARG(3), ARG(4), ARG(5), ARG(6), ARG(7))); }
|
||||
};
|
||||
|
||||
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
|
||||
class binder_func_7<void, T1, T2, T3, T4, T5, T6, T7> : public func_caller
|
||||
{
|
||||
typedef void (*func_t)(T1, T2, T3, T4, T5, T6, T7);
|
||||
const func_t m_call;
|
||||
|
||||
public:
|
||||
binder_func_7(func_t call) : func_caller(), m_call(call) {}
|
||||
virtual void operator()() { declCPU(); m_call(ARG(1), ARG(2), ARG(3), ARG(4), ARG(5), ARG(6), ARG(7)); }
|
||||
};
|
||||
|
||||
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
||||
class binder_func_8 : public func_caller
|
||||
{
|
||||
typedef TR (*func_t)(T1, T2, T3, T4, T5, T6, T7, T8);
|
||||
const func_t m_call;
|
||||
|
||||
public:
|
||||
binder_func_8(func_t call) : func_caller(), m_call(call) {}
|
||||
virtual void operator()() { declCPU(); RESULT(m_call(ARG(1), ARG(2), ARG(3), ARG(4), ARG(5), ARG(6), ARG(7), ARG(8))); }
|
||||
};
|
||||
|
||||
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
||||
class binder_func_8<void, T1, T2, T3, T4, T5, T6, T7, T8> : public func_caller
|
||||
{
|
||||
typedef void (*func_t)(T1, T2, T3, T4, T5, T6, T7, T8);
|
||||
const func_t m_call;
|
||||
|
||||
public:
|
||||
binder_func_8(func_t call) : func_caller(), m_call(call) {}
|
||||
virtual void operator()() { declCPU(); m_call(ARG(1), ARG(2), ARG(3), ARG(4), ARG(5), ARG(6), ARG(7), ARG(8)); }
|
||||
};
|
||||
|
||||
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
|
||||
class binder_func_9 : public func_caller
|
||||
{
|
||||
typedef TR (*func_t)(T1, T2, T3, T4, T5, T6, T7, T8, T9);
|
||||
const func_t m_call;
|
||||
|
||||
public:
|
||||
binder_func_9(func_t call) : func_caller(), m_call(call) {}
|
||||
virtual void operator()() { declCPU(); RESULT(m_call(ARG(1), ARG(2), ARG(3), ARG(4), ARG(5), ARG(6), ARG(7), ARG(8), ARG(9))); }
|
||||
};
|
||||
|
||||
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
|
||||
class binder_func_9<void, T1, T2, T3, T4, T5, T6, T7, T8, T9> : public func_caller
|
||||
{
|
||||
typedef void (*func_t)(T1, T2, T3, T4, T5, T6, T7, T8, T9);
|
||||
const func_t m_call;
|
||||
|
||||
public:
|
||||
binder_func_9(func_t call) : func_caller(), m_call(call) {}
|
||||
virtual void operator()() { declCPU(); m_call(ARG(1), ARG(2), ARG(3), ARG(4), ARG(5), ARG(6), ARG(7), ARG(8), ARG(9)); }
|
||||
};
|
||||
|
||||
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10>
|
||||
class binder_func_10 : public func_caller
|
||||
{
|
||||
typedef TR (*func_t)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
|
||||
const func_t m_call;
|
||||
|
||||
public:
|
||||
binder_func_10(func_t call) : func_caller(), m_call(call) {}
|
||||
virtual void operator()() { declCPU(); RESULT(m_call(ARG(1), ARG(2), ARG(3), ARG(4), ARG(5), ARG(6), ARG(7), ARG(8), ARG(9), ARG(10))); }
|
||||
};
|
||||
|
||||
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10>
|
||||
class binder_func_10<void, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> : public func_caller
|
||||
{
|
||||
typedef void (*func_t)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
|
||||
const func_t m_call;
|
||||
|
||||
public:
|
||||
binder_func_10(func_t call) : func_caller(), m_call(call) {}
|
||||
virtual void operator()() { declCPU(); m_call(ARG(1), ARG(2), ARG(3), ARG(4), ARG(5), ARG(6), ARG(7), ARG(8), ARG(9), ARG(10)); }
|
||||
};
|
||||
|
||||
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11>
|
||||
class binder_func_11 : public func_caller
|
||||
{
|
||||
typedef TR (*func_t)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);
|
||||
const func_t m_call;
|
||||
|
||||
public:
|
||||
binder_func_11(func_t call) : func_caller(), m_call(call) {}
|
||||
virtual void operator()() { declCPU(); RESULT(m_call(ARG(1), ARG(2), ARG(3), ARG(4), ARG(5), ARG(6), ARG(7), ARG(8), ARG(9), ARG(10), ARG(11))); }
|
||||
};
|
||||
|
||||
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11>
|
||||
class binder_func_11<void, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> : public func_caller
|
||||
{
|
||||
typedef void (*func_t)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);
|
||||
const func_t m_call;
|
||||
|
||||
public:
|
||||
binder_func_11(func_t call) : func_caller(), m_call(call) {}
|
||||
virtual void operator()() { declCPU(); m_call(ARG(1), ARG(2), ARG(3), ARG(4), ARG(5), ARG(6), ARG(7), ARG(8), ARG(9), ARG(10), ARG(11)); }
|
||||
};
|
||||
|
||||
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12>
|
||||
class binder_func_12 : public func_caller
|
||||
{
|
||||
typedef TR (*func_t)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12);
|
||||
const func_t m_call;
|
||||
|
||||
public:
|
||||
binder_func_12(func_t call) : func_caller(), m_call(call) {}
|
||||
virtual void operator()() { declCPU(); RESULT(m_call(ARG(1), ARG(2), ARG(3), ARG(4), ARG(5), ARG(6), ARG(7), ARG(8), ARG(9), ARG(10), ARG(11), ARG(12))); }
|
||||
};
|
||||
|
||||
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12>
|
||||
class binder_func_12<void, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> : public func_caller
|
||||
{
|
||||
typedef void (*func_t)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12);
|
||||
const func_t m_call;
|
||||
|
||||
public:
|
||||
binder_func_12(func_t call) : func_caller(), m_call(call) {}
|
||||
virtual void operator()() { declCPU(); m_call(ARG(1), ARG(2), ARG(3), ARG(4), ARG(5), ARG(6), ARG(7), ARG(8), ARG(9), ARG(10), ARG(11), ARG(12)); }
|
||||
};
|
||||
|
||||
#undef ARG
|
||||
|
||||
template<typename TR>
|
||||
func_caller* bind_func(TR (*call)())
|
||||
{
|
||||
return new binder_func_0<TR>(call);
|
||||
typedef typename std::decay<Tuple>::type ttype;
|
||||
return detail::call_impl<RT, F, Tuple, 0 == std::tuple_size<ttype>::value, std::tuple_size<ttype>::value>::call(f, std::forward<Tuple>(t));
|
||||
}
|
||||
|
||||
template<typename TR, typename T1>
|
||||
func_caller* bind_func(TR (*call)(T1))
|
||||
template<int g_count, int f_count, int v_count>
|
||||
static __forceinline std::tuple<> iterate(PPUThread& CPU)
|
||||
{
|
||||
return new binder_func_1<TR, T1>(call);
|
||||
return std::tuple<>();
|
||||
}
|
||||
|
||||
template<typename TR, typename T1, typename T2>
|
||||
func_caller* bind_func(TR (*call)(T1, T2))
|
||||
template<int g_count, int f_count, int v_count, typename T, typename... A>
|
||||
static __forceinline std::tuple<T, A...> iterate(PPUThread& CPU)
|
||||
{
|
||||
return new binder_func_2<TR, T1, T2>(call);
|
||||
// TODO: check calculations
|
||||
const bind_arg_type t = std::is_floating_point<T>::value
|
||||
? ((f_count >= 12) ? ARG_STACK : ARG_FLOAT)
|
||||
: ((g_count >= 8) ? ARG_STACK : ARG_GENERAL);
|
||||
const int g = g_count + (std::is_floating_point<T>::value ? 0 : 1);
|
||||
const int f = f_count + (std::is_floating_point<T>::value ? 1 : 0);
|
||||
const int v = v_count; // TODO: vector arguments support (if possible)
|
||||
static_assert(!v_count, "ARG_VECTOR not supported");
|
||||
static_assert(!std::is_pointer<T>::value, "Invalid function argument type: pointer");
|
||||
return std::tuple_cat<std::tuple<T>, std::tuple<A...>>(std::tuple<T>(bind_arg<T, t, g, f, v>::func(CPU)), iterate<g, f, v, A...>(CPU));
|
||||
}
|
||||
|
||||
template<typename TR, typename T1, typename T2, typename T3>
|
||||
func_caller* bind_func(TR (*call)(T1, T2, T3))
|
||||
template<typename RT, typename... TA>
|
||||
class func_binder;
|
||||
|
||||
template<typename... TA>
|
||||
class func_binder<void, TA...> : public func_caller
|
||||
{
|
||||
typedef void(*func_t)(TA...);
|
||||
const func_t m_call;
|
||||
|
||||
public:
|
||||
func_binder(func_t call)
|
||||
: func_caller()
|
||||
, m_call(call)
|
||||
{
|
||||
return new binder_func_3<TR, T1, T2, T3>(call);
|
||||
}
|
||||
|
||||
template<typename TR, typename T1, typename T2, typename T3, typename T4>
|
||||
func_caller* bind_func(TR (*call)(T1, T2, T3, T4))
|
||||
virtual void operator()()
|
||||
{
|
||||
declCPU();
|
||||
call<void>(m_call, iterate<0, 0, 0, TA...>(CPU));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename TR, typename... TA>
|
||||
class func_binder : public func_caller
|
||||
{
|
||||
typedef TR(*func_t)(TA...);
|
||||
const func_t m_call;
|
||||
|
||||
public:
|
||||
func_binder(func_t call)
|
||||
: func_caller()
|
||||
, m_call(call)
|
||||
{
|
||||
return new binder_func_4<TR, T1, T2, T3, T4>(call);
|
||||
}
|
||||
|
||||
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
func_caller* bind_func(TR (*call)(T1, T2, T3, T4, T5))
|
||||
virtual void operator()()
|
||||
{
|
||||
return new binder_func_5<TR, T1, T2, T3, T4, T5>(call);
|
||||
declCPU();
|
||||
bind_result<TR>::func(CPU, call<TR>(m_call, iterate<0, 0, 0, TA...>(CPU)));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
|
||||
func_caller* bind_func(TR (*call)(T1, T2, T3, T4, T5, T6))
|
||||
template<typename TR, typename... TA>
|
||||
func_caller* bind_func(TR(*call)(TA...))
|
||||
{
|
||||
return new binder_func_6<TR, T1, T2, T3, T4, T5, T6>(call);
|
||||
}
|
||||
|
||||
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
|
||||
func_caller* bind_func(TR (*call)(T1, T2, T3, T4, T5, T6, T7))
|
||||
{
|
||||
return new binder_func_7<TR, T1, T2, T3, T4, T5, T6, T7>(call);
|
||||
}
|
||||
|
||||
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
||||
func_caller* bind_func(TR (*call)(T1, T2, T3, T4, T5, T6, T7, T8))
|
||||
{
|
||||
return new binder_func_8<TR, T1, T2, T3, T4, T5, T6, T7, T8>(call);
|
||||
}
|
||||
|
||||
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
|
||||
func_caller* bind_func(TR (*call)(T1, T2, T3, T4, T5, T6, T7, T8, T9))
|
||||
{
|
||||
return new binder_func_9<TR, T1, T2, T3, T4, T5, T6, T7, T8, T9>(call);
|
||||
}
|
||||
|
||||
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10>
|
||||
func_caller* bind_func(TR (*call)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10))
|
||||
{
|
||||
return new binder_func_10<TR, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(call);
|
||||
}
|
||||
|
||||
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11>
|
||||
func_caller* bind_func(TR (*call)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11))
|
||||
{
|
||||
return new binder_func_11<TR, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(call);
|
||||
}
|
||||
|
||||
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12>
|
||||
func_caller* bind_func(TR (*call)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12))
|
||||
{
|
||||
return new binder_func_12<TR, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(call);
|
||||
return new detail::func_binder<TR, TA...>(call);
|
||||
}
|
@ -924,7 +924,7 @@ void default_syscall()
|
||||
case 988:
|
||||
LOG_WARNING(HLE, "SysCall 988! r3: 0x%llx, r4: 0x%llx, pc: 0x%llx",
|
||||
CPU.GPR[3], CPU.GPR[4], CPU.PC);
|
||||
RESULT(0);
|
||||
CPU.GPR[3] = 0;
|
||||
return;
|
||||
|
||||
case 999:
|
||||
@ -940,7 +940,7 @@ void default_syscall()
|
||||
}
|
||||
|
||||
LOG_ERROR(HLE, "Unknown syscall: %d - %08x", code, code);
|
||||
RESULT(0);
|
||||
CPU.GPR[3] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -963,7 +963,7 @@ void SysCalls::DoSyscall(u32 code)
|
||||
|
||||
LOG_ERROR(HLE, "TODO: %s", GetHLEFuncName(code).c_str());
|
||||
declCPU();
|
||||
RESULT(0);
|
||||
CPU.GPR[3] = 0;
|
||||
}
|
||||
|
||||
IdManager& SysCallBase::GetIdManager() const
|
||||
|
Loading…
x
Reference in New Issue
Block a user