Skip to content

Commit 4a8a58c

Browse files
committed
Update PPUThread.cpp
1 parent c36603f commit 4a8a58c

File tree

5 files changed

+74
-7
lines changed

5 files changed

+74
-7
lines changed

rpcs3/Emu/Cell/PPUAnalyser.cpp

+30-3
Original file line numberDiff line numberDiff line change
@@ -2080,7 +2080,9 @@ bool ppu_module::analyse(u32 lib_toc, u32 entry, const u32 sec_end, const std::b
20802080

20812081
bool fail = false;
20822082

2083-
for (const auto& [addr, size] : func.blocks)
2083+
//for (const auto& [addr, size] : func.blocks)
2084+
const u32 addr = func.addr;
2085+
const u32 size = func.size;
20842086
{
20852087
if (size == 0)
20862088
{
@@ -2096,6 +2098,16 @@ bool ppu_module::analyse(u32 lib_toc, u32 entry, const u32 sec_end, const std::b
20962098

20972099
if (itype != ppu_itype::BC && itype != ppu_itype::B)
20982100
{
2101+
if (i == fend - 4)
2102+
{
2103+
if (!(itype & ppu_itype::branch) && itype != ppu_itype::SC)
2104+
{
2105+
// Inserts a branch to following code
2106+
fail = true;
2107+
break;
2108+
}
2109+
}
2110+
20992111
continue;
21002112
}
21012113

@@ -2106,6 +2118,16 @@ bool ppu_module::analyse(u32 lib_toc, u32 entry, const u32 sec_end, const std::b
21062118
fail = true;
21072119
break;
21082120
}
2121+
2122+
if (itype == ppu_itype::BC && (op.bo & 0x14) != 0x14)
2123+
{
2124+
if (i == fend - 4)
2125+
{
2126+
// Can branch to next
2127+
fail = true;
2128+
break;
2129+
}
2130+
}
21092131
}
21102132

21112133
if (fail)
@@ -2141,11 +2163,16 @@ bool ppu_module::analyse(u32 lib_toc, u32 entry, const u32 sec_end, const std::b
21412163

21422164
if (data.first > 1)
21432165
{
2144-
dups_count++;
2166+
duplicate_map[func.addr] = data.second;
2167+
2168+
for (const auto& [addr, size] : func.blocks)
2169+
{
2170+
duplicate_map[addr] = data.second + (addr - func.addr);
2171+
}
21452172

21462173
if (func.addr != data.second)
21472174
{
2148-
duplicate_map[func.addr] = data.second;
2175+
dups_count++;
21492176
}
21502177

21512178
ppu_log.trace("Found PPU function duplicate: func 0x%x (%d times)", data.second, data.first);

rpcs3/Emu/Cell/PPUAnalyser.h

+1
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ struct ppu_module
108108
secs = info.secs;
109109
allocations = info.allocations;
110110
addr_to_seg_index = info.addr_to_seg_index;
111+
duplicate_map = info.duplicate_map;
111112
}
112113

113114
bool analyse(u32 lib_toc, u32 entry, u32 end, const std::basic_string<u32>& applied, std::function<bool()> check_aborted = {});

rpcs3/Emu/Cell/PPUThread.cpp

+20-2
Original file line numberDiff line numberDiff line change
@@ -4643,8 +4643,15 @@ bool ppu_initialize(const ppu_module& info, bool check_only, u64 file_size)
46434643
// Copy block or function entry
46444644
ppu_function& entry = part.funcs.emplace_back(func);
46454645

4646+
u32 og_func = entry.addr;
4647+
4648+
if (auto it = info.duplicate_map.find(entry.addr); it != info.duplicate_map.end())
4649+
{
4650+
og_func = it->second;
4651+
}
4652+
46464653
// Fixup some information
4647-
entry.name = fmt::format("__0x%x", entry.addr - reloc);
4654+
entry.name = fmt::format("__0x%x", og_func - reloc);
46484655

46494656
if (has_mfvscr && g_cfg.core.ppu_set_sat_bit)
46504657
{
@@ -5037,6 +5044,8 @@ bool ppu_initialize(const ppu_module& info, bool check_only, u64 file_size)
50375044

50385045
bool early_exit = false;
50395046

5047+
std::map<std::string, ppu_intrp_func_t> func_ptr_map;
5048+
50405049
// Get and install function addresses
50415050
for (const auto& func : info.funcs)
50425051
{
@@ -5063,10 +5072,14 @@ bool ppu_initialize(const ppu_module& info, bool check_only, u64 file_size)
50635072

50645073
const auto name = fmt::format("__0x%x", og_func - reloc);
50655074

5075+
ppu_intrp_func_t dummy{};
5076+
ppu_intrp_func_t& func_ptr = is_first ? func_ptr_map[name] : dummy;
5077+
50665078
// Try to locate existing function if it is not the first time
5067-
const auto addr = is_first ? ensure(reinterpret_cast<ppu_intrp_func_t>(jit->get(name)))
5079+
const auto addr = is_first ? (func_ptr ? func_ptr : ensure(reinterpret_cast<ppu_intrp_func_t>(jit->get(name))))
50685080
: reinterpret_cast<ppu_intrp_func_t>(ensure(jit_mod.funcs[index]));
50695081

5082+
func_ptr = addr;
50705083
jit_mod.funcs.emplace_back(addr);
50715084

50725085
if (func.size == 4 && !BLR_func && *info.get_ptr<u32>(func.addr) == ppu_instructions::BLR())
@@ -5155,6 +5168,11 @@ static void ppu_initialize2(jit_compiler& jit, const ppu_module& module_part, co
51555168
{
51565169
if (func.size)
51575170
{
5171+
if (auto it = module_part.duplicate_map.find(func.addr); it != module_part.duplicate_map.end() && it->second != it->first)
5172+
{
5173+
continue;
5174+
}
5175+
51585176
const auto f = cast<Function>(_module->getOrInsertFunction(func.name, _func).getCallee());
51595177
f->setCallingConv(CallingConv::GHC);
51605178
f->addParamAttr(1, llvm::Attribute::NoAlias);

rpcs3/Emu/Cell/PPUTranslator.cpp

+20-2
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ Function* PPUTranslator::Translate(const ppu_function& info)
148148
const u64 base = m_reloc ? m_reloc->addr : 0;
149149
m_addr = info.addr - base;
150150
m_attr = info.attr;
151+
m_func_base = m_addr;
151152

152153
// Don't emit check in small blocks without terminator
153154
bool need_check = info.size >= 16;
@@ -304,13 +305,30 @@ Value* PPUTranslator::VecHandleResult(Value* val)
304305

305306
Value* PPUTranslator::GetAddr(u64 _add)
306307
{
308+
const bool is_duplicate = m_info.duplicate_map.contains(m_func_base);
309+
const auto old_cia = std::exchange(m_cia, nullptr);
310+
const auto cia_reg = is_duplicate ? ZExt(RegLoad(m_cia)) : nullptr;
311+
const u32 inst_diff = is_duplicate ? m_addr - m_func_base : m_addr;
312+
313+
m_cia = old_cia;
314+
Value* cia = nullptr;
315+
307316
if (m_reloc)
308317
{
309318
// Load segment address from global variable, compute actual instruction address
310-
return m_ir->CreateAdd(m_ir->getInt64(m_addr + _add), m_seg0);
319+
cia = m_ir->CreateAdd(m_ir->getInt64(inst_diff + _add), m_seg0);
320+
}
321+
else
322+
{
323+
cia = m_ir->getInt64(inst_diff + _add);
324+
}
325+
326+
if (cia_reg)
327+
{
328+
cia = m_ir->CreateAdd(cia_reg, cia);
311329
}
312330

313-
return m_ir->getInt64(m_addr + _add);
331+
return cia;
314332
}
315333

316334
Type* PPUTranslator::ScaleType(Type* type, s32 pow2)

rpcs3/Emu/Cell/PPUTranslator.h

+3
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ class PPUTranslator final : public cpu_translator
2828
// Current position-independent address
2929
u64 m_addr = 0;
3030

31+
// Function start
32+
u64 m_func_base = 0;
33+
3134
// Function attributes
3235
bs_t<ppu_attr> m_attr{};
3336

0 commit comments

Comments
 (0)