mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-09 00:11:24 +12:00
CB_FUNC/SC_FUNC fixed
This commit is contained in:
parent
a1b1f6be63
commit
bd71c1200e
6 changed files with 157 additions and 77 deletions
|
@ -475,6 +475,7 @@ namespace psv_func_detail
|
||||||
|
|
||||||
static __forceinline void func(ARMv7Thread& CPU, T result)
|
static __forceinline void func(ARMv7Thread& CPU, T result)
|
||||||
{
|
{
|
||||||
|
CPU.GPR[0] = 0; // TODO
|
||||||
(T&)CPU.GPR[0] = result;
|
(T&)CPU.GPR[0] = result;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -811,4 +811,89 @@ public:
|
||||||
cpu_thread& args(std::initializer_list<std::string> values) override;
|
cpu_thread& args(std::initializer_list<std::string> values) override;
|
||||||
cpu_thread& run() override;
|
cpu_thread& run() override;
|
||||||
ppu_thread& gpr(uint index, u64 value);
|
ppu_thread& gpr(uint index, u64 value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T, size_t size = sizeof(T)>
|
||||||
|
struct cast_ppu_gpr
|
||||||
|
{
|
||||||
|
static_assert(sizeof(T) <= 8, "Type for cast_ppu_gpr is invalid (too big)");
|
||||||
|
|
||||||
|
static u64 func(const T& value)
|
||||||
|
{
|
||||||
|
u64 result = 0;
|
||||||
|
(T&)result = value;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct cast_ppu_gpr<T, 1>
|
||||||
|
{
|
||||||
|
static u64 func(const T& value)
|
||||||
|
{
|
||||||
|
return (u8&)value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct cast_ppu_gpr<T, 2>
|
||||||
|
{
|
||||||
|
static u64 func(const T& value)
|
||||||
|
{
|
||||||
|
return (u16&)value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct cast_ppu_gpr<T, 4>
|
||||||
|
{
|
||||||
|
static u64 func(const T& value)
|
||||||
|
{
|
||||||
|
return (u32&)value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct cast_ppu_gpr<T, 8>
|
||||||
|
{
|
||||||
|
static u64 func(const T& value)
|
||||||
|
{
|
||||||
|
return (u64&)value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct cast_ppu_gpr<s8, 1>
|
||||||
|
{
|
||||||
|
static u64 func(const s8& value)
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct cast_ppu_gpr<s16, 2>
|
||||||
|
{
|
||||||
|
static u64 func(const s16& value)
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct cast_ppu_gpr<s32, 4>
|
||||||
|
{
|
||||||
|
static u64 func(const s32& value)
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct cast_ppu_gpr<s64, 8>
|
||||||
|
{
|
||||||
|
static u64 func(const s64& value)
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "Memory.h"
|
#include "Memory.h"
|
||||||
|
|
||||||
|
class CPUThread;
|
||||||
|
|
||||||
namespace vm
|
namespace vm
|
||||||
{
|
{
|
||||||
enum memory_location : uint
|
enum memory_location : uint
|
||||||
|
@ -171,6 +173,9 @@ namespace vm
|
||||||
}
|
}
|
||||||
|
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
|
u32 stack_push(CPUThread& CPU, u32 size, u32 align, u32& old_pos);
|
||||||
|
void stack_pop(CPUThread& CPU, u32 addr, u32 old_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "vm_ref.h"
|
#include "vm_ref.h"
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
class CPUThread;
|
class CPUThread;
|
||||||
class PPUThread;
|
|
||||||
class SPUThread;
|
|
||||||
class ARMv7Thread;
|
|
||||||
|
|
||||||
namespace vm
|
namespace vm
|
||||||
{
|
{
|
||||||
|
@ -501,108 +498,102 @@ namespace vm
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
u32 stack_push(CPUThread& CPU, u32 size, u32 align, u32& old_pos);
|
|
||||||
void stack_pop(CPUThread& CPU, u32 addr, u32 old_pos);
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class stackvar
|
class stackvar
|
||||||
{
|
{
|
||||||
T* m_ptr;
|
struct stack_allocation
|
||||||
u32 m_addr;
|
|
||||||
u32 m_size;
|
|
||||||
u32 m_align;
|
|
||||||
u32 m_old_pos;
|
|
||||||
CPUThread& m_thread;
|
|
||||||
|
|
||||||
void alloc()
|
|
||||||
{
|
{
|
||||||
m_addr = stack_push(m_thread, m_size, m_align, m_old_pos);
|
T* ptr;
|
||||||
m_ptr = vm::get_ptr<T>(m_addr);
|
u32 addr;
|
||||||
}
|
u32 size;
|
||||||
|
u32 align;
|
||||||
|
u32 old_pos;
|
||||||
|
|
||||||
void dealloc()
|
stack_allocation(CPUThread& CPU, u32 size, u32 align)
|
||||||
{
|
: size(size)
|
||||||
if (m_addr)
|
, align(align)
|
||||||
{
|
{
|
||||||
stack_pop(m_thread, m_addr, m_old_pos);
|
addr = stack_push(CPU, size, align, old_pos);
|
||||||
m_addr = 0;
|
ptr = vm::get_ptr<T>(addr);
|
||||||
m_ptr = vm::get_ptr<T>(0u);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
stack_allocation() = delete;
|
||||||
|
stack_allocation(const stack_allocation& r) = delete;
|
||||||
|
stack_allocation(stack_allocation&& r) = delete;
|
||||||
|
stack_allocation& operator = (const stack_allocation& r) = delete;
|
||||||
|
stack_allocation& operator = (stack_allocation&& r) = delete;
|
||||||
|
|
||||||
|
} const m_data;
|
||||||
|
|
||||||
|
CPUThread& m_thread;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
stackvar(CPUThread& CPU, u32 size = sizeof(T), u32 align = __alignof(T))
|
stackvar(CPUThread& CPU, u32 size = sizeof(T), u32 align = __alignof(T))
|
||||||
: m_size(size)
|
: m_data(CPU, size, align)
|
||||||
, m_align(align)
|
|
||||||
, m_thread(CPU)
|
, m_thread(CPU)
|
||||||
{
|
{
|
||||||
alloc();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stackvar(const stackvar& r)
|
stackvar(const stackvar& r)
|
||||||
: m_size(r.m_size)
|
: m_data(r.m_thread, r.m_data.m_size, r.m_data.m_align)
|
||||||
, m_align(r.m_align)
|
|
||||||
, m_thread(r.m_thread)
|
, m_thread(r.m_thread)
|
||||||
{
|
{
|
||||||
alloc();
|
*m_data.ptr = *r.m_data.ptr;
|
||||||
*m_ptr = *r.m_ptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stackvar(stackvar&& r)
|
stackvar(stackvar&& r) = delete;
|
||||||
: m_ptr(r.m_ptr)
|
|
||||||
, m_addr(r.m_addr)
|
|
||||||
, m_size(r.m_size)
|
|
||||||
, m_align(r.m_align)
|
|
||||||
, m_old_pos(r.m_old_pos)
|
|
||||||
, m_thread(r.m_thread)
|
|
||||||
{
|
|
||||||
r.m_addr = 0;
|
|
||||||
r.m_ptr = vm::get_ptr<T>(0u);
|
|
||||||
}
|
|
||||||
|
|
||||||
~stackvar()
|
~stackvar()
|
||||||
{
|
{
|
||||||
dealloc();
|
stack_pop(m_thread, m_data.addr, m_data.old_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stackvar& operator = (const stackvar& r)
|
||||||
|
{
|
||||||
|
*m_data.ptr = *r.m_data.ptr;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
stackvar& operator = (stackvar&& r) = delete;
|
||||||
|
|
||||||
T* operator -> ()
|
T* operator -> ()
|
||||||
{
|
{
|
||||||
return m_ptr;
|
return m_data.ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const T* operator -> () const
|
const T* operator -> () const
|
||||||
{
|
{
|
||||||
return m_ptr;
|
return m_data.ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
T* get_ptr()
|
T* get_ptr()
|
||||||
{
|
{
|
||||||
return m_ptr;
|
return m_data.ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const T* get_ptr() const
|
const T* get_ptr() const
|
||||||
{
|
{
|
||||||
return m_ptr;
|
return m_data.ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
T& value()
|
T& value()
|
||||||
{
|
{
|
||||||
return *m_ptr;
|
return *m_data.ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const T& value() const
|
const T& value() const
|
||||||
{
|
{
|
||||||
return *m_ptr;
|
return *m_data.ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 addr() const
|
u32 addr() const
|
||||||
{
|
{
|
||||||
return m_addr;
|
return m_data.addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 size() const
|
u32 size() const
|
||||||
{
|
{
|
||||||
return m_size;
|
return m_data.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -614,22 +605,22 @@ namespace vm
|
||||||
|
|
||||||
template<typename AT> operator const ps3::ptr<T, 1, AT>() const
|
template<typename AT> operator const ps3::ptr<T, 1, AT>() const
|
||||||
{
|
{
|
||||||
return ps3::ptr<T, 1, AT>::make(m_addr);
|
return ps3::ptr<T, 1, AT>::make(m_data.addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename AT> operator const ps3::ptr<const T, 1, AT>() const
|
template<typename AT> operator const ps3::ptr<const T, 1, AT>() const
|
||||||
{
|
{
|
||||||
return ps3::ptr<const T, 1, AT>::make(m_addr);
|
return ps3::ptr<const T, 1, AT>::make(m_data.addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
operator T&()
|
operator T&()
|
||||||
{
|
{
|
||||||
return *m_ptr;
|
return *m_data.ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator const T&() const
|
operator const T&() const
|
||||||
{
|
{
|
||||||
return *m_ptr;
|
return *m_data.ptr;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -24,9 +24,9 @@ namespace cb_detail
|
||||||
{
|
{
|
||||||
static_assert(sizeof(T) <= 8, "Invalid callback argument type for ARG_GENERAL");
|
static_assert(sizeof(T) <= 8, "Invalid callback argument type for ARG_GENERAL");
|
||||||
|
|
||||||
__forceinline static void set_value(PPUThread& CPU, const T arg)
|
__forceinline static void set_value(PPUThread& CPU, const T& arg)
|
||||||
{
|
{
|
||||||
(T&)CPU.GPR[g_count + 2] = arg;
|
CPU.GPR[g_count + 2] = cast_ppu_gpr<T>::func(arg);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ namespace cb_detail
|
||||||
{
|
{
|
||||||
static_assert(sizeof(T) <= 8, "Invalid callback argument type for ARG_FLOAT");
|
static_assert(sizeof(T) <= 8, "Invalid callback argument type for ARG_FLOAT");
|
||||||
|
|
||||||
__forceinline static void set_value(PPUThread& CPU, const T arg)
|
__forceinline static void set_value(PPUThread& CPU, const T& arg)
|
||||||
{
|
{
|
||||||
CPU.FPR[f_count] = arg;
|
CPU.FPR[f_count] = arg;
|
||||||
}
|
}
|
||||||
|
@ -46,9 +46,9 @@ namespace cb_detail
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<T, u128>::value, "Invalid callback argument type for ARG_VECTOR");
|
static_assert(std::is_same<T, u128>::value, "Invalid callback argument type for ARG_VECTOR");
|
||||||
|
|
||||||
__forceinline static void set_value(PPUThread& CPU, const T arg)
|
__forceinline static void set_value(PPUThread& CPU, const T& arg)
|
||||||
{
|
{
|
||||||
(T&)CPU.VPR[v_count + 1] = arg;
|
CPU.VPR[v_count + 1] = arg;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -59,13 +59,11 @@ namespace cb_detail
|
||||||
static_assert(v_count <= 12, "TODO: Unsupported stack argument type (vector)");
|
static_assert(v_count <= 12, "TODO: Unsupported stack argument type (vector)");
|
||||||
static_assert(sizeof(T) <= 8, "Invalid callback argument type for ARG_STACK");
|
static_assert(sizeof(T) <= 8, "Invalid callback argument type for ARG_STACK");
|
||||||
|
|
||||||
__forceinline static void set_value(PPUThread& CPU, const T arg)
|
__forceinline static void set_value(PPUThread& CPU, const T& arg)
|
||||||
{
|
{
|
||||||
const int stack_pos = 0x70 + (g_count - 9) * 8 - FIXED_STACK_FRAME_SIZE;
|
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)");
|
static_assert(stack_pos < 0, "TODO: Increase fixed stack frame size (arg count limit broken)");
|
||||||
u64 value = 0;
|
vm::write64(CPU.GPR[1] + stack_pos, cast_ppu_gpr<T>::func(arg));
|
||||||
(T&)value = arg;
|
|
||||||
vm::write64(CPU.GPR[1] + stack_pos, value);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -121,11 +119,11 @@ namespace cb_detail
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct _func_res<T, ARG_VECTOR>
|
struct _func_res<T, ARG_VECTOR>
|
||||||
{
|
{
|
||||||
static_assert(sizeof(T) == 16, "Invalid callback result type for ARG_VECTOR");
|
static_assert(std::is_same<T, u128>::value, "Invalid callback result type for ARG_VECTOR");
|
||||||
|
|
||||||
__forceinline static T get_value(const PPUThread& CPU)
|
__forceinline static T get_value(const PPUThread& CPU)
|
||||||
{
|
{
|
||||||
return (T&)CPU.VPR[2];
|
return CPU.VPR[2];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -167,8 +165,8 @@ namespace vm
|
||||||
template<typename AT, typename RT, typename... T>
|
template<typename AT, typename RT, typename... T>
|
||||||
__forceinline RT _ptr_base<RT(*)(T...), 1, AT>::call(CPUThread& CPU, T... args) const
|
__forceinline RT _ptr_base<RT(*)(T...), 1, AT>::call(CPUThread& CPU, T... args) const
|
||||||
{
|
{
|
||||||
const u32 pc = vm::get_ref<be_t<u32>>(m_addr);
|
const u32 pc = vm::get_ref<be_t<u32>>((u32)m_addr);
|
||||||
const u32 rtoc = vm::get_ref<be_t<u32>>(m_addr + 4);
|
const u32 rtoc = vm::get_ref<be_t<u32>>((u32)m_addr + 4);
|
||||||
|
|
||||||
return cb_detail::_func_caller<RT, T...>::call(static_cast<PPUThread&>(CPU), pc, rtoc, args...);
|
return cb_detail::_func_caller<RT, T...>::call(static_cast<PPUThread&>(CPU), pc, rtoc, args...);
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,11 +46,11 @@ namespace detail
|
||||||
template<typename T, int g_count, int f_count, int v_count>
|
template<typename T, int g_count, int f_count, int v_count>
|
||||||
struct bind_arg<T, ARG_VECTOR, g_count, f_count, v_count>
|
struct bind_arg<T, ARG_VECTOR, g_count, f_count, v_count>
|
||||||
{
|
{
|
||||||
static_assert(sizeof(T) == 16, "Invalid function argument type for ARG_VECTOR");
|
static_assert(std::is_same<T, u128>::value, "Invalid function argument type for ARG_VECTOR");
|
||||||
|
|
||||||
static __forceinline T func(PPUThread& CPU)
|
static __forceinline T func(PPUThread& CPU)
|
||||||
{
|
{
|
||||||
return (T&)CPU.VPR[v_count + 1];
|
return CPU.VPR[v_count + 1];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -75,9 +75,9 @@ namespace detail
|
||||||
static_assert(type == ARG_GENERAL, "Wrong use of bind_result template");
|
static_assert(type == ARG_GENERAL, "Wrong use of bind_result template");
|
||||||
static_assert(sizeof(T) <= 8, "Invalid function result type for ARG_GENERAL");
|
static_assert(sizeof(T) <= 8, "Invalid function result type for ARG_GENERAL");
|
||||||
|
|
||||||
static __forceinline void func(PPUThread& CPU, T result)
|
static __forceinline void func(PPUThread& CPU, const T& result)
|
||||||
{
|
{
|
||||||
(T&)CPU.GPR[3] = result;
|
CPU.GPR[3] = cast_ppu_gpr<T>::func(result);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ namespace detail
|
||||||
{
|
{
|
||||||
static_assert(sizeof(T) <= 8, "Invalid function result type for ARG_FLOAT");
|
static_assert(sizeof(T) <= 8, "Invalid function result type for ARG_FLOAT");
|
||||||
|
|
||||||
static __forceinline void func(PPUThread& CPU, T result)
|
static __forceinline void func(PPUThread& CPU, const T& result)
|
||||||
{
|
{
|
||||||
CPU.FPR[1] = (double)result;
|
CPU.FPR[1] = (double)result;
|
||||||
}
|
}
|
||||||
|
@ -95,11 +95,11 @@ namespace detail
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct bind_result<T, ARG_VECTOR>
|
struct bind_result<T, ARG_VECTOR>
|
||||||
{
|
{
|
||||||
static_assert(sizeof(T) == 16, "Invalid function result type for ARG_VECTOR");
|
static_assert(std::is_same<T, u128>::value, "Invalid function result type for ARG_VECTOR");
|
||||||
|
|
||||||
static __forceinline void func(PPUThread& CPU, const T result)
|
static __forceinline void func(PPUThread& CPU, const T& result)
|
||||||
{
|
{
|
||||||
(T&)CPU.VPR[2] = result;
|
CPU.VPR[2] = result;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue