mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-29 00:33:01 +00:00
SPU ASMJIT: add PIC support (fix)
Also cleanup and adapt for GHC CC.
This commit is contained in:
parent
82295d131a
commit
c481472faf
File diff suppressed because it is too large
Load Diff
@ -19,18 +19,26 @@ private:
|
||||
// ASMJIT runtime
|
||||
::jit_runtime m_asmrt;
|
||||
|
||||
u32 m_base;
|
||||
|
||||
// emitter:
|
||||
asmjit::X86Assembler* c;
|
||||
|
||||
// arguments:
|
||||
const asmjit::X86Gp* cpu;
|
||||
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* qw1;
|
||||
|
||||
// temporary:
|
||||
const asmjit::X86Gp* addr;
|
||||
std::array<const asmjit::X86Xmm*, 6> vec;
|
||||
std::array<const asmjit::X86Xmm*, 16> vec;
|
||||
|
||||
// workload for the end of function:
|
||||
std::vector<std::function<void()>> after;
|
||||
@ -81,12 +89,11 @@ private:
|
||||
asmjit::X86Mem XmmConst(__m128 data);
|
||||
asmjit::X86Mem XmmConst(__m128i data);
|
||||
|
||||
asmjit::X86Mem get_pc(u32 addr);
|
||||
void branch_fixed(u32 target);
|
||||
void branch_indirect(spu_opcode_t op, bool jt = false, bool ret = true);
|
||||
void branch_set_link(u32 target);
|
||||
void fall(spu_opcode_t op);
|
||||
void save_rcx();
|
||||
void load_rcx();
|
||||
|
||||
void get_events();
|
||||
|
||||
|
@ -174,6 +174,16 @@ DECLARE(spu_runtime::g_gateway) = build_function_asm<spu_function_t>([](asmjit::
|
||||
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;
|
||||
|
||||
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
|
||||
for (auto& pred : m_preds)
|
||||
{
|
||||
@ -4331,15 +4330,6 @@ public:
|
||||
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
|
||||
m_test_state = llvm::cast<llvm::Function>(m_module->getOrInsertFunction("spu_test_state", get_ftype<void, u8*>()).getCallee());
|
||||
m_test_state->setLinkage(GlobalValue::InternalLinkage);
|
||||
@ -4349,7 +4339,7 @@ public:
|
||||
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->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->SetInsertPoint(escape_no);
|
||||
m_ir->CreateRetVoid();
|
||||
|
@ -105,6 +105,9 @@ public:
|
||||
// Recompiler entry point
|
||||
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
|
||||
static spu_function_t g_interpreter;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user