SPU: implement spu_runtime::g_tail_escape

May help to avoid gateway costs in some cases.
This commit is contained in:
Nekotekina 2019-05-15 18:44:53 +03:00
parent 4e75d2c2f7
commit 007108100e
2 changed files with 22 additions and 2 deletions

View File

@ -180,8 +180,25 @@ DECLARE(spu_runtime::g_escape) = build_function_asm<void(*)(spu_thread*)>([](asm
// Restore native stack pointer (longjmp emulation)
c.mov(x86::rsp, x86::qword_ptr(args[0], ::offset32(&spu_thread::saved_native_sp)));
c.sub(x86::rsp, 8);
c.ret();
// Return to the return location
c.jmp(x86::qword_ptr(x86::rsp, -8));
});
DECLARE(spu_runtime::g_tail_escape) = build_function_asm<void(*)(spu_thread*, spu_function_t, u8*)>([](asmjit::X86Assembler& c, auto& args)
{
using namespace asmjit;
// Restore native stack pointer (longjmp emulation)
c.mov(x86::rsp, x86::qword_ptr(args[0], ::offset32(&spu_thread::saved_native_sp)));
// Tail call, GHC CC (second arg)
c.mov(x86::r13, args[0]);
c.mov(x86::ebp, x86::dword_ptr(args[0], ::offset32(&spu_thread::offset)));
c.add(x86::rbp, x86::qword_ptr(args[0], ::offset32(&spu_thread::memory_base_addr)));
c.mov(x86::r12, args[2]);
c.xor_(x86::ebx, x86::ebx);
c.jmp(args[1]);
});
DECLARE(spu_runtime::g_interpreter) = nullptr;

View File

@ -111,6 +111,9 @@ public:
// Longjmp to the end of the gateway function (native CC)
static void(*const g_escape)(spu_thread*);
// Similar to g_escape, but doing tail call to the new function.
static void(*const g_tail_escape)(spu_thread*, spu_function_t, u8*);
// Interpreter entry point
static spu_function_t g_interpreter;