SPU LLVM: simplify function prototype

Pass only $3
This commit is contained in:
Nekotekina 2019-05-15 16:18:13 +03:00
parent 16401722f1
commit adc7d96683

View File

@ -3287,8 +3287,9 @@ class spu_llvm_recompiler : public spu_recompiler_base, public cpu_translator
if (ffound != m_funcs.end() && ffound->second.good) if (ffound != m_funcs.end() && ffound->second.good)
{ {
// Real function type (not equal to chunk type) // Real function type (not equal to chunk type)
// 4. $SP (only 32 bit value) // 4. $SP
const auto func_type = get_ftype<u32[4][2], u8*, u8*, u32, u32[4], u32[4], u32[4]>(); // 5. $3
const auto func_type = get_ftype<u32[4], u8*, u8*, u32, u32[4], u32[4]>();
const std::string fname = fmt::format("spu-function-0x%05x", addr); const std::string fname = fmt::format("spu-function-0x%05x", addr);
llvm::Function* fn = llvm::cast<llvm::Function>(m_module->getOrInsertFunction(fname, func_type).getCallee()); llvm::Function* fn = llvm::cast<llvm::Function>(m_module->getOrInsertFunction(fname, func_type).getCallee());
@ -3360,30 +3361,22 @@ class spu_llvm_recompiler : public spu_recompiler_base, public cpu_translator
{ {
llvm::Value* lr{}; llvm::Value* lr{};
llvm::Value* sp{}; llvm::Value* sp{};
llvm::Value* args[2]{}; llvm::Value* r3{};
if (!m_finfo->fn && !m_block) if (!m_finfo->fn && !m_block)
{ {
lr = m_ir->CreateLoad(spu_ptr<u32>(&spu_thread::gpr, +s_reg_lr, &v128::_u32, 3)); lr = m_ir->CreateLoad(spu_ptr<u32>(&spu_thread::gpr, +s_reg_lr, &v128::_u32, 3));
sp = m_ir->CreateLoad(spu_ptr<u32[4]>(&spu_thread::gpr, +s_reg_sp)); sp = m_ir->CreateLoad(spu_ptr<u32[4]>(&spu_thread::gpr, +s_reg_sp));
r3 = m_ir->CreateLoad(spu_ptr<u32[4]>(&spu_thread::gpr, 3));
for (u32 i = 3; i < 3 + std::size(args); i++)
{
args[i - 3] = m_ir->CreateLoad(spu_ptr<u32[4]>(&spu_thread::gpr, +i));
}
} }
else else
{ {
lr = m_ir->CreateExtractElement(get_reg_fixed<u32[4]>(s_reg_lr).value, 3); lr = m_ir->CreateExtractElement(get_reg_fixed<u32[4]>(s_reg_lr).value, 3);
sp = get_reg_fixed<u32[4]>(s_reg_sp).value; sp = get_reg_fixed<u32[4]>(s_reg_sp).value;
r3 = get_reg_fixed<u32[4]>(3).value;
for (u32 i = 3; i < 3 + std::size(args); i++)
{
args[i - 3] = get_reg_fixed<u32[4]>(i).value;
}
} }
const auto _call = m_ir->CreateCall(verify(HERE, fn), {m_thread, m_lsptr, m_base_pc, sp, args[0], args[1]}); const auto _call = m_ir->CreateCall(verify(HERE, fn), {m_thread, m_lsptr, m_base_pc, sp, r3});
_call->setCallingConv(fn->getCallingConv()); _call->setCallingConv(fn->getCallingConv());
@ -3392,7 +3385,7 @@ class spu_llvm_recompiler : public spu_recompiler_base, public cpu_translator
{ {
lr = m_ir->CreateAnd(lr, 0x3fffc); lr = m_ir->CreateAnd(lr, 0x3fffc);
m_ir->CreateStore(lr, spu_ptr<u32>(&spu_thread::pc)); m_ir->CreateStore(lr, spu_ptr<u32>(&spu_thread::pc));
m_ir->CreateStore(_call, spu_ptr<u32[4][2]>(&spu_thread::gpr, 3)); m_ir->CreateStore(_call, spu_ptr<u32[4]>(&spu_thread::gpr, 3));
m_ir->CreateBr(add_block_indirect({}, value<u32>(lr))); m_ir->CreateBr(add_block_indirect({}, value<u32>(lr)));
} }
else if (tail) else if (tail)
@ -3411,24 +3404,15 @@ class spu_llvm_recompiler : public spu_recompiler_base, public cpu_translator
} }
} }
for (u32 i = 3; i < 3 + std::size(args); i++) // Set result
{ m_block->reg[3] = _call;
m_block->reg[i] = m_ir->CreateExtractValue(_call, {i - 3});
}
} }
} }
// Emit return from the real function // Emit return from the real function
void ret_function() void ret_function()
{ {
llvm::Value* r = llvm::ConstantAggregateZero::get(get_type<u32[4][2]>()); m_ir->CreateRet(get_reg_fixed<u32[4]>(3).value);
for (u32 i = 3; i < 5; i++)
{
r = m_ir->CreateInsertValue(r, get_reg_fixed<u32[4]>(i).value, {i - 3});
}
m_ir->CreateRet(r);
} }
void set_function(llvm::Function* func) void set_function(llvm::Function* func)
@ -3485,10 +3469,7 @@ class spu_llvm_recompiler : public spu_recompiler_base, public cpu_translator
m_finfo->load[s_reg_sp] = &*(fn->arg_begin() + 3); m_finfo->load[s_reg_sp] = &*(fn->arg_begin() + 3);
// Load first args // Load first args
for (u32 i = 3; i < 5; i++) m_finfo->load[3] = &*(fn->arg_begin() + 4);
{
m_finfo->load[i] = &*(fn->arg_begin() + i + 1);
}
} }
} }
else if (m_block_info[target / 4] && m_entry_info[target / 4] && !(pred_found && m_entry == target) && (!m_finfo->fn || !m_ret_info[target / 4])) else if (m_block_info[target / 4] && m_entry_info[target / 4] && !(pred_found && m_entry == target) && (!m_finfo->fn || !m_ret_info[target / 4]))
@ -3915,7 +3896,7 @@ class spu_llvm_recompiler : public spu_recompiler_base, public cpu_translator
if (m_finfo && m_finfo->fn) if (m_finfo && m_finfo->fn)
{ {
if (index == s_reg_lr || (index >= 3 && index <= 4) || (index >= s_reg_80 && index <= s_reg_127)) if (index == s_reg_lr || index == 3 || (index >= s_reg_80 && index <= s_reg_127))
{ {
// Don't save some registers in true functions // Don't save some registers in true functions
return; return;