mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-04 03:40:11 +00:00
PPU LLVM improved
This commit is contained in:
parent
2fd58dc7e8
commit
b1f1a5885b
@ -358,25 +358,22 @@ std::string ppu_thread::dump() const
|
||||
for (uint i = 0; i < 32; ++i) ret += fmt::format("FPR[%d] = %.6G\n", i, fpr[i]);
|
||||
for (uint i = 0; i < 32; ++i) ret += fmt::format("VR[%d] = %s [x: %g y: %g z: %g w: %g]\n", i, vr[i], vr[i]._f[3], vr[i]._f[2], vr[i]._f[1], vr[i]._f[0]);
|
||||
|
||||
if (g_cfg_ppu_decoder.get() != ppu_decoder_type::llvm)
|
||||
{
|
||||
ret += fmt::format("CR = 0x%08x\n", cr_pack());
|
||||
ret += fmt::format("LR = 0x%llx\n", lr);
|
||||
ret += fmt::format("CTR = 0x%llx\n", ctr);
|
||||
ret += fmt::format("VRSAVE = 0x%08x\n", vrsave);
|
||||
ret += fmt::format("XER = [CA=%u | OV=%u | SO=%u | CNT=%u]\n", xer.ca, xer.ov, xer.so, xer.cnt);
|
||||
ret += fmt::format("VSCR = [SAT=%u | NJ=%u]\n", sat, nj);
|
||||
ret += fmt::format("FPSCR = [FL=%u | FG=%u | FE=%u | FU=%u]\n", fpscr.fl, fpscr.fg, fpscr.fe, fpscr.fu);
|
||||
ret += fmt::format("CR = 0x%08x\n", cr_pack());
|
||||
ret += fmt::format("LR = 0x%llx\n", lr);
|
||||
ret += fmt::format("CTR = 0x%llx\n", ctr);
|
||||
ret += fmt::format("VRSAVE = 0x%08x\n", vrsave);
|
||||
ret += fmt::format("XER = [CA=%u | OV=%u | SO=%u | CNT=%u]\n", xer.ca, xer.ov, xer.so, xer.cnt);
|
||||
ret += fmt::format("VSCR = [SAT=%u | NJ=%u]\n", sat, nj);
|
||||
ret += fmt::format("FPSCR = [FL=%u | FG=%u | FE=%u | FU=%u]\n", fpscr.fl, fpscr.fg, fpscr.fe, fpscr.fu);
|
||||
|
||||
// TODO: support foreign stack
|
||||
ret += "\nCall stack:\n=========\n";
|
||||
ret += fmt::format("0x%08x (0x0) called\n", cia);
|
||||
const u32 stack_max = ::align(stack_addr + stack_size, 0x200) - 0x200;
|
||||
for (u64 sp = vm::read64(static_cast<u32>(gpr[1])); sp >= stack_addr && sp < stack_max; sp = vm::read64(static_cast<u32>(sp)))
|
||||
{
|
||||
// TODO: print also function addresses
|
||||
ret += fmt::format("> from 0x%08llx (0x0)\n", vm::read64(static_cast<u32>(sp + 16)));
|
||||
}
|
||||
// TODO: support foreign stack
|
||||
ret += "\nCall stack:\n=========\n";
|
||||
ret += fmt::format("0x%08x (0x0) called\n", g_cfg_ppu_decoder.get() == ppu_decoder_type::llvm ? 0 : cia);
|
||||
const u32 stack_max = ::align(stack_addr + stack_size, 0x200) - 0x200;
|
||||
for (u64 sp = vm::read64(static_cast<u32>(gpr[1])); sp >= stack_addr && sp < stack_max; sp = vm::read64(static_cast<u32>(sp)))
|
||||
{
|
||||
// TODO: print also function addresses
|
||||
ret += fmt::format("> from 0x%08llx (0x0)\n", vm::read64(static_cast<u32>(sp + 16)));
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -47,6 +47,11 @@ public:
|
||||
|
||||
alignas(16) bool cr[32] = {}; // Condition Registers (abstract representation)
|
||||
|
||||
u64 lr{}; // Link Register
|
||||
u64 ctr{}; // Counter Register
|
||||
u32 vrsave{0xffffffff}; // VR Save Register (almost unused)
|
||||
u32 cia{}; // Current Instruction Address
|
||||
|
||||
// Pack CR bits
|
||||
u32 cr_pack() const
|
||||
{
|
||||
@ -125,11 +130,7 @@ public:
|
||||
u32 raddr{0}; // Reservation addr
|
||||
u64 rtime{0};
|
||||
u64 rdata{0}; // Reservation data
|
||||
u64 lr{}; // Link Register
|
||||
u64 ctr{}; // Counter Register
|
||||
u32 vrsave{0xffffffff}; // VR Save Register (almost unused)
|
||||
|
||||
u32 cia{}; // Current Instruction Address
|
||||
|
||||
atomic_t<u32> prio{0}; // Thread priority (0..3071)
|
||||
const u32 stack_size; // Stack size
|
||||
const u32 stack_addr; // Stack address
|
||||
|
@ -84,6 +84,7 @@ PPUTranslator::PPUTranslator(LLVMContext& context, Module* module, u64 base)
|
||||
thread_struct.insert(thread_struct.end(), 32, GetType<f64>()); // fpr[0..31]
|
||||
thread_struct.insert(thread_struct.end(), 32, GetType<u32[4]>()); // vr[0..31]
|
||||
thread_struct.insert(thread_struct.end(), 32, GetType<bool>()); // cr[0..31]
|
||||
thread_struct.insert(thread_struct.end(), 2, GetType<u64>()); // lr, ctr
|
||||
|
||||
m_thread_type = StructType::create(m_context, thread_struct, "context_t");
|
||||
|
||||
@ -139,6 +140,7 @@ Function* PPUTranslator::TranslateToIR(const ppu_function& info, be_t<u32>* bin,
|
||||
m_g_gpr[1] = m_ir->CreateConstGEP2_32(nullptr, m_thread, 0, 3 + 1, ".spg");
|
||||
m_g_gpr[2] = m_ir->CreateConstGEP2_32(nullptr, m_thread, 0, 3 + 2, ".rtoc");
|
||||
m_g_gpr[13] = m_ir->CreateConstGEP2_32(nullptr, m_thread, 0, 3 + 13, ".tls");
|
||||
m_g_lr = m_ir->CreateConstGEP2_32(nullptr, m_thread, 0, 3 + 128, ".glr");
|
||||
m_gpr[1] = m_ir->CreateAlloca(GetType<u64>(), nullptr, ".sp");
|
||||
|
||||
// Registers used for args or results (TODO)
|
||||
@ -210,12 +212,14 @@ Function* PPUTranslator::TranslateToIR(const ppu_function& info, be_t<u32>* bin,
|
||||
|
||||
/* Initialize local variables */
|
||||
m_ir->CreateStore(m_ir->CreateLoad(m_g_gpr[1]), m_gpr[1]); // SP
|
||||
m_ir->CreateStore(m_ir->CreateLoad(m_g_lr), m_reg_lr); // LR
|
||||
m_ir->CreateStore(m_ir->getFalse(), m_xer_so); // XER.SO
|
||||
m_ir->CreateStore(m_ir->getFalse(), m_vscr_sat); // VSCR.SAT
|
||||
m_ir->CreateStore(m_ir->getTrue(), m_vscr_nj);
|
||||
|
||||
// TODO: only loaded r0 and r12 (r12 is extended argument for program initialization)
|
||||
// TODO: only loaded r0, r11, r12 (extended arguments for program initialization)
|
||||
if (!m_g_gpr[0]) m_ir->CreateStore(m_ir->CreateLoad(m_ir->CreateConstGEP2_32(nullptr, m_thread, 0, 3 + 0)), m_gpr[0]);
|
||||
if (!m_g_gpr[11]) m_ir->CreateStore(m_ir->CreateLoad(m_ir->CreateConstGEP2_32(nullptr, m_thread, 0, 3 + 11)), m_gpr[11]);
|
||||
if (!m_g_gpr[12]) m_ir->CreateStore(m_ir->CreateLoad(m_ir->CreateConstGEP2_32(nullptr, m_thread, 0, 3 + 12)), m_gpr[12]);
|
||||
|
||||
m_jtr = BasicBlock::Create(m_context, "__jtr", m_function);
|
||||
@ -1772,6 +1776,7 @@ void PPUTranslator::BC(ppu_opcode_t op)
|
||||
|
||||
// External branch
|
||||
UseCondition(CheckBranchProbability(op.bo), cond);
|
||||
if (op.lk) m_ir->CreateStore(m_ir->getInt64(m_current_addr + 4), m_g_lr);
|
||||
CallFunction(target, !op.lk);
|
||||
}
|
||||
|
||||
@ -1808,6 +1813,7 @@ void PPUTranslator::B(ppu_opcode_t op)
|
||||
}
|
||||
|
||||
// External branch or recursive call
|
||||
if (op.lk) m_ir->CreateStore(m_ir->getInt64(m_current_addr + 4), m_g_lr);
|
||||
CallFunction(target, !op.lk);
|
||||
}
|
||||
|
||||
@ -1827,6 +1833,7 @@ void PPUTranslator::BCLR(ppu_opcode_t op)
|
||||
if (op.lk)
|
||||
{
|
||||
// Sort of indirect call
|
||||
m_ir->CreateStore(m_ir->getInt64(m_current_addr + 4), m_g_lr);
|
||||
CallFunction(0, false, m_ir->CreateLoad(m_reg_lr));
|
||||
}
|
||||
else
|
||||
@ -1941,6 +1948,7 @@ void PPUTranslator::BCCTR(ppu_opcode_t op)
|
||||
}
|
||||
|
||||
// Indirect call
|
||||
m_ir->CreateStore(m_ir->getInt64(m_current_addr + 4), m_g_lr);
|
||||
CallFunction(0, false, m_ir->CreateLoad(m_reg_ctr));
|
||||
}
|
||||
}
|
||||
|
@ -175,6 +175,7 @@ class PPUTranslator final //: public CPUTranslator
|
||||
llvm::Value** const m_vr = m_locals + 64;
|
||||
|
||||
llvm::Value* m_cr[32]{};
|
||||
llvm::Value* m_g_lr;
|
||||
llvm::Value* m_reg_lr;
|
||||
llvm::Value* m_reg_ctr; // CTR register (counter)
|
||||
llvm::Value* m_reg_vrsave;
|
||||
|
Loading…
x
Reference in New Issue
Block a user