mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-09 00:11:24 +12:00
SPU ASMJIT: add PIC support (fix)
Also cleanup and adapt for GHC CC.
This commit is contained in:
parent
82295d131a
commit
c481472faf
4 changed files with 336 additions and 359 deletions
File diff suppressed because it is too large
Load diff
|
@ -19,18 +19,26 @@ private:
|
||||||
// ASMJIT runtime
|
// ASMJIT runtime
|
||||||
::jit_runtime m_asmrt;
|
::jit_runtime m_asmrt;
|
||||||
|
|
||||||
|
u32 m_base;
|
||||||
|
|
||||||
// emitter:
|
// emitter:
|
||||||
asmjit::X86Assembler* c;
|
asmjit::X86Assembler* c;
|
||||||
|
|
||||||
// arguments:
|
// arguments:
|
||||||
const asmjit::X86Gp* cpu;
|
const asmjit::X86Gp* cpu;
|
||||||
const asmjit::X86Gp* ls;
|
const asmjit::X86Gp* ls;
|
||||||
|
const asmjit::X86Gp* rip;
|
||||||
|
const asmjit::X86Gp* pc0;
|
||||||
|
|
||||||
|
// Native args or temp variables:
|
||||||
|
const asmjit::X86Gp* arg0;
|
||||||
|
const asmjit::X86Gp* arg1;
|
||||||
const asmjit::X86Gp* qw0;
|
const asmjit::X86Gp* qw0;
|
||||||
const asmjit::X86Gp* qw1;
|
const asmjit::X86Gp* qw1;
|
||||||
|
|
||||||
// temporary:
|
// temporary:
|
||||||
const asmjit::X86Gp* addr;
|
const asmjit::X86Gp* addr;
|
||||||
std::array<const asmjit::X86Xmm*, 6> vec;
|
std::array<const asmjit::X86Xmm*, 16> vec;
|
||||||
|
|
||||||
// workload for the end of function:
|
// workload for the end of function:
|
||||||
std::vector<std::function<void()>> after;
|
std::vector<std::function<void()>> after;
|
||||||
|
@ -81,12 +89,11 @@ private:
|
||||||
asmjit::X86Mem XmmConst(__m128 data);
|
asmjit::X86Mem XmmConst(__m128 data);
|
||||||
asmjit::X86Mem XmmConst(__m128i data);
|
asmjit::X86Mem XmmConst(__m128i data);
|
||||||
|
|
||||||
|
asmjit::X86Mem get_pc(u32 addr);
|
||||||
void branch_fixed(u32 target);
|
void branch_fixed(u32 target);
|
||||||
void branch_indirect(spu_opcode_t op, bool jt = false, bool ret = true);
|
void branch_indirect(spu_opcode_t op, bool jt = false, bool ret = true);
|
||||||
void branch_set_link(u32 target);
|
void branch_set_link(u32 target);
|
||||||
void fall(spu_opcode_t op);
|
void fall(spu_opcode_t op);
|
||||||
void save_rcx();
|
|
||||||
void load_rcx();
|
|
||||||
|
|
||||||
void get_events();
|
void get_events();
|
||||||
|
|
||||||
|
|
|
@ -174,6 +174,16 @@ DECLARE(spu_runtime::g_gateway) = build_function_asm<spu_function_t>([](asmjit::
|
||||||
c.ret();
|
c.ret();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
DECLARE(spu_runtime::g_escape) = build_function_asm<void(*)(spu_thread*)>([](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)));
|
||||||
|
c.sub(x86::rsp, 8);
|
||||||
|
c.ret();
|
||||||
|
});
|
||||||
|
|
||||||
DECLARE(spu_runtime::g_interpreter) = nullptr;
|
DECLARE(spu_runtime::g_interpreter) = nullptr;
|
||||||
|
|
||||||
spu_cache::spu_cache(const std::string& loc)
|
spu_cache::spu_cache(const std::string& loc)
|
||||||
|
@ -2062,17 +2072,6 @@ const std::vector<u32>& spu_recompiler_base::analyse(const be_t<u32>* ls, u32 en
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip some steps for asmjit
|
|
||||||
if (g_cfg.core.spu_decoder == spu_decoder_type::asmjit)
|
|
||||||
{
|
|
||||||
if (result.size() == 1)
|
|
||||||
{
|
|
||||||
result.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fill block info
|
// Fill block info
|
||||||
for (auto& pred : m_preds)
|
for (auto& pred : m_preds)
|
||||||
{
|
{
|
||||||
|
@ -4331,15 +4330,6 @@ public:
|
||||||
m_ir->CreateRet(m_ir->CreateLoad(dispatcher));
|
m_ir->CreateRet(m_ir->CreateLoad(dispatcher));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Longjmp analogue (restore saved host thread's stack pointer)
|
|
||||||
const auto escape = llvm::cast<llvm::Function>(m_module->getOrInsertFunction("spu_escape", get_ftype<void, u8*>()).getCallee());
|
|
||||||
escape->setLinkage(GlobalValue::InternalLinkage);
|
|
||||||
m_ir->SetInsertPoint(BasicBlock::Create(m_context, "", escape));
|
|
||||||
const auto load_sp = m_ir->CreateLoad(_ptr<u64>(&*escape->arg_begin(), ::offset32(&spu_thread::saved_native_sp)));
|
|
||||||
const auto rsp_name = MetadataAsValue::get(m_context, MDNode::get(m_context, {MDString::get(m_context, "rsp")}));
|
|
||||||
m_ir->CreateCall(get_intrinsic<u64>(Intrinsic::write_register), {rsp_name, m_ir->CreateSub(load_sp, m_ir->getInt64(8))});
|
|
||||||
m_ir->CreateRetVoid();
|
|
||||||
|
|
||||||
// Function that executes check_state and escapes if necessary
|
// Function that executes check_state and escapes if necessary
|
||||||
m_test_state = llvm::cast<llvm::Function>(m_module->getOrInsertFunction("spu_test_state", get_ftype<void, u8*>()).getCallee());
|
m_test_state = llvm::cast<llvm::Function>(m_module->getOrInsertFunction("spu_test_state", get_ftype<void, u8*>()).getCallee());
|
||||||
m_test_state->setLinkage(GlobalValue::InternalLinkage);
|
m_test_state->setLinkage(GlobalValue::InternalLinkage);
|
||||||
|
@ -4349,7 +4339,7 @@ public:
|
||||||
const auto escape_no = BasicBlock::Create(m_context, "", m_test_state);
|
const auto escape_no = BasicBlock::Create(m_context, "", m_test_state);
|
||||||
m_ir->CreateCondBr(call("spu_exec_check_state", &exec_check_state, &*m_test_state->arg_begin()), escape_yes, escape_no);
|
m_ir->CreateCondBr(call("spu_exec_check_state", &exec_check_state, &*m_test_state->arg_begin()), escape_yes, escape_no);
|
||||||
m_ir->SetInsertPoint(escape_yes);
|
m_ir->SetInsertPoint(escape_yes);
|
||||||
m_ir->CreateCall(escape, {&*m_test_state->arg_begin()});
|
call("spu_escape", spu_runtime::g_escape, &*m_test_state->arg_begin());
|
||||||
m_ir->CreateRetVoid();
|
m_ir->CreateRetVoid();
|
||||||
m_ir->SetInsertPoint(escape_no);
|
m_ir->SetInsertPoint(escape_no);
|
||||||
m_ir->CreateRetVoid();
|
m_ir->CreateRetVoid();
|
||||||
|
|
|
@ -105,6 +105,9 @@ public:
|
||||||
// Recompiler entry point
|
// Recompiler entry point
|
||||||
static const spu_function_t g_gateway;
|
static const spu_function_t g_gateway;
|
||||||
|
|
||||||
|
// Longjmp to the end of the gateway function (native CC)
|
||||||
|
static void(*const g_escape)(spu_thread*);
|
||||||
|
|
||||||
// Interpreter entry point
|
// Interpreter entry point
|
||||||
static spu_function_t g_interpreter;
|
static spu_function_t g_interpreter;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue