mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-05 22:41:25 +12:00
PPU LLVM: remove unnecessary code
This commit is contained in:
parent
cd4f290d3d
commit
1196e9decc
3 changed files with 25 additions and 198 deletions
|
@ -875,141 +875,6 @@ static bool adde_carry(u64 a, u64 b, bool c)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string ppu_context_prologue()
|
|
||||||
{
|
|
||||||
std::string c;
|
|
||||||
//c += "\xCC";
|
|
||||||
#ifndef _WIN32
|
|
||||||
c += "\x48\x89\xF9"; // mov rcx, rdi
|
|
||||||
#endif
|
|
||||||
c += "\x48\xB8"; // mov rax, imm64
|
|
||||||
uptr ptr = (uptr)&vm::g_base_addr;
|
|
||||||
c.append((const char*)&ptr, 8);
|
|
||||||
c += "\x48\x8B"; // mov rax, [rax]
|
|
||||||
c += '\0';
|
|
||||||
c += "\x48\x03\x41"; // add rax, [ppu+r3]
|
|
||||||
c += char(offset32(&ppu_thread::gpr, 3));
|
|
||||||
c += "\x48\x83\xC0\x0F"; // add rax, 15
|
|
||||||
c += "\x48\x83\xE0\xF0"; // and rax, -16
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto ppu_get_context = []() -> std::string
|
|
||||||
{
|
|
||||||
std::string c = ppu_context_prologue();
|
|
||||||
c += "\x48\x8B\x51"; // mov rdx, [rcx+r1]
|
|
||||||
c += char(offset32(&ppu_thread::gpr, 1));
|
|
||||||
c += "\x48\x89\x10"; // mov [rax], rdx
|
|
||||||
c += "\x48\x8B\x51"; // mov rdx, [rcx+r2]
|
|
||||||
c += char(offset32(&ppu_thread::gpr, 2));
|
|
||||||
c += "\x48\x89\x50\x08"; // mov [rax+8], rdx
|
|
||||||
c += "\x48\x8B\x54\x24\xF8"; // mov rdx, [rsp-8]
|
|
||||||
c += "\x48\x89\x50\x10"; // mov [rax+0x10], rdx
|
|
||||||
|
|
||||||
c += "\x48\x89\x60\x18"; // mov [rax+0x18], rsp
|
|
||||||
c += "\x48\x89\x58\x20"; // mov [rax+0x20], rbx
|
|
||||||
c += "\x48\x89\x68\x28"; // mov [rax+0x28], rbp
|
|
||||||
#ifdef _WIN32
|
|
||||||
c += "\x48\x89\x70\x30"; // mov [rax+0x30], rsi
|
|
||||||
c += "\x48\x89\x78\x38"; // mov [rax+0x38], rdi
|
|
||||||
#endif
|
|
||||||
c += "\x4C\x89\x60\x40"; // mov [rax+0x40], r12
|
|
||||||
c += "\x4C\x89\x68\x48"; // mov [rax+0x48], r13
|
|
||||||
c += "\x4C\x89\x70\x50"; // mov [rax+0x50], r14
|
|
||||||
c += "\x4C\x89\x78\x58"; // mov [rax+0x58], r15
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
c += "\x66\x0F\x7F\x70\x60"; // movdqa [rax+0x60], xmm6
|
|
||||||
c += "\x66\x0F\x7F\x78\x70"; // movdqa [rax+0x70], xmm7
|
|
||||||
c += "\x66\x44\x0F\x7F\x80\x80\x00\x00\x00"s; // ...
|
|
||||||
c += "\x66\x44\x0F\x7F\x88\x90\x00\x00\x00"s;
|
|
||||||
c += "\x66\x44\x0F\x7F\x90\xA0\x00\x00\x00"s;
|
|
||||||
c += "\x66\x44\x0F\x7F\x98\xB0\x00\x00\x00"s;
|
|
||||||
c += "\x66\x44\x0F\x7F\xA0\xC0\x00\x00\x00"s;
|
|
||||||
c += "\x66\x44\x0F\x7F\xA8\xD0\x00\x00\x00"s;
|
|
||||||
c += "\x66\x44\x0F\x7F\xB0\xE0\x00\x00\x00"s;
|
|
||||||
c += "\x66\x44\x0F\x7F\xB8\xF0\x00\x00\x00"s;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
c += "\x48\xC7\x41"; // mov [rcx+r3], 0
|
|
||||||
c += char(offset32(&ppu_thread::gpr, 3));
|
|
||||||
c.append(4, '\0');
|
|
||||||
//c += "\xCC";
|
|
||||||
c += "\xC3"; // ret
|
|
||||||
return c;
|
|
||||||
}();
|
|
||||||
|
|
||||||
const auto ppu_set_context = []() -> std::string
|
|
||||||
{
|
|
||||||
std::string c = ppu_context_prologue();
|
|
||||||
c += "\xCC";
|
|
||||||
c += "\x48\x8B\x10"; // mov rdx, [rax]
|
|
||||||
c += "\x48\x89\x51"; // mov [rcx+r1], rdx
|
|
||||||
c += char(offset32(&ppu_thread::gpr, 1));
|
|
||||||
|
|
||||||
c += "\x48\x8B\x50\x08"; // mov rdx, [rax+8]
|
|
||||||
c += "\x48\x89\x51"; // mov [rcx+r2], rdx
|
|
||||||
c += char(offset32(&ppu_thread::gpr, 2));
|
|
||||||
|
|
||||||
c += "\x48\x8B\x60\x18"; // mov rsp, [rax+0x18]
|
|
||||||
c += "\x48\x8B\x58\x20"; // mov rbx, [rax+0x20]
|
|
||||||
c += "\x48\x8B\x68\x28"; // mov rbp, [rax+0x28]
|
|
||||||
#ifdef _WIN32
|
|
||||||
c += "\x48\x8B\x70\x30"; // mov rsi, [rax+0x30]
|
|
||||||
c += "\x48\x8B\x78\x38"; // mov rdi, [rax+0x38]
|
|
||||||
#endif
|
|
||||||
c += "\x4C\x8B\x60\x40"; // mov r12, [rax+0x40]
|
|
||||||
c += "\x4C\x8B\x68\x48"; // mov r13, [rax+0x48]
|
|
||||||
c += "\x4C\x8B\x70\x50"; // mov r14, [rax+0x50]
|
|
||||||
c += "\x4C\x8B\x78\x58"; // mov r15, [rax+0x58]
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
c += "\x66\x0F\x6F\x70\x60"; // movdqa xmm6, [rax+0x60]
|
|
||||||
c += "\x66\x0F\x6F\x78\x70"; // movdqa xmm7, [rax+0x70]
|
|
||||||
c += "\x66\x44\x0F\x6F\x80\x80\x00\x00\x00"s; // ...
|
|
||||||
c += "\x66\x44\x0F\x6F\x88\x90\x00\x00\x00"s;
|
|
||||||
c += "\x66\x44\x0F\x6F\x90\xA0\x00\x00\x00"s;
|
|
||||||
c += "\x66\x44\x0F\x6F\x98\xB0\x00\x00\x00"s;
|
|
||||||
c += "\x66\x44\x0F\x6F\xA0\xC0\x00\x00\x00"s;
|
|
||||||
c += "\x66\x44\x0F\x6F\xA8\xD0\x00\x00\x00"s;
|
|
||||||
c += "\x66\x44\x0F\x6F\xB0\xE0\x00\x00\x00"s;
|
|
||||||
c += "\x66\x44\x0F\x6F\xB8\xF0\x00\x00\x00"s;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
c += "\x48\x8B\x50\x10"; // mov rdx, [rax+0x10]
|
|
||||||
c += "\x48\x89\x54\x24\xF8"; // mov [rsp-8], rdx
|
|
||||||
c += "\x48\x8B\x51"; // mov rdx, [rcx+r4]
|
|
||||||
c += char(offset32(&ppu_thread::gpr, 4));
|
|
||||||
c += "\x48\x85\xD2"; // test rdx, rdx
|
|
||||||
c += "\x0F\x94\xC2"; // setz dl
|
|
||||||
c += "\x48\x0F\xB6\xD2"; // movzx rdx, dl
|
|
||||||
c += "\x48\x89\x51"; // mov [rcx+r3], rdx
|
|
||||||
c += char(offset32(&ppu_thread::gpr, 3));
|
|
||||||
c += "\xC3"; // ret
|
|
||||||
return c;
|
|
||||||
}();
|
|
||||||
|
|
||||||
const auto ppu_use_context = []() -> std::string
|
|
||||||
{
|
|
||||||
std::string c;
|
|
||||||
c += "\x48\xB8"; // mov rax, imm64
|
|
||||||
uptr ptr = (uptr)&vm::g_exec_addr;
|
|
||||||
c.append((const char*)&ptr, 8);
|
|
||||||
c += "\x48\x8B\x20"; // mov rsp, [rax]
|
|
||||||
#ifdef _WIN32
|
|
||||||
c += "\x48\x01\xD4"; // add rsp,rdx
|
|
||||||
#else
|
|
||||||
c += "\x48\x01\xFC"; // add rsp,rsi
|
|
||||||
#endif
|
|
||||||
//c += "\x48\x83\xE4\xE0"; // and rsp, -0x20
|
|
||||||
#ifdef _WIN32
|
|
||||||
c += "\x41\xFF\xD0"; // call r8
|
|
||||||
#else
|
|
||||||
c += "\xFF\xD2"; // call rdx
|
|
||||||
#endif
|
|
||||||
return c;
|
|
||||||
}();
|
|
||||||
|
|
||||||
extern void ppu_initialize()
|
extern void ppu_initialize()
|
||||||
{
|
{
|
||||||
const auto _funcs = fxm::withdraw<std::vector<ppu_function>>();
|
const auto _funcs = fxm::withdraw<std::vector<ppu_function>>();
|
||||||
|
@ -1380,60 +1245,6 @@ static void ppu_initialize2(jit_compiler& jit, const ppu_module& module_part, co
|
||||||
|
|
||||||
// Run optimization passes
|
// Run optimization passes
|
||||||
pm.run(*func);
|
pm.run(*func);
|
||||||
|
|
||||||
const auto _syscall = module->getFunction("__syscall");
|
|
||||||
|
|
||||||
for (auto i = inst_begin(*func), end = inst_end(*func); i != end;)
|
|
||||||
{
|
|
||||||
const auto inst = &*i++;
|
|
||||||
|
|
||||||
if (const auto ci = dyn_cast<CallInst>(inst))
|
|
||||||
{
|
|
||||||
const auto cif = ci->getCalledFunction();
|
|
||||||
const auto op1 = ci->getNumArgOperands() > 1 ? ci->getArgOperand(1) : nullptr;
|
|
||||||
|
|
||||||
if (cif == _syscall && op1 && isa<ConstantInt>(op1))
|
|
||||||
{
|
|
||||||
// Try to determine syscall using the value from r11 (requires constant propagation)
|
|
||||||
const u64 index = cast<ConstantInt>(op1)->getZExtValue();
|
|
||||||
|
|
||||||
if (const auto ptr = ppu_get_syscall(index))
|
|
||||||
{
|
|
||||||
const auto n = ppu_get_syscall_name(index);
|
|
||||||
const auto f = cast<Function>(module->getOrInsertFunction(n, _func));
|
|
||||||
|
|
||||||
// Call the syscall directly
|
|
||||||
ReplaceInstWithInst(ci, CallInst::Create(f, {ci->getArgOperand(0)}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (const auto li = dyn_cast<LoadInst>(inst))
|
|
||||||
{
|
|
||||||
// TODO: more careful check
|
|
||||||
if (li->getNumUses() == 0)
|
|
||||||
{
|
|
||||||
// Remove unreferenced volatile loads
|
|
||||||
li->eraseFromParent();
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (const auto si = dyn_cast<StoreInst>(inst))
|
|
||||||
{
|
|
||||||
// TODO: more careful check
|
|
||||||
if (isa<UndefValue>(si->getOperand(0)) && si->getParent() == &func->getEntryBlock())
|
|
||||||
{
|
|
||||||
// Remove undef volatile stores
|
|
||||||
si->eraseFromParent();
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
#include "../Utilities/Log.h"
|
#include "../Utilities/Log.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
extern std::string ppu_get_syscall_name(u64 code);
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
const ppu_decoder<PPUTranslator> s_ppu_decoder;
|
const ppu_decoder<PPUTranslator> s_ppu_decoder;
|
||||||
|
@ -1636,6 +1638,21 @@ void PPUTranslator::SC(ppu_opcode_t op)
|
||||||
const auto num = GetGpr(11);
|
const auto num = GetGpr(11);
|
||||||
RegStore(m_ir->getInt32(m_current_addr), m_cia);
|
RegStore(m_ir->getInt32(m_current_addr), m_cia);
|
||||||
FlushRegisters();
|
FlushRegisters();
|
||||||
|
|
||||||
|
if (!op.lev && isa<ConstantInt>(num))
|
||||||
|
{
|
||||||
|
// Try to determine syscall using the constant value from r11
|
||||||
|
const u64 index = cast<ConstantInt>(num)->getZExtValue();
|
||||||
|
|
||||||
|
if (index < 1024)
|
||||||
|
{
|
||||||
|
// Call the syscall directly
|
||||||
|
Call(GetType<void>(), ppu_get_syscall_name(index), m_thread);
|
||||||
|
m_ir->CreateRetVoid();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Call(GetType<void>(), op.lev ? "__lv1call" : "__syscall", m_thread, num);
|
Call(GetType<void>(), op.lev ? "__lv1call" : "__syscall", m_thread, num);
|
||||||
m_ir->CreateRetVoid();
|
m_ir->CreateRetVoid();
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,13 @@
|
||||||
|
|
||||||
extern std::string ppu_get_syscall_name(u64 code);
|
extern std::string ppu_get_syscall_name(u64 code);
|
||||||
|
|
||||||
static constexpr ppu_function_t null_func = nullptr;
|
static bool null_func(ppu_thread& ppu)
|
||||||
|
{
|
||||||
|
LOG_TODO(HLE, "Unimplemented syscall %s -> CELL_OK", ppu_get_syscall_name(ppu.gpr[11]));
|
||||||
|
ppu.gpr[3] = 0;
|
||||||
|
ppu.cia += 4;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
std::array<ppu_function_t, 1024> g_ppu_syscall_table{};
|
std::array<ppu_function_t, 1024> g_ppu_syscall_table{};
|
||||||
|
|
||||||
|
@ -974,15 +980,8 @@ extern void ppu_execute_syscall(ppu_thread& ppu, u64 code)
|
||||||
{
|
{
|
||||||
func(ppu);
|
func(ppu);
|
||||||
LOG_TRACE(PPU, "Syscall '%s' (%llu) finished, r3=0x%llx", ppu_get_syscall_name(code), code, ppu.gpr[3]);
|
LOG_TRACE(PPU, "Syscall '%s' (%llu) finished, r3=0x%llx", ppu_get_syscall_name(code), code, ppu.gpr[3]);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG_TODO(HLE, "Unimplemented syscall %s -> CELL_OK", ppu_get_syscall_name(code));
|
|
||||||
ppu.gpr[3] = 0;
|
|
||||||
ppu.cia += 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt::throw_exception("Invalid syscall number (%llu)", code);
|
fmt::throw_exception("Invalid syscall number (%llu)", code);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue