SPU ASMJIT: internal jumptable

Allow indirect calls within current function using a jumptable
This restores some functionality removed in SPU ASMJIT 2.0
Change SPUThread::get_ch_value prototype
This commit is contained in:
Nekotekina
2018-04-30 19:39:06 +03:00
parent df453d6d4f
commit 767dfa271e
7 changed files with 302 additions and 229 deletions
+14 -23
View File
@@ -133,12 +133,8 @@ bool spursDma(SPUThread& spu, u32 cmd, u64 ea, u32 lsa, u32 size, u32 tag)
if (cmd == MFC_GETLLAR_CMD || cmd == MFC_PUTLLC_CMD || cmd == MFC_PUTLLUC_CMD)
{
u32 rv;
spu.get_ch_value(MFC_RdAtomicStat, rv);
auto success = rv ? true : false;
success = cmd == MFC_PUTLLC_CMD ? !success : success;
return success;
const u32 rv = spu.get_ch_value(MFC_RdAtomicStat);
return cmd == MFC_PUTLLC_CMD ? !rv : true;
}
return true;
@@ -149,7 +145,7 @@ u32 spursDmaGetCompletionStatus(SPUThread& spu, u32 tagMask)
{
spu.set_ch_value(MFC_WrTagMask, tagMask);
spu.set_ch_value(MFC_WrTagUpdate, MFC_TAG_UPDATE_IMMEDIATE);
u32 rv; spu.get_ch_value(MFC_RdTagStat, rv); return rv;
return spu.get_ch_value(MFC_RdTagStat);
}
// Wait for DMA operations to complete
@@ -157,7 +153,7 @@ u32 spursDmaWaitForCompletion(SPUThread& spu, u32 tagMask, bool waitForAll)
{
spu.set_ch_value(MFC_WrTagMask, tagMask);
spu.set_ch_value(MFC_WrTagUpdate, waitForAll ? MFC_TAG_UPDATE_ALL : MFC_TAG_UPDATE_ANY);
u32 rv; spu.get_ch_value(MFC_RdTagStat, rv); return rv;
return spu.get_ch_value(MFC_RdTagStat);
}
// Halt the SPU
@@ -168,16 +164,15 @@ void spursHalt(SPUThread& spu)
void sys_spu_thread_exit(SPUThread& spu, s32 status)
{
u32 _v;
// Cancel any pending status update requests
spu.set_ch_value(MFC_WrTagUpdate, 0);
while (spu.get_ch_count(MFC_RdTagStat) != 1);
spu.get_ch_value(MFC_RdTagStat, _v);
spu.get_ch_value(MFC_RdTagStat);
// Wait for all pending DMA operations to complete
spu.set_ch_value(MFC_WrTagMask, 0xFFFFFFFF);
spu.set_ch_value(MFC_WrTagUpdate, MFC_TAG_UPDATE_ALL);
spu.get_ch_value(MFC_RdTagStat, _v);
spu.get_ch_value(MFC_RdTagStat);
spu.set_ch_value(SPU_WrOutMbox, status);
spu.stop_and_signal(0x102);
@@ -185,16 +180,15 @@ void sys_spu_thread_exit(SPUThread& spu, s32 status)
void sys_spu_thread_group_exit(SPUThread& spu, s32 status)
{
u32 _v;
// Cancel any pending status update requests
spu.set_ch_value(MFC_WrTagUpdate, 0);
while (spu.get_ch_count(MFC_RdTagStat) != 1);
spu.get_ch_value(MFC_RdTagStat, _v);
spu.get_ch_value(MFC_RdTagStat);
// Wait for all pending DMA operations to complete
spu.set_ch_value(MFC_WrTagMask, 0xFFFFFFFF);
spu.set_ch_value(MFC_WrTagUpdate, MFC_TAG_UPDATE_ALL);
spu.get_ch_value(MFC_RdTagStat, _v);
spu.get_ch_value(MFC_RdTagStat);
spu.set_ch_value(SPU_WrOutMbox, status);
spu.stop_and_signal(0x101);
@@ -214,9 +208,7 @@ s32 sys_spu_thread_send_event(SPUThread& spu, u8 spup, u32 data0, u32 data1)
spu.set_ch_value(SPU_WrOutMbox, data1);
spu.set_ch_value(SPU_WrOutIntrMbox, (spup << 24) | (data0 & 0x00FFFFFF));
spu.get_ch_value(SPU_RdInMbox, data0);
return data0;
return static_cast<u32>(spu.get_ch_value(SPU_RdInMbox));
}
s32 sys_spu_thread_switch_system_module(SPUThread& spu, u32 status)
@@ -231,18 +223,18 @@ s32 sys_spu_thread_switch_system_module(SPUThread& spu, u32 status)
// Cancel any pending status update requests
spu.set_ch_value(MFC_WrTagUpdate, 0);
while (spu.get_ch_count(MFC_RdTagStat) != 1);
spu.get_ch_value(MFC_RdTagStat, result);
spu.get_ch_value(MFC_RdTagStat);
// Wait for all pending DMA operations to complete
spu.set_ch_value(MFC_WrTagMask, 0xFFFFFFFF);
spu.set_ch_value(MFC_WrTagUpdate, MFC_TAG_UPDATE_ALL);
spu.get_ch_value(MFC_RdTagStat, result);
spu.get_ch_value(MFC_RdTagStat);
do
{
spu.set_ch_value(SPU_WrOutMbox, status);
spu.stop_and_signal(0x120);
spu.get_ch_value(SPU_RdInMbox, result);
result = spu.get_ch_value(SPU_RdInMbox);
}
while (result == CELL_EBUSY);
@@ -1719,9 +1711,8 @@ s32 spursTasketSaveTaskContext(SPUThread& spu)
v128 r;
spu.fpscr.Read(r);
ctxt->savedContextFpscr = r;
u32 r32;
spu.get_ch_value(SPU_RdEventMask, r32); ctxt->savedSpuWriteEventMask = r32;
spu.get_ch_value(MFC_RdTagMask, r32); ctxt->savedWriteTagGroupQueryMask = r32;
ctxt->savedSpuWriteEventMask = spu.get_ch_value(SPU_RdEventMask);
ctxt->savedWriteTagGroupQueryMask = spu.get_ch_value(MFC_RdTagMask);
// Store the processor context
const u32 contextSaveStorage = vm::cast(taskInfo->context_save_storage_and_alloc_ls_blocks & -0x80, HERE);