1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-22 10:42:36 +01:00

Merge pull request #955 from Nekotekina/master

vm::stackvar, callback args and syscall results fixed
This commit is contained in:
B1ackDaemon 2015-01-08 00:58:24 +02:00
commit 1d0f2c16e0
14 changed files with 356 additions and 64 deletions

View File

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

View File

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

View File

@ -1,5 +1,7 @@
#include "stdafx.h"
#include "Memory.h"
#include "Emu/CPU/CPUThread.h"
#include "Emu/Cell/PPUThread.h"
namespace vm
{
@ -143,4 +145,84 @@ namespace vm
{
Memory.Close();
}
u32 stack_push(CPUThread& CPU, u32 size, u32 align_v, u32& old_pos)
{
switch (CPU.GetType())
{
case CPU_THREAD_PPU:
{
PPUThread& PPU = static_cast<PPUThread&>(CPU);
assert(align_v);
old_pos = (u32)PPU.GPR[1];
PPU.GPR[1] -= align(size, 8); // room minimal possible size
PPU.GPR[1] &= ~(align_v - 1); // fix stack alignment
if (PPU.GPR[1] < CPU.GetStackAddr())
{
// stack overflow
PPU.GPR[1] = old_pos;
return 0;
}
else
{
return (u32)PPU.GPR[1];
}
}
case CPU_THREAD_SPU:
case CPU_THREAD_RAW_SPU:
{
assert(!"stack_push(): SPU not supported");
return 0;
}
case CPU_THREAD_ARMv7:
{
assert(!"stack_push(): ARMv7 not supported");
return 0;
}
default:
{
assert(!"stack_push(): invalid thread type");
return 0;
}
}
}
void stack_pop(CPUThread& CPU, u32 addr, u32 old_pos)
{
switch (CPU.GetType())
{
case CPU_THREAD_PPU:
{
PPUThread& PPU = static_cast<PPUThread&>(CPU);
assert(PPU.GPR[1] == addr);
PPU.GPR[1] = old_pos;
return;
}
case CPU_THREAD_SPU:
case CPU_THREAD_RAW_SPU:
{
assert(!"stack_pop(): SPU not supported");
return;
}
case CPU_THREAD_ARMv7:
{
assert(!"stack_pop(): ARMv7 not supported");
return;
}
default:
{
assert(!"stack_pop(): invalid thread type");
return;
}
}
}
}

View File

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

View File

@ -1,5 +1,7 @@
#pragma once
class CPUThread;
namespace vm
{
template<typename T>
@ -495,4 +497,130 @@ namespace vm
return (NT*)(m_ptr + offset);
}
};
template<typename T>
class stackvar
{
struct stack_allocation
{
T* ptr;
u32 addr;
u32 size;
u32 align;
u32 old_pos;
stack_allocation(CPUThread& CPU, u32 size, u32 align)
: size(size)
, align(align)
{
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_data(CPU, size, align)
, m_thread(CPU)
{
}
stackvar(const stackvar& r)
: m_data(r.m_thread, r.m_data.m_size, r.m_data.m_align)
, m_thread(r.m_thread)
{
*m_data.ptr = *r.m_data.ptr;
}
stackvar(stackvar&& r) = delete;
~stackvar()
{
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_data.ptr;
}
const T* operator -> () const
{
return m_data.ptr;
}
T* get_ptr()
{
return m_data.ptr;
}
const T* get_ptr() const
{
return m_data.ptr;
}
T& value()
{
return *m_data.ptr;
}
const T& value() const
{
return *m_data.ptr;
}
u32 addr() const
{
return m_data.addr;
}
u32 size() const
{
return m_data.size;
}
/*
operator const ref<T>() const
{
return addr();
}
*/
template<typename AT> operator const ps3::ptr<T, 1, AT>() const
{
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_data.addr);
}
operator T&()
{
return *m_data.ptr;
}
operator const T&() const
{
return *m_data.ptr;
}
};
}

View File

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

View File

@ -36,11 +36,11 @@ int cellFontGetRevisionFlags(vm::ptr<be_t<u64>> revisionFlags)
return CELL_FONT_OK;
}
int cellFontInit(vm::ptr<CellFontConfig> config)
int cellFontInit(PPUThread& CPU, vm::ptr<CellFontConfig> config)
{
cellFont->Log("cellFontInit(config=0x%x)", config.addr());
vm::var<be_t<u64>> revisionFlags;
vm::stackvar<be_t<u64>> revisionFlags(CPU);
revisionFlags.value() = 0;
cellFontGetRevisionFlags(revisionFlags);
return cellFontInitializeWithRevision(revisionFlags.value(), config);
@ -101,7 +101,7 @@ int cellFontOpenFontFile(vm::ptr<CellFontLibrary> library, vm::ptr<const char> f
return ret;
}
int cellFontOpenFontset(vm::ptr<CellFontLibrary> library, vm::ptr<CellFontType> fontType, vm::ptr<CellFont> font)
int cellFontOpenFontset(PPUThread& CPU, vm::ptr<CellFontLibrary> library, vm::ptr<CellFontType> fontType, vm::ptr<CellFont> font)
{
cellFont->Log("cellFontOpenFontset(library_addr=0x%x, fontType_addr=0x%x, font_addr=0x%x)",
library.addr(), fontType.addr(), font.addr());
@ -177,7 +177,7 @@ int cellFontOpenFontset(vm::ptr<CellFontLibrary> library, vm::ptr<CellFontType>
return CELL_FONT_ERROR_NO_SUPPORT_FONTSET;
}
vm::var<char> f((u32)file.length() + 1, 1);
vm::stackvar<char> f(CPU, (u32)file.length() + 1, 1);
memcpy(f.get_ptr(), file.c_str(), file.size() + 1);
int ret = cellFontOpenFontFile(library, f, 0, 0, font); //TODO: Find the correct values of subNum, uniqueId
font->origin = CELL_FONT_OPEN_FONTSET;

View File

@ -201,7 +201,7 @@ int cellGameContentPermit(vm::ptr<char[CELL_GAME_PATH_MAX]> contentInfoPath, vm:
return CELL_GAME_RET_OK;
}
int cellGameDataCheckCreate2(u32 version, vm::ptr<const char> dirName, u32 errDialog,
int cellGameDataCheckCreate2(PPUThread& CPU, u32 version, vm::ptr<const char> dirName, u32 errDialog,
vm::ptr<void(*)(vm::ptr<CellGameDataCBResult> cbResult, vm::ptr<CellGameDataStatGet> get, vm::ptr<CellGameDataStatSet> set)> funcStat, u32 container)
{
cellGame->Warning("cellGameDataCheckCreate(2)(version=0x%x, dirName_addr=0x%x, errDialog=0x%x, funcStat_addr=0x%x, container=%d)",
@ -238,10 +238,9 @@ int cellGameDataCheckCreate2(u32 version, vm::ptr<const char> dirName, u32 errDi
return CELL_GAMEDATA_ERROR_BROKEN;
}
// TODO: use memory container
vm::var<CellGameDataCBResult> cbResult;
vm::var<CellGameDataStatGet> cbGet;
vm::var<CellGameDataStatSet> cbSet;
vm::stackvar<CellGameDataCBResult> cbResult(CPU);
vm::stackvar<CellGameDataStatGet> cbGet(CPU);
vm::stackvar<CellGameDataStatSet> cbSet(CPU);
cbGet.value() = {};
@ -307,11 +306,11 @@ int cellGameDataCheckCreate2(u32 version, vm::ptr<const char> dirName, u32 errDi
}
}
int cellGameDataCheckCreate(u32 version, vm::ptr<const char> dirName, u32 errDialog,
int cellGameDataCheckCreate(PPUThread& CPU, u32 version, vm::ptr<const char> dirName, u32 errDialog,
vm::ptr<void(*)(vm::ptr<CellGameDataCBResult> cbResult, vm::ptr<CellGameDataStatGet> get, vm::ptr<CellGameDataStatSet> set)> funcStat, u32 container)
{
// TODO: almost identical, the only difference is that this function will always calculate the size of game data
return cellGameDataCheckCreate2(version, dirName, errDialog, funcStat, container);
return cellGameDataCheckCreate2(CPU, version, dirName, errDialog, funcStat, container);
}
int cellGameCreateGameData(vm::ptr<CellGameSetInitParams> init, vm::ptr<char> tmp_contentInfoPath, vm::ptr<char> tmp_usrdirPath)

View File

@ -199,4 +199,4 @@ struct CellGameDataStatSet
{
vm::bptr<CellGameDataSystemFileParam> setParam;
be_t<u32> reserved;
};
};

View File

@ -1287,7 +1287,7 @@ s32 _cellSyncLFQueueCompletePushPointer2(vm::ptr<CellSyncLFQueue> queue, s32 poi
return syncLFQueueCompletePushPointer2(queue, pointer, fpSendSignal);
}
s32 _cellSyncLFQueuePushBody(vm::ptr<CellSyncLFQueue> queue, vm::ptr<const void> buffer, u32 isBlocking)
s32 _cellSyncLFQueuePushBody(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, vm::ptr<const void> buffer, u32 isBlocking)
{
// cellSyncLFQueuePush has 1 in isBlocking param, cellSyncLFQueueTryPush has 0
cellSync->Warning("_cellSyncLFQueuePushBody(queue_addr=0x%x, buffer_addr=0x%x, isBlocking=%d)", queue.addr(), buffer.addr(), isBlocking);
@ -1302,10 +1302,8 @@ s32 _cellSyncLFQueuePushBody(vm::ptr<CellSyncLFQueue> queue, vm::ptr<const void>
}
s32 position;
//syncLFQueueDump(queue);
#ifdef PRX_DEBUG
vm::var<be_t<s32>> position_v;
vm::stackvar<be_t<s32>> position_v(CPU);
#endif
while (true)
{
@ -1314,7 +1312,7 @@ s32 _cellSyncLFQueuePushBody(vm::ptr<CellSyncLFQueue> queue, vm::ptr<const void>
if (queue->m_direction != CELL_SYNC_QUEUE_ANY2ANY)
{
#ifdef PRX_DEBUG_XXX
res = cb_caller<s32, vm::ptr<CellSyncLFQueue>, u32, u32, u64>::call(GetCurrentPPUThread(), libsre + 0x24B0, libsre_rtoc,
res = cb_call<s32, vm::ptr<CellSyncLFQueue>, u32, u32, u64>(CPU, libsre + 0x24B0, libsre_rtoc,
queue, position_v.addr(), isBlocking, 0);
position = position_v->ToLE();
#else
@ -1324,7 +1322,7 @@ s32 _cellSyncLFQueuePushBody(vm::ptr<CellSyncLFQueue> queue, vm::ptr<const void>
else
{
#ifdef PRX_DEBUG
res = cb_call<s32, vm::ptr<CellSyncLFQueue>, u32, u32, u64>(GetCurrentPPUThread(), libsre + 0x3050, libsre_rtoc,
res = cb_call<s32, vm::ptr<CellSyncLFQueue>, u32, u32, u64>(CPU, libsre + 0x3050, libsre_rtoc,
queue, position_v.addr(), isBlocking, 0);
position = position_v->ToLE();
#else
@ -1332,9 +1330,6 @@ s32 _cellSyncLFQueuePushBody(vm::ptr<CellSyncLFQueue> queue, vm::ptr<const void>
#endif
}
//LOG_NOTICE(HLE, "... position = %d", position);
//syncLFQueueDump(queue);
if (!isBlocking || res != CELL_SYNC_ERROR_AGAIN)
{
if (res)
@ -1360,7 +1355,7 @@ s32 _cellSyncLFQueuePushBody(vm::ptr<CellSyncLFQueue> queue, vm::ptr<const void>
if (queue->m_direction != CELL_SYNC_QUEUE_ANY2ANY)
{
#ifdef PRX_DEBUG_XXX
res = cb_caller<s32, vm::ptr<CellSyncLFQueue>, s32, u64>::call(GetCurrentPPUThread(), libsre + 0x26C0, libsre_rtoc,
res = cb_call<s32, vm::ptr<CellSyncLFQueue>, s32, u64>(CPU, libsre + 0x26C0, libsre_rtoc,
queue, position, 0);
#else
res = syncLFQueueCompletePushPointer(queue, position, nullptr);
@ -1369,14 +1364,13 @@ s32 _cellSyncLFQueuePushBody(vm::ptr<CellSyncLFQueue> queue, vm::ptr<const void>
else
{
#ifdef PRX_DEBUG
res = cb_call<s32, vm::ptr<CellSyncLFQueue>, s32, u64>(GetCurrentPPUThread(), libsre + 0x355C, libsre_rtoc,
res = cb_call<s32, vm::ptr<CellSyncLFQueue>, s32, u64>(CPU, libsre + 0x355C, libsre_rtoc,
queue, position, 0);
#else
res = syncLFQueueCompletePushPointer2(queue, position, nullptr);
#endif
}
//syncLFQueueDump(queue);
return res;
}
@ -1669,7 +1663,7 @@ s32 _cellSyncLFQueueCompletePopPointer2(vm::ptr<CellSyncLFQueue> queue, s32 poin
return syncLFQueueCompletePopPointer2(queue, pointer, fpSendSignal, noQueueFull);
}
s32 _cellSyncLFQueuePopBody(vm::ptr<CellSyncLFQueue> queue, vm::ptr<void> buffer, u32 isBlocking)
s32 _cellSyncLFQueuePopBody(PPUThread& CPU, vm::ptr<CellSyncLFQueue> queue, vm::ptr<void> buffer, u32 isBlocking)
{
// cellSyncLFQueuePop has 1 in isBlocking param, cellSyncLFQueueTryPop has 0
cellSync->Warning("_cellSyncLFQueuePopBody(queue_addr=0x%x, buffer_addr=0x%x, isBlocking=%d)", queue.addr(), buffer.addr(), isBlocking);
@ -1685,7 +1679,7 @@ s32 _cellSyncLFQueuePopBody(vm::ptr<CellSyncLFQueue> queue, vm::ptr<void> buffer
s32 position;
#ifdef PRX_DEBUG
vm::var<be_t<s32>> position_v;
vm::stackvar<be_t<s32>> position_v(CPU);
#endif
while (true)
{
@ -1693,7 +1687,7 @@ s32 _cellSyncLFQueuePopBody(vm::ptr<CellSyncLFQueue> queue, vm::ptr<void> buffer
if (queue->m_direction != CELL_SYNC_QUEUE_ANY2ANY)
{
#ifdef PRX_DEBUG_XXX
res = cb_caller<s32, vm::ptr<CellSyncLFQueue>, u32, u32, u64, u64>::call(GetCurrentPPUThread(), libsre + 0x2A90, libsre_rtoc,
res = cb_call<s32, vm::ptr<CellSyncLFQueue>, u32, u32, u64, u64>(CPU, libsre + 0x2A90, libsre_rtoc,
queue, position_v.addr(), isBlocking, 0, 0);
position = position_v->ToLE();
#else
@ -1703,7 +1697,7 @@ s32 _cellSyncLFQueuePopBody(vm::ptr<CellSyncLFQueue> queue, vm::ptr<void> buffer
else
{
#ifdef PRX_DEBUG
res = cb_call<s32, vm::ptr<CellSyncLFQueue>, u32, u32, u64>(GetCurrentPPUThread(), libsre + 0x39AC, libsre_rtoc,
res = cb_call<s32, vm::ptr<CellSyncLFQueue>, u32, u32, u64>(CPU, libsre + 0x39AC, libsre_rtoc,
queue, position_v.addr(), isBlocking, 0);
position = position_v->ToLE();
#else
@ -1736,7 +1730,7 @@ s32 _cellSyncLFQueuePopBody(vm::ptr<CellSyncLFQueue> queue, vm::ptr<void> buffer
if (queue->m_direction != CELL_SYNC_QUEUE_ANY2ANY)
{
#ifdef PRX_DEBUG_XXX
res = cb_caller<s32, vm::ptr<CellSyncLFQueue>, s32, u64, u64>::call(GetCurrentPPUThread(), libsre + 0x2CA8, libsre_rtoc,
res = cb_call<s32, vm::ptr<CellSyncLFQueue>, s32, u64, u64>(CPU, libsre + 0x2CA8, libsre_rtoc,
queue, position, 0, 0);
#else
res = syncLFQueueCompletePopPointer(queue, position, nullptr, 0);
@ -1745,7 +1739,7 @@ s32 _cellSyncLFQueuePopBody(vm::ptr<CellSyncLFQueue> queue, vm::ptr<void> buffer
else
{
#ifdef PRX_DEBUG
res = cb_call<s32, vm::ptr<CellSyncLFQueue>, s32, u64, u64>(GetCurrentPPUThread(), libsre + 0x3EB8, libsre_rtoc,
res = cb_call<s32, vm::ptr<CellSyncLFQueue>, s32, u64, u64>(CPU, libsre + 0x3EB8, libsre_rtoc,
queue, position, 0, 0);
#else
res = syncLFQueueCompletePopPointer2(queue, position, nullptr, 0);

View File

@ -835,10 +835,10 @@ int cellWebBrowserEstimate2(const vm::ptr<const CellWebBrowserConfig2> config, v
return CELL_OK;
}
extern int cellGameDataCheckCreate2(u32 version, vm::ptr<const char> dirName, u32 errDialog,
extern int cellGameDataCheckCreate2(PPUThread& CPU, u32 version, vm::ptr<const char> dirName, u32 errDialog,
vm::ptr<void(*)(vm::ptr<CellGameDataCBResult> cbResult, vm::ptr<CellGameDataStatGet> get, vm::ptr<CellGameDataStatSet> set)> funcStat, u32 container);
extern int cellGameDataCheckCreate(u32 version, vm::ptr<const char> dirName, u32 errDialog,
extern int cellGameDataCheckCreate(PPUThread& CPU, u32 version, vm::ptr<const char> dirName, u32 errDialog,
vm::ptr<void(*)(vm::ptr<CellGameDataCBResult> cbResult, vm::ptr<CellGameDataStatGet> get, vm::ptr<CellGameDataStatSet> set)> funcStat, u32 container);
extern void cellSysutil_SaveData_init();

View File

@ -286,7 +286,7 @@ s32 _sys_spu_printf_finalize()
return CELL_OK;
}
s64 _sys_spu_printf_attach_group(u32 group)
s32 _sys_spu_printf_attach_group(PPUThread& CPU, u32 group)
{
sysPrxForUser->Warning("_sys_spu_printf_attach_group(group=%d)", group);
@ -295,10 +295,10 @@ s64 _sys_spu_printf_attach_group(u32 group)
return CELL_ESTAT;
}
return spu_printf_agcb(group);
return spu_printf_agcb.call(CPU, group);
}
s64 _sys_spu_printf_detach_group(u32 group)
s32 _sys_spu_printf_detach_group(PPUThread& CPU, u32 group)
{
sysPrxForUser->Warning("_sys_spu_printf_detach_group(group=%d)", group);
@ -307,10 +307,10 @@ s64 _sys_spu_printf_detach_group(u32 group)
return CELL_ESTAT;
}
return spu_printf_dgcb(group);
return spu_printf_dgcb.call(CPU, group);
}
s64 _sys_spu_printf_attach_thread(u32 thread)
s32 _sys_spu_printf_attach_thread(PPUThread& CPU, u32 thread)
{
sysPrxForUser->Warning("_sys_spu_printf_attach_thread(thread=%d)", thread);
@ -319,10 +319,10 @@ s64 _sys_spu_printf_attach_thread(u32 thread)
return CELL_ESTAT;
}
return spu_printf_atcb(thread);
return spu_printf_atcb.call(CPU, thread);
}
s64 _sys_spu_printf_detach_thread(u32 thread)
s32 _sys_spu_printf_detach_thread(PPUThread& CPU, u32 thread)
{
sysPrxForUser->Warning("_sys_spu_printf_detach_thread(thread=%d)", thread);
@ -331,7 +331,7 @@ s64 _sys_spu_printf_detach_thread(u32 thread)
return CELL_ESTAT;
}
return spu_printf_dtcb(thread);
return spu_printf_dtcb.call(CPU, thread);
}
s32 _sys_snprintf(vm::ptr<char> dst, u32 count, vm::ptr<const char> fmt) // va_args...

View File

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

View File

@ -1000,13 +1000,13 @@ int cellFsAioFinish(vm::ptr<const char> mount_point)
return CELL_OK;
}
int cellFsReadWithOffset(u32 fd, u64 offset, vm::ptr<void> buf, u64 buffer_size, vm::ptr<be_t<u64>> nread)
int cellFsReadWithOffset(PPUThread& CPU, u32 fd, u64 offset, vm::ptr<void> buf, u64 buffer_size, vm::ptr<be_t<u64>> nread)
{
sys_fs->Warning("cellFsReadWithOffset(fd=%d, offset=0x%llx, buf_addr=0x%x, buffer_size=%lld nread=0x%llx)",
fd, offset, buf.addr(), buffer_size, nread.addr());
int ret;
vm::var<be_t<u64>> oldPos, newPos;
vm::stackvar<be_t<u64>> oldPos(CPU), newPos(CPU);
ret = cellFsLseek(fd, 0, CELL_SEEK_CUR, oldPos); // Save the current position
if (ret) return ret;
ret = cellFsLseek(fd, offset, CELL_SEEK_SET, newPos); // Move to the specified offset