1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-22 02:32:36 +01:00

Fix std::basic_string warnings (#16261)

This commit is contained in:
oltolm 2024-11-11 20:54:44 +01:00 committed by GitHub
parent 2262ac1684
commit 2b0f786b2d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 147 additions and 130 deletions

View File

@ -4,6 +4,7 @@
#include "StrUtil.h" #include "StrUtil.h"
#include "Crypto/sha1.h" #include "Crypto/sha1.h"
#include <span>
#include <unordered_map> #include <unordered_map>
#include <algorithm> #include <algorithm>
#include <cstring> #include <cstring>
@ -293,7 +294,7 @@ namespace fs
struct id_view struct id_view
{ {
std::string_view type_view; std::string_view type_view;
std::basic_string_view<u8> data_view; std::span<const u8> data_view;
}; };
id_view _rhs{rhs.type, {rhs.data.data(), rhs.data.size()}}; id_view _rhs{rhs.type, {rhs.data.data(), rhs.data.size()}};
@ -311,7 +312,7 @@ namespace fs
} }
// Remove offsets data // Remove offsets data
id.data_view.remove_suffix(sizeof(u64) * offset_count); id.data_view = id.data_view.subspan(sizeof(u64) * offset_count);
// Get last category identifier // Get last category identifier
if (usz sep = id.type_view.rfind(": "); sep != umax) if (usz sep = id.type_view.rfind(": "); sep != umax)
@ -329,7 +330,7 @@ namespace fs
return false; return false;
} }
return _rhs.type_view == _lhs.type_view && _rhs.data_view == _lhs.data_view; return _rhs.type_view == _lhs.type_view && std::equal(_rhs.data_view.begin(), _rhs.data_view.end(), _lhs.data_view.begin(), _lhs.data_view.end());
} }
dir_base::~dir_base() dir_base::~dir_base()

View File

@ -9,11 +9,11 @@
#include "Emu/VFS.h" #include "Emu/VFS.h"
#include "util/types.hpp" #include "util/types.hpp"
#include "util/endian.hpp"
#include "util/asm.hpp" #include "util/asm.hpp"
#include <charconv> #include <charconv>
#include <regex> #include <regex>
#include <vector>
LOG_CHANNEL(patch_log, "PAT"); LOG_CHANNEL(patch_log, "PAT");
@ -907,7 +907,7 @@ void unmap_vm_area(std::shared_ptr<vm::block_t>& ptr)
} }
// Returns old 'applied' size // Returns old 'applied' size
static usz apply_modification(std::basic_string<u32>& applied, patch_engine::patch_info& patch, std::function<u8*(u32, u32)> mem_translate, u32 filesz, u32 min_addr) static usz apply_modification(std::vector<u32>& applied, patch_engine::patch_info& patch, std::function<u8*(u32, u32)> mem_translate, u32 filesz, u32 min_addr)
{ {
const usz old_applied_size = applied.size(); const usz old_applied_size = applied.size();
@ -1447,14 +1447,13 @@ static usz apply_modification(std::basic_string<u32>& applied, patch_engine::pat
return old_applied_size; return old_applied_size;
} }
std::basic_string<u32> patch_engine::apply(const std::string& name, std::function<u8*(u32, u32)> mem_translate, u32 filesz, u32 min_addr) void patch_engine::apply(std::vector<u32>& applied_total, const std::string& name, std::function<u8*(u32, u32)> mem_translate, u32 filesz, u32 min_addr)
{ {
if (!m_map.contains(name)) if (!m_map.contains(name))
{ {
return {}; return;
} }
std::basic_string<u32> applied_total;
const patch_container& container = ::at32(m_map, name); const patch_container& container = ::at32(m_map, name);
const std::string& serial = Emu.GetTitleID(); const std::string& serial = Emu.GetTitleID();
const std::string& app_version = Emu.GetAppVersion(); const std::string& app_version = Emu.GetAppVersion();
@ -1598,8 +1597,6 @@ std::basic_string<u32> patch_engine::apply(const std::string& name, std::functio
} }
} }
} }
return applied_total;
} }
void patch_engine::unload(const std::string& name) void patch_engine::unload(const std::string& name)

View File

@ -215,7 +215,7 @@ public:
void append_title_patches(std::string_view title_id); void append_title_patches(std::string_view title_id);
// Apply patch (returns the number of entries applied) // Apply patch (returns the number of entries applied)
std::basic_string<u32> apply(const std::string& name, std::function<u8*(u32, u32)> mem_translate, u32 filesz = -1, u32 min_addr = 0); void apply(std::vector<u32>& applied_total, const std::string& name, std::function<u8*(u32, u32)> mem_translate, u32 filesz = -1, u32 min_addr = 0);
// Deallocate memory used by patches // Deallocate memory used by patches
void unload(const std::string& name); void unload(const std::string& name);

View File

@ -5,11 +5,11 @@
#include "lz.h" #include "lz.h"
#include "ec.h" #include "ec.h"
#include "Utilities/mutex.h"
#include "Emu/system_utils.hpp" #include "Emu/system_utils.hpp"
#include <cmath>
#include "util/asm.hpp" #include "util/asm.hpp"
#include <algorithm>
#include <span>
LOG_CHANNEL(edat_log, "EDAT"); LOG_CHANNEL(edat_log, "EDAT");
@ -614,9 +614,11 @@ bool validate_npd_hashes(std::string_view file_name, const u8* klicensee, NPD_HE
std::memcpy(buf_lower.get(), buf.get(), buf_len); std::memcpy(buf_lower.get(), buf.get(), buf_len);
std::memcpy(buf_upper.get(), buf.get(), buf_len); std::memcpy(buf_upper.get(), buf.get(), buf_len);
for (usz i = std::basic_string_view<u8>(buf.get() + 0x30, file_name.size()).find_last_of('.'); i < buf_len; i++) const auto buf_span = std::span(buf.get(), buf.get() + buf_len);
const auto it = std::find(buf_span.rbegin(), buf_span.rend() - 0x30, '.');
for (usz i = std::distance(it, buf_span.rend()) - 1; i < buf_len; ++i)
{ {
const u8 c = static_cast<u8>(buf[i]); const u8 c = buf[i];
buf_upper[i] = std::toupper(c); buf_upper[i] = std::toupper(c);
buf_lower[i] = std::tolower(c); buf_lower[i] = std::tolower(c);
} }

View File

@ -17,9 +17,10 @@
#include "Utilities/StrUtil.h" #include "Utilities/StrUtil.h"
#include "Emu/Cell/lv2/sys_event.h" #include "Emu/Cell/lv2/sys_event.h"
#include "Emu/Cell/lv2/sys_process.h"
#include "Emu/Cell/lv2/sys_fs.h" #include "Emu/Cell/lv2/sys_fs.h"
#include <algorithm>
#include <functional>
#include <shared_mutex> #include <shared_mutex>
#include "util/asm.hpp" #include "util/asm.hpp"
@ -479,7 +480,7 @@ error_code sceNpTrophyCreateContext(vm::ptr<u32> context, vm::cptr<SceNpCommunic
return SCE_NP_TROPHY_ERROR_INVALID_NP_COMM_ID; return SCE_NP_TROPHY_ERROR_INVALID_NP_COMM_ID;
} }
if (std::basic_string_view<u8>(&commSign_data.data[6], 6).find_first_not_of('\0') != umax) if (std::any_of(&commSign_data.data[6], &commSign_data.data[6] + 6, FN(x != '\0')))
{ {
// 6 padding bytes - must be 0 // 6 padding bytes - must be 0
return SCE_NP_TROPHY_ERROR_INVALID_NP_COMM_ID; return SCE_NP_TROPHY_ERROR_INVALID_NP_COMM_ID;

View File

@ -2,8 +2,7 @@
#include "PPUAnalyser.h" #include "PPUAnalyser.h"
#include "PPUOpcodes.h" #include "PPUOpcodes.h"
#include "PPUModule.h" #include "PPUThread.h"
#include "Emu/system_config.h"
#include <unordered_set> #include <unordered_set>
#include "util/yaml.hpp" #include "util/yaml.hpp"
@ -530,7 +529,7 @@ namespace ppu_patterns
}; };
} }
bool ppu_module::analyse(u32 lib_toc, u32 entry, const u32 sec_end, const std::basic_string<u32>& applied, const std::vector<u32>& exported_funcs, std::function<bool()> check_aborted) bool ppu_module::analyse(u32 lib_toc, u32 entry, const u32 sec_end, const std::vector<u32>& applied, const std::vector<u32>& exported_funcs, std::function<bool()> check_aborted)
{ {
if (segs.empty()) if (segs.empty())
{ {

View File

@ -109,7 +109,7 @@ struct ppu_module
addr_to_seg_index = info.addr_to_seg_index; addr_to_seg_index = info.addr_to_seg_index;
} }
bool analyse(u32 lib_toc, u32 entry, u32 end, const std::basic_string<u32>& applied, const std::vector<u32>& exported_funcs = std::vector<u32>{}, std::function<bool()> check_aborted = {}); bool analyse(u32 lib_toc, u32 entry, u32 end, const std::vector<u32>& applied, const std::vector<u32>& exported_funcs = std::vector<u32>{}, std::function<bool()> check_aborted = {});
void validate(u32 reloc); void validate(u32 reloc);
template <typename T> template <typename T>
@ -181,7 +181,7 @@ struct main_ppu_module : public ppu_module
{ {
u32 elf_entry{}; u32 elf_entry{};
u32 seg0_code_end{}; u32 seg0_code_end{};
std::basic_string<u32> applied_patches; std::vector<u32> applied_patches;
}; };
// Aux // Aux

View File

@ -27,7 +27,6 @@
#include <span> #include <span>
#include <set> #include <set>
#include <algorithm> #include <algorithm>
#include <shared_mutex>
#include "util/asm.hpp" #include "util/asm.hpp"
LOG_CHANNEL(ppu_loader); LOG_CHANNEL(ppu_loader);
@ -683,7 +682,7 @@ extern bool ppu_register_library_lock(std::string_view libname, bool lock_lib)
} }
// Load and register exports; return special exports found (nameless module) // Load and register exports; return special exports found (nameless module)
static auto ppu_load_exports(const ppu_module& _module, ppu_linkage_info* link, u32 exports_start, u32 exports_end, bool for_observing_callbacks = false, std::vector<u32>* funcs = nullptr, std::basic_string<bool>* loaded_flags = nullptr) static auto ppu_load_exports(const ppu_module& _module, ppu_linkage_info* link, u32 exports_start, u32 exports_end, bool for_observing_callbacks = false, std::vector<u32>* funcs = nullptr, std::basic_string<char>* loaded_flags = nullptr)
{ {
std::unordered_map<u32, u32> result; std::unordered_map<u32, u32> result;
@ -984,7 +983,7 @@ static auto ppu_load_imports(const ppu_module& _module, std::vector<ppu_reloc>&
} }
// For _sys_prx_register_module // For _sys_prx_register_module
void ppu_manual_load_imports_exports(u32 imports_start, u32 imports_size, u32 exports_start, u32 exports_size, std::basic_string<bool>& loaded_flags) void ppu_manual_load_imports_exports(u32 imports_start, u32 imports_size, u32 exports_start, u32 exports_size, std::basic_string<char>& loaded_flags)
{ {
auto& _main = g_fxo->get<main_ppu_module>(); auto& _main = g_fxo->get<main_ppu_module>();
auto& link = g_fxo->get<ppu_linkage_info>(); auto& link = g_fxo->get<ppu_linkage_info>();
@ -1289,7 +1288,7 @@ static void ppu_check_patch_spu_images(const ppu_module& mod, const ppu_segment&
std::string name; std::string name;
std::string dump; std::string dump;
std::basic_string<u32> applied; std::vector<u32> applied;
// Executable hash // Executable hash
sha1_context sha2; sha1_context sha2;
@ -1363,12 +1362,12 @@ static void ppu_check_patch_spu_images(const ppu_module& mod, const ppu_segment&
} }
// Apply the patch // Apply the patch
applied += g_fxo->get<patch_engine>().apply(hash, [&](u32 addr, u32 /*size*/) { return addr + elf_header + prog.p_offset; }, prog.p_filesz, prog.p_vaddr); g_fxo->get<patch_engine>().apply(applied, hash, [&](u32 addr, u32 /*size*/) { return addr + elf_header + prog.p_offset; }, prog.p_filesz, prog.p_vaddr);
if (!Emu.GetTitleID().empty()) if (!Emu.GetTitleID().empty())
{ {
// Alternative patch // Alternative patch
applied += g_fxo->get<patch_engine>().apply(Emu.GetTitleID() + '-' + hash, [&](u32 addr, u32 /*size*/) { return addr + elf_header + prog.p_offset; }, prog.p_filesz, prog.p_vaddr); g_fxo->get<patch_engine>().apply(applied, Emu.GetTitleID() + '-' + hash, [&](u32 addr, u32 /*size*/) { return addr + elf_header + prog.p_offset; }, prog.p_filesz, prog.p_vaddr);
} }
} }
@ -1830,7 +1829,7 @@ std::shared_ptr<lv2_prx> ppu_load_prx(const ppu_prx_object& elf, bool virtual_lo
liblv2_end = prx->segs[0].addr + prx->segs[0].size; liblv2_end = prx->segs[0].addr + prx->segs[0].size;
} }
std::basic_string<u32> applied; std::vector<u32> applied;
for (usz i = Emu.DeserialManager() ? prx->segs.size() : 0; i < prx->segs.size(); i++) for (usz i = Emu.DeserialManager() ? prx->segs.size() : 0; i < prx->segs.size(); i++)
{ {
@ -1841,18 +1840,19 @@ std::shared_ptr<lv2_prx> ppu_load_prx(const ppu_prx_object& elf, bool virtual_lo
const std::string hash_seg = fmt::format("%s-%u", hash, i); const std::string hash_seg = fmt::format("%s-%u", hash, i);
// Apply the patch // Apply the patch
auto _applied = g_fxo->get<patch_engine>().apply(hash_seg, [&](u32 addr, u32 size) { return prx->get_ptr<u8>(addr + seg.addr, size); }, seg.size); std::vector<u32> _applied;
g_fxo->get<patch_engine>().apply(_applied, hash_seg, [&](u32 addr, u32 size) { return prx->get_ptr<u8>(addr + seg.addr, size); }, seg.size);
if (!Emu.GetTitleID().empty()) if (!Emu.GetTitleID().empty())
{ {
// Alternative patch // Alternative patch
_applied += g_fxo->get<patch_engine>().apply(Emu.GetTitleID() + '-' + hash_seg, [&](u32 addr, u32 size) { return prx->get_ptr<u8>(addr + seg.addr, size); }, seg.size); g_fxo->get<patch_engine>().apply(_applied, Emu.GetTitleID() + '-' + hash_seg, [&](u32 addr, u32 size) { return prx->get_ptr<u8>(addr + seg.addr, size); }, seg.size);
} }
// Rebase patch offsets // Rebase patch offsets
std::for_each(_applied.begin(), _applied.end(), [&](u32& res) { if (res != umax) res += seg.addr; }); std::for_each(_applied.begin(), _applied.end(), [&](u32& res) { if (res != umax) res += seg.addr; });
applied += _applied; applied.insert(applied.end(), _applied.begin(), _applied.end());
if (_applied.empty()) if (_applied.empty())
{ {
@ -1877,10 +1877,11 @@ std::shared_ptr<lv2_prx> ppu_load_prx(const ppu_prx_object& elf, bool virtual_lo
// Find the first segment // Find the first segment
if (prog.p_type == 0x1u /* LOAD */ && prog.p_memsz) if (prog.p_type == 0x1u /* LOAD */ && prog.p_memsz)
{ {
std::basic_string_view<uchar> elf_memory{prog.bin.data(), prog.bin.size()}; std::span<const uchar> elf_memory{prog.bin.begin(), prog.bin.size()};
elf_memory.remove_prefix(end - prx->segs[0].addr); elf_memory = elf_memory.subspan(end - prx->segs[0].addr);
if (elf_memory != std::basic_string_view<uchar>{&prx->get_ref<uchar>(end), elf_memory.size()}) const auto tmp = std::span<uchar>{&prx->get_ref<uchar>(end), elf_memory.size()};
if (!std::equal(elf_memory.begin(), elf_memory.end(), tmp.begin(), tmp.end()))
{ {
// There are changes, disable analysis optimization // There are changes, disable analysis optimization
ppu_loader.notice("Disabling analysis optimization due to memory changes from original file"); ppu_loader.notice("Disabling analysis optimization due to memory changes from original file");
@ -2198,12 +2199,13 @@ bool ppu_load_exec(const ppu_exec_object& elf, bool virtual_load, const std::str
Emu.SetExecutableHash(hash); Emu.SetExecutableHash(hash);
// Apply the patch // Apply the patch
auto applied = g_fxo->get<patch_engine>().apply(!ar ? hash : std::string{}, [&](u32 addr, u32 size) { return _main.get_ptr<u8>(addr, size); }); std::vector<u32> applied;
g_fxo->get<patch_engine>().apply(applied, !ar ? hash : std::string{}, [&](u32 addr, u32 size) { return _main.get_ptr<u8>(addr, size); });
if (!ar && !Emu.GetTitleID().empty()) if (!ar && !Emu.GetTitleID().empty())
{ {
// Alternative patch // Alternative patch
applied += g_fxo->get<patch_engine>().apply(Emu.GetTitleID() + '-' + hash, [&](u32 addr, u32 size) { return _main.get_ptr<u8>(addr, size); }); g_fxo->get<patch_engine>().apply(applied, Emu.GetTitleID() + '-' + hash, [&](u32 addr, u32 size) { return _main.get_ptr<u8>(addr, size); });
} }
if (!applied.empty() || ar) if (!applied.empty() || ar)
@ -2216,10 +2218,11 @@ bool ppu_load_exec(const ppu_exec_object& elf, bool virtual_load, const std::str
// Find the first segment // Find the first segment
if (prog.p_type == 0x1u /* LOAD */ && prog.p_memsz) if (prog.p_type == 0x1u /* LOAD */ && prog.p_memsz)
{ {
std::basic_string_view<uchar> elf_memory{prog.bin.data(), prog.bin.size()}; std::span<const uchar> elf_memory{prog.bin.begin(), prog.bin.size()};
elf_memory.remove_prefix(end - _main.segs[0].addr); elf_memory = elf_memory.subspan(end - _main.segs[0].addr);
if (elf_memory != std::basic_string_view<uchar>{&_main.get_ref<u8>(end), elf_memory.size()}) const auto tmp = std::span<uchar>{&_main.get_ref<u8>(end), elf_memory.size()};
if (!std::equal(elf_memory.begin(), elf_memory.end(), tmp.begin(), tmp.end()))
{ {
// There are changes, disable analysis optimization // There are changes, disable analysis optimization
ppu_loader.notice("Disabling analysis optimization due to memory changes from original file"); ppu_loader.notice("Disabling analysis optimization due to memory changes from original file");
@ -2881,12 +2884,13 @@ std::pair<std::shared_ptr<lv2_overlay>, CellError> ppu_load_overlay(const ppu_ex
} }
// Apply the patch // Apply the patch
auto applied = g_fxo->get<patch_engine>().apply(!Emu.DeserialManager() ? hash : std::string{}, [ovlm](u32 addr, u32 size) { return ovlm->get_ptr<u8>(addr, size); }); std::vector<u32> applied;
g_fxo->get<patch_engine>().apply(applied, !Emu.DeserialManager() ? hash : std::string{}, [ovlm](u32 addr, u32 size) { return ovlm->get_ptr<u8>(addr, size); });
if (!Emu.DeserialManager() && !Emu.GetTitleID().empty()) if (!Emu.DeserialManager() && !Emu.GetTitleID().empty())
{ {
// Alternative patch // Alternative patch
applied += g_fxo->get<patch_engine>().apply(Emu.GetTitleID() + '-' + hash, [ovlm](u32 addr, u32 size) { return ovlm->get_ptr<u8>(addr, size); }); g_fxo->get<patch_engine>().apply(applied, Emu.GetTitleID() + '-' + hash, [ovlm](u32 addr, u32 size) { return ovlm->get_ptr<u8>(addr, size); });
} }
if (!applied.empty() || ar) if (!applied.empty() || ar)
@ -2899,10 +2903,10 @@ std::pair<std::shared_ptr<lv2_overlay>, CellError> ppu_load_overlay(const ppu_ex
// Find the first segment // Find the first segment
if (prog.p_type == 0x1u /* LOAD */ && prog.p_memsz) if (prog.p_type == 0x1u /* LOAD */ && prog.p_memsz)
{ {
std::basic_string_view<uchar> elf_memory{prog.bin.data(), prog.bin.size()}; std::span<const uchar> elf_memory{prog.bin.begin(), prog.bin.size()};
elf_memory.remove_prefix(end - ovlm->segs[0].addr); elf_memory = elf_memory.subspan(end - ovlm->segs[0].addr);
if (elf_memory != std::basic_string_view<uchar>{&ovlm->get_ref<u8>(end), elf_memory.size()}) if (!std::equal(elf_memory.begin(), elf_memory.end(), &ovlm->get_ref<u8>(end)))
{ {
// There are changes, disable analysis optimization // There are changes, disable analysis optimization
ppu_loader.notice("Disabling analysis optimization due to memory changes from original file"); ppu_loader.notice("Disabling analysis optimization due to memory changes from original file");

View File

@ -20,6 +20,7 @@
#include "SPUInterpreter.h" #include "SPUInterpreter.h"
#include "SPUDisAsm.h" #include "SPUDisAsm.h"
#include <algorithm> #include <algorithm>
#include <cstring>
#include <optional> #include <optional>
#include <unordered_set> #include <unordered_set>
@ -33,6 +34,15 @@ const extern spu_decoder<spu_iflag> g_spu_iflag;
constexpr u32 s_reg_max = spu_recompiler_base::s_reg_max; constexpr u32 s_reg_max = spu_recompiler_base::s_reg_max;
template<typename T>
struct span_less
{
bool operator()(const std::span<T>& this_, const std::span<T>& that) const
{
return std::memcmp(this_.data(), that.data(), std::min(this_.size_bytes(), that.size_bytes())) < 0;
}
};
// Move 4 args for calling native function from a GHC calling convention function // Move 4 args for calling native function from a GHC calling convention function
#if defined(ARCH_X64) #if defined(ARCH_X64)
static u8* move_args_ghc_to_native(u8* raw) static u8* move_args_ghc_to_native(u8* raw)
@ -533,7 +543,7 @@ extern void utilize_spu_data_segment(u32 vaddr, const void* ls_data_vaddr, u32 s
return; return;
} }
std::basic_string<u32> data(size / 4, 0); std::vector<u32> data(size / 4, 0);
std::memcpy(data.data(), ls_data_vaddr, size); std::memcpy(data.data(), ls_data_vaddr, size);
spu_cache::precompile_data_t obj{vaddr, std::move(data)}; spu_cache::precompile_data_t obj{vaddr, std::move(data)};
@ -926,7 +936,7 @@ void spu_cache::initialize(bool build_existing_cache)
u32 next_func = 0; u32 next_func = 0;
u32 sec_addr = umax; u32 sec_addr = umax;
u32 sec_idx = 0; u32 sec_idx = 0;
std::basic_string_view<u32> inst_data; std::vector<u32> inst_data;
// Try to get the data this index points to // Try to get the data this index points to
for (auto& sec : data_list) for (auto& sec : data_list)
@ -976,7 +986,7 @@ void spu_cache::initialize(bool build_existing_cache)
u32 block_addr = func_addr; u32 block_addr = func_addr;
std::map<u32, std::basic_string<u32>> targets; std::map<u32, std::vector<u32>> targets;
// Call analyser // Call analyser
spu_program func2 = compiler->analyse(ls.data(), block_addr, &targets); spu_program func2 = compiler->analyse(ls.data(), block_addr, &targets);
@ -1135,12 +1145,12 @@ void spu_cache::initialize(bool build_existing_cache)
std::string dump; std::string dump;
dump.reserve(10'000'000); dump.reserve(10'000'000);
std::map<std::basic_string_view<u8>, spu_program*> sorted; std::map<std::span<u8>, spu_program*, span_less<u8>> sorted;
for (auto&& f : func_list) for (auto&& f : func_list)
{ {
// Interpret as a byte string // Interpret as a byte string
std::basic_string_view<u8> data = {reinterpret_cast<u8*>(f.data.data()), f.data.size() * sizeof(u32)}; std::span<u8> data = {reinterpret_cast<u8*>(f.data.data()), f.data.size() * sizeof(u32)};
sorted[data] = &f; sorted[data] = &f;
} }
@ -1252,9 +1262,9 @@ bool spu_program::operator<(const spu_program& rhs) const noexcept
const u32 rhs_offs = (rhs.entry_point - rhs.lower_bound) / 4; const u32 rhs_offs = (rhs.entry_point - rhs.lower_bound) / 4;
// Select range for comparison // Select range for comparison
std::basic_string_view<u32> lhs_data(data.data() + lhs_offs, data.size() - lhs_offs); std::span<const u32> lhs_data(data.data() + lhs_offs, data.size() - lhs_offs);
std::basic_string_view<u32> rhs_data(rhs.data.data() + rhs_offs, rhs.data.size() - rhs_offs); std::span<const u32> rhs_data(rhs.data.data() + rhs_offs, rhs.data.size() - rhs_offs);
const auto cmp0 = lhs_data.compare(rhs_data); const auto cmp0 = std::memcmp(lhs_data.data(), rhs_data.data(), std::min(lhs_data.size_bytes(), rhs_data.size_bytes()));
if (cmp0 < 0) if (cmp0 < 0)
return true; return true;
@ -1264,7 +1274,7 @@ bool spu_program::operator<(const spu_program& rhs) const noexcept
// Compare from address 0 to the point before the entry point (TODO: undesirable) // Compare from address 0 to the point before the entry point (TODO: undesirable)
lhs_data = {data.data(), lhs_offs}; lhs_data = {data.data(), lhs_offs};
rhs_data = {rhs.data.data(), rhs_offs}; rhs_data = {rhs.data.data(), rhs_offs};
const auto cmp1 = lhs_data.compare(rhs_data); const auto cmp1 = std::memcmp(lhs_data.data(), rhs_data.data(), std::min(lhs_data.size_bytes(), rhs_data.size_bytes()));
if (cmp1 < 0) if (cmp1 < 0)
return true; return true;
@ -1330,7 +1340,7 @@ spu_item* spu_runtime::add_empty(spu_program&& data)
spu_function_t spu_runtime::rebuild_ubertrampoline(u32 id_inst) spu_function_t spu_runtime::rebuild_ubertrampoline(u32 id_inst)
{ {
// Prepare sorted list // Prepare sorted list
static thread_local std::vector<std::pair<std::basic_string_view<u32>, spu_function_t>> m_flat_list; static thread_local std::vector<std::pair<std::span<const u32>, spu_function_t>> m_flat_list;
// Remember top position // Remember top position
auto stuff_it = ::at32(m_stuff, id_inst >> 12).begin(); auto stuff_it = ::at32(m_stuff, id_inst >> 12).begin();
@ -1347,8 +1357,8 @@ spu_function_t spu_runtime::rebuild_ubertrampoline(u32 id_inst)
{ {
if (const auto ptr = it->compiled.load()) if (const auto ptr = it->compiled.load())
{ {
std::basic_string_view<u32> range{it->data.data.data(), it->data.data.size()}; std::span<const u32> range{it->data.data.data(), it->data.data.size()};
range.remove_prefix((it->data.entry_point - it->data.lower_bound) / 4); range = range.subspan((it->data.entry_point - it->data.lower_bound) / 4);
m_flat_list.emplace_back(range, ptr); m_flat_list.emplace_back(range, ptr);
} }
else else
@ -1359,7 +1369,7 @@ spu_function_t spu_runtime::rebuild_ubertrampoline(u32 id_inst)
} }
} }
std::sort(m_flat_list.begin(), m_flat_list.end(), FN(x.first < y.first)); std::sort(m_flat_list.begin(), m_flat_list.end(), FN(std::memcmp(x.first.data(), y.first.data(), std::min(x.first.size_bytes(), y.first.size_bytes())) < 0));
struct work struct work
{ {
@ -1551,13 +1561,13 @@ spu_function_t spu_runtime::rebuild_ubertrampoline(u32 id_inst)
// Resort subrange starting from the new level // Resort subrange starting from the new level
std::stable_sort(w.beg, w.end, [&](const auto& a, const auto& b) std::stable_sort(w.beg, w.end, [&](const auto& a, const auto& b)
{ {
std::basic_string_view<u32> lhs = a.first; std::span<const u32> lhs = a.first;
std::basic_string_view<u32> rhs = b.first; std::span<const u32> rhs = b.first;
lhs.remove_prefix(w.level); lhs = lhs.subspan(w.level);
rhs.remove_prefix(w.level); rhs = rhs.subspan(w.level);
return lhs < rhs; return std::memcmp(lhs.data(), rhs.data(), std::min(lhs.size_bytes(), rhs.size_bytes())) < 0;
}); });
continue; continue;
@ -1919,15 +1929,15 @@ spu_function_t spu_runtime::find(const u32* ls, u32 addr) const
{ {
if (const auto ptr = item.compiled.load()) if (const auto ptr = item.compiled.load())
{ {
std::basic_string_view<u32> range{item.data.data.data(), item.data.data.size()}; std::span<const u32> range{item.data.data.data(), item.data.data.size()};
range.remove_prefix((item.data.entry_point - item.data.lower_bound) / 4); range = range.subspan((item.data.entry_point - item.data.lower_bound) / 4);
if (addr / 4 + range.size() > 0x10000) if (addr / 4 + range.size() > 0x10000)
{ {
continue; continue;
} }
if (range.compare(0, range.size(), ls + addr / 4, range.size()) == 0) if (std::equal(range.begin(), range.end(), ls + addr / 4))
{ {
return ptr; return ptr;
} }
@ -2836,7 +2846,7 @@ struct block_reg_info
} }
}; };
spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, std::map<u32, std::basic_string<u32>>* out_target_list) spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, std::map<u32, std::vector<u32>>* out_target_list)
{ {
// Result: addr + raw instruction data // Result: addr + raw instruction data
spu_program result; spu_program result;
@ -2920,7 +2930,7 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
} }
// Add predecessor // Add predecessor
if (m_preds[target].find_first_of(pos) + 1 == 0) if (std::find(m_preds[target].begin(), m_preds[target].end(), pos) == m_preds[target].end())
{ {
m_preds[target].push_back(pos); m_preds[target].push_back(pos);
} }
@ -3077,8 +3087,8 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
else if (type == spu_itype::BI && g_cfg.core.spu_block_size != spu_block_size_type::safe && !op.d && !op.e && !sync) else if (type == spu_itype::BI && g_cfg.core.spu_block_size != spu_block_size_type::safe && !op.d && !op.e && !sync)
{ {
// Analyse jump table (TODO) // Analyse jump table (TODO)
std::basic_string<u32> jt_abs; std::vector<u32> jt_abs;
std::basic_string<u32> jt_rel; std::vector<u32> jt_rel;
const u32 start = pos + 4; const u32 start = pos + 4;
u64 dabs = 0; u64 dabs = 0;
u64 drel = 0; u64 drel = 0;
@ -3585,7 +3595,7 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
} }
// All (direct and indirect) predecessors to check // All (direct and indirect) predecessors to check
std::basic_string<u32> workload; std::vector<u32> workload;
// Bit array used to deduplicate workload list // Bit array used to deduplicate workload list
workload.push_back(pair.first); workload.push_back(pair.first);
@ -4028,7 +4038,7 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
workload.push_back(entry_point); workload.push_back(entry_point);
ensure(m_bbs.count(entry_point)); ensure(m_bbs.count(entry_point));
std::basic_string<u32> new_entries; std::vector<u32> new_entries;
for (u32 wi = 0; wi < workload.size(); wi++) for (u32 wi = 0; wi < workload.size(); wi++)
{ {
@ -4707,7 +4717,7 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
{ {
if (target < bb.func || target >= flim || (bb.terminator == term_type::call && target == bb.func)) if (target < bb.func || target >= flim || (bb.terminator == term_type::call && target == bb.func))
{ {
if (func.calls.find_first_of(target) + 1 == 0) if (std::find(func.calls.begin(), func.calls.end(), target) == func.calls.end())
{ {
func.calls.push_back(target); func.calls.push_back(target);
} }
@ -4861,7 +4871,7 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
reg_state_t ch_state{+vf::is_null}; // Channel stat, example: RCNCNT ch_state, MFC_Cmd reg_state_t ch_state{+vf::is_null}; // Channel stat, example: RCNCNT ch_state, MFC_Cmd
reg_state_t ch_product{+vf::is_null}; // Optional comparison state for channl state, example: CEQI ch_product, ch_state, 1 reg_state_t ch_product{+vf::is_null}; // Optional comparison state for channl state, example: CEQI ch_product, ch_state, 1
bool product_test_negate = false; // Compare the opposite way, such as: CEQI ch_product, ch_state, 0 which turns 0 t -1 and 1 to 0 bool product_test_negate = false; // Compare the opposite way, such as: CEQI ch_product, ch_state, 0 which turns 0 t -1 and 1 to 0
std::basic_string<u32> origins; std::vector<u32> origins;
u32 branch_pc = SPU_LS_SIZE; // Where the loop branch is located u32 branch_pc = SPU_LS_SIZE; // Where the loop branch is located
u32 branch_target = SPU_LS_SIZE; // The target of the loop branch u32 branch_target = SPU_LS_SIZE; // The target of the loop branch
@ -5216,7 +5226,7 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
u32 stackframe_pc = SPU_LS_SIZE; u32 stackframe_pc = SPU_LS_SIZE;
usz entry_index = umax; usz entry_index = umax;
auto get_block_targets = [&](u32 pc) -> std::basic_string_view<u32> auto get_block_targets = [&](u32 pc) -> std::span<u32>
{ {
if (m_block_info[pc / 4] && m_bbs.count(pc)) if (m_block_info[pc / 4] && m_bbs.count(pc))
{ {
@ -5658,7 +5668,7 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
if (rchcnt_loop->active) if (rchcnt_loop->active)
{ {
if (rchcnt_loop->origins.find_first_of(pos) != umax) if (std::find(rchcnt_loop->origins.begin(), rchcnt_loop->origins.end(), pos) != rchcnt_loop->origins.end())
{ {
rchcnt_loop->failed = true; rchcnt_loop->failed = true;
rchcnt_loop->active = false; rchcnt_loop->active = false;
@ -7032,7 +7042,7 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
if (rchcnt_loop->active) if (rchcnt_loop->active)
{ {
if (rchcnt_loop->origins.find_first_of(vregs[op_rt].origin) == umax) if (std::find(rchcnt_loop->origins.begin(), rchcnt_loop->origins.end(), vregs[op_rt].origin) == rchcnt_loop->origins.end())
{ {
rchcnt_loop->origins.push_back(vregs[op_rt].origin); rchcnt_loop->origins.push_back(vregs[op_rt].origin);
} }
@ -8002,7 +8012,7 @@ std::array<reg_state_t, s_reg_max>& block_reg_info::evaluate_start_state(const s
if (!has_true_state) if (!has_true_state)
{ {
std::array<reg_state_t, s_reg_max> temp; std::array<reg_state_t, s_reg_max> temp;
std::basic_string<u32> been_there; std::vector<u32> been_there;
struct iterator_info struct iterator_info
{ {

View File

@ -13,10 +13,8 @@
#include "SPUThread.h" #include "SPUThread.h"
#include "SPUAnalyser.h" #include "SPUAnalyser.h"
#include "SPUInterpreter.h" #include "SPUInterpreter.h"
#include "SPUDisAsm.h"
#include <algorithm> #include <algorithm>
#include <thread> #include <thread>
#include <unordered_set>
#include "util/v128.hpp" #include "util/v128.hpp"
#include "util/simd.hpp" #include "util/simd.hpp"
@ -406,7 +404,7 @@ class spu_llvm_recompiler : public spu_recompiler_base, public cpu_translator
llvm::BasicBlock* add_block(u32 target, bool absolute = false) llvm::BasicBlock* add_block(u32 target, bool absolute = false)
{ {
// Check the predecessor // Check the predecessor
const bool pred_found = m_block_info[target / 4] && m_preds[target].find_first_of(m_pos) + 1; const bool pred_found = m_block_info[target / 4] && std::find(m_preds[target].begin(), m_preds[target].end(), m_pos) != m_preds[target].end();
if (m_blocks.empty()) if (m_blocks.empty())
{ {
@ -2053,7 +2051,7 @@ public:
{ {
const auto tfound = m_targets.find(m_pos); const auto tfound = m_targets.find(m_pos);
if (tfound == m_targets.end() || tfound->second.find_first_of(target) + 1 == 0) if (tfound == m_targets.end() || std::find(tfound->second.begin(), tfound->second.end(), target) == tfound->second.end())
{ {
spu_log.error("[%s] Unregistered fallthrough to 0x%x (chunk=0x%x, entry=0x%x)", m_hash, target, m_entry, m_function_queue[0]); spu_log.error("[%s] Unregistered fallthrough to 0x%x (chunk=0x%x, entry=0x%x)", m_hash, target, m_entry, m_function_queue[0]);
} }

View File

@ -40,7 +40,7 @@ public:
struct precompile_data_t struct precompile_data_t
{ {
u32 vaddr; u32 vaddr;
std::basic_string<u32> inst_data; std::vector<u32> inst_data;
std::vector<u32> funcs; std::vector<u32> funcs;
}; };
@ -291,10 +291,10 @@ protected:
std::bitset<0x10000> m_use_rc; std::bitset<0x10000> m_use_rc;
// List of possible targets for the instruction (entry shouldn't exist for simple instructions) // List of possible targets for the instruction (entry shouldn't exist for simple instructions)
std::unordered_map<u32, std::basic_string<u32>, value_hash<u32, 2>> m_targets; std::unordered_map<u32, std::vector<u32>, value_hash<u32, 2>> m_targets;
// List of block predecessors // List of block predecessors
std::unordered_map<u32, std::basic_string<u32>, value_hash<u32, 2>> m_preds; std::unordered_map<u32, std::vector<u32>, value_hash<u32, 2>> m_preds;
// List of function entry points and return points (set after BRSL, BRASL, BISL, BISLED) // List of function entry points and return points (set after BRSL, BRASL, BISL, BISLED)
std::bitset<0x10000> m_entry_info; std::bitset<0x10000> m_entry_info;
@ -351,17 +351,17 @@ protected:
std::array<u32, s_reg_max> reg_origin, reg_origin_abs; std::array<u32, s_reg_max> reg_origin, reg_origin_abs;
// All possible successor blocks // All possible successor blocks
std::basic_string<u32> targets; std::vector<u32> targets;
// All predeccessor blocks // All predeccessor blocks
std::basic_string<u32> preds; std::vector<u32> preds;
}; };
// Sorted basic block info // Sorted basic block info
std::map<u32, block_info> m_bbs; std::map<u32, block_info> m_bbs;
// Sorted advanced block (chunk) list // Sorted advanced block (chunk) list
std::basic_string<u32> m_chunks; std::vector<u32> m_chunks;
// Function information // Function information
struct func_info struct func_info
@ -373,7 +373,7 @@ protected:
bool good = false; bool good = false;
// Call targets // Call targets
std::basic_string<u32> calls; std::vector<u32> calls;
// Register save info (stack offset) // Register save info (stack offset)
std::array<u32, s_reg_max> reg_save_off{}; std::array<u32, s_reg_max> reg_save_off{};
@ -432,7 +432,7 @@ public:
static void old_interpreter(spu_thread&, void* ls, u8*); static void old_interpreter(spu_thread&, void* ls, u8*);
// Get the function data at specified address // Get the function data at specified address
spu_program analyse(const be_t<u32>* ls, u32 entry_point, std::map<u32, std::basic_string<u32>>* out_target_list = nullptr); spu_program analyse(const be_t<u32>* ls, u32 entry_point, std::map<u32, std::vector<u32>>* out_target_list = nullptr);
// Print analyser internal state // Print analyser internal state
void dump(const spu_program& result, std::string& out); void dump(const spu_program& result, std::string& out);

View File

@ -1412,7 +1412,7 @@ std::vector<std::pair<u32, u32>> spu_thread::dump_callstack_list() const
std::vector<bool> passed(_pc / 4); std::vector<bool> passed(_pc / 4);
// Start with PC // Start with PC
std::basic_string<u32> start_points{_pc}; std::vector<u32> start_points{_pc};
bool is_ok = false; bool is_ok = false;
bool all_failed = false; bool all_failed = false;

View File

@ -51,6 +51,7 @@
#include "sys_uart.h" #include "sys_uart.h"
#include "sys_crypto_engine.h" #include "sys_crypto_engine.h"
#include <algorithm>
#include <optional> #include <optional>
#include <deque> #include <deque>
#include "util/tsc.hpp" #include "util/tsc.hpp"
@ -1338,15 +1339,14 @@ bool lv2_obj::sleep(cpu_thread& cpu, const u64 timeout)
{ {
// Ignore outdated notification request // Ignore outdated notification request
} }
else if (usz notify_later_idx = std::basic_string_view<const void*>{g_to_notify, std::size(g_to_notify)}.find_first_of(std::add_pointer_t<const void>{}); else if (auto it = std::find(g_to_notify, std::end(g_to_notify), std::add_pointer_t<const void>{}); it != std::end(g_to_notify))
notify_later_idx != umax)
{ {
g_to_notify[notify_later_idx] = vm::reservation_notifier_notify(addr, true); *it = vm::reservation_notifier_notify(addr, true);
if (notify_later_idx < std::size(g_to_notify) - 1) if (it < std::end(g_to_notify) - 1)
{ {
// Null-terminate the list if it ends before last slot // Null-terminate the list if it ends before last slot
g_to_notify[notify_later_idx + 1] = nullptr; *(it + 1) = nullptr;
} }
} }
else else
@ -1392,15 +1392,14 @@ bool lv2_obj::awake(cpu_thread* thread, s32 prio)
{ {
// Ignore outdated notification request // Ignore outdated notification request
} }
else if (usz notify_later_idx = std::basic_string_view<const void*>{g_to_notify, std::size(g_to_notify)}.find_first_of(std::add_pointer_t<const void>{}); else if (auto it = std::find(g_to_notify, std::end(g_to_notify), std::add_pointer_t<const void>{}); it != std::end(g_to_notify))
notify_later_idx != umax)
{ {
g_to_notify[notify_later_idx] = vm::reservation_notifier_notify(addr, true); *it = vm::reservation_notifier_notify(addr, true);
if (notify_later_idx < std::size(g_to_notify) - 1) if (it < std::end(g_to_notify) - 1)
{ {
// Null-terminate the list if it ends before last slot // Null-terminate the list if it ends before last slot
g_to_notify[notify_later_idx + 1] = nullptr; *(it + 1) = nullptr;
} }
} }
else else
@ -1834,7 +1833,7 @@ void lv2_obj::cleanup()
void lv2_obj::schedule_all(u64 current_time) void lv2_obj::schedule_all(u64 current_time)
{ {
usz notify_later_idx = std::basic_string_view<const void*>{g_to_notify, std::size(g_to_notify)}.find_first_of(std::add_pointer_t<const void>{}); auto it = std::find(g_to_notify, std::end(g_to_notify), std::add_pointer_t<const void>{});
if (!g_pending && g_scheduler_ready) if (!g_pending && g_scheduler_ready)
{ {
@ -1857,14 +1856,14 @@ void lv2_obj::schedule_all(u64 current_time)
continue; continue;
} }
if (notify_later_idx >= std::size(g_to_notify)) if (it == std::end(g_to_notify))
{ {
// Out of notification slots, notify locally (resizable container is not worth it) // Out of notification slots, notify locally (resizable container is not worth it)
target->state.notify_one(); target->state.notify_one();
} }
else else
{ {
g_to_notify[notify_later_idx++] = &target->state; *it++ = &target->state;
} }
} }
} }
@ -1891,14 +1890,14 @@ void lv2_obj::schedule_all(u64 current_time)
ensure(!target->state.test_and_set(cpu_flag::notify)); ensure(!target->state.test_and_set(cpu_flag::notify));
// Otherwise notify it to wake itself // Otherwise notify it to wake itself
if (notify_later_idx >= std::size(g_to_notify)) if (it == std::end(g_to_notify))
{ {
// Out of notification slots, notify locally (resizable container is not worth it) // Out of notification slots, notify locally (resizable container is not worth it)
target->state.notify_one(); target->state.notify_one();
} }
else else
{ {
g_to_notify[notify_later_idx++] = &target->state; *it++ = &target->state;
} }
} }
} }
@ -1909,10 +1908,10 @@ void lv2_obj::schedule_all(u64 current_time)
} }
} }
if (notify_later_idx - 1 < std::size(g_to_notify) - 1) if (it < std::end(g_to_notify) - 1)
{ {
// Null-terminate the list if it ends before last slot // Null-terminate the list if it ends before last slot
g_to_notify[notify_later_idx] = nullptr; *(it + 1) = nullptr;
} }
if (const u64 freq = s_yield_frequency) if (const u64 freq = s_yield_frequency)

View File

@ -1,7 +1,9 @@
#pragma once #pragma once
#include "Emu/Cell/PPUAnalyser.h" #include "Emu/Cell/PPUAnalyser.h"
#include "Emu/Memory/vm_ptr.h"
#include "sys_sync.h" #include "sys_sync.h"
#include <vector>
struct lv2_overlay final : lv2_obj, ppu_module struct lv2_overlay final : lv2_obj, ppu_module
{ {
@ -9,7 +11,7 @@ struct lv2_overlay final : lv2_obj, ppu_module
u32 entry{}; u32 entry{};
u32 seg0_code_end{}; u32 seg0_code_end{};
std::basic_string<u32> applied_patches; std::vector<u32> applied_patches;
lv2_overlay() = default; lv2_overlay() = default;
lv2_overlay(utils::serial&){} lv2_overlay(utils::serial&){}

View File

@ -8,7 +8,7 @@
#include "Crypto/unself.h" #include "Crypto/unself.h"
#include "Loader/ELF.h" #include "Loader/ELF.h"
#include "Emu/Cell/PPUModule.h" #include "Emu/Cell/PPUThread.h"
#include "Emu/Cell/ErrorCodes.h" #include "Emu/Cell/ErrorCodes.h"
#include "Crypto/unedat.h" #include "Crypto/unedat.h"
#include "Utilities/StrUtil.h" #include "Utilities/StrUtil.h"
@ -23,7 +23,7 @@ extern std::shared_ptr<lv2_prx> ppu_load_prx(const ppu_prx_object&, bool virtual
extern void ppu_unload_prx(const lv2_prx& prx); extern void ppu_unload_prx(const lv2_prx& prx);
extern bool ppu_initialize(const ppu_module&, bool check_only = false, u64 file_size = 0); extern bool ppu_initialize(const ppu_module&, bool check_only = false, u64 file_size = 0);
extern void ppu_finalize(const ppu_module& info, bool force_mem_release = false); extern void ppu_finalize(const ppu_module& info, bool force_mem_release = false);
extern void ppu_manual_load_imports_exports(u32 imports_start, u32 imports_size, u32 exports_start, u32 exports_size, std::basic_string<bool>& loaded_flags); extern void ppu_manual_load_imports_exports(u32 imports_start, u32 imports_size, u32 exports_start, u32 exports_size, std::basic_string<char>& loaded_flags);
LOG_CHANNEL(sys_prx); LOG_CHANNEL(sys_prx);
@ -327,7 +327,7 @@ std::shared_ptr<void> lv2_prx::load(utils::serial& ar)
if (seg_count) if (seg_count)
{ {
std::basic_string<bool> loaded_flags, external_flags; std::basic_string<char> loaded_flags, external_flags;
ar(loaded_flags, external_flags); ar(loaded_flags, external_flags);
@ -771,7 +771,7 @@ void lv2_prx::restore_exports()
{ {
constexpr usz sizeof_export_data = 0x1C; constexpr usz sizeof_export_data = 0x1C;
std::basic_string<bool> loaded_flags_empty; std::basic_string<char> loaded_flags_empty;
for (u32 start = exports_start, i = 0; start < exports_end; i++, start += vm::read8(start) ? vm::read8(start) : sizeof_export_data) for (u32 start = exports_start, i = 0; start < exports_end; i++, start += vm::read8(start) ? vm::read8(start) : sizeof_export_data)
{ {
@ -791,7 +791,7 @@ void lv2_prx::unload_exports()
return; return;
} }
std::basic_string<bool> merged = m_loaded_flags; std::basic_string<char> merged = m_loaded_flags;
for (usz i = 0; i < merged.size(); i++) for (usz i = 0; i < merged.size(); i++)
{ {
@ -848,7 +848,7 @@ error_code _sys_prx_register_module(ppu_thread& ppu, vm::cptr<char> name, vm::pt
{ {
if (Emu.IsVsh()) if (Emu.IsVsh())
{ {
ppu_manual_load_imports_exports(info.lib_stub_ea.addr(), info.lib_stub_size, info.lib_entries_ea.addr(), info.lib_entries_size, *std::make_unique<std::basic_string<bool>>()); ppu_manual_load_imports_exports(info.lib_stub_ea.addr(), info.lib_stub_size, info.lib_entries_ea.addr(), info.lib_entries_size, *std::make_unique<std::basic_string<char>>());
} }
else else
{ {
@ -884,7 +884,7 @@ error_code _sys_prx_register_library(ppu_thread& ppu, vm::ptr<void> library)
std::array<char, sizeof_lib> mem_copy{}; std::array<char, sizeof_lib> mem_copy{};
std::memcpy(mem_copy.data(), library.get_ptr(), sizeof_lib); std::memcpy(mem_copy.data(), library.get_ptr(), sizeof_lib);
std::basic_string<bool> flags; std::basic_string<char> flags;
ppu_manual_load_imports_exports(0, 0, library.addr(), sizeof_lib, flags); ppu_manual_load_imports_exports(0, 0, library.addr(), sizeof_lib, flags);
if (flags.front()) if (flags.front())
@ -897,7 +897,7 @@ error_code _sys_prx_register_library(ppu_thread& ppu, vm::ptr<void> library)
{ {
if (std::memcpy(vm::base(lib_addr), mem_copy.data(), sizeof_lib) == 0) if (std::memcpy(vm::base(lib_addr), mem_copy.data(), sizeof_lib) == 0)
{ {
atomic_storage<bool>::release(prx.m_external_loaded_flags[index], true); atomic_storage<char>::release(prx.m_external_loaded_flags[index], true);
return true; return true;
} }
} }

View File

@ -195,8 +195,8 @@ struct lv2_prx final : lv2_obj, ppu_module
u32 exports_start = umax; u32 exports_start = umax;
u32 exports_end = 0; u32 exports_end = 0;
std::basic_string<bool> m_loaded_flags; std::basic_string<char> m_loaded_flags;
std::basic_string<bool> m_external_loaded_flags; std::basic_string<char> m_external_loaded_flags;
void load_exports(); // (Re)load exports void load_exports(); // (Re)load exports
void restore_exports(); // For savestates void restore_exports(); // For savestates

View File

@ -190,12 +190,13 @@ void sys_spu_image::deploy(u8* loc, std::span<const sys_spu_segment> segs, bool
}; };
// Apply the patch // Apply the patch
auto applied = g_fxo->get<patch_engine>().apply(hash, mem_translate); std::vector<u32> applied;
g_fxo->get<patch_engine>().apply(applied, hash, mem_translate);
if (!Emu.GetTitleID().empty()) if (!Emu.GetTitleID().empty())
{ {
// Alternative patch // Alternative patch
applied += g_fxo->get<patch_engine>().apply(Emu.GetTitleID() + '-' + hash, mem_translate); g_fxo->get<patch_engine>().apply(applied, Emu.GetTitleID() + '-' + hash, mem_translate);
} }
(is_verbose ? spu_log.notice : sys_spu.trace)("Loaded SPU image: %s (<- %u)%s", hash, applied.size(), dump); (is_verbose ? spu_log.notice : sys_spu.trace)("Loaded SPU image: %s (<- %u)%s", hash, applied.size(), dump);

View File

@ -1,5 +1,6 @@
#include "stdafx.h" #include "stdafx.h"
#include "Emu/System.h" #include "Emu/System.h"
#include <span>
#include "np_structs_extra.h" #include "np_structs_extra.h"
LOG_CHANNEL(sceNp); LOG_CHANNEL(sceNp);
@ -39,7 +40,7 @@ namespace extra_nps
if (ptr && size) if (ptr && size)
{ {
sceNp2.warning("Data: %s", std::basic_string_view<u8>{ptr.get_ptr(), size}); sceNp2.warning("Data: %s", std::span<u8>{ptr.get_ptr(), size});
} }
} }
@ -57,7 +58,7 @@ namespace extra_nps
void print_SceNpMatching2PresenceOptionData(const SceNpMatching2PresenceOptionData* opt) void print_SceNpMatching2PresenceOptionData(const SceNpMatching2PresenceOptionData* opt)
{ {
sceNp2.warning("Data: %s", std::basic_string_view<u8>{std::data(opt->data), std::size(opt->data)}); sceNp2.warning("Data: %s", std::span<const u8>{std::data(opt->data), std::size(opt->data)});
} }
void print_range(const SceNpMatching2Range* range) void print_range(const SceNpMatching2Range* range)

View File

@ -1260,8 +1260,8 @@ game_boot_result Emulator::Load(const std::string& title_id, bool is_disc_patch,
if (game_data.find_first_of('\0') != umax || !sysutil_check_name_string(game_data.c_str(), 1, CELL_GAME_DIRNAME_SIZE)) if (game_data.find_first_of('\0') != umax || !sysutil_check_name_string(game_data.c_str(), 1, CELL_GAME_DIRNAME_SIZE))
{ {
const std::basic_string_view<u8> dirname{reinterpret_cast<const u8*>(game_data.data()), game_data.size()}; const std::span<const u8> dirname{reinterpret_cast<const u8*>(game_data.data()), game_data.size()};
fmt::throw_exception("HDD0 deserialization failed: Invalid directory name: %s, ar=%s", dirname.substr(0, CELL_GAME_DIRNAME_SIZE + 1), *m_ar); fmt::throw_exception("HDD0 deserialization failed: Invalid directory name: %s, ar=%s", dirname.subspan(0, CELL_GAME_DIRNAME_SIZE + 1), *m_ar);
} }
load_tar(hdd0_game + game_data, ""); load_tar(hdd0_game + game_data, "");

View File

@ -2,6 +2,7 @@
#include "PSF.h" #include "PSF.h"
#include "util/asm.hpp" #include "util/asm.hpp"
#include <span>
LOG_CHANNEL(psf_log, "PSF"); LOG_CHANNEL(psf_log, "PSF");
@ -75,7 +76,7 @@ void fmt_class_string<psf::registry>::format(std::string& out, u64 arg)
continue; continue;
} }
fmt::append(out, "%s: %s\n", entry.first, std::basic_string_view<u8>(reinterpret_cast<const u8*>(entry.second.as_string().data()), entry.second.size())); fmt::append(out, "%s: %s\n", entry.first, std::span<const u8>(reinterpret_cast<const u8*>(entry.second.as_string().data()), entry.second.size()));
} }
} }

View File

@ -31,7 +31,8 @@
#include <QTimer> #include <QTimer>
#include <QCheckBox> #include <QCheckBox>
#include <QMessageBox> #include <QMessageBox>
#include <charconv> #include <algorithm>
#include <functional>
#include "util/asm.hpp" #include "util/asm.hpp"
@ -753,8 +754,8 @@ void debugger_frame::keyPressEvent(QKeyEvent* event)
default: break; default: break;
} }
if (const usz pos = std::basic_string_view<u32>(res.data(), 2).find_last_not_of(umax); pos != umax) if (auto it = std::find_if(res.rbegin(), res.rend(), FN(x != umax)); it != res.rend())
m_debugger_list->ShowAddress(res[pos] - std::max(row, 0) * 4, true); m_debugger_list->ShowAddress(*it - std::max(row, 0) * 4, true);
return; return;
} }

View File

@ -398,7 +398,7 @@ void logs::message::broadcast(const char* fmt, const fmt_type_info* sup, ...) co
// Get text, extract va_args // Get text, extract va_args
/*constinit thread_local*/ std::string text; /*constinit thread_local*/ std::string text;
/*constinit thread_local*/ std::basic_string<u64> args; /*constinit thread_local*/ std::vector<u64> args;
static constexpr fmt_type_info empty_sup{}; static constexpr fmt_type_info empty_sup{};