Skip to content

Commit

Permalink
PPU: block info fix
Browse files Browse the repository at this point in the history
  • Loading branch information
Nekotekina committed Feb 22, 2017
1 parent dac72ff commit 7c418f7
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 61 deletions.
9 changes: 7 additions & 2 deletions rpcs3/Emu/Cell/PPUAnalyser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -867,7 +867,7 @@ std::vector<ppu_function> ppu_analyse(const std::vector<std::pair<u32, u32>>& se
add_block(_ptr.addr());
}

if (op.lk && (target == iaddr || test(pfunc->attr, ppu_attr::no_return)))
if (is_call && test(pfunc->attr, ppu_attr::no_return))
{
// Nothing
}
Expand Down Expand Up @@ -946,8 +946,13 @@ std::vector<ppu_function> ppu_analyse(const std::vector<std::pair<u32, u32>>& se
block.second = _ptr.addr() - block.first;
break;
}
else if (op.opcode == ppu_instructions::TRAP())
else if (type == ppu_itype::TW || type == ppu_itype::TWI || type == ppu_itype::TD || type == ppu_itype::TDI)
{
if (op.opcode != ppu_instructions::TRAP())
{
add_block(_ptr.addr());
}

block.second = _ptr.addr() - block.first;
break;
}
Expand Down
8 changes: 0 additions & 8 deletions rpcs3/Emu/Cell/PPUThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -790,14 +790,6 @@ static void ppu_initialize()
f->addAttribute(1, Attribute::NoAlias);
translator->AddFunction(info.addr, f);
}

for (const auto& b : info.blocks)
{
if (b.second)
{
translator->AddBlockInfo(b.first);
}
}
}

legacy::FunctionPassManager pm(module.get());
Expand Down
90 changes: 48 additions & 42 deletions rpcs3/Emu/Cell/PPUTranslator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,6 @@ void PPUTranslator::AddFunction(u64 addr, Function* func, FunctionType* type)
}
}

void PPUTranslator::AddBlockInfo(u64 addr)
{
m_block_info.emplace(addr);
}

Function* PPUTranslator::TranslateToIR(const ppu_function& info, be_t<u32>* bin, void(*custom)(PPUTranslator*))
{
m_function = m_func_list[info.addr];
Expand Down Expand Up @@ -225,8 +220,19 @@ Function* PPUTranslator::TranslateToIR(const ppu_function& info, be_t<u32>* bin,

m_jtr = BasicBlock::Create(m_context, "__jtr", m_function);

// Create basic blocks
for (auto&& block : info.blocks)
{
if (block.second && block.first >= m_start_addr && block.first < m_end_addr)
{
m_blocks[block.first] = BasicBlock::Create(m_context, fmt::format("loc_%llx", block.first), m_function);
}
}

m_blocks[m_end_addr] = BasicBlock::Create(m_context, "loc_end", m_function);

/* Convert each instruction to LLVM IR */
const auto start = GetBasicBlock(m_start_addr);
const auto start = m_blocks.at(m_start_addr);
m_ir->CreateBr(start);
m_ir->SetInsertPoint(start);

Expand All @@ -235,7 +241,7 @@ Function* PPUTranslator::TranslateToIR(const ppu_function& info, be_t<u32>* bin,
// Preserve current address (m_current_addr may be changed by the decoder)
const u64 addr = m_current_addr;

if (m_current_addr == m_start_addr || info.blocks.count(m_current_addr))
if (m_blocks.count(m_current_addr))
{
// Bloat the beginning of each block: check state
const auto vstate = m_ir->CreateLoad(m_ir->CreateConstGEP2_32(nullptr, m_thread, 0, 1));
Expand All @@ -250,23 +256,29 @@ Function* PPUTranslator::TranslateToIR(const ppu_function& info, be_t<u32>* bin,
}

// Translate opcode
const u32 op = *(m_bin = bin + (addr - m_start_addr) / sizeof(u32));
(this->*(s_ppu_decoder.decode(op)))({op});
if (!m_ir->GetInsertBlock()->getTerminator())
{
const u32 op = *(m_bin = bin + (addr - m_start_addr) / sizeof(u32));
(this->*(s_ppu_decoder.decode(op)))({op});
}

// Calculate next address if necessary
// Get next address
if (m_current_addr == addr) m_current_addr += sizeof(u32);

// Get next block
const auto next = GetBasicBlock(m_current_addr);

// Finalize current block if necessary (create branch to next address)
if (!m_ir->GetInsertBlock()->getTerminator())
// Get next block if necessary
if (m_blocks.count(m_current_addr))
{
m_ir->CreateBr(next);
}
const auto next = m_blocks.at(m_current_addr);

// Start next block
m_ir->SetInsertPoint(next);
// Finalize current block if necessary (create branch to next address)
if (!m_ir->GetInsertBlock()->getTerminator())
{
m_ir->CreateBr(next);
}

// Start next block
m_ir->SetInsertPoint(next);
}
}

// Run custom IR generation function
Expand All @@ -287,22 +299,28 @@ Function* PPUTranslator::TranslateToIR(const ppu_function& info, be_t<u32>* bin,
}
else
{
// Get block entries
const std::vector<u64> cases{m_block_info.upper_bound(m_start_addr), m_block_info.lower_bound(m_end_addr)};

const auto _ctr = m_ir->CreateLoad(m_reg_ctr);
const auto _default = BasicBlock::Create(m_context, "__jtr.def", m_function);
const auto _switch = m_ir->CreateSwitch(_ctr, _default, ::size32(cases));
const auto _switch = m_ir->CreateSwitch(_ctr, _default, ::size32(m_blocks));

for (const u64 addr : cases)
for (const auto& pair : m_blocks)
{
_switch->addCase(m_ir->getInt64(addr), GetBasicBlock(addr));
_switch->addCase(m_ir->getInt64(pair.first), pair.second);
}

m_ir->SetInsertPoint(_default);
CallFunction(0, true, _ctr);
}

for (auto&& block : *m_function)
{
if (!block.getTerminator())
{
m_ir->SetInsertPoint(&block);
m_ir->CreateUnreachable();
}
}

return m_function;
}

Expand Down Expand Up @@ -394,18 +412,6 @@ void PPUTranslator::UndefineVolatileRegisters()
//m_ir->CreateStore(m_ir->getFalse(), m_vscr_sat); // VSCR.SAT
}

BasicBlock* PPUTranslator::GetBasicBlock(u64 address)
{
if (auto& block = m_blocks[address])
{
return block;
}
else
{
return block = BasicBlock::Create(m_context, fmt::format("loc_%llx", address/* - m_start_addr*/), m_function);
}
}

Value* PPUTranslator::Solid(Value* value)
{
const u32 size = value->getType()->getPrimitiveSizeInBits();
Expand Down Expand Up @@ -565,7 +571,7 @@ void PPUTranslator::UseCondition(MDNode* hint, Value* cond)
if (cond)
{
const auto local = BasicBlock::Create(m_context, fmt::format("loc_%llx.cond", m_current_addr/* - m_start_addr*/), m_function);
m_ir->CreateCondBr(cond, local, GetBasicBlock(m_current_addr + 4), hint);
m_ir->CreateCondBr(cond, local, m_blocks.at(m_current_addr + 4), hint);
m_ir->SetInsertPoint(local);
}
}
Expand Down Expand Up @@ -1761,12 +1767,12 @@ void PPUTranslator::BC(ppu_opcode_t op)
}
else if (cond)
{
m_ir->CreateCondBr(cond, GetBasicBlock(target), GetBasicBlock(m_current_addr + 4), CheckBranchProbability(op.bo));
m_ir->CreateCondBr(cond, m_blocks.at(target), m_blocks.at(m_current_addr + 4), CheckBranchProbability(op.bo));
return;
}
else
{
m_ir->CreateBr(GetBasicBlock(target));
m_ir->CreateBr(m_blocks.at(target));
return;
}
}
Expand Down Expand Up @@ -1809,7 +1815,7 @@ void PPUTranslator::B(ppu_opcode_t op)
}
else
{
m_ir->CreateBr(GetBasicBlock(target));
m_ir->CreateBr(m_blocks.at(target));
return;
}
}
Expand Down Expand Up @@ -1927,7 +1933,7 @@ void PPUTranslator::BCCTR(ppu_opcode_t op)

for (const u64 target : targets)
{
_switch->addCase(m_ir->getInt64(target), GetBasicBlock(target));
_switch->addCase(m_ir->getInt64(target), m_blocks.at(target));
}

m_ir->SetInsertPoint(_default);
Expand Down
9 changes: 0 additions & 9 deletions rpcs3/Emu/Cell/PPUTranslator.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,6 @@ class PPUTranslator final //: public CPUTranslator
// Basic blocks for current function
std::unordered_map<u64, llvm::BasicBlock*> m_blocks;

// Supplementary block info for all functions
std::set<u64> m_block_info;

// JT resolver block
llvm::BasicBlock* m_jtr;

Expand Down Expand Up @@ -239,9 +236,6 @@ class PPUTranslator final //: public CPUTranslator
// Set some registers to undef (after function call)
void UndefineVolatileRegisters();

// Get the basic block for the specified address
llvm::BasicBlock* GetBasicBlock(u64 addr);

// Load gpr
llvm::Value* GetGpr(u32 r, u32 num_bits = 64);

Expand Down Expand Up @@ -447,9 +441,6 @@ class PPUTranslator final //: public CPUTranslator
// Add function
void AddFunction(u64 addr, llvm::Function* func, llvm::FunctionType* type = nullptr);

// Add block entry hint (not essential)
void AddBlockInfo(u64 addr);

// Parses PPU opcodes and translate them into LLVM IR
llvm::Function* TranslateToIR(const ppu_function& info, be_t<u32>* bin, void(*custom)(PPUTranslator*) = nullptr);

Expand Down

0 comments on commit 7c418f7

Please sign in to comment.