mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-16 23:17:29 +00:00
PPU: Allow HLE execution from pure instruction decoder type interpreter
This commit is contained in:
parent
0445ef393f
commit
bfe1a8673a
@ -164,7 +164,7 @@ bool statichle_handler::check_against_patterns(vm::cptr<u8>& data, u32 size, u32
|
||||
}
|
||||
|
||||
const auto sfunc = &smodule->functions.at(pat.fnid);
|
||||
const u32 target = ppu_function_manager::addr + 8 * sfunc->index;
|
||||
const u32 target = ppu_function_manager::func_addr(sfunc->index) + 4;
|
||||
|
||||
// write stub
|
||||
vm::write32(addr, ppu_instructions::LIS(0, (target&0xFFFF0000)>>16));
|
||||
|
@ -417,7 +417,7 @@ error_code _cellGcmInitBody(ppu_thread& ppu, vm::pptr<CellGcmContextData> contex
|
||||
gcm_cfg->current_context.begin.set(g_defaultCommandBufferBegin + 4096); // 4 kb reserved at the beginning
|
||||
gcm_cfg->current_context.end.set(g_defaultCommandBufferBegin + 32 * 1024 - 4); // 4b at the end for jump
|
||||
gcm_cfg->current_context.current = gcm_cfg->current_context.begin;
|
||||
gcm_cfg->current_context.callback.set(ppu_function_manager::addr + 8 * FIND_FUNC(cellGcmCallback));
|
||||
gcm_cfg->current_context.callback.set(ppu_function_manager::func_addr(FIND_FUNC(cellGcmCallback)));
|
||||
|
||||
gcm_cfg->ctxt_addr = context.addr();
|
||||
gcm_cfg->gcm_buffers.set(vm::alloc(sizeof(CellGcmDisplayInfo) * 8, vm::main));
|
||||
|
@ -255,7 +255,7 @@ error_code open_exit_dialog(const std::string& message, bool is_exit_requested)
|
||||
|
||||
if (is_exit_requested)
|
||||
{
|
||||
callback.set(ppu_function_manager::addr + 8 * FIND_FUNC(exit_game));
|
||||
callback.set(ppu_function_manager::func_addr(FIND_FUNC(exit_game)));
|
||||
}
|
||||
|
||||
const error_code res = open_msg_dialog
|
||||
|
@ -2346,12 +2346,12 @@ extern std::vector<std::string> g_ppu_function_names;
|
||||
|
||||
void PPUDisAsm::UNK(ppu_opcode_t op)
|
||||
{
|
||||
if (op.opcode == dump_pc && ppu_function_manager::addr)
|
||||
if (ppu_function_manager::addr)
|
||||
{
|
||||
// HLE function index
|
||||
const u32 index = (dump_pc - ppu_function_manager::addr) / 8;
|
||||
|
||||
if (index < ppu_function_manager::get().size())
|
||||
if (dump_pc % 8 == 4 && index < ppu_function_manager::get().size())
|
||||
{
|
||||
Write(fmt::format("Function : %s (index %u)", index < g_ppu_function_names.size() ? g_ppu_function_names[index].c_str() : "?", index));
|
||||
return;
|
||||
|
@ -281,6 +281,16 @@ public:
|
||||
return access();
|
||||
}
|
||||
|
||||
static inline u32 func_addr(u32 index)
|
||||
{
|
||||
if (index >= access().size() || !addr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return addr + index * 8;
|
||||
}
|
||||
|
||||
// Allocation address
|
||||
static u32 addr;
|
||||
};
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "PPUThread.h"
|
||||
#include "Utilities/sysinfo.h"
|
||||
#include "Emu/Cell/Common.h"
|
||||
#include "Emu/Cell/PPUFunction.h"
|
||||
|
||||
#include <bit>
|
||||
#include <cmath>
|
||||
@ -5173,5 +5174,15 @@ bool ppu_interpreter::FCFID(ppu_thread& ppu, ppu_opcode_t op)
|
||||
|
||||
bool ppu_interpreter::UNK(ppu_thread& ppu, ppu_opcode_t op)
|
||||
{
|
||||
// HLE function index
|
||||
const u32 index = (ppu.cia - ppu_function_manager::addr) / 8;
|
||||
|
||||
const auto& hle_funcs = ppu_function_manager::get();
|
||||
|
||||
if (ppu.cia % 8 == 4 && index < hle_funcs.size())
|
||||
{
|
||||
return hle_funcs[index](ppu);
|
||||
}
|
||||
|
||||
fmt::throw_exception("Unknown/Illegal opcode: 0x%08x at 0x%x", op.opcode, ppu.cia);
|
||||
}
|
||||
|
@ -253,13 +253,13 @@ static void ppu_initialize_modules(ppu_linkage_info* link)
|
||||
// Fill the array (visible data: self address and function index)
|
||||
for (u32 addr = ppu_function_manager::addr, index = 0; index < hle_funcs.size(); addr += 8, index++)
|
||||
{
|
||||
// Function address = current address, RTOC = BLR instruction for the interpreter
|
||||
vm::write32(addr + 0, addr);
|
||||
vm::write32(addr + 4, ppu_instructions::BLR());
|
||||
// Function address = next CIA, RTOC = 0 (vm::null)
|
||||
vm::write32(addr + 0, addr + 4);
|
||||
vm::write32(addr + 4, 0);
|
||||
|
||||
// Register the HLE function directly
|
||||
ppu_register_function_at(addr + 0, 4, hle_funcs[index]);
|
||||
ppu_register_function_at(addr + 4, 4, nullptr);
|
||||
ppu_register_function_at(addr + 0, 4, nullptr);
|
||||
ppu_register_function_at(addr + 4, 4, hle_funcs[index]);
|
||||
}
|
||||
|
||||
// Set memory protection to read-only
|
||||
@ -303,7 +303,7 @@ static void ppu_initialize_modules(ppu_linkage_info* link)
|
||||
auto& flink = linkage.functions[function.first];
|
||||
|
||||
flink.static_func = &function.second;
|
||||
flink.export_addr = ppu_function_manager::addr + 8 * function.second.index;
|
||||
flink.export_addr = ppu_function_manager::func_addr(function.second.index);
|
||||
function.second.export_addr = &flink.export_addr;
|
||||
}
|
||||
}
|
||||
@ -507,7 +507,7 @@ static auto ppu_load_exports(ppu_linkage_info* link, u32 exports_start, u32 expo
|
||||
// Function linkage info
|
||||
auto& flink = mlink.functions[fnid];
|
||||
|
||||
if (flink.static_func && flink.export_addr == ppu_function_manager::addr + 8 * flink.static_func->index)
|
||||
if (flink.static_func && flink.export_addr == ppu_function_manager::func_addr(flink.static_func->index))
|
||||
{
|
||||
flink.export_addr = 0;
|
||||
}
|
||||
@ -525,10 +525,10 @@ static auto ppu_load_exports(ppu_linkage_info* link, u32 exports_start, u32 expo
|
||||
{
|
||||
// Inject a branch to the HLE implementation
|
||||
const u32 _entry = vm::read32(faddr);
|
||||
const u32 target = ppu_function_manager::addr + 8 * _sf->index;
|
||||
const u32 target = ppu_function_manager::func_addr(_sf->index) + 4;
|
||||
|
||||
// Set exported function
|
||||
flink.export_addr = target;
|
||||
flink.export_addr = target - 4;
|
||||
|
||||
if ((target <= _entry && _entry - target <= 0x2000000) || (target > _entry && target - _entry < 0x2000000))
|
||||
{
|
||||
@ -1107,7 +1107,7 @@ void ppu_unload_prx(const lv2_prx& prx)
|
||||
// auto pinfo = static_cast<ppu_linkage_info::module_data::info*>(exp.second);
|
||||
// if (pinfo->static_func)
|
||||
// {
|
||||
// pinfo->export_addr = ppu_function_manager::addr + 8 * pinfo->static_func->index;
|
||||
// pinfo->export_addr = ppu_function_manager::func_addr(pinfo->static_func->index);
|
||||
// }
|
||||
// else if (pinfo->static_var)
|
||||
// {
|
||||
|
@ -183,21 +183,11 @@ void ppu_reservation_fallback(ppu_thread& ppu)
|
||||
{
|
||||
const auto& table = g_ppu_interpreter_fast.get_table();
|
||||
|
||||
const u32 min_hle = ppu_function_manager::addr ? ppu_function_manager::addr : UINT32_MAX;
|
||||
const u32 max_hle = min_hle + ppu_function_manager::get().size() * 8 - 1;
|
||||
|
||||
while (true)
|
||||
{
|
||||
// Run instructions in interpreter
|
||||
const u32 op = vm::read32(ppu.cia);
|
||||
|
||||
if (op == ppu.cia && ppu.cia >= min_hle && ppu.cia <= max_hle)
|
||||
{
|
||||
// HLE function
|
||||
// ppu.raddr = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (table[ppu_decode(op)](ppu, {op})) [[likely]]
|
||||
{
|
||||
ppu.cia += 4;
|
||||
@ -643,7 +633,7 @@ std::vector<std::pair<u32, u32>> ppu_thread::dump_callstack_list() const
|
||||
}
|
||||
|
||||
// Ignore HLE stop address
|
||||
return addr == ppu_function_manager::addr + 8;
|
||||
return addr == ppu_function_manager::func_addr(1) + 4;
|
||||
};
|
||||
|
||||
if (is_invalid(addr))
|
||||
@ -1039,7 +1029,7 @@ void ppu_thread::fast_call(u32 addr, u32 rtoc)
|
||||
|
||||
cia = addr;
|
||||
gpr[2] = rtoc;
|
||||
lr = ppu_function_manager::addr + 8; // HLE stop address
|
||||
lr = ppu_function_manager::func_addr(1) + 4; // HLE stop address
|
||||
current_function = nullptr;
|
||||
|
||||
g_tls_log_prefix = []
|
||||
|
Loading…
Reference in New Issue
Block a user