mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 03:25:16 +00: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)
|
||||
{
|
||||
CPU.GPR[0] = 0; // TODO
|
||||
(T&)CPU.GPR[0] = result;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -811,4 +811,89 @@ public:
|
|||
cpu_thread& args(std::initializer_list<std::string> values) override;
|
||||
cpu_thread& run() override;
|
||||
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
|
||||
#include "Memory.h"
|
||||
|
||||
class CPUThread;
|
||||
|
||||
namespace vm
|
||||
{
|
||||
enum memory_location : uint
|
||||
|
@ -171,6 +173,9 @@ namespace vm
|
|||
}
|
||||
|
||||
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"
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
class CPUThread;
|
||||
class PPUThread;
|
||||
class SPUThread;
|
||||
class ARMv7Thread;
|
||||
|
||||
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>
|
||||
class stackvar
|
||||
{
|
||||
T* m_ptr;
|
||||
u32 m_addr;
|
||||
u32 m_size;
|
||||
u32 m_align;
|
||||
u32 m_old_pos;
|
||||
CPUThread& m_thread;
|
||||
|
||||
void alloc()
|
||||
struct stack_allocation
|
||||
{
|
||||
m_addr = stack_push(m_thread, m_size, m_align, m_old_pos);
|
||||
m_ptr = vm::get_ptr<T>(m_addr);
|
||||
}
|
||||
T* ptr;
|
||||
u32 addr;
|
||||
u32 size;
|
||||
u32 align;
|
||||
u32 old_pos;
|
||||
|
||||
void dealloc()
|
||||
{
|
||||
if (m_addr)
|
||||
stack_allocation(CPUThread& CPU, u32 size, u32 align)
|
||||
: size(size)
|
||||
, align(align)
|
||||
{
|
||||
stack_pop(m_thread, m_addr, m_old_pos);
|
||||
m_addr = 0;
|
||||
m_ptr = vm::get_ptr<T>(0u);
|
||||
addr = stack_push(CPU, size, align, old_pos);
|
||||
ptr = vm::get_ptr<T>(addr);
|
||||
}
|
||||
}
|
||||
|
||||
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:
|
||||
stackvar(CPUThread& CPU, u32 size = sizeof(T), u32 align = __alignof(T))
|
||||
: m_size(size)
|
||||
, m_align(align)
|
||||
: m_data(CPU, size, align)
|
||||
, m_thread(CPU)
|
||||
{
|
||||
alloc();
|
||||
}
|
||||
|
||||
stackvar(const stackvar& r)
|
||||
: m_size(r.m_size)
|
||||
, m_align(r.m_align)
|
||||
: m_data(r.m_thread, r.m_data.m_size, r.m_data.m_align)
|
||||
, m_thread(r.m_thread)
|
||||
{
|
||||
alloc();
|
||||
*m_ptr = *r.m_ptr;
|
||||
*m_data.ptr = *r.m_data.ptr;
|
||||
}
|
||||
|
||||
stackvar(stackvar&& r)
|
||||
: 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&& r) = delete;
|
||||
|
||||
~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 -> ()
|
||||
{
|
||||
return m_ptr;
|
||||
return m_data.ptr;
|
||||
}
|
||||
|
||||
const T* operator -> () const
|
||||
{
|
||||
return m_ptr;
|
||||
return m_data.ptr;
|
||||
}
|
||||
|
||||
T* get_ptr()
|
||||
{
|
||||
return m_ptr;
|
||||
return m_data.ptr;
|
||||
}
|
||||
|
||||
const T* get_ptr() const
|
||||
{
|
||||
return m_ptr;
|
||||
return m_data.ptr;
|
||||
}
|
||||
|
||||
T& value()
|
||||
{
|
||||
return *m_ptr;
|
||||
return *m_data.ptr;
|
||||
}
|
||||
|
||||
const T& value() const
|
||||
{
|
||||
return *m_ptr;
|
||||
return *m_data.ptr;
|
||||
}
|
||||
|
||||
u32 addr() const
|
||||
{
|
||||
return m_addr;
|
||||
return m_data.addr;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
return ps3::ptr<const T, 1, AT>::make(m_addr);
|
||||
return ps3::ptr<const T, 1, AT>::make(m_data.addr);
|
||||
}
|
||||
|
||||
operator T&()
|
||||
{
|
||||
return *m_ptr;
|
||||
return *m_data.ptr;
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
__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");
|
||||
|
||||
__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;
|
||||
}
|
||||
|
@ -46,9 +46,9 @@ namespace cb_detail
|
|||
{
|
||||
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(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;
|
||||
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);
|
||||
vm::write64(CPU.GPR[1] + stack_pos, cast_ppu_gpr<T>::func(arg));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -121,11 +119,11 @@ namespace cb_detail
|
|||
template<typename T>
|
||||
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)
|
||||
{
|
||||
return (T&)CPU.VPR[2];
|
||||
return CPU.VPR[2];
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -167,8 +165,8 @@ namespace vm
|
|||
template<typename AT, typename RT, typename... T>
|
||||
__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 rtoc = vm::get_ref<be_t<u32>>(m_addr + 4);
|
||||
const u32 pc = vm::get_ref<be_t<u32>>((u32)m_addr);
|
||||
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...);
|
||||
}
|
||||
|
|
|
@ -46,11 +46,11 @@ namespace detail
|
|||
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_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)
|
||||
{
|
||||
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(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 __forceinline void func(PPUThread& CPU, T result)
|
||||
static __forceinline void func(PPUThread& CPU, const T& result)
|
||||
{
|
||||
CPU.FPR[1] = (double)result;
|
||||
}
|
||||
|
@ -95,11 +95,11 @@ namespace detail
|
|||
template<typename T>
|
||||
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
Reference in a new issue