diff --git a/Utilities/Atomic.h b/Utilities/Atomic.h index 6790d56400..4022164be4 100644 --- a/Utilities/Atomic.h +++ b/Utilities/Atomic.h @@ -1,6 +1,7 @@ #pragma once #include "types.h" +#include "Platform.h" // Helper class, provides access to compiler-specific atomic intrinsics template @@ -744,9 +745,9 @@ public: while (true) { - func(_new = old, args...); + func((_new = old), args...); - if (atomic_storage::compare_exchange(m_data, old, _new)) return old; + if (LIKELY(atomic_storage::compare_exchange(m_data, old, _new))) return old; } } @@ -765,9 +766,9 @@ public: while (true) { - func(_new = old, args...); + func((_new = old), args...); - if (atomic_storage::compare_exchange(m_data, old, _new)) return _new; + if (LIKELY(atomic_storage::compare_exchange(m_data, old, _new))) return _new; } } @@ -786,9 +787,9 @@ public: while (true) { - RT&& result = func(_new = old, args...); + RT&& result = func((_new = old), args...); - if (atomic_storage::compare_exchange(m_data, old, _new)) return std::move(result); + if (LIKELY(atomic_storage::compare_exchange(m_data, old, _new))) return std::move(result); } } @@ -800,9 +801,9 @@ public: while (true) { - func(_new = old, args...); + func((_new = old), args...); - if (atomic_storage::compare_exchange(m_data, old, _new)) return; + if (LIKELY(atomic_storage::compare_exchange(m_data, old, _new))) return; } } diff --git a/Utilities/AutoPause.h b/Utilities/AutoPause.h index 13a2f0c133..87f3ea48cc 100644 --- a/Utilities/AutoPause.h +++ b/Utilities/AutoPause.h @@ -1,5 +1,7 @@ #pragma once +#include + // Regarded as a Debugger Enchantment namespace debug { diff --git a/Utilities/Config.cpp b/Utilities/Config.cpp index e7368683c3..32330188ee 100644 --- a/Utilities/Config.cpp +++ b/Utilities/Config.cpp @@ -5,7 +5,7 @@ namespace cfg { - _log::channel cfg("CFG", _log::level::notice); + logs::channel cfg("CFG", logs::level::notice); entry_base::entry_base(type _type) : m_type(_type) diff --git a/Utilities/Config.h b/Utilities/Config.h index d9b0d76938..2463321e7c 100644 --- a/Utilities/Config.h +++ b/Utilities/Config.h @@ -179,7 +179,7 @@ namespace cfg for (const auto& v : init) { // Ensure elements are unique - ASSERT(map.emplace(v.first, v.second).second); + VERIFY(map.emplace(v.first, v.second).second); } return map; @@ -529,4 +529,4 @@ namespace cfg } // Registered log channel -#define LOG_CHANNEL(name) _log::channel name(#name, _log::level::notice); namespace _log { cfg::enum_entry<_log::level, true> name(cfg::root.log, #name, ::name.enabled); } +#define LOG_CHANNEL(name) extern logs::channel name; namespace logs { static cfg::enum_entry name(cfg::root.log, #name, ::name.enabled); } diff --git a/Utilities/File.cpp b/Utilities/File.cpp index ea24c4d26f..573b251b83 100644 --- a/Utilities/File.cpp +++ b/Utilities/File.cpp @@ -69,6 +69,19 @@ static time_t to_time(const FILETIME& ft) return to_time(v); } +static fs::error to_error(DWORD e) +{ + switch (e) + { + case ERROR_FILE_NOT_FOUND: return fs::error::noent; + case ERROR_PATH_NOT_FOUND: return fs::error::noent; + case ERROR_ALREADY_EXISTS: return fs::error::exist; + case ERROR_FILE_EXISTS: return fs::error::exist; + case ERROR_NEGATIVE_SEEK: return fs::error::inval; + default: throw fmt::exception("Unknown Win32 error: %u.", e); + } +} + #else #include @@ -87,11 +100,22 @@ static time_t to_time(const FILETIME& ft) #include #endif +static fs::error to_error(int e) +{ + switch (e) + { + case ENOENT: return fs::error::noent; + case EEXIST: return fs::error::exist; + case EINVAL: return fs::error::inval; + default: throw fmt::exception("Unknown system error: %d.", e); + } +} + #endif namespace fs { - thread_local uint error = 0; + thread_local error g_tls_error = error::ok; class device_manager final { @@ -146,7 +170,7 @@ std::shared_ptr fs::get_virtual_device(const std::string& path) std::shared_ptr fs::set_virtual_device(const std::string& name, const std::shared_ptr& device) { - Expects(name.size() > 2 && name[0] == '/' && name[1] == '/' && name.find('/', 2) == -1); + EXPECTS(name.size() > 2 && name[0] == '/' && name[1] == '/' && name.find('/', 2) == -1); return get_device_manager().set_device(name, device); } @@ -178,26 +202,26 @@ std::string fs::get_parent_dir(const std::string& path) static const auto test_get_parent_dir = []() -> bool { // Success: - ASSERT(fs::get_parent_dir("/x/y///") == "/x"); - ASSERT(fs::get_parent_dir("/x/y/") == "/x"); - ASSERT(fs::get_parent_dir("/x/y") == "/x"); - ASSERT(fs::get_parent_dir("x:/y") == "x:"); - ASSERT(fs::get_parent_dir("//x/y") == "//x"); + VERIFY(fs::get_parent_dir("/x/y///") == "/x"); + VERIFY(fs::get_parent_dir("/x/y/") == "/x"); + VERIFY(fs::get_parent_dir("/x/y") == "/x"); + VERIFY(fs::get_parent_dir("x:/y") == "x:"); + VERIFY(fs::get_parent_dir("//x/y") == "//x"); // Failure: - ASSERT(fs::get_parent_dir("").empty()); - ASSERT(fs::get_parent_dir("x/").empty()); - ASSERT(fs::get_parent_dir("x").empty()); - ASSERT(fs::get_parent_dir("x///").empty()); - ASSERT(fs::get_parent_dir("/x/").empty()); - ASSERT(fs::get_parent_dir("/x").empty()); - ASSERT(fs::get_parent_dir("/").empty()); - ASSERT(fs::get_parent_dir("//").empty()); - ASSERT(fs::get_parent_dir("//x").empty()); - ASSERT(fs::get_parent_dir("//x/").empty()); - ASSERT(fs::get_parent_dir("///").empty()); - ASSERT(fs::get_parent_dir("///x").empty()); - ASSERT(fs::get_parent_dir("///x/").empty()); + VERIFY(fs::get_parent_dir("").empty()); + VERIFY(fs::get_parent_dir("x/").empty()); + VERIFY(fs::get_parent_dir("x").empty()); + VERIFY(fs::get_parent_dir("x///").empty()); + VERIFY(fs::get_parent_dir("/x/").empty()); + VERIFY(fs::get_parent_dir("/x").empty()); + VERIFY(fs::get_parent_dir("/").empty()); + VERIFY(fs::get_parent_dir("//").empty()); + VERIFY(fs::get_parent_dir("//x").empty()); + VERIFY(fs::get_parent_dir("//x/").empty()); + VERIFY(fs::get_parent_dir("///").empty()); + VERIFY(fs::get_parent_dir("///x").empty()); + VERIFY(fs::get_parent_dir("///x/").empty()); return false; }(); @@ -213,14 +237,7 @@ bool fs::stat(const std::string& path, stat_t& info) WIN32_FILE_ATTRIBUTE_DATA attrs; if (!GetFileAttributesExW(to_wchar(path).get(), GetFileExInfoStandard, &attrs)) { - // TODO: convert Win32 error code to errno - switch (DWORD error = GetLastError()) - { - case ERROR_FILE_NOT_FOUND: fs::error = ENOENT; break; - case ERROR_PATH_NOT_FOUND: fs::error = ENOENT; break; - default: throw fmt::exception("Unknown Win32 error: %u (%s)." HERE, error, path); - } - + g_tls_error = to_error(GetLastError()); return false; } @@ -234,7 +251,7 @@ bool fs::stat(const std::string& path, stat_t& info) struct ::stat file_info; if (::stat(path.c_str(), &file_info) != 0) { - fs::error = errno; + g_tls_error = to_error(errno); return false; } @@ -260,14 +277,7 @@ bool fs::exists(const std::string& path) #ifdef _WIN32 if (GetFileAttributesW(to_wchar(path).get()) == INVALID_FILE_ATTRIBUTES) { - // TODO: convert Win32 error code to errno - switch (DWORD error = GetLastError()) - { - case ERROR_FILE_NOT_FOUND: fs::error = ENOENT; break; - case ERROR_PATH_NOT_FOUND: fs::error = ENOENT; break; - default: throw fmt::exception("Unknown Win32 error: %u (%s)." HERE, error, path); - } - + g_tls_error = to_error(GetLastError()); return false; } @@ -276,7 +286,7 @@ bool fs::exists(const std::string& path) struct ::stat file_info; if (::stat(path.c_str(), &file_info) != 0) { - fs::error = errno; + g_tls_error = to_error(errno); return false; } @@ -296,7 +306,7 @@ bool fs::is_file(const std::string& path) if (info.is_directory) { - fs::error = EEXIST; + g_tls_error = error::exist; return false; } @@ -307,21 +317,14 @@ bool fs::is_file(const std::string& path) const DWORD attrs = GetFileAttributesW(to_wchar(path).get()); if (attrs == INVALID_FILE_ATTRIBUTES) { - // TODO: convert Win32 error code to errno - switch (DWORD error = GetLastError()) - { - case ERROR_FILE_NOT_FOUND: fs::error = ENOENT; break; - case ERROR_PATH_NOT_FOUND: fs::error = ENOENT; break; - default: throw fmt::exception("Unknown Win32 error: %u (%s)." HERE, error, path); - } - + g_tls_error = to_error(GetLastError()); return false; } #else struct ::stat file_info; if (::stat(path.c_str(), &file_info) != 0) { - fs::error = errno; + g_tls_error = to_error(errno); return false; } #endif @@ -333,7 +336,7 @@ bool fs::is_file(const std::string& path) if (S_ISDIR(file_info.st_mode)) #endif { - fs::error = EEXIST; + g_tls_error = error::exist; return false; } @@ -352,7 +355,7 @@ bool fs::is_dir(const std::string& path) if (info.is_directory == false) { - fs::error = EEXIST; + g_tls_error = error::exist; return false; } @@ -363,21 +366,14 @@ bool fs::is_dir(const std::string& path) const DWORD attrs = GetFileAttributesW(to_wchar(path).get()); if (attrs == INVALID_FILE_ATTRIBUTES) { - // TODO: convert Win32 error code to errno - switch (DWORD error = GetLastError()) - { - case ERROR_FILE_NOT_FOUND: fs::error = ENOENT; break; - case ERROR_PATH_NOT_FOUND: fs::error = ENOENT; break; - default: throw fmt::exception("Unknown Win32 error: %u (%s)." HERE, error, path); - } - + g_tls_error = to_error(GetLastError()); return false; } #else struct ::stat file_info; if (::stat(path.c_str(), &file_info) != 0) { - fs::error = errno; + g_tls_error = to_error(errno); return false; } #endif @@ -388,7 +384,7 @@ bool fs::is_dir(const std::string& path) if (!S_ISDIR(file_info.st_mode)) #endif { - fs::error = EEXIST; + g_tls_error = error::exist; return false; } @@ -405,14 +401,7 @@ bool fs::create_dir(const std::string& path) #ifdef _WIN32 if (!CreateDirectoryW(to_wchar(path).get(), NULL)) { - // TODO: convert Win32 error code to errno - switch (DWORD error = GetLastError()) - { - case ERROR_ALREADY_EXISTS: fs::error = EEXIST; break; - case ERROR_PATH_NOT_FOUND: fs::error = ENOENT; break; - default: throw fmt::exception("Unknown Win32 error: %u (%s)." HERE, error, path); - } - + g_tls_error = to_error(GetLastError()); return false; } @@ -420,7 +409,7 @@ bool fs::create_dir(const std::string& path) #else if (::mkdir(path.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) != 0) { - fs::error = errno; + g_tls_error = to_error(errno); return false; } @@ -450,13 +439,7 @@ bool fs::remove_dir(const std::string& path) #ifdef _WIN32 if (!RemoveDirectoryW(to_wchar(path).get())) { - // TODO: convert Win32 error code to errno - switch (DWORD error = GetLastError()) - { - case ERROR_PATH_NOT_FOUND: fs::error = ENOENT; break; - default: throw fmt::exception("Unknown Win32 error: %u (%s)." HERE, error, path); - } - + g_tls_error = to_error(GetLastError()); return false; } @@ -464,7 +447,7 @@ bool fs::remove_dir(const std::string& path) #else if (::rmdir(path.c_str()) != 0) { - fs::error = errno; + g_tls_error = to_error(errno); return false; } @@ -489,13 +472,7 @@ bool fs::rename(const std::string& from, const std::string& to) #ifdef _WIN32 if (!MoveFileW(to_wchar(from).get(), to_wchar(to).get())) { - // TODO: convert Win32 error code to errno - switch (DWORD error = GetLastError()) - { - case ERROR_PATH_NOT_FOUND: fs::error = ENOENT; break; - default: throw fmt::exception("Unknown Win32 error: %u.\nFrom: %s\nTo: %s" HERE, error, from, to); - } - + g_tls_error = to_error(GetLastError()); return false; } @@ -503,7 +480,7 @@ bool fs::rename(const std::string& from, const std::string& to) #else if (::rename(from.c_str(), to.c_str()) != 0) { - fs::error = errno; + g_tls_error = to_error(errno); return false; } @@ -523,13 +500,7 @@ bool fs::copy_file(const std::string& from, const std::string& to, bool overwrit #ifdef _WIN32 if (!CopyFileW(to_wchar(from).get(), to_wchar(to).get(), !overwrite)) { - // TODO: convert Win32 error code to errno - switch (DWORD error = GetLastError()) - { - case ERROR_PATH_NOT_FOUND: fs::error = ENOENT; break; - default: throw fmt::exception("Unknown Win32 error: %u.\nFrom: %s\nTo: %s" HERE, error, from, to); - } - + g_tls_error = to_error(GetLastError()); return false; } @@ -540,7 +511,7 @@ bool fs::copy_file(const std::string& from, const std::string& to, bool overwrit const int input = ::open(from.c_str(), O_RDONLY); if (input == -1) { - fs::error = errno; + g_tls_error = to_error(errno); return false; } @@ -550,7 +521,7 @@ bool fs::copy_file(const std::string& from, const std::string& to, bool overwrit const int err = errno; ::close(input); - fs::error = err; + g_tls_error = to_error(err); return false; } @@ -569,7 +540,7 @@ bool fs::copy_file(const std::string& from, const std::string& to, bool overwrit ::close(input); ::close(output); - fs::error = err; + g_tls_error = to_error(err); return false; } @@ -589,14 +560,7 @@ bool fs::remove_file(const std::string& path) #ifdef _WIN32 if (!DeleteFileW(to_wchar(path).get())) { - // TODO: convert Win32 error code to errno - switch (DWORD error = GetLastError()) - { - case ERROR_FILE_NOT_FOUND: fs::error = ENOENT; break; - case ERROR_PATH_NOT_FOUND: fs::error = ENOENT; break; - default: throw fmt::exception("Unknown Win32 error: %u (%s)." HERE, error, path); - } - + g_tls_error = to_error(GetLastError()); return false; } @@ -604,7 +568,7 @@ bool fs::remove_file(const std::string& path) #else if (::unlink(path.c_str()) != 0) { - fs::error = errno; + g_tls_error = to_error(errno); return false; } @@ -624,14 +588,7 @@ bool fs::truncate_file(const std::string& path, u64 length) const auto handle = CreateFileW(to_wchar(path).get(), GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (handle == INVALID_HANDLE_VALUE) { - // TODO: convert Win32 error code to errno - switch (DWORD error = GetLastError()) - { - case ERROR_FILE_NOT_FOUND: fs::error = ENOENT; break; - case ERROR_PATH_NOT_FOUND: fs::error = ENOENT; break; - default: throw fmt::exception("Unknown Win32 error: %u (%s)." HERE, error, path); - } - + g_tls_error = to_error(GetLastError()); return false; } @@ -641,13 +598,7 @@ bool fs::truncate_file(const std::string& path, u64 length) // Seek and truncate if (!SetFilePointerEx(handle, distance, NULL, FILE_BEGIN) || !SetEndOfFile(handle)) { - // TODO: convert Win32 error code to errno - switch (DWORD error = GetLastError()) - { - case ERROR_NEGATIVE_SEEK: fs::error = EINVAL; break; - default: throw fmt::exception("Unknown Win32 error: %u (length=0x%llx)." HERE, error, length); - } - + g_tls_error = to_error(GetLastError()); CloseHandle(handle); return false; } @@ -657,7 +608,7 @@ bool fs::truncate_file(const std::string& path, u64 length) #else if (::truncate(path.c_str(), length) != 0) { - fs::error = errno; + g_tls_error = to_error(errno); return false; } @@ -672,7 +623,7 @@ void fs::file::xnull() const void fs::file::xfail() const { - throw fmt::exception("Unexpected fs::file error %u", fs::error); + throw fmt::exception("Unexpected fs::error %u", g_tls_error); } bool fs::file::open(const std::string& path, bitset_t mode) @@ -704,7 +655,7 @@ bool fs::file::open(const std::string& path, bitset_t mode) { if (mode & fs::excl) { - fs::error = EINVAL; + g_tls_error = error::inval; return false; } @@ -715,15 +666,7 @@ bool fs::file::open(const std::string& path, bitset_t mode) if (handle == INVALID_HANDLE_VALUE) { - // TODO: convert Win32 error code to errno - switch (DWORD error = GetLastError()) - { - case ERROR_FILE_NOT_FOUND: fs::error = ENOENT; break; - case ERROR_PATH_NOT_FOUND: fs::error = ENOENT; break; - case ERROR_FILE_EXISTS: fs::error = EEXIST; break; - default: throw fmt::exception("Unknown Win32 error: %u (%s)." HERE, error, path); - } - + g_tls_error = to_error(GetLastError()); return false; } @@ -747,12 +690,7 @@ bool fs::file::open(const std::string& path, bitset_t mode) FILE_BASIC_INFO basic_info; if (!GetFileInformationByHandleEx(m_handle, FileBasicInfo, &basic_info, sizeof(FILE_BASIC_INFO))) { - // TODO: convert Win32 error code to errno - switch (DWORD error = GetLastError()) - { - case 0: - default: throw fmt::exception("Win32 error: %u." HERE, error); - } + throw fmt::exception("Win32 error: %u." HERE, GetLastError()); } stat_t info; @@ -773,47 +711,22 @@ bool fs::file::open(const std::string& path, bitset_t mode) pos.QuadPart = 0; if (!SetFilePointerEx(m_handle, pos, &old, FILE_CURRENT)) // get old position { - // TODO: convert Win32 error code to errno - switch (DWORD error = GetLastError()) - { - case 0: - default: throw fmt::exception("Unknown Win32 error: %u." HERE, error); - } - + g_tls_error = to_error(GetLastError()); return false; } pos.QuadPart = length; if (!SetFilePointerEx(m_handle, pos, NULL, FILE_BEGIN)) // set new position { - // TODO: convert Win32 error code to errno - switch (DWORD error = GetLastError()) - { - case ERROR_NEGATIVE_SEEK: fs::error = EINVAL; break; - default: throw fmt::exception("Unknown Win32 error: %u." HERE, error); - } - + g_tls_error = to_error(GetLastError()); return false; } const BOOL result = SetEndOfFile(m_handle); // change file size - if (!result) + if (!result || !SetFilePointerEx(m_handle, old, NULL, FILE_BEGIN)) // restore position { - // TODO: convert Win32 error code to errno - switch (DWORD error = GetLastError()) - { - case 0: - default: throw fmt::exception("Unknown Win32 error: %u." HERE, error); - } - } - - if (!SetFilePointerEx(m_handle, old, NULL, FILE_BEGIN) && result) // restore position - { - if (DWORD error = GetLastError()) - { - throw fmt::exception("Win32 error: %u." HERE, error); - } + throw fmt::exception("Win32 error: %u." HERE, GetLastError()); } return result != FALSE; @@ -823,16 +736,12 @@ bool fs::file::open(const std::string& path, bitset_t mode) { // TODO (call ReadFile multiple times if count is too big) const int size = ::narrow(count, "Too big count" HERE); - Expects(size >= 0); + EXPECTS(size >= 0); DWORD nread; if (!ReadFile(m_handle, buffer, size, &nread, NULL)) { - switch (DWORD error = GetLastError()) - { - case 0: - default: throw fmt::exception("Win32 error: %u." HERE, error); - } + throw fmt::exception("Win32 error: %u." HERE, GetLastError()); } return nread; @@ -842,16 +751,12 @@ bool fs::file::open(const std::string& path, bitset_t mode) { // TODO (call WriteFile multiple times if count is too big) const int size = ::narrow(count, "Too big count" HERE); - Expects(size >= 0); + EXPECTS(size >= 0); DWORD nwritten; if (!WriteFile(m_handle, buffer, size, &nwritten, NULL)) { - switch (DWORD error = GetLastError()) - { - case 0: - default: throw fmt::exception("Win32 error: %u." HERE, error); - } + throw fmt::exception("Win32 error: %u." HERE, GetLastError()); } return nwritten; @@ -870,11 +775,7 @@ bool fs::file::open(const std::string& path, bitset_t mode) if (!SetFilePointerEx(m_handle, pos, &pos, mode)) { - switch (DWORD error = GetLastError()) - { - case 0: - default: throw fmt::exception("Win32 error: %u." HERE, error); - } + throw fmt::exception("Win32 error: %u." HERE, GetLastError()); } return pos.QuadPart; @@ -885,11 +786,7 @@ bool fs::file::open(const std::string& path, bitset_t mode) LARGE_INTEGER size; if (!GetFileSizeEx(m_handle, &size)) { - switch (DWORD error = GetLastError()) - { - case 0: - default: throw fmt::exception("Win32 error: %u." HERE, error); - } + throw fmt::exception("Win32 error: %u." HERE, GetLastError()); } return size.QuadPart; @@ -913,8 +810,7 @@ bool fs::file::open(const std::string& path, bitset_t mode) if (fd == -1) { - // TODO: errno - fs::error = errno; + g_tls_error = to_error(errno); return false; } @@ -938,11 +834,7 @@ bool fs::file::open(const std::string& path, bitset_t mode) struct ::stat file_info; if (::fstat(m_fd, &file_info) != 0) { - switch (int error = errno) - { - case 0: - default: throw fmt::exception("Unknown error: %d." HERE, error); - } + throw fmt::exception("System error: %d." HERE, errno); } stat_t info; @@ -960,12 +852,7 @@ bool fs::file::open(const std::string& path, bitset_t mode) { if (::ftruncate(m_fd, length) != 0) { - switch (int error = errno) - { - case 0: - default: throw fmt::exception("Unknown error: %d." HERE, error); - } - + g_tls_error = to_error(errno); return false; } @@ -977,11 +864,7 @@ bool fs::file::open(const std::string& path, bitset_t mode) const auto result = ::read(m_fd, buffer, count); if (result == -1) { - switch (int error = errno) - { - case 0: - default: throw fmt::exception("Unknown error: %d." HERE, error); - } + throw fmt::exception("System error: %d." HERE, errno); } return result; @@ -992,11 +875,7 @@ bool fs::file::open(const std::string& path, bitset_t mode) const auto result = ::write(m_fd, buffer, count); if (result == -1) { - switch (int error = errno) - { - case 0: - default: throw fmt::exception("Unknown error: %d." HERE, error); - } + throw fmt::exception("System error: %d." HERE, errno); } return result; @@ -1013,11 +892,7 @@ bool fs::file::open(const std::string& path, bitset_t mode) const auto result = ::lseek(m_fd, offset, mode); if (result == -1) { - switch (int error = errno) - { - case 0: - default: throw fmt::exception("Unknown error: %d." HERE, error); - } + throw fmt::exception("System error: %d." HERE, errno); } return result; @@ -1028,11 +903,7 @@ bool fs::file::open(const std::string& path, bitset_t mode) struct ::stat file_info; if (::fstat(m_fd, &file_info) != 0) { - switch (int error = errno) - { - case 0: - default: throw fmt::exception("Unknown error: %d." HERE, error); - } + throw fmt::exception("System error: %d." HERE, errno); } return file_info.st_size; @@ -1049,7 +920,7 @@ fs::file::file(const void* ptr, std::size_t size) { class memory_stream : public file_base { - u64 m_pos{}; // TODO: read/seek could modify m_pos atomically + u64 m_pos{}; const char* const m_ptr; const u64 m_size; @@ -1063,26 +934,26 @@ fs::file::file(const void* ptr, std::size_t size) fs::stat_t stat() override { - throw std::logic_error("memory_stream doesn't support stat()"); + throw std::logic_error("Not supported" HERE); } bool trunc(u64 length) override { - throw std::logic_error("memory_stream doesn't support trunc()"); + throw std::logic_error("Not allowed" HERE); } u64 read(void* buffer, u64 count) override { const u64 start = m_pos; const u64 end = seek(count, fs::seek_cur); - const u64 read_size = end >= start ? end - start : throw std::logic_error("memory_stream::read(): overflow"); + const u64 read_size = end >= start ? end - start : throw std::logic_error("Stream overflow" HERE); std::memcpy(buffer, m_ptr + start, read_size); return read_size; } u64 write(const void* buffer, u64 count) override { - throw std::logic_error("memory_stream is not writable"); + throw std::logic_error("Not allowed" HERE); } u64 seek(s64 offset, fs::seek_mode whence) override @@ -1091,7 +962,7 @@ fs::file::file(const void* ptr, std::size_t size) whence == fs::seek_set ? m_pos = std::min(offset, m_size) : whence == fs::seek_cur ? m_pos = std::min(offset + m_pos, m_size) : whence == fs::seek_end ? m_pos = std::min(offset + m_size, m_size) : - throw std::logic_error("memory_stream::seek(): invalid whence"); + throw fmt::exception("Invalid whence (0x%x)" HERE, whence); } u64 size() override @@ -1127,14 +998,7 @@ bool fs::dir::open(const std::string& path) if (handle == INVALID_HANDLE_VALUE) { - // TODO: convert Win32 error code to errno - switch (DWORD error = GetLastError()) - { - case ERROR_FILE_NOT_FOUND: fs::error = ENOENT; break; - case ERROR_PATH_NOT_FOUND: fs::error = ENOENT; break; - default: throw fmt::exception("Unknown Win32 error: %u." HERE, error); - } - + g_tls_error = to_error(GetLastError()); return false; } @@ -1179,11 +1043,12 @@ bool fs::dir::open(const std::string& path) WIN32_FIND_DATAW found; if (!FindNextFileW(m_handle, &found)) { - switch (DWORD error = GetLastError()) + if (ERROR_NO_MORE_FILES == GetLastError()) { - case ERROR_NO_MORE_FILES: return false; - default: throw fmt::exception("Unknown Win32 error: %u." HERE, error); + return false; } + + throw fmt::exception("Win32 error: %u." HERE, GetLastError()); } add_entry(found); @@ -1205,8 +1070,7 @@ bool fs::dir::open(const std::string& path) if (!ptr) { - // TODO: errno - fs::error = errno; + g_tls_error = to_error(errno); return false; } @@ -1236,11 +1100,7 @@ bool fs::dir::open(const std::string& path) struct ::stat file_info; if (::fstatat(::dirfd(m_dd), found->d_name, &file_info, 0) != 0) { - switch (int error = errno) - { - case 0: - default: throw fmt::exception("Unknown error: %d." HERE, error); - } + throw fmt::exception("System error: %d." HERE, errno); } info.name = found->d_name; diff --git a/Utilities/File.h b/Utilities/File.h index 0c6e0284ee..5fd7645fd4 100644 --- a/Utilities/File.h +++ b/Utilities/File.h @@ -10,9 +10,6 @@ namespace fs { - // Error code returned - extern thread_local uint error; - // File open mode flags enum struct open_mode : u32 { @@ -265,6 +262,13 @@ namespace fs return read(&str[0], str.size()) == str.size(); } + // Read std::string + bool read(std::string& str, std::size_t size) const + { + str.resize(size); + return read(&str[0], size) == size; + } + // Read POD, sizeof(T) is used template std::enable_if_t::value && !std::is_pointer::value, bool> read(T& data) const @@ -279,6 +283,14 @@ namespace fs return read(vec.data(), sizeof(T) * vec.size()) == sizeof(T) * vec.size(); } + // Read POD std::vector + template + std::enable_if_t::value && !std::is_pointer::value, bool> read(std::vector& vec, std::size_t size) const + { + vec.resize(size); + return read(vec.data(), sizeof(T) * size) == sizeof(T) * size; + } + // Read POD (experimental) template std::enable_if_t::value && !std::is_pointer::value, T> read() const @@ -432,4 +444,16 @@ namespace fs // Get size of all files recursively u64 get_dir_size(const std::string& path); + + enum class error : uint + { + ok = 0, + + inval, + noent, + exist, + }; + + // Error code returned + extern thread_local error g_tls_error; } diff --git a/Utilities/GSL.h b/Utilities/GSL.h index aa74c93610..6d4df0873f 100644 --- a/Utilities/GSL.h +++ b/Utilities/GSL.h @@ -3,12 +3,8 @@ #define GSL_THROW_ON_CONTRACT_VIOLATION #pragma push_macro("new") -#pragma push_macro("Expects") -#pragma push_macro("Ensures") #undef new +#include +#pragma pop_macro("new") #undef Expects #undef Ensures -#include -#pragma pop_macro("Ensures") -#pragma pop_macro("Expects") -#pragma pop_macro("new") diff --git a/Utilities/Log.cpp b/Utilities/Log.cpp index 3a48116d9f..b1d7718c55 100644 --- a/Utilities/Log.cpp +++ b/Utilities/Log.cpp @@ -8,7 +8,11 @@ // Thread-specific log prefix provider thread_local std::string(*g_tls_log_prefix)() = nullptr; -namespace _log +#ifndef _MSC_VER +constexpr DECLARE(bijective::map); +#endif + +namespace logs { struct listener { @@ -65,7 +69,7 @@ namespace _log channel ARMv7("ARMv7"); } -void _log::channel::broadcast(const _log::channel& ch, _log::level sev, const char* fmt...) +void logs::channel::broadcast(const logs::channel& ch, logs::level sev, const char* fmt...) { va_list args; va_start(args, fmt); @@ -75,13 +79,13 @@ void _log::channel::broadcast(const _log::channel& ch, _log::level sev, const ch [[noreturn]] extern void catch_all_exceptions(); -_log::file_writer::file_writer(const std::string& name) +logs::file_writer::file_writer(const std::string& name) { try { if (!m_file.open(fs::get_config_dir() + name, fs::rewrite + fs::append)) { - throw fmt::exception("Can't create log file %s (error %d)", name, fs::error); + throw fmt::exception("Can't create log file %s (error %d)", name, fs::g_tls_error); } } catch (...) @@ -90,17 +94,17 @@ _log::file_writer::file_writer(const std::string& name) } } -void _log::file_writer::log(const std::string& text) +void logs::file_writer::log(const std::string& text) { m_file.write(text); } -std::size_t _log::file_writer::size() const +std::size_t logs::file_writer::size() const { return m_file.pos(); } -void _log::file_listener::log(const _log::channel& ch, _log::level sev, const std::string& text) +void logs::file_listener::log(const logs::channel& ch, logs::level sev, const std::string& text) { std::string msg; msg.reserve(text.size() + 200); diff --git a/Utilities/Log.h b/Utilities/Log.h index 4a6d72e35b..0918e74554 100644 --- a/Utilities/Log.h +++ b/Utilities/Log.h @@ -3,7 +3,7 @@ #include "types.h" #include "Atomic.h" -namespace _log +namespace logs { enum class level : uint { @@ -79,27 +79,27 @@ namespace _log } template<> -struct bijective<_log::level, const char*> +struct bijective { - static constexpr bijective_pair<_log::level, const char*> map[] + static constexpr bijective_pair map[] { - { _log::level::always, "Nothing" }, - { _log::level::fatal, "Fatal" }, - { _log::level::error, "Error" }, - { _log::level::todo, "TODO" }, - { _log::level::success, "Success" }, - { _log::level::warning, "Warning" }, - { _log::level::notice, "Notice" }, - { _log::level::trace, "Trace" }, + { logs::level::always, "Nothing" }, + { logs::level::fatal, "Fatal" }, + { logs::level::error, "Error" }, + { logs::level::todo, "TODO" }, + { logs::level::success, "Success" }, + { logs::level::warning, "Warning" }, + { logs::level::notice, "Notice" }, + { logs::level::trace, "Trace" }, }; }; // Legacy: -#define LOG_SUCCESS(ch, fmt, ...) _log::ch.success(fmt, ##__VA_ARGS__) -#define LOG_NOTICE(ch, fmt, ...) _log::ch.notice (fmt, ##__VA_ARGS__) -#define LOG_WARNING(ch, fmt, ...) _log::ch.warning(fmt, ##__VA_ARGS__) -#define LOG_ERROR(ch, fmt, ...) _log::ch.error (fmt, ##__VA_ARGS__) -#define LOG_TODO(ch, fmt, ...) _log::ch.todo (fmt, ##__VA_ARGS__) -#define LOG_TRACE(ch, fmt, ...) _log::ch.trace (fmt, ##__VA_ARGS__) -#define LOG_FATAL(ch, fmt, ...) _log::ch.fatal (fmt, ##__VA_ARGS__) +#define LOG_SUCCESS(ch, fmt, ...) logs::ch.success(fmt, ##__VA_ARGS__) +#define LOG_NOTICE(ch, fmt, ...) logs::ch.notice (fmt, ##__VA_ARGS__) +#define LOG_WARNING(ch, fmt, ...) logs::ch.warning(fmt, ##__VA_ARGS__) +#define LOG_ERROR(ch, fmt, ...) logs::ch.error (fmt, ##__VA_ARGS__) +#define LOG_TODO(ch, fmt, ...) logs::ch.todo (fmt, ##__VA_ARGS__) +#define LOG_TRACE(ch, fmt, ...) logs::ch.trace (fmt, ##__VA_ARGS__) +#define LOG_FATAL(ch, fmt, ...) logs::ch.fatal (fmt, ##__VA_ARGS__) diff --git a/Utilities/Macro.h b/Utilities/Macro.h index 7e08fa83de..13ed979921 100644 --- a/Utilities/Macro.h +++ b/Utilities/Macro.h @@ -41,6 +41,7 @@ constexpr std::uint32_t size32(const T(&)[Size]) #define CHECK_ALIGN(type, align) static_assert(alignof(type) == align, "Invalid " #type " type alignment") #define CHECK_MAX_SIZE(type, size) static_assert(sizeof(type) <= size, #type " type size is too big") #define CHECK_SIZE_ALIGN(type, size, align) CHECK_SIZE(type, size); CHECK_ALIGN(type, align) +#define CHECK_STORAGE(type, storage) static_assert(sizeof(type) <= sizeof(storage) && alignof(type) <= alignof(decltype(storage)), #type " is too small") // Return 32 bit sizeof() to avoid widening/narrowing conversions with size_t #define SIZE_32(type) static_cast(sizeof(type)) @@ -60,20 +61,22 @@ constexpr std::uint32_t size32(const T(&)[Size]) #define STRINGIZE_DETAIL(x) #x #define STRINGIZE(x) STRINGIZE_DETAIL(x) -// Macro set, allows to hide "return" in simple lambda expressions. +// Macro set, wraps an expression into lambda #define WRAP_EXPR(expr, ...) [&](__VA_ARGS__) { return expr; } #define COPY_EXPR(expr, ...) [=](__VA_ARGS__) { return expr; } #define PURE_EXPR(expr, ...) [] (__VA_ARGS__) { return expr; } +#define return_ return + #define HERE "\n(in file " __FILE__ ":" STRINGIZE(__LINE__) ")" // Ensure that the expression is evaluated to true. Always evaluated and allowed to have side effects (unlike assert() macro). -#define ASSERT(expr) if (!(expr)) throw std::runtime_error("Assertion failed: " #expr HERE) +#define VERIFY(expr) do { if (!(expr)) throw std::runtime_error("Verification failed: " #expr HERE); } while (0) -// Expects() and Ensures() are intended to check function arguments and results. -// Expressions are not guaranteed to evaluate. Redefinition with ASSERT macro for better unification. -#define Expects ASSERT -#define Ensures ASSERT +// EXPECTS() and ENSURES() are intended to check function arguments and results. +// Expressions are not guaranteed to evaluate. +#define EXPECTS(expr) do { if (!(expr)) throw std::runtime_error("Precondition failed: " #expr HERE); } while (0) +#define ENSURES(expr) do { if (!(expr)) throw std::runtime_error("Postcondition failed: " #expr HERE); } while (0) #define DECLARE(...) decltype(__VA_ARGS__) __VA_ARGS__ diff --git a/Utilities/Semaphore.h b/Utilities/Semaphore.h index 4042cbbcbc..5ecde9a44c 100644 --- a/Utilities/Semaphore.h +++ b/Utilities/Semaphore.h @@ -35,7 +35,7 @@ public: bool try_wait() { - return LIKELY(m_value.compare_and_swap_test(1, 0)); + return m_value.compare_and_swap_test(1, 0); } void post() diff --git a/Utilities/SharedMutex.cpp b/Utilities/SharedMutex.cpp index b6b30c3b6f..1a97b8d472 100644 --- a/Utilities/SharedMutex.cpp +++ b/Utilities/SharedMutex.cpp @@ -140,6 +140,34 @@ void shared_mutex::unlock_notify() } } +void shared_mutex::lock_upgrade_hard() +{ + unlock_shared(); + lock(); +} + +void shared_mutex::lock_degrade_hard() +{ + initialize_once(); + + std::unique_lock lock(m_data->mutex); + + m_ctrl -= SM_WRITER_LOCK - 1; + + if (m_data->rq_size) + { + // Notify all readers + lock.unlock(); + m_data->rcv.notify_all(); + } + else if (m_data->wq_size) + { + // Notify next exclusive owner + lock.unlock(); + m_data->wcv.notify_one(); + } +} + void shared_mutex::initialize_once() { if (UNLIKELY(!m_data)) diff --git a/Utilities/SharedMutex.h b/Utilities/SharedMutex.h index b1200cffad..0d69d36e07 100644 --- a/Utilities/SharedMutex.h +++ b/Utilities/SharedMutex.h @@ -32,6 +32,9 @@ class shared_mutex final void lock_hard(); void unlock_notify(); + void lock_upgrade_hard(); + void lock_degrade_hard(); + public: constexpr shared_mutex() = default; @@ -42,15 +45,9 @@ public: bool try_lock_shared() { - auto ctrl = m_ctrl.load(); + const u32 ctrl = m_ctrl.load(); - if (UNLIKELY(ctrl >= SM_READER_MAX)) - { - ctrl = 0; - } - - // Weak attempt - return LIKELY(m_ctrl.compare_and_swap_test(ctrl, ctrl + 1)); + return ctrl < SM_READER_MAX && m_ctrl.compare_and_swap_test(ctrl, ctrl + 1); } void lock_shared() @@ -72,12 +69,12 @@ public: bool try_lock() { - return LIKELY(m_ctrl.compare_and_swap_test(0, SM_WRITER_LOCK)); + return !m_ctrl && m_ctrl.compare_and_swap_test(0, SM_WRITER_LOCK); } void lock() { - if (UNLIKELY(!try_lock())) + if (UNLIKELY(!m_ctrl.compare_and_swap_test(0, SM_WRITER_LOCK))) { lock_hard(); } @@ -85,11 +82,39 @@ public: void unlock() { - if (UNLIKELY(m_ctrl.fetch_sub(SM_WRITER_LOCK) != SM_WRITER_LOCK)) + m_ctrl &= ~SM_WRITER_LOCK; + + if (UNLIKELY(m_ctrl)) { unlock_notify(); } } + + bool try_lock_upgrade() + { + return m_ctrl == 1 && m_ctrl.compare_and_swap_test(1, SM_WRITER_LOCK); + } + + bool try_lock_degrade() + { + return m_ctrl == SM_WRITER_LOCK && m_ctrl.compare_and_swap_test(SM_WRITER_LOCK, 1); + } + + void lock_upgrade() + { + if (UNLIKELY(!m_ctrl.compare_and_swap_test(1, SM_WRITER_LOCK))) + { + lock_upgrade_hard(); + } + } + + void lock_degrade() + { + if (UNLIKELY(!m_ctrl.compare_and_swap_test(SM_WRITER_LOCK, 1))) + { + lock_degrade_hard(); + } + } }; //! Simplified shared (reader) lock implementation. @@ -133,3 +158,23 @@ public: m_mutex.unlock(); } }; + +// Exclusive (writer) lock in the scope of shared (reader) lock. +class upgraded_lock final +{ + shared_mutex& m_mutex; + +public: + upgraded_lock(const writer_lock&) = delete; + + upgraded_lock(shared_mutex& mutex) + : m_mutex(mutex) + { + m_mutex.lock_upgrade(); + } + + ~upgraded_lock() + { + m_mutex.lock_degrade(); + } +}; diff --git a/Utilities/SleepQueue.h b/Utilities/SleepQueue.h index fc97baad52..aa5120bb78 100644 --- a/Utilities/SleepQueue.h +++ b/Utilities/SleepQueue.h @@ -59,17 +59,27 @@ public: // Remove thread from the sleep queue void leave() { - auto it = std::find(m_queue.begin(), m_queue.end(), &m_thread); - - if (it != m_queue.end()) + for (auto it = m_queue.begin(), end = m_queue.end(); it != end; it++) { - m_queue.erase(it); + if (*it == &m_thread) + { + m_queue.erase(it); + return; + } } } // Check whether the thread exists in the sleep queue explicit operator bool() const { - return std::find(m_queue.begin(), m_queue.end(), &m_thread) != m_queue.end(); + for (auto it = m_queue.begin(), end = m_queue.end(); it != end; it++) + { + if (*it == &m_thread) + { + return true; + } + } + + return false; } }; diff --git a/Utilities/StrFmt.cpp b/Utilities/StrFmt.cpp index 8d61b09b25..274ca09f19 100644 --- a/Utilities/StrFmt.cpp +++ b/Utilities/StrFmt.cpp @@ -5,6 +5,7 @@ #include #include #include +#include std::string v128::to_hex() const { diff --git a/Utilities/StrFmt.h b/Utilities/StrFmt.h index b2dbe5551a..124222b799 100644 --- a/Utilities/StrFmt.h +++ b/Utilities/StrFmt.h @@ -1,8 +1,8 @@ #pragma once #include -#include #include +#include #include "Platform.h" #include "types.h" @@ -14,7 +14,7 @@ namespace fmt // Formatting function template - inline std::string format(const char* fmt, const Args&... args) noexcept + inline std::string format(const char* fmt, const Args&... args) { return unsafe_format(fmt, ::unveil::get(args)...); } @@ -34,7 +34,6 @@ namespace fmt class exception : public exception_base { public: - // Formatting constructor template exception(const char* fmt, const Args&... args) : exception_base(fmt, ::unveil::get(args)...) diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index 4ab6439fac..94e8cb1684 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -1263,9 +1263,11 @@ const bool s_self_test = []() -> bool return true; }(); +#include #include #include #include +#include thread_local DECLARE(thread_ctrl::g_tls_this_thread) = nullptr; @@ -1278,17 +1280,20 @@ struct thread_ctrl::internal task_stack atexit; std::exception_ptr exception; // Caught exception + + std::chrono::high_resolution_clock::time_point time_limit; }; -// Temporarily until better interface is implemented -extern std::condition_variable& get_current_thread_cv() -{ - return thread_ctrl::get_current()->get_data()->cond; -} +thread_local thread_ctrl::internal* g_tls_internal = nullptr; extern std::mutex& get_current_thread_mutex() { - return thread_ctrl::get_current()->get_data()->mutex; + return g_tls_internal->mutex; +} + +extern std::condition_variable& get_current_thread_cv() +{ + return g_tls_internal->cond; } // TODO @@ -1296,10 +1301,64 @@ extern atomic_t g_thread_count(0); extern thread_local std::string(*g_tls_log_prefix)(); +void thread_ctrl::start(const std::shared_ptr& ctrl, task_stack task) +{ + reinterpret_cast(ctrl->m_thread) = std::thread([ctrl, task = std::move(task)] + { + try + { + ctrl->initialize(); + task.exec(); + } + catch (...) + { + ctrl->initialize_once(); + ctrl->m_data->exception = std::current_exception(); + } + + ctrl->finalize(); + }); +} + +void thread_ctrl::wait_start(u64 timeout) +{ + initialize_once(); + + m_data->time_limit = std::chrono::high_resolution_clock::now() + std::chrono::microseconds(timeout); +} + +bool thread_ctrl::wait_wait(u64 timeout) +{ + initialize_once(); + + std::unique_lock lock(m_data->mutex, std::adopt_lock); + + if (timeout && m_data->cond.wait_until(lock, m_data->time_limit) == std::cv_status::timeout) + { + lock.release(); + return false; + } + + m_data->cond.wait(lock); + lock.release(); + return true; +} + +void thread_ctrl::test() +{ + if (m_data && m_data->exception) + { + std::rethrow_exception(m_data->exception); + } +} + void thread_ctrl::initialize() { + initialize_once(); // TODO (temporarily) + // Initialize TLS variable g_tls_this_thread = this; + g_tls_internal = this->m_data; g_tls_log_prefix = [] { @@ -1339,12 +1398,6 @@ void thread_ctrl::initialize() #endif } -void thread_ctrl::set_exception() noexcept -{ - initialize_once(); - m_data->exception = std::current_exception(); -} - void thread_ctrl::finalize() noexcept { // TODO @@ -1355,30 +1408,43 @@ void thread_ctrl::finalize() noexcept --g_thread_count; -#ifdef _MSC_VER +#ifdef _WIN32 ULONG64 time; - QueryThreadCycleTime(m_thread.native_handle(), &time); + QueryThreadCycleTime(GetCurrentThread(), &time); LOG_NOTICE(GENERAL, "Thread time: %f Gc", time / 1000000000.); #endif } -task_stack& thread_ctrl::get_atexit() const +void thread_ctrl::push_atexit(task_stack task) { initialize_once(); - return m_data->atexit; + m_data->atexit.push(std::move(task)); +} + +thread_ctrl::thread_ctrl(std::string&& name) + : m_name(std::move(name)) +{ + CHECK_STORAGE(std::thread, m_thread); + +#pragma push_macro("new") +#undef new + new (&m_thread) std::thread; +#pragma pop_macro("new") } thread_ctrl::~thread_ctrl() { - if (m_thread.joinable()) + if (reinterpret_cast(m_thread).joinable()) { - m_thread.detach(); + reinterpret_cast(m_thread).detach(); } delete m_data; + + reinterpret_cast(m_thread).~thread(); } -void thread_ctrl::initialize_once() const +void thread_ctrl::initialize_once() { if (UNLIKELY(!m_data)) { @@ -1393,33 +1459,37 @@ void thread_ctrl::initialize_once() const void thread_ctrl::join() { - if (LIKELY(m_thread.joinable())) + // Increase contention counter + const u32 _j = m_joining++; + + if (LIKELY(_j >= 0x80000000)) { - // Increase contention counter - if (UNLIKELY(m_joining++)) + // Already joined (signal condition) + m_joining = 0x80000000; + } + else if (LIKELY(_j == 0)) + { + // Winner joins the thread + reinterpret_cast(m_thread).join(); + + // Notify others if necessary + if (UNLIKELY(m_joining.exchange(0x80000000) != 1)) { - // Hard way initialize_once(); - std::unique_lock lock(m_data->mutex); - m_data->join.wait(lock, WRAP_EXPR(!m_thread.joinable())); + // Serialize for reliable notification + m_data->mutex.lock(); + m_data->mutex.unlock(); + m_data->join.notify_all(); } - else - { - // Winner joins the thread - m_thread.join(); + } + else + { + // Hard way + initialize_once(); - // Notify others if necessary - if (UNLIKELY(m_joining > 1)) - { - initialize_once(); - - // Serialize for reliable notification - m_data->mutex.lock(); - m_data->mutex.unlock(); - m_data->join.notify_all(); - } - } + std::unique_lock lock(m_data->mutex); + m_data->join.wait(lock, WRAP_EXPR(m_joining >= 0x80000000)); } if (UNLIKELY(m_data && m_data->exception)) @@ -1428,7 +1498,18 @@ void thread_ctrl::join() } } -void thread_ctrl::lock_notify() const +void thread_ctrl::lock() +{ + initialize_once(); + m_data->mutex.lock(); +} + +void thread_ctrl::unlock() +{ + m_data->mutex.unlock(); +} + +void thread_ctrl::lock_notify() { if (UNLIKELY(g_tls_this_thread == this)) { @@ -1443,16 +1524,19 @@ void thread_ctrl::lock_notify() const m_data->cond.notify_one(); } -void thread_ctrl::notify() const +void thread_ctrl::notify() { - initialize_once(); m_data->cond.notify_one(); } -thread_ctrl::internal* thread_ctrl::get_data() const +void thread_ctrl::set_exception(std::exception_ptr e) { - initialize_once(); - return m_data; + m_data->exception = e; +} + +void thread_ctrl::sleep(u64 useconds) +{ + std::this_thread::sleep_for(std::chrono::microseconds(useconds)); } @@ -1462,7 +1546,6 @@ named_thread::named_thread() named_thread::~named_thread() { - LOG_TRACE(GENERAL, "%s", __func__); } std::string named_thread::get_name() const diff --git a/Utilities/Thread.h b/Utilities/Thread.h index 2bf7b63566..46782c8c98 100644 --- a/Utilities/Thread.h +++ b/Utilities/Thread.h @@ -1,8 +1,8 @@ #pragma once +#include #include #include -#include #include "Platform.h" #include "Atomic.h" @@ -28,38 +28,41 @@ class task_stack } }; + template + struct task_type : task_base + { + std::remove_reference_t func; + + task_type(F&& func) + : func(std::forward(func)) + { + } + + void exec() override + { + func(); + task_base::exec(); + } + }; + std::unique_ptr m_stack; public: + task_stack() = default; + template - void push(F&& func) + task_stack(F&& func) + : m_stack(new task_type(std::forward(func))) { - struct task_t : task_base - { - std::remove_reference_t func; + } - task_t(F&& func) - : func(std::forward(func)) - { - } - - void exec() override - { - func(); - task_base::exec(); - } - }; - - auto _top = new task_t(std::forward(func)); + void push(task_stack stack) + { + auto _top = stack.m_stack.release(); auto _next = m_stack.release(); m_stack.reset(_top); -#ifndef _MSC_VER + while (UNLIKELY(_top->next)) _top = _top->next.get(); _top->next.reset(_next); -#else - auto& next = _top->next; - next.release(); - next.reset(_next); -#endif } void reset() @@ -79,42 +82,48 @@ public: // Thread control class class thread_ctrl final { +public: // TODO struct internal; +private: static thread_local thread_ctrl* g_tls_this_thread; - // Thread handle - std::thread m_thread; + // Thread handle storage + std::aligned_storage_t<16> m_thread; // Thread join contention counter - atomic_t m_joining{}; + atomic_t m_joining{}; + + // Thread internals + atomic_t m_data{}; // Fixed name std::string m_name; - // Thread internals - mutable atomic_t m_data{}; + // Start thread + static void start(const std::shared_ptr&, task_stack); // Called at the thread start void initialize(); - // Set std::current_exception - void set_exception() noexcept; - // Called at the thread end void finalize() noexcept; // Get atexit function - task_stack& get_atexit() const; + void push_atexit(task_stack); + + // Start waiting + void wait_start(u64 timeout); + + // Proceed waiting + bool wait_wait(u64 timeout); + + // Check exception + void test(); public: - template - thread_ctrl(N&& name) - : m_name(std::forward(name)) - { - } + thread_ctrl(std::string&& name); - // Disable copy/move constructors and operators thread_ctrl(const thread_ctrl&) = delete; ~thread_ctrl(); @@ -126,54 +135,139 @@ public: } // Initialize internal data - void initialize_once() const; + void initialize_once(); // Get thread result (may throw, simultaneous joining allowed) void join(); + // Lock thread mutex + void lock(); + + // Lock conditionally (double-checked) + template + bool lock_if(F&& pred) + { + if (pred()) + { + lock(); + + try + { + if (LIKELY(pred())) + { + return true; + } + else + { + unlock(); + return false; + } + } + catch (...) + { + unlock(); + throw; + } + } + else + { + return false; + } + } + + // Unlock thread mutex (internal data must be initialized) + void unlock(); + // Lock, unlock, notify the thread (required if the condition changed locklessly) - void lock_notify() const; + void lock_notify(); - // Notify the thread, beware the condition change - void notify() const; + // Notify the thread (internal data must be initialized) + void notify(); - // - internal* get_data() const; + // Set exception (internal data must be initialized, thread mutex must be locked) + void set_exception(std::exception_ptr); + + // Current thread sleeps for specified amount of microseconds. + // Wrapper for std::this_thread::sleep, doesn't require valid thread_ctrl. + [[deprecated]] static void sleep(u64 useconds); + + // Wait until pred(). Abortable, may throw. Thread must be locked. + // Timeout in microseconds (zero means infinite). + template + static inline auto wait(u64 useconds, F&& pred) + { + g_tls_this_thread->wait_start(useconds); + + while (true) + { + g_tls_this_thread->test(); + + if (auto&& result = pred()) + { + return result; + } + else if (!g_tls_this_thread->wait_wait(useconds) && useconds) + { + return result; + } + } + } + + // Wait until pred(). Abortable, may throw. Thread must be locked. + template + static inline auto wait(F&& pred) + { + while (true) + { + g_tls_this_thread->test(); + + if (auto&& result = pred()) + { + return result; + } + + g_tls_this_thread->wait_wait(0); + } + } + + // Wait once. Thread must be locked. + static inline void wait() + { + g_tls_this_thread->test(); + g_tls_this_thread->wait_wait(0); + g_tls_this_thread->test(); + } + + // Wait unconditionally until aborted. Thread must be locked. + [[noreturn]] static inline void eternalize() + { + while (true) + { + g_tls_this_thread->test(); + g_tls_this_thread->wait_wait(0); + } + } // Get current thread (may be nullptr) - static const thread_ctrl* get_current() + static thread_ctrl* get_current() { return g_tls_this_thread; } // Register function at thread exit (for the current thread) template - static inline void at_exit(F&& func) + static inline void atexit(F&& func) { - return g_tls_this_thread->get_atexit().push(std::forward(func)); + return g_tls_this_thread->push_atexit(std::forward(func)); } // Named thread factory - template - static inline std::shared_ptr spawn(N&& name, F&& func, Args&&... args) + template + static inline std::shared_ptr spawn(N&& name, F&& func) { auto ctrl = std::make_shared(std::forward(name)); - ctrl->m_thread = std::thread([ctrl, task = std::forward(func)](Args&&... args) - { - try - { - ctrl->initialize(); - task(std::forward(args)...); - } - catch (...) - { - ctrl->set_exception(); - } - - ctrl->finalize(); - - }, std::forward(args)...); + thread_ctrl::start(ctrl, std::forward(func)); return ctrl; } @@ -218,22 +312,43 @@ public: m_thread->join(); } - // Get thread_ctrl - const thread_ctrl* operator->() const + // Access thread_ctrl + thread_ctrl* operator->() const { return m_thread.get(); } +}; - // Lock mutex, notify condition variable - void lock_notify() const +// Simple thread mutex locker +class thread_lock final +{ + thread_ctrl* m_thread; + +public: + thread_lock(const thread_lock&) = delete; + + // Lock specified thread + thread_lock(thread_ctrl* thread) + : m_thread(thread) { - m_thread->lock_notify(); + m_thread->lock(); } - // Notify condition variable - void notify() const + // Lock specified named_thread + thread_lock(named_thread& thread) + : thread_lock(thread.operator->()) { - m_thread->notify(); + } + + // Lock current thread + thread_lock() + : thread_lock(thread_ctrl::get_current()) + { + } + + ~thread_lock() + { + m_thread->unlock(); } }; diff --git a/Utilities/VirtualMemory.cpp b/Utilities/VirtualMemory.cpp index e0b2b2ed61..a7e85ff4ff 100644 --- a/Utilities/VirtualMemory.cpp +++ b/Utilities/VirtualMemory.cpp @@ -17,10 +17,10 @@ namespace memory_helper { #ifdef _WIN32 void* ret = VirtualAlloc(NULL, size, MEM_RESERVE, PAGE_NOACCESS); - Ensures(ret != NULL); + ENSURES(ret != NULL); #else void* ret = mmap(nullptr, size, PROT_NONE, MAP_ANON | MAP_PRIVATE, -1, 0); - Ensures(ret != 0); + ENSURES(ret != 0); #endif return ret; } @@ -28,18 +28,18 @@ namespace memory_helper void commit_page_memory(void* pointer, size_t page_size) { #ifdef _WIN32 - ASSERT(VirtualAlloc((u8*)pointer, page_size, MEM_COMMIT, PAGE_READWRITE) != NULL); + VERIFY(VirtualAlloc((u8*)pointer, page_size, MEM_COMMIT, PAGE_READWRITE) != NULL); #else - ASSERT(mprotect((u8*)pointer, page_size, PROT_READ | PROT_WRITE) != -1); + VERIFY(mprotect((u8*)pointer, page_size, PROT_READ | PROT_WRITE) != -1); #endif } void free_reserved_memory(void* pointer, size_t size) { #ifdef _WIN32 - ASSERT(VirtualFree(pointer, 0, MEM_RELEASE) != 0); + VERIFY(VirtualFree(pointer, 0, MEM_RELEASE) != 0); #else - ASSERT(munmap(pointer, size) == 0); + VERIFY(munmap(pointer, size) == 0); #endif } } diff --git a/Utilities/lockless.h b/Utilities/lockless.h new file mode 100644 index 0000000000..863fe1d647 --- /dev/null +++ b/Utilities/lockless.h @@ -0,0 +1,105 @@ +#pragma once + +#include "types.h" +#include "Atomic.h" +#include "Platform.h" + +//! Simple sizeless array base for concurrent access. Cannot shrink, only growths automatically. +//! There is no way to know the current size. The smaller index is, the faster it's accessed. +//! +//! T is the type of elements. Currently, default constructor of T shall be constexpr. +//! N is initial element count, available without any memory allocation and only stored contiguously. +template +class lf_array +{ + // Data (default-initialized) + T m_data[N]{}; + + // Next array block + atomic_t m_next{}; + +public: + constexpr lf_array() = default; + + ~lf_array() + { + for (auto ptr = m_next.raw(); UNLIKELY(ptr);) + { + delete std::exchange(ptr, std::exchange(ptr->m_next.raw(), nullptr)); + } + } + + T& operator [](std::size_t index) + { + if (LIKELY(index < N)) + { + return m_data[index]; + } + else if (UNLIKELY(!m_next)) + { + // Create new array block. It's not a full-fledged once-synchronization, unlikely needed. + for (auto _new = new lf_array, ptr = this; UNLIKELY(ptr);) + { + // Install the pointer. If failed, go deeper. + ptr = ptr->m_next.compare_and_swap(nullptr, _new); + } + } + + // Access recursively + return (*m_next)[index - N]; + } +}; + +//! Simple lock-free FIFO queue base. Based on lf_array itself. Currently uses 32-bit counters. +//! There is no "push_end" or "pop_begin" provided, the queue element must signal its state on its own. +template +class lf_fifo : public lf_array +{ + struct alignas(8) ctrl_t + { + u32 push; + u32 pop; + }; + + atomic_t m_ctrl{}; + +public: + constexpr lf_fifo() = default; + + // Get current "push" position + u32 size() + { + return reinterpret_cast&>(m_ctrl).load(); // Hack + } + + // Acquire the place for one or more elements. + u32 push_begin(u32 count = 1) + { + return reinterpret_cast&>(m_ctrl).fetch_add(count); // Hack + } + + // Get current "pop" position + u32 peek() + { + return m_ctrl.load().pop; + } + + // Acknowledge processed element, return number of the next one. + // Perform clear if possible, zero is returned in this case. + u32 pop_end(u32 count = 1) + { + return m_ctrl.atomic_op([&](ctrl_t& ctrl) + { + ctrl.pop += count; + + if (ctrl.pop == ctrl.push) + { + // Clean if possible + ctrl.push = 0; + ctrl.pop = 0; + } + + return ctrl.pop; + }); + } +}; diff --git a/Utilities/sync.h b/Utilities/sync.h new file mode 100644 index 0000000000..ba91a76e1f --- /dev/null +++ b/Utilities/sync.h @@ -0,0 +1,192 @@ +#pragma once + +/* For internal use. Don't include. */ + +#include "types.h" +#include "Macro.h" +#include "Atomic.h" + +#ifdef _WIN32 + +#include + +#define DYNAMIC_IMPORT(handle, name) do { name = reinterpret_cast(GetProcAddress(handle, #name)); } while (0) + +static NTSTATUS(*NtSetTimerResolution)(ULONG DesiredResolution, BOOLEAN SetResolution, PULONG CurrentResolution); +static NTSTATUS(*NtWaitForKeyedEvent)(HANDLE Handle, PVOID Key, BOOLEAN Alertable, PLARGE_INTEGER Timeout); +static NTSTATUS(*NtReleaseKeyedEvent)(HANDLE Handle, PVOID Key, BOOLEAN Alertable, PLARGE_INTEGER Timeout); + +namespace util +{ + static const bool keyed_init = [] + { + const auto handle = LoadLibraryA("ntdll.dll"); + DYNAMIC_IMPORT(handle, NtSetTimerResolution); + DYNAMIC_IMPORT(handle, NtWaitForKeyedEvent); + DYNAMIC_IMPORT(handle, NtReleaseKeyedEvent); + FreeLibrary(handle); + + ULONG res = 100; + NtSetTimerResolution(100, TRUE, &res); + + return NtWaitForKeyedEvent && NtReleaseKeyedEvent; + }(); + + // Wait for specified condition. func() acknowledges success by value modification. + template + inline void keyed_wait(atomic_t& key, F&& func) + { + while (true) + { + NtWaitForKeyedEvent(NULL, &key, FALSE, NULL); + + u32 read = key.load(); + u32 copy = read; + + while (pred(read), read != copy) + { + read = key.compare_and_swap(copy, read); + + if (copy == read) + { + break; + } + + copy = read; + } + } + } + + // Try to wake up a thread. + inline bool keyed_post(atomic_t& key, u32 acknowledged_value) + { + LARGE_INTEGER zero; + zero.QuadPart = 0; + + while (UNLIKELY(NtReleaseKeyedEvent(NULL, &key, FALSE, &zero) == WAIT_TIMEOUT)) + { + if (key.load() != acknowledged_value) + return false; + + //NtReleaseKeyedEvent(NULL, &key, FALSE, NULL); + //return true; + } + + return true; + } + + struct native_rwlock + { + SRWLOCK rwlock = SRWLOCK_INIT; + + constexpr native_rwlock() = default; + + native_rwlock(const native_rwlock&) = delete; + + void lock() + { + AcquireSRWLockExclusive(&rwlock); + } + + bool try_lock() + { + return TryAcquireSRWLockExclusive(&rwlock) != 0; + } + + void unlock() + { + ReleaseSRWLockExclusive(&rwlock); + } + + void lock_shared() + { + AcquireSRWLockShared(&rwlock); + } + + bool try_lock_shared() + { + return TryAcquireSRWLockShared(&rwlock) != 0; + } + + void unlock_shared() + { + ReleaseSRWLockShared(&rwlock); + } + }; + + struct native_cond + { + CONDITION_VARIABLE cond = CONDITION_VARIABLE_INIT; + + constexpr native_cond() = default; + + native_cond(const native_cond&) = delete; + + void notify_one() + { + WakeConditionVariable(&cond); + } + + void notify_all() + { + WakeAllConditionVariable(&cond); + } + + void wait(native_rwlock& rwlock) + { + SleepConditionVariableSRW(&cond, &rwlock.rwlock, INFINITE, 0); + } + + void wait_shared(native_rwlock& rwlock) + { + SleepConditionVariableSRW(&cond, &rwlock.rwlock, INFINITE, CONDITION_VARIABLE_LOCKMODE_SHARED); + } + }; + + class exclusive_lock + { + native_rwlock& m_rwlock; + + public: + exclusive_lock(native_rwlock& rwlock) + : m_rwlock(rwlock) + { + m_rwlock.lock(); + } + + ~exclusive_lock() + { + m_rwlock.unlock(); + } + }; + + class shared_lock + { + native_rwlock& m_rwlock; + + public: + shared_lock(native_rwlock& rwlock) + : m_rwlock(rwlock) + { + m_rwlock.lock_shared(); + } + + ~shared_lock() + { + m_rwlock.unlock_shared(); + } + }; +} + +#else + +namespace util +{ + struct native_rwlock; + struct native_cond; +} + +#endif + +CHECK_SIZE_ALIGN(util::native_rwlock, sizeof(void*), alignof(void*)); +CHECK_SIZE_ALIGN(util::native_cond, sizeof(void*), alignof(void*)); diff --git a/Utilities/types.h b/Utilities/types.h index cff51f5c04..c822aba50a 100644 --- a/Utilities/types.h +++ b/Utilities/types.h @@ -407,12 +407,22 @@ struct ignore } }; +// Simplified hash algorithm for pointers. May be used in std::unordered_(map|set). +template +struct pointer_hash +{ + std::size_t operator()(T* ptr) const + { + return reinterpret_cast(ptr) / Align; + } +}; + // Contains value of any POD type with fixed size and alignment. TT<> is the type converter applied. // For example, `simple_t` may be used to remove endianness. template class TT, std::size_t S, std::size_t A = S> struct alignas(A) any_pod { - enum class byte : char {} data[S]; + std::aligned_storage_t data; any_pod() = default; diff --git a/rpcs3/CMakeLists.txt b/rpcs3/CMakeLists.txt index bd631662f2..d4416d6c75 100644 --- a/rpcs3/CMakeLists.txt +++ b/rpcs3/CMakeLists.txt @@ -40,7 +40,7 @@ if(NOT MSVC) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O1") # fix for travis gcc OoM crash. Might be fixed with the move to containers. endif() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -fexceptions") - add_compile_options(-msse -msse2 -mcx16 -mssse3) + add_compile_options(-msse -msse2 -mcx16 -mssse3 -march=native) else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:throwingNew /D _CRT_SECURE_NO_DEPRECATE=1 /D _CRT_NON_CONFORMING_SWPRINTFS=1 /D _SCL_SECURE_NO_WARNINGS=1") endif() diff --git a/rpcs3/Emu/ARMv7/Modules/sceRtc.h b/rpcs3/Emu/ARMv7/Modules/sceRtc.h deleted file mode 100644 index 6f70f09bee..0000000000 --- a/rpcs3/Emu/ARMv7/Modules/sceRtc.h +++ /dev/null @@ -1 +0,0 @@ -#pragma once diff --git a/rpcs3/Emu/Audio/AudioDumper.cpp b/rpcs3/Emu/Audio/AudioDumper.cpp index 670227b896..a61e62c4be 100644 --- a/rpcs3/Emu/Audio/AudioDumper.cpp +++ b/rpcs3/Emu/Audio/AudioDumper.cpp @@ -24,7 +24,7 @@ void AudioDumper::WriteData(const void* buffer, u32 size) { if (GetCh()) { - ASSERT(m_output.write(buffer, size) == size); + VERIFY(m_output.write(buffer, size) == size); m_header.Size += size; m_header.RIFF.Size += size; } diff --git a/rpcs3/Emu/CPU/CPUThread.cpp b/rpcs3/Emu/CPU/CPUThread.cpp index 27e970e81a..294a1b6e73 100644 --- a/rpcs3/Emu/CPU/CPUThread.cpp +++ b/rpcs3/Emu/CPU/CPUThread.cpp @@ -1,15 +1,15 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/IdManager.h" - -#include "Emu/Cell/PPUThread.h" -#include "Emu/Cell/SPUThread.h" -#include "Emu/Cell/RawSPUThread.h" -#include "Emu/ARMv7/ARMv7Thread.h" #include "CPUThread.h" +#include +#include + thread_local cpu_thread* g_tls_current_cpu_thread = nullptr; +extern std::mutex& get_current_thread_mutex(); +extern std::condition_variable& get_current_thread_cv(); + void cpu_thread::on_task() { state -= cpu_state::exit; @@ -61,7 +61,7 @@ void cpu_thread::on_task() void cpu_thread::on_stop() { state += cpu_state::exit; - lock_notify(); + (*this)->lock_notify(); } cpu_thread::~cpu_thread() @@ -121,35 +121,3 @@ bool cpu_thread::check_status() return false; } - -[[noreturn]] void cpu_thread::xsleep() -{ - throw std::runtime_error("cpu_thread: sleep()/awake() inconsistency"); -} - -std::vector> get_all_cpu_threads() -{ - std::vector> result; - - for (auto& t : idm::get_all()) - { - result.emplace_back(t); - } - - for (auto& t : idm::get_all()) - { - result.emplace_back(t); - } - - for (auto& t : idm::get_all()) - { - result.emplace_back(t); - } - - for (auto& t : idm::get_all()) - { - result.emplace_back(t); - } - - return result; -} diff --git a/rpcs3/Emu/CPU/CPUThread.h b/rpcs3/Emu/CPU/CPUThread.h index eae4cacb02..89cbb179cf 100644 --- a/rpcs3/Emu/CPU/CPUThread.h +++ b/rpcs3/Emu/CPU/CPUThread.h @@ -40,7 +40,6 @@ public: const std::string name; const cpu_type type; - const id_value<> id{}; cpu_thread(cpu_type type, const std::string& name); @@ -48,36 +47,34 @@ public: // Public thread state atomic_t> state{ cpu_state::stop }; - // Recursively enter sleep state - void sleep() - { - if (!++m_sleep) xsleep(); - } + // Public recursive sleep state counter + atomic_t sleep_counter{}; - // Leave sleep state - void awake() - { - if (!m_sleep--) xsleep(); - } + // Object associated with sleep state, possibly synchronization primitive (mutex, semaphore, etc.) + atomic_t owner{}; // Process thread state, return true if the checker must return bool check_status(); - virtual std::string dump() const = 0; // Print CPU state + // Increse sleep counter + void sleep() + { + if (!sleep_counter++) return; //handle_interrupt(); + } + + // Decrese sleep counter + void awake() + { + if (!--sleep_counter) owner = nullptr; + } + + // Print CPU state + virtual std::string dump() const = 0; virtual void cpu_init() {} virtual void cpu_task() = 0; virtual bool handle_interrupt() { return false; } - -private: - [[noreturn]] void xsleep(); - - // Sleep/Awake counter - atomic_t m_sleep{}; }; -extern std::mutex& get_current_thread_mutex(); -extern std::condition_variable& get_current_thread_cv(); - inline cpu_thread* get_current_cpu_thread() noexcept { extern thread_local cpu_thread* g_tls_current_cpu_thread; @@ -85,4 +82,26 @@ inline cpu_thread* get_current_cpu_thread() noexcept return g_tls_current_cpu_thread; } -extern std::vector> get_all_cpu_threads(); +// Helper for cpu_thread. +// 1) Calls sleep() and locks the thread in the constructor. +// 2) Calls awake() and unlocks the thread in the destructor. +class cpu_thread_lock final +{ + cpu_thread& m_thread; + +public: + cpu_thread_lock(const cpu_thread_lock&) = delete; + + cpu_thread_lock(cpu_thread& thread) + : m_thread(thread) + { + m_thread.sleep(); + m_thread->lock(); + } + + ~cpu_thread_lock() + { + m_thread.awake(); + m_thread->unlock(); + } +}; diff --git a/rpcs3/Emu/Cell/ErrorCodes.h b/rpcs3/Emu/Cell/ErrorCodes.h index 05445a6aa0..15c0698bb8 100644 --- a/rpcs3/Emu/Cell/ErrorCodes.h +++ b/rpcs3/Emu/Cell/ErrorCodes.h @@ -110,9 +110,12 @@ struct ppu_error_code { } + // Helper + enum class not_an_error : s32 {}; + // Silence any error - constexpr ppu_error_code(s32 value, const std::nothrow_t&) - : value(value) + constexpr ppu_error_code(not_an_error value) + : value(static_cast(value)) { } @@ -124,7 +127,7 @@ struct ppu_error_code }; // Helper macro for silencing possible error checks on returning ppu_error_code values -#define NOT_AN_ERROR(value) { static_cast(value), std::nothrow } +#define NOT_AN_ERROR(...) static_cast(__VA_ARGS__) template struct ppu_gpr_cast_impl; diff --git a/rpcs3/Emu/Cell/Modules/cellAdec.cpp b/rpcs3/Emu/Cell/Modules/cellAdec.cpp index b6acc1f23c..6214c8fb41 100644 --- a/rpcs3/Emu/Cell/Modules/cellAdec.cpp +++ b/rpcs3/Emu/Cell/Modules/cellAdec.cpp @@ -15,7 +15,9 @@ extern "C" #include "cellPamf.h" #include "cellAdec.h" -LOG_CHANNEL(cellAdec); +#include + +logs::channel cellAdec("cellAdec", logs::level::notice); AudioDecoder::AudioDecoder(s32 type, u32 addr, u32 size, vm::ptr func, u32 arg) : type(type) @@ -468,7 +470,7 @@ void adecOpen(u32 adec_id) // TODO: call from the constructor adec.adecCb->cpu_init(); adec.adecCb->state -= cpu_state::stop; - adec.adecCb->lock_notify(); + (*adec.adecCb)->lock_notify(); } bool adecCheckType(s32 type) @@ -569,7 +571,7 @@ s32 cellAdecClose(u32 handle) { CHECK_EMU_STATUS; - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + std::this_thread::sleep_for(1ms); // hack } idm::remove(adec->adecCb->id); @@ -682,7 +684,7 @@ s32 cellAdecGetPcm(u32 handle, vm::ptr outBuffer) AdecFrame af; if (!adec->frames.try_pop(af)) { - //std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + //std::this_thread::sleep_for(1ms); // hack return CELL_ADEC_ERROR_EMPTY; } @@ -798,7 +800,7 @@ s32 cellAdecGetPcmItem(u32 handle, vm::pptr pcmItem) AdecFrame af; if (!adec->frames.try_peek(af)) { - //std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + //std::this_thread::sleep_for(1ms); // hack return CELL_ADEC_ERROR_EMPTY; } diff --git a/rpcs3/Emu/Cell/Modules/cellAtrac.cpp b/rpcs3/Emu/Cell/Modules/cellAtrac.cpp index d251fe9bcb..0a6fb4360e 100644 --- a/rpcs3/Emu/Cell/Modules/cellAtrac.cpp +++ b/rpcs3/Emu/Cell/Modules/cellAtrac.cpp @@ -4,7 +4,7 @@ #include "cellAtrac.h" -LOG_CHANNEL(cellAtrac); +logs::channel cellAtrac("cellAtrac", logs::level::notice); s32 cellAtracSetDataAndGetMemSize(vm::ptr pHandle, vm::ptr pucBufferAddr, u32 uiReadByte, u32 uiBufferByte, vm::ptr puiWorkMemByte) { diff --git a/rpcs3/Emu/Cell/Modules/cellAtracMulti.cpp b/rpcs3/Emu/Cell/Modules/cellAtracMulti.cpp index 75e1263f62..c7dac5b60b 100644 --- a/rpcs3/Emu/Cell/Modules/cellAtracMulti.cpp +++ b/rpcs3/Emu/Cell/Modules/cellAtracMulti.cpp @@ -4,7 +4,7 @@ #include "cellAtracMulti.h" -LOG_CHANNEL(cellAtracMulti); +logs::channel cellAtracMulti("cellAtracMulti", logs::level::notice); s32 cellAtracMultiSetDataAndGetMemSize(vm::ptr pHandle, vm::ptr pucBufferAddr, u32 uiReadByte, u32 uiBufferByte, u32 uiOutputChNum, vm::ptr piTrackArray, vm::ptr puiWorkMemByte) { diff --git a/rpcs3/Emu/Cell/Modules/cellAudio.cpp b/rpcs3/Emu/Cell/Modules/cellAudio.cpp index 9a119a0865..a6364a6ed0 100644 --- a/rpcs3/Emu/Cell/Modules/cellAudio.cpp +++ b/rpcs3/Emu/Cell/Modules/cellAudio.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Emu/System.h" #include "Emu/IdManager.h" #include "Emu/Cell/PPUModule.h" @@ -8,7 +9,9 @@ #include "Emu/Audio/AudioThread.h" #include "cellAudio.h" -LOG_CHANNEL(cellAudio); +#include + +logs::channel cellAudio("cellAudio", logs::level::notice); cfg::bool_entry g_cfg_audio_dump_to_file(cfg::root.audio, "Dump to file"); cfg::bool_entry g_cfg_audio_convert_to_u16(cfg::root.audio, "Convert to 16 bit"); diff --git a/rpcs3/Emu/Cell/Modules/cellAudioOut.cpp b/rpcs3/Emu/Cell/Modules/cellAudioOut.cpp index 8383a7657f..0472272b0a 100644 --- a/rpcs3/Emu/Cell/Modules/cellAudioOut.cpp +++ b/rpcs3/Emu/Cell/Modules/cellAudioOut.cpp @@ -3,7 +3,7 @@ #include "cellAudioOut.h" -extern _log::channel cellSysutil; +extern logs::channel cellSysutil; s32 cellAudioOutGetSoundAvailability(u32 audioOut, u32 type, u32 fs, u32 option) { diff --git a/rpcs3/Emu/Cell/Modules/cellAvconfExt.cpp b/rpcs3/Emu/Cell/Modules/cellAvconfExt.cpp index 7a005dc34a..fc7bb16c26 100644 --- a/rpcs3/Emu/Cell/Modules/cellAvconfExt.cpp +++ b/rpcs3/Emu/Cell/Modules/cellAvconfExt.cpp @@ -6,7 +6,7 @@ #include "cellAudioOut.h" #include "cellVideoOut.h" -LOG_CHANNEL(cellAvconfExt); +logs::channel cellAvconfExt("cellAvconfExt", logs::level::notice); vm::gvar g_gamma; // TODO diff --git a/rpcs3/Emu/Cell/Modules/cellBgdl.cpp b/rpcs3/Emu/Cell/Modules/cellBgdl.cpp index b83c0fa791..8847bafebd 100644 --- a/rpcs3/Emu/Cell/Modules/cellBgdl.cpp +++ b/rpcs3/Emu/Cell/Modules/cellBgdl.cpp @@ -2,7 +2,7 @@ #include "Emu/System.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellBGDL); +logs::channel cellBGDL("cellBGDL", logs::level::notice); // Return Codes enum diff --git a/rpcs3/Emu/Cell/Modules/cellCamera.cpp b/rpcs3/Emu/Cell/Modules/cellCamera.cpp index 6a2c491a43..9c445f1a65 100644 --- a/rpcs3/Emu/Cell/Modules/cellCamera.cpp +++ b/rpcs3/Emu/Cell/Modules/cellCamera.cpp @@ -1,11 +1,12 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Emu/IdManager.h" #include "Emu/System.h" #include "Emu/Cell/PPUModule.h" #include "cellCamera.h" -LOG_CHANNEL(cellCamera); +logs::channel cellCamera("cellCamera", logs::level::notice); cfg::map_entry g_cfg_camera(cfg::root.io, "Camera", { diff --git a/rpcs3/Emu/Cell/Modules/cellCelp8Enc.cpp b/rpcs3/Emu/Cell/Modules/cellCelp8Enc.cpp index bb0b24b9ef..b834d9b57d 100644 --- a/rpcs3/Emu/Cell/Modules/cellCelp8Enc.cpp +++ b/rpcs3/Emu/Cell/Modules/cellCelp8Enc.cpp @@ -2,7 +2,7 @@ #include "Emu/System.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellCelp8Enc); +logs::channel cellCelp8Enc("cellCelp8Enc", logs::level::notice); // Return Codes enum diff --git a/rpcs3/Emu/Cell/Modules/cellCelpEnc.cpp b/rpcs3/Emu/Cell/Modules/cellCelpEnc.cpp index bb551877bb..0cd61d2504 100644 --- a/rpcs3/Emu/Cell/Modules/cellCelpEnc.cpp +++ b/rpcs3/Emu/Cell/Modules/cellCelpEnc.cpp @@ -2,7 +2,7 @@ #include "Emu/System.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellCelpEnc); +logs::channel cellCelpEnc("cellCelpEnc", logs::level::notice); // Return Codes enum diff --git a/rpcs3/Emu/Cell/Modules/cellDaisy.cpp b/rpcs3/Emu/Cell/Modules/cellDaisy.cpp index bd82c4d31b..4f37bc46e7 100644 --- a/rpcs3/Emu/Cell/Modules/cellDaisy.cpp +++ b/rpcs3/Emu/Cell/Modules/cellDaisy.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellDaisy); +logs::channel cellDaisy("cellDaisy", logs::level::notice); s32 _ZN4cell5Daisy17LFQueue2PushCloseEPNS0_8LFQueue2EPFiPvjE() { diff --git a/rpcs3/Emu/Cell/Modules/cellDmux.cpp b/rpcs3/Emu/Cell/Modules/cellDmux.cpp index cb86cb76bb..7ea8c97263 100644 --- a/rpcs3/Emu/Cell/Modules/cellDmux.cpp +++ b/rpcs3/Emu/Cell/Modules/cellDmux.cpp @@ -6,7 +6,9 @@ #include "cellPamf.h" #include "cellDmux.h" -LOG_CHANNEL(cellDmux); +#include + +logs::channel cellDmux("cellDmux", logs::level::notice); PesHeader::PesHeader(DemuxerStream& stream) : pts(CODEC_TS_INVALID) @@ -142,7 +144,7 @@ void ElementaryStream::push_au(u32 size, u64 dts, u64 pts, u64 userdata, bool ra u32 addr; { std::lock_guard lock(m_mutex); - ASSERT(!is_full(size)); + VERIFY(!is_full(size)); if (put + size + 128 > memAddr + memSize) { @@ -183,7 +185,7 @@ void ElementaryStream::push_au(u32 size, u64 dts, u64 pts, u64 userdata, bool ra put_count++; } - ASSERT(entries.push(addr, &dmux->is_closed)); + VERIFY(entries.push(addr, &dmux->is_closed)); } void ElementaryStream::push(DemuxerStream& stream, u32 size) @@ -447,7 +449,7 @@ void dmuxOpen(u32 dmux_id) // TODO: call from the constructor if (es.raw_data.size() > 1024 * 1024) { stream = backup; - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + std::this_thread::sleep_for(1ms); // hack continue; } @@ -543,7 +545,7 @@ void dmuxOpen(u32 dmux_id) // TODO: call from the constructor if (es.isfull(old_size)) { stream = backup; - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + std::this_thread::sleep_for(1ms); // hack continue; } @@ -711,7 +713,7 @@ void dmuxOpen(u32 dmux_id) // TODO: call from the constructor { if (Emu.IsStopped() || dmux.is_closed) break; - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + std::this_thread::sleep_for(1ms); // hack } es.push_au(old_size, es.last_dts, es.last_pts, stream.userdata, false, 0); @@ -759,7 +761,7 @@ void dmuxOpen(u32 dmux_id) // TODO: call from the constructor dmux.dmuxCb->cpu_init(); dmux.dmuxCb->state -= cpu_state::stop; - dmux.dmuxCb->lock_notify(); + (*dmux.dmuxCb)->lock_notify(); } s32 cellDmuxQueryAttr(vm::cptr type, vm::ptr attr) @@ -865,7 +867,7 @@ s32 cellDmuxClose(u32 handle) return CELL_OK; } - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + std::this_thread::sleep_for(1ms); // hack } idm::remove(dmux->dmuxCb->id); @@ -886,7 +888,7 @@ s32 cellDmuxSetStream(u32 handle, u32 streamAddress, u32 streamSize, b8 disconti if (dmux->is_running.exchange(true)) { - //std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + //std::this_thread::sleep_for(1ms); // hack return CELL_DMUX_ERROR_BUSY; } @@ -943,7 +945,7 @@ s32 cellDmuxResetStreamAndWaitDone(u32 handle) cellDmux.warning("cellDmuxResetStreamAndWaitDone(%d) aborted", handle); return CELL_OK; } - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + std::this_thread::sleep_for(1ms); // hack } return CELL_OK; diff --git a/rpcs3/Emu/Cell/Modules/cellFiber.cpp b/rpcs3/Emu/Cell/Modules/cellFiber.cpp index ba744dc37a..8229bb859d 100644 --- a/rpcs3/Emu/Cell/Modules/cellFiber.cpp +++ b/rpcs3/Emu/Cell/Modules/cellFiber.cpp @@ -4,7 +4,7 @@ #include "cellFiber.h" -LOG_CHANNEL(cellFiber); +logs::channel cellFiber("cellFiber", logs::level::notice); s32 _cellFiberPpuInitialize() { diff --git a/rpcs3/Emu/Cell/Modules/cellFont.cpp b/rpcs3/Emu/Cell/Modules/cellFont.cpp index 0d3f10c2a5..cc3df1b933 100644 --- a/rpcs3/Emu/Cell/Modules/cellFont.cpp +++ b/rpcs3/Emu/Cell/Modules/cellFont.cpp @@ -8,7 +8,7 @@ #include "cellFont.h" -LOG_CHANNEL(cellFont); +logs::channel cellFont("cellFont", logs::level::notice); // Functions s32 cellFontInitializeWithRevision(u64 revisionFlags, vm::ptr config) diff --git a/rpcs3/Emu/Cell/Modules/cellFontFT.cpp b/rpcs3/Emu/Cell/Modules/cellFontFT.cpp index 5821d440c6..20b3167a9f 100644 --- a/rpcs3/Emu/Cell/Modules/cellFontFT.cpp +++ b/rpcs3/Emu/Cell/Modules/cellFontFT.cpp @@ -3,7 +3,7 @@ #include "cellFontFT.h" -LOG_CHANNEL(cellFontFT); +logs::channel cellFontFT("cellFontFT", logs::level::notice); s32 cellFontInitLibraryFreeTypeWithRevision(u64 revisionFlags, vm::ptr config, vm::pptr lib) { diff --git a/rpcs3/Emu/Cell/Modules/cellFs.cpp b/rpcs3/Emu/Cell/Modules/cellFs.cpp index 220df6262a..1ac9a05dfe 100644 --- a/rpcs3/Emu/Cell/Modules/cellFs.cpp +++ b/rpcs3/Emu/Cell/Modules/cellFs.cpp @@ -8,7 +8,7 @@ #include "Utilities/StrUtil.h" -LOG_CHANNEL(cellFs); +logs::channel cellFs("cellFs", logs::level::notice); s32 cellFsOpen(vm::cptr path, s32 flags, vm::ptr fd, vm::cptr arg, u64 size) { @@ -527,7 +527,7 @@ s32 cellFsStReadStart(u32 fd, u64 offset, u64 size) } } - file->cv.wait_for(lock, std::chrono::milliseconds(1)); + file->cv.wait_for(lock, 1ms); } file->st_status.compare_and_swap(SSS_STOPPED, SSS_INITIALIZED); @@ -688,7 +688,7 @@ s32 cellFsStReadWait(u32 fd, u64 size) { CHECK_EMU_STATUS; - file->cv.wait_for(lock, std::chrono::milliseconds(1)); + file->cv.wait_for(lock, 1ms); } return CELL_OK; diff --git a/rpcs3/Emu/Cell/Modules/cellGame.cpp b/rpcs3/Emu/Cell/Modules/cellGame.cpp index 632d72000b..32bace6827 100644 --- a/rpcs3/Emu/Cell/Modules/cellGame.cpp +++ b/rpcs3/Emu/Cell/Modules/cellGame.cpp @@ -10,7 +10,9 @@ #include "Loader/PSF.h" #include "Utilities/StrUtil.h" -LOG_CHANNEL(cellGame); +#include + +logs::channel cellGame("cellGame", logs::level::notice); // Normal content directory (if is_temporary is not involved): // contentInfo = dir @@ -308,7 +310,7 @@ ppu_error_code cellGameContentPermit(vm::ptr contentIn } // Create PARAM.SFO - fs::file(dir + "/PARAM.SFO", fs::rewrite).write(psf::save_object(prm->sfo)); + psf::save_object(fs::file(dir + "/PARAM.SFO", fs::rewrite), prm->sfo); // Disable deletion prm->is_temporary = false; @@ -555,7 +557,7 @@ ppu_error_code cellGameGetParamString(s32 id, vm::ptr buf, u32 bufsize) std::string&& value = psf::get_string(prm->sfo, key); value.resize(bufsize - 1); - std::copy_n(value.c_str(), value.size() + 1, buf.get_ptr()); + std::memcpy(buf.get_ptr(), value.c_str(), bufsize); return CELL_OK; } diff --git a/rpcs3/Emu/Cell/Modules/cellGameExec.cpp b/rpcs3/Emu/Cell/Modules/cellGameExec.cpp index 9367db8796..411f51043a 100644 --- a/rpcs3/Emu/Cell/Modules/cellGameExec.cpp +++ b/rpcs3/Emu/Cell/Modules/cellGameExec.cpp @@ -3,7 +3,7 @@ #include "cellGame.h" -LOG_CHANNEL(cellGameExec); +logs::channel cellGameExec("cellGameExec", logs::level::notice); s32 cellGameSetExitParam() { diff --git a/rpcs3/Emu/Cell/Modules/cellGcmSys.cpp b/rpcs3/Emu/Cell/Modules/cellGcmSys.cpp index cb290a71a1..962218925c 100644 --- a/rpcs3/Emu/Cell/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/Cell/Modules/cellGcmSys.cpp @@ -8,7 +8,9 @@ #include "Emu/RSX/GSRender.h" #include "cellGcmSys.h" -LOG_CHANNEL(cellGcmSys); +#include + +logs::channel cellGcmSys("cellGcmSys", logs::level::notice); extern s32 cellGcmCallback(vm::ptr context, u32 count); @@ -933,7 +935,7 @@ s32 cellGcmMapEaIoAddressWithFlags(u32 ea, u32 io, u32 size, u32 flags) { cellGcmSys.warning("cellGcmMapEaIoAddressWithFlags(ea=0x%x, io=0x%x, size=0x%x, flags=0x%x)", ea, io, size, flags); - ASSERT(flags == 2 /*CELL_GCM_IOMAP_FLAG_STRICT_ORDERING*/); + VERIFY(flags == 2 /*CELL_GCM_IOMAP_FLAG_STRICT_ORDERING*/); return gcmMapEaIoAddress(ea, io, size, true); } @@ -1257,7 +1259,7 @@ static std::pair getNextCommandBufferBeginEnd(u32 current) static u32 getOffsetFromAddress(u32 address) { const u32 upper = offsetTable.ioAddress[address >> 20]; // 12 bits - Expects(upper != 0xFFFF); + EXPECTS(upper != 0xFFFF); return (upper << 20) | (address & 0xFFFFF); } diff --git a/rpcs3/Emu/Cell/Modules/cellGem.cpp b/rpcs3/Emu/Cell/Modules/cellGem.cpp index f10e41ea58..a33cd86879 100644 --- a/rpcs3/Emu/Cell/Modules/cellGem.cpp +++ b/rpcs3/Emu/Cell/Modules/cellGem.cpp @@ -4,7 +4,7 @@ #include "cellGem.h" -LOG_CHANNEL(cellGem); +logs::channel cellGem("cellGem", logs::level::notice); struct gem_t { diff --git a/rpcs3/Emu/Cell/Modules/cellGifDec.cpp b/rpcs3/Emu/Cell/Modules/cellGifDec.cpp index 64c10ca7cf..f5420ed299 100644 --- a/rpcs3/Emu/Cell/Modules/cellGifDec.cpp +++ b/rpcs3/Emu/Cell/Modules/cellGifDec.cpp @@ -9,7 +9,7 @@ #include "Emu/Cell/lv2/sys_fs.h" #include "cellGifDec.h" -LOG_CHANNEL(cellGifDec); +logs::channel cellGifDec("cellGifDec", logs::level::notice); // cellGifDec aliases (only for cellGifDec.cpp) using PPMainHandle = vm::pptr; diff --git a/rpcs3/Emu/Cell/Modules/cellHttp.cpp b/rpcs3/Emu/Cell/Modules/cellHttp.cpp index 46328b1cf7..e8036bdc30 100644 --- a/rpcs3/Emu/Cell/Modules/cellHttp.cpp +++ b/rpcs3/Emu/Cell/Modules/cellHttp.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellHttp); +logs::channel cellHttp("cellHttp", logs::level::notice); s32 cellHttpInit() { diff --git a/rpcs3/Emu/Cell/Modules/cellHttpUtil.cpp b/rpcs3/Emu/Cell/Modules/cellHttpUtil.cpp index 35c7c5328c..c68c4344ce 100644 --- a/rpcs3/Emu/Cell/Modules/cellHttpUtil.cpp +++ b/rpcs3/Emu/Cell/Modules/cellHttpUtil.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellHttpUtil); +logs::channel cellHttpUtil("cellHttpUtil", logs::level::notice); s32 cellHttpUtilParseUri() { diff --git a/rpcs3/Emu/Cell/Modules/cellImejp.cpp b/rpcs3/Emu/Cell/Modules/cellImejp.cpp index 278103fd3f..4a56d547de 100644 --- a/rpcs3/Emu/Cell/Modules/cellImejp.cpp +++ b/rpcs3/Emu/Cell/Modules/cellImejp.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellImeJp); +logs::channel cellImeJp("cellImeJp", logs::level::notice); // Return Codes enum diff --git a/rpcs3/Emu/Cell/Modules/cellJpgDec.cpp b/rpcs3/Emu/Cell/Modules/cellJpgDec.cpp index 3fcb2a967e..2cfc9f5efc 100644 --- a/rpcs3/Emu/Cell/Modules/cellJpgDec.cpp +++ b/rpcs3/Emu/Cell/Modules/cellJpgDec.cpp @@ -9,7 +9,7 @@ #include "Emu/Cell/lv2/sys_fs.h" #include "cellJpgDec.h" -LOG_CHANNEL(cellJpgDec); +logs::channel cellJpgDec("cellJpgDec", logs::level::notice); s32 cellJpgDecCreate(u32 mainHandle, u32 threadInParam, u32 threadOutParam) { diff --git a/rpcs3/Emu/Cell/Modules/cellJpgEnc.cpp b/rpcs3/Emu/Cell/Modules/cellJpgEnc.cpp index 605a04e930..96a46b3900 100644 --- a/rpcs3/Emu/Cell/Modules/cellJpgEnc.cpp +++ b/rpcs3/Emu/Cell/Modules/cellJpgEnc.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellJpgEnc); +logs::channel cellJpgEnc("cellJpgEnc", logs::level::notice); // Error Codes enum diff --git a/rpcs3/Emu/Cell/Modules/cellKb.cpp b/rpcs3/Emu/Cell/Modules/cellKb.cpp index a4647993b1..08d69ae94d 100644 --- a/rpcs3/Emu/Cell/Modules/cellKb.cpp +++ b/rpcs3/Emu/Cell/Modules/cellKb.cpp @@ -6,7 +6,7 @@ #include "Emu/Io/KeyboardHandler.h" #include "cellKb.h" -extern _log::channel sys_io; +extern logs::channel sys_io; s32 cellKbInit(u32 max_connect) { diff --git a/rpcs3/Emu/Cell/Modules/cellKey2char.cpp b/rpcs3/Emu/Cell/Modules/cellKey2char.cpp index 3a51a3c347..9ca2554aea 100644 --- a/rpcs3/Emu/Cell/Modules/cellKey2char.cpp +++ b/rpcs3/Emu/Cell/Modules/cellKey2char.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellKey2char); +logs::channel cellKey2char("cellKey2char", logs::level::notice); // Return Codes enum diff --git a/rpcs3/Emu/Cell/Modules/cellL10n.cpp b/rpcs3/Emu/Cell/Modules/cellL10n.cpp index 73ec6cad6c..7dbc9c3da5 100644 --- a/rpcs3/Emu/Cell/Modules/cellL10n.cpp +++ b/rpcs3/Emu/Cell/Modules/cellL10n.cpp @@ -14,7 +14,7 @@ typedef const char *HostCode; #include "cellL10n.h" -LOG_CHANNEL(cellL10n); +logs::channel cellL10n("cellL10n", logs::level::notice); // Translate code id to code name. some codepage may has another name. // If this makes your compilation fail, try replace the string code with one in "iconv -l" diff --git a/rpcs3/Emu/Cell/Modules/cellMic.cpp b/rpcs3/Emu/Cell/Modules/cellMic.cpp index b0cd2b8ba7..059d508642 100644 --- a/rpcs3/Emu/Cell/Modules/cellMic.cpp +++ b/rpcs3/Emu/Cell/Modules/cellMic.cpp @@ -4,7 +4,7 @@ #include "cellMic.h" -LOG_CHANNEL(cellMic); +logs::channel cellMic("cellMic", logs::level::notice); s32 cellMicInit() { diff --git a/rpcs3/Emu/Cell/Modules/cellMouse.cpp b/rpcs3/Emu/Cell/Modules/cellMouse.cpp index e9cea73dc8..fd91435ed9 100644 --- a/rpcs3/Emu/Cell/Modules/cellMouse.cpp +++ b/rpcs3/Emu/Cell/Modules/cellMouse.cpp @@ -6,7 +6,7 @@ #include "Emu/Io/MouseHandler.h" #include "cellMouse.h" -extern _log::channel sys_io; +extern logs::channel sys_io; s32 cellMouseInit(u32 max_connect) { diff --git a/rpcs3/Emu/Cell/Modules/cellMsgDialog.cpp b/rpcs3/Emu/Cell/Modules/cellMsgDialog.cpp index 880a126d1c..e4c7fe221c 100644 --- a/rpcs3/Emu/Cell/Modules/cellMsgDialog.cpp +++ b/rpcs3/Emu/Cell/Modules/cellMsgDialog.cpp @@ -6,7 +6,9 @@ #include "cellSysutil.h" #include "cellMsgDialog.h" -extern _log::channel cellSysutil; +#include + +extern logs::channel cellSysutil; s32 cellMsgDialogOpen() { diff --git a/rpcs3/Emu/Cell/Modules/cellMusic.cpp b/rpcs3/Emu/Cell/Modules/cellMusic.cpp index 6fe8cd4146..7cd839bfdd 100644 --- a/rpcs3/Emu/Cell/Modules/cellMusic.cpp +++ b/rpcs3/Emu/Cell/Modules/cellMusic.cpp @@ -5,7 +5,7 @@ #include "cellMusic.h" -LOG_CHANNEL(cellMusic); +logs::channel cellMusic("cellMusic", logs::level::notice); struct music2_t { diff --git a/rpcs3/Emu/Cell/Modules/cellMusicDecode.cpp b/rpcs3/Emu/Cell/Modules/cellMusicDecode.cpp index dcb43e75a8..f850afa90d 100644 --- a/rpcs3/Emu/Cell/Modules/cellMusicDecode.cpp +++ b/rpcs3/Emu/Cell/Modules/cellMusicDecode.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellMusicDecode); +logs::channel cellMusicDecode("cellMusicDecode", logs::level::notice); // Return Codes enum diff --git a/rpcs3/Emu/Cell/Modules/cellMusicExport.cpp b/rpcs3/Emu/Cell/Modules/cellMusicExport.cpp index 0c614e907e..924306c3b3 100644 --- a/rpcs3/Emu/Cell/Modules/cellMusicExport.cpp +++ b/rpcs3/Emu/Cell/Modules/cellMusicExport.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellMusicExport); +logs::channel cellMusicExport("cellMusicExport", logs::level::notice); // Return Codes enum diff --git a/rpcs3/Emu/Cell/Modules/cellNetCtl.cpp b/rpcs3/Emu/Cell/Modules/cellNetCtl.cpp index 65ceda8e18..4114c89444 100644 --- a/rpcs3/Emu/Cell/Modules/cellNetCtl.cpp +++ b/rpcs3/Emu/Cell/Modules/cellNetCtl.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Emu/System.h" #include "Emu/Cell/PPUModule.h" @@ -7,7 +8,7 @@ #include "Utilities/StrUtil.h" -LOG_CHANNEL(cellNetCtl); +logs::channel cellNetCtl("cellNetCtl", logs::level::notice); cfg::map_entry g_cfg_net_status(cfg::root.net, "Connection status", { diff --git a/rpcs3/Emu/Cell/Modules/cellOskDialog.cpp b/rpcs3/Emu/Cell/Modules/cellOskDialog.cpp index ccc0c51f7f..605d59578a 100644 --- a/rpcs3/Emu/Cell/Modules/cellOskDialog.cpp +++ b/rpcs3/Emu/Cell/Modules/cellOskDialog.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellOskDialog); +logs::channel cellOskDialog("cellOskDialog", logs::level::notice); s32 cellOskDialogLoadAsync() { diff --git a/rpcs3/Emu/Cell/Modules/cellOvis.cpp b/rpcs3/Emu/Cell/Modules/cellOvis.cpp index 49e22da87f..2b4716f959 100644 --- a/rpcs3/Emu/Cell/Modules/cellOvis.cpp +++ b/rpcs3/Emu/Cell/Modules/cellOvis.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellOvis); +logs::channel cellOvis("cellOvis", logs::level::notice); // Return Codes enum diff --git a/rpcs3/Emu/Cell/Modules/cellPad.cpp b/rpcs3/Emu/Cell/Modules/cellPad.cpp index f0441cc739..bed38f18de 100644 --- a/rpcs3/Emu/Cell/Modules/cellPad.cpp +++ b/rpcs3/Emu/Cell/Modules/cellPad.cpp @@ -6,7 +6,7 @@ #include "Emu/Io/PadHandler.h" #include "cellPad.h" -extern _log::channel sys_io; +extern logs::channel sys_io; s32 cellPadInit(u32 max_connect) { diff --git a/rpcs3/Emu/Cell/Modules/cellPamf.cpp b/rpcs3/Emu/Cell/Modules/cellPamf.cpp index fcd64720b6..a4a05d92f7 100644 --- a/rpcs3/Emu/Cell/Modules/cellPamf.cpp +++ b/rpcs3/Emu/Cell/Modules/cellPamf.cpp @@ -12,12 +12,12 @@ bool squeue_test_exit() return Emu.IsStopped(); } -LOG_CHANNEL(cellPamf); +logs::channel cellPamf("cellPamf", logs::level::notice); s32 pamfStreamTypeToEsFilterId(u8 type, u8 ch, CellCodecEsFilterId& pEsFilterId) { // convert type and ch to EsFilterId - Expects(ch < 16); + EXPECTS(ch < 16); pEsFilterId.supplementalInfo1 = type == CELL_PAMF_STREAM_TYPE_AVC; pEsFilterId.supplementalInfo2 = 0; @@ -117,7 +117,7 @@ s32 pamfStreamTypeToEsFilterId(u8 type, u8 ch, CellCodecEsFilterId& pEsFilterId) u8 pamfGetStreamType(vm::ptr pSelf, u32 stream) { // TODO: get stream type correctly - Expects(stream < (u32)pSelf->pAddr->stream_count); + EXPECTS(stream < (u32)pSelf->pAddr->stream_count); auto& header = pSelf->pAddr->stream_headers[stream]; switch (header.type) @@ -138,7 +138,7 @@ u8 pamfGetStreamType(vm::ptr pSelf, u32 stream) u8 pamfGetStreamChannel(vm::ptr pSelf, u32 stream) { // TODO: get stream channel correctly - Expects(stream < (u32)pSelf->pAddr->stream_count); + EXPECTS(stream < (u32)pSelf->pAddr->stream_count); auto& header = pSelf->pAddr->stream_headers[stream]; switch (header.type) @@ -146,29 +146,29 @@ u8 pamfGetStreamChannel(vm::ptr pSelf, u32 stream) case 0x1b: // AVC case 0x02: // M2V { - Expects((header.fid_major & 0xf0) == 0xe0 && header.fid_minor == 0); + EXPECTS((header.fid_major & 0xf0) == 0xe0 && header.fid_minor == 0); return header.fid_major % 16; } case 0xdc: // ATRAC3PLUS { - Expects(header.fid_major == 0xbd && (header.fid_minor & 0xf0) == 0); + EXPECTS(header.fid_major == 0xbd && (header.fid_minor & 0xf0) == 0); return header.fid_minor % 16; } case 0x80: // LPCM { - Expects(header.fid_major == 0xbd && (header.fid_minor & 0xf0) == 0x40); + EXPECTS(header.fid_major == 0xbd && (header.fid_minor & 0xf0) == 0x40); return header.fid_minor % 16; } case 0x81: // AC3 { - Expects(header.fid_major == 0xbd && (header.fid_minor & 0xf0) == 0x30); + EXPECTS(header.fid_major == 0xbd && (header.fid_minor & 0xf0) == 0x30); return header.fid_minor % 16; } case 0xdd: { - Expects(header.fid_major == 0xbd && (header.fid_minor & 0xf0) == 0x20); + EXPECTS(header.fid_major == 0xbd && (header.fid_minor & 0xf0) == 0x20); return header.fid_minor % 16; } } @@ -454,7 +454,7 @@ s32 cellPamfReaderGetEsFilterId(vm::ptr pSelf, vm::ptrstream < (u32)pSelf->pAddr->stream_count); + EXPECTS((u32)pSelf->stream < (u32)pSelf->pAddr->stream_count); auto& header = pSelf->pAddr->stream_headers[pSelf->stream]; pEsFilterId->filterIdMajor = header.fid_major; pEsFilterId->filterIdMinor = header.fid_minor; @@ -467,7 +467,7 @@ s32 cellPamfReaderGetStreamInfo(vm::ptr pSelf, vm::ptr pIn { cellPamf.warning("cellPamfReaderGetStreamInfo(pSelf=*0x%x, pInfo=*0x%x, size=%d)", pSelf, pInfo, size); - Expects((u32)pSelf->stream < (u32)pSelf->pAddr->stream_count); + EXPECTS((u32)pSelf->stream < (u32)pSelf->pAddr->stream_count); auto& header = pSelf->pAddr->stream_headers[pSelf->stream]; const u8 type = pamfGetStreamType(pSelf, pSelf->stream); const u8 ch = pamfGetStreamChannel(pSelf, pSelf->stream); diff --git a/rpcs3/Emu/Cell/Modules/cellPamf.h b/rpcs3/Emu/Cell/Modules/cellPamf.h index 4dd45b3256..60d042e77e 100644 --- a/rpcs3/Emu/Cell/Modules/cellPamf.h +++ b/rpcs3/Emu/Cell/Modules/cellPamf.h @@ -400,6 +400,8 @@ CHECK_SIZE(CellPamfReader, 128); s32 cellPamfReaderInitialize(vm::ptr pSelf, vm::cptr pAddr, u64 fileSize, u32 attribute); +#include +#include extern const std::function SQUEUE_ALWAYS_EXIT; extern const std::function SQUEUE_NEVER_EXIT; @@ -462,8 +464,8 @@ public: while (u32 res = m_sync.atomic_op([&pos](squeue_sync_var_t& sync) -> u32 { - Expects(sync.count <= sq_size); - Expects(sync.position < sq_size); + EXPECTS(sync.count <= sq_size); + EXPECTS(sync.position < sq_size); if (sync.push_lock) { @@ -492,9 +494,9 @@ public: m_sync.atomic_op([](squeue_sync_var_t& sync) { - Expects(sync.count <= sq_size); - Expects(sync.position < sq_size); - Expects(sync.push_lock); + EXPECTS(sync.count <= sq_size); + EXPECTS(sync.position < sq_size); + EXPECTS(sync.push_lock); sync.push_lock = 0; sync.count++; }); @@ -525,8 +527,8 @@ public: while (u32 res = m_sync.atomic_op([&pos](squeue_sync_var_t& sync) -> u32 { - Expects(sync.count <= sq_size); - Expects(sync.position < sq_size); + EXPECTS(sync.count <= sq_size); + EXPECTS(sync.position < sq_size); if (!sync.count) { @@ -555,9 +557,9 @@ public: m_sync.atomic_op([](squeue_sync_var_t& sync) { - Expects(sync.count <= sq_size); - Expects(sync.position < sq_size); - Expects(sync.pop_lock); + EXPECTS(sync.count <= sq_size); + EXPECTS(sync.position < sq_size); + EXPECTS(sync.pop_lock); sync.pop_lock = 0; sync.position++; sync.count--; @@ -589,13 +591,13 @@ public: bool peek(T& data, u32 start_pos, const std::function& test_exit) { - Expects(start_pos < sq_size); + EXPECTS(start_pos < sq_size); u32 pos = 0; while (u32 res = m_sync.atomic_op([&pos, start_pos](squeue_sync_var_t& sync) -> u32 { - Expects(sync.count <= sq_size); - Expects(sync.position < sq_size); + EXPECTS(sync.count <= sq_size); + EXPECTS(sync.position < sq_size); if (sync.count <= start_pos) { @@ -624,9 +626,9 @@ public: m_sync.atomic_op([](squeue_sync_var_t& sync) { - Expects(sync.count <= sq_size); - Expects(sync.position < sq_size); - Expects(sync.pop_lock); + EXPECTS(sync.count <= sq_size); + EXPECTS(sync.position < sq_size); + EXPECTS(sync.pop_lock); sync.pop_lock = 0; }); @@ -665,7 +667,7 @@ public: public: T& operator [] (u32 index) { - Expects(index < m_count); + EXPECTS(index < m_count); index += m_pos; index = index < sq_size ? index : index - sq_size; return m_data[index]; @@ -678,8 +680,8 @@ public: while (m_sync.atomic_op([&pos, &count](squeue_sync_var_t& sync) -> u32 { - Expects(sync.count <= sq_size); - Expects(sync.position < sq_size); + EXPECTS(sync.count <= sq_size); + EXPECTS(sync.position < sq_size); if (sync.pop_lock || sync.push_lock) { @@ -701,9 +703,9 @@ public: m_sync.atomic_op([](squeue_sync_var_t& sync) { - Expects(sync.count <= sq_size); - Expects(sync.position < sq_size); - Expects(sync.pop_lock && sync.push_lock); + EXPECTS(sync.count <= sq_size); + EXPECTS(sync.position < sq_size); + EXPECTS(sync.pop_lock && sync.push_lock); sync.pop_lock = 0; sync.push_lock = 0; }); @@ -716,8 +718,8 @@ public: { while (m_sync.atomic_op([](squeue_sync_var_t& sync) -> u32 { - Expects(sync.count <= sq_size); - Expects(sync.position < sq_size); + EXPECTS(sync.count <= sq_size); + EXPECTS(sync.position < sq_size); if (sync.pop_lock || sync.push_lock) { diff --git a/rpcs3/Emu/Cell/Modules/cellPhotoDecode.cpp b/rpcs3/Emu/Cell/Modules/cellPhotoDecode.cpp index 90f759f1e4..6d971b8b1c 100644 --- a/rpcs3/Emu/Cell/Modules/cellPhotoDecode.cpp +++ b/rpcs3/Emu/Cell/Modules/cellPhotoDecode.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellPhotoDecode); +logs::channel cellPhotoDecode("cellPhotoDecode", logs::level::notice); // Return Codes enum diff --git a/rpcs3/Emu/Cell/Modules/cellPhotoExport.cpp b/rpcs3/Emu/Cell/Modules/cellPhotoExport.cpp index 3b9f4a6381..dd1d76396d 100644 --- a/rpcs3/Emu/Cell/Modules/cellPhotoExport.cpp +++ b/rpcs3/Emu/Cell/Modules/cellPhotoExport.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellPhotoExport); +logs::channel cellPhotoExport("cellPhotoExport", logs::level::notice); // Return Codes enum diff --git a/rpcs3/Emu/Cell/Modules/cellPhotoImport.cpp b/rpcs3/Emu/Cell/Modules/cellPhotoImport.cpp index 4bb17ce497..5813848716 100644 --- a/rpcs3/Emu/Cell/Modules/cellPhotoImport.cpp +++ b/rpcs3/Emu/Cell/Modules/cellPhotoImport.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellPhotoImportUtil); +logs::channel cellPhotoImportUtil("cellPhotoImportUtil", logs::level::notice); // Return Codes enum diff --git a/rpcs3/Emu/Cell/Modules/cellPngDec.cpp b/rpcs3/Emu/Cell/Modules/cellPngDec.cpp index 431170548e..82b8038ee5 100644 --- a/rpcs3/Emu/Cell/Modules/cellPngDec.cpp +++ b/rpcs3/Emu/Cell/Modules/cellPngDec.cpp @@ -7,7 +7,7 @@ #include "png.h" #include "cellPngDec.h" -LOG_CHANNEL(cellPngDec); +logs::channel cellPngDec("cellPngDec", logs::level::notice); // cellPngDec aliases to improve readability using PPHandle = vm::pptr; diff --git a/rpcs3/Emu/Cell/Modules/cellPngEnc.cpp b/rpcs3/Emu/Cell/Modules/cellPngEnc.cpp index a1efb70795..5ccf49dadb 100644 --- a/rpcs3/Emu/Cell/Modules/cellPngEnc.cpp +++ b/rpcs3/Emu/Cell/Modules/cellPngEnc.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellPngEnc); +logs::channel cellPngEnc("cellPngEnc", logs::level::notice); // Error Codes enum diff --git a/rpcs3/Emu/Cell/Modules/cellPrint.cpp b/rpcs3/Emu/Cell/Modules/cellPrint.cpp index b0a37969cd..648237c75f 100644 --- a/rpcs3/Emu/Cell/Modules/cellPrint.cpp +++ b/rpcs3/Emu/Cell/Modules/cellPrint.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellPrint); +logs::channel cellPrint("cellPrint", logs::level::notice); // Error Codes enum diff --git a/rpcs3/Emu/Cell/Modules/cellRec.cpp b/rpcs3/Emu/Cell/Modules/cellRec.cpp index ce3aa50e99..5d61b2d8c8 100644 --- a/rpcs3/Emu/Cell/Modules/cellRec.cpp +++ b/rpcs3/Emu/Cell/Modules/cellRec.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellRec); +logs::channel cellRec("cellRec", logs::level::notice); s32 cellRecOpen() { diff --git a/rpcs3/Emu/Cell/Modules/cellRemotePlay.cpp b/rpcs3/Emu/Cell/Modules/cellRemotePlay.cpp index 0c7983bb12..fdd9c072cb 100644 --- a/rpcs3/Emu/Cell/Modules/cellRemotePlay.cpp +++ b/rpcs3/Emu/Cell/Modules/cellRemotePlay.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellRemotePlay); +logs::channel cellRemotePlay("cellRemotePlay", logs::level::notice); s32 cellRemotePlayGetStatus() { diff --git a/rpcs3/Emu/Cell/Modules/cellResc.cpp b/rpcs3/Emu/Cell/Modules/cellResc.cpp index 00e1a5f8f9..182bfd0e14 100644 --- a/rpcs3/Emu/Cell/Modules/cellResc.cpp +++ b/rpcs3/Emu/Cell/Modules/cellResc.cpp @@ -6,7 +6,7 @@ #include "Emu/RSX/GCM.h" #include "cellResc.h" -LOG_CHANNEL(cellResc); +logs::channel cellResc("cellResc", logs::level::notice); s32 cellRescInit(vm::ptr initConfig) { diff --git a/rpcs3/Emu/Cell/Modules/cellRtc.cpp b/rpcs3/Emu/Cell/Modules/cellRtc.cpp index 8648da34ee..0c53abf9f4 100644 --- a/rpcs3/Emu/Cell/Modules/cellRtc.cpp +++ b/rpcs3/Emu/Cell/Modules/cellRtc.cpp @@ -3,7 +3,7 @@ #include "cellRtc.h" -LOG_CHANNEL(cellRtc); +logs::channel cellRtc("cellRtc", logs::level::notice); s64 convertToUNIXTime(u16 seconds, u16 minutes, u16 hours, u16 days, s32 years) { diff --git a/rpcs3/Emu/Cell/Modules/cellRudp.cpp b/rpcs3/Emu/Cell/Modules/cellRudp.cpp index f72f07fa01..c7ae11dfda 100644 --- a/rpcs3/Emu/Cell/Modules/cellRudp.cpp +++ b/rpcs3/Emu/Cell/Modules/cellRudp.cpp @@ -5,7 +5,7 @@ #include "cellRudp.h" -LOG_CHANNEL(cellRudp); +logs::channel cellRudp("cellRudp", logs::level::notice); struct rudp_t { diff --git a/rpcs3/Emu/Cell/Modules/cellSail.cpp b/rpcs3/Emu/Cell/Modules/cellSail.cpp index 8193c663ff..970bd2a324 100644 --- a/rpcs3/Emu/Cell/Modules/cellSail.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSail.cpp @@ -5,7 +5,7 @@ #include "cellSail.h" #include "cellPamf.h" -LOG_CHANNEL(cellSail); +logs::channel cellSail("cellSail", logs::level::notice); void playerBoot(vm::ptr pSelf, u64 userParam) { @@ -818,7 +818,7 @@ s32 cellSailPlayerCreateDescriptor(vm::ptr pSelf, s32 streamType u32 buffer = vm::alloc(size, vm::main); auto bufPtr = vm::cptr::make(buffer); PamfHeader *buf = const_cast(bufPtr.get_ptr()); - ASSERT(f.read(buf, size) == size); + VERIFY(f.read(buf, size) == size); u32 sp_ = vm::alloc(sizeof(CellPamfReader), vm::main); auto sp = vm::ptr::make(sp_); u32 reader = cellPamfReaderInitialize(sp, bufPtr, size, 0); diff --git a/rpcs3/Emu/Cell/Modules/cellSailRec.cpp b/rpcs3/Emu/Cell/Modules/cellSailRec.cpp index 7840bc8461..e7c7b7b306 100644 --- a/rpcs3/Emu/Cell/Modules/cellSailRec.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSailRec.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellSailRec); +logs::channel cellSailRec("cellSailRec", logs::level::notice); // Error Codes enum diff --git a/rpcs3/Emu/Cell/Modules/cellSaveData.cpp b/rpcs3/Emu/Cell/Modules/cellSaveData.cpp index 97389a9a41..b55023b667 100644 --- a/rpcs3/Emu/Cell/Modules/cellSaveData.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSaveData.cpp @@ -7,7 +7,9 @@ #include "Loader/PSF.h" #include "Utilities/StrUtil.h" -LOG_CHANNEL(cellSaveData); +#include + +logs::channel cellSaveData("cellSaveData", logs::level::notice); // cellSaveData aliases (only for cellSaveData.cpp) using PSetList = vm::ptr; @@ -609,7 +611,7 @@ static never_inline s32 savedata_op(PPUThread& ppu, u32 operation, u32 version, // Write PARAM.SFO if (psf.size()) { - fs::file(sfo_path, fs::rewrite).write(psf::save_object(psf)); + psf::save_object(fs::file(sfo_path, fs::rewrite), psf); } return CELL_OK; diff --git a/rpcs3/Emu/Cell/Modules/cellScreenshot.cpp b/rpcs3/Emu/Cell/Modules/cellScreenshot.cpp index b062a1d5e8..613fa93f11 100644 --- a/rpcs3/Emu/Cell/Modules/cellScreenshot.cpp +++ b/rpcs3/Emu/Cell/Modules/cellScreenshot.cpp @@ -4,7 +4,7 @@ #include "cellScreenshot.h" -LOG_CHANNEL(cellScreenshot); +logs::channel cellScreenshot("cellScreenshot", logs::level::notice); s32 cellScreenShotSetParameter() //const CellScreenShotSetParam *param { diff --git a/rpcs3/Emu/Cell/Modules/cellSearch.cpp b/rpcs3/Emu/Cell/Modules/cellSearch.cpp index 6c9e43fc6c..e1e199f450 100644 --- a/rpcs3/Emu/Cell/Modules/cellSearch.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSearch.cpp @@ -4,7 +4,7 @@ #include "cellSearch.h" -LOG_CHANNEL(cellSearch); +logs::channel cellSearch("cellSearch", logs::level::notice); s32 cellSearchInitialize(CellSearchMode mode, u32 container, vm::ptr func, vm::ptr userData) { diff --git a/rpcs3/Emu/Cell/Modules/cellSheap.cpp b/rpcs3/Emu/Cell/Modules/cellSheap.cpp index fe8ac83558..314178e1eb 100644 --- a/rpcs3/Emu/Cell/Modules/cellSheap.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSheap.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellSheap); +logs::channel cellSheap("cellSheap", logs::level::notice); // Return Codes enum diff --git a/rpcs3/Emu/Cell/Modules/cellSpudll.cpp b/rpcs3/Emu/Cell/Modules/cellSpudll.cpp index 5aeaa9ae77..9d7b095223 100644 --- a/rpcs3/Emu/Cell/Modules/cellSpudll.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSpudll.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellSpudll); +logs::channel cellSpudll("cellSpudll", logs::level::notice); s32 cellSpudllGetImageSize(vm::ptr psize, vm::cptr so_elf, vm::cptr config) { diff --git a/rpcs3/Emu/Cell/Modules/cellSpurs.cpp b/rpcs3/Emu/Cell/Modules/cellSpurs.cpp index d20b448ce4..db522166bb 100644 --- a/rpcs3/Emu/Cell/Modules/cellSpurs.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSpurs.cpp @@ -15,7 +15,7 @@ #include "sysPrxForUser.h" #include "cellSpurs.h" -LOG_CHANNEL(cellSpurs); +logs::channel cellSpurs("cellSpurs", logs::level::notice); // TODO struct cell_error_t @@ -30,6 +30,28 @@ struct cell_error_t #define CHECK_SUCCESS(expr) if (cell_error_t error{expr}) throw fmt::exception("Failure: %s -> 0x%x" HERE, #expr, error.value) +static u32 ppu_thread_create(u32 entry, u64 arg, s32 prio, u32 stacksize, const std::string& name, std::function task) +{ + const auto ppu = idm::make_ptr(name); + + ppu->prio = prio; + ppu->stack_size = stacksize; + ppu->custom_task = std::move(task); + ppu->cpu_init(); + + if (entry) + { + ppu->pc = vm::read32(entry); + ppu->GPR[2] = vm::read32(entry + 4); // rtoc + } + + ppu->GPR[3] = arg; + ppu->state -= cpu_state::stop; + (*ppu)->lock_notify(); + + return ppu->id; +} + //---------------------------------------------------------------------------- // Function prototypes //---------------------------------------------------------------------------- @@ -588,7 +610,7 @@ void _spurs::handler_entry(PPUThread& ppu, vm::ptr spurs) if ((spurs->flags1 & SF1_EXIT_IF_NO_WORK) == 0) { - ASSERT(spurs->handlerExiting == 1); + VERIFY(spurs->handlerExiting == 1); return sys_ppu_thread_exit(ppu, 0); } @@ -651,16 +673,16 @@ s32 _spurs::wakeup_shutdown_completion_waiter(PPUThread& ppu, vm::ptr { wklF->hook(ppu, spurs, wid, wklF->hookArg); - ASSERT(wklEvent->load() & 0x01); - ASSERT(wklEvent->load() & 0x02); - ASSERT((wklEvent->load() & 0x20) == 0); + VERIFY(wklEvent->load() & 0x01); + VERIFY(wklEvent->load() & 0x02); + VERIFY((wklEvent->load() & 0x20) == 0); wklEvent->fetch_or(0x20); } s32 rc = CELL_OK; if (!wklF->hook || wklEvent->load() & 0x10) { - ASSERT(wklF->x28 == 2); + VERIFY(wklF->x28 == 2); rc = sys_semaphore_post((u32)wklF->sem, 1); } @@ -1027,7 +1049,7 @@ s32 _spurs::initialize(PPUThread& ppu, vm::ptr spurs, u32 revision, u // Import SPURS kernel spurs->spuImg.type = SYS_SPU_IMAGE_TYPE_USER; - spurs->spuImg.segs = { vm::alloc(0x40000, vm::main), vm::addr }; + spurs->spuImg.segs = vm::cast(vm::alloc(0x40000, vm::main)); spurs->spuImg.entry_point = isSecond ? CELL_SPURS_KERNEL2_ENTRY_ADDR : CELL_SPURS_KERNEL1_ENTRY_ADDR; spurs->spuImg.nsegs = 1; @@ -2117,8 +2139,8 @@ s32 _spurs::add_workload(vm::ptr spurs, vm::ptr wid, vm::cptrwklCurrentContention[wnum] & 0xf) == 0); - ASSERT((spurs->wklPendingContention[wnum] & 0xf) == 0); + VERIFY((spurs->wklCurrentContention[wnum] & 0xf) == 0); + VERIFY((spurs->wklPendingContention[wnum] & 0xf) == 0); spurs->wklState1[wnum] = 1; spurs->wklStatus1[wnum] = 0; spurs->wklEvent1[wnum] = 0; @@ -2153,8 +2175,8 @@ s32 _spurs::add_workload(vm::ptr spurs, vm::ptr wid, vm::cptrwklCurrentContention[index] & 0xf0) == 0); - ASSERT((spurs->wklPendingContention[index] & 0xf0) == 0); + VERIFY((spurs->wklCurrentContention[index] & 0xf0) == 0); + VERIFY((spurs->wklPendingContention[index] & 0xf0) == 0); spurs->wklState2[index] = 1; spurs->wklStatus2[index] = 0; spurs->wklEvent2[index] = 0; @@ -2233,7 +2255,7 @@ s32 _spurs::add_workload(vm::ptr spurs, vm::ptr wid, vm::cptr> wnum); }); - ASSERT(res_wkl <= 31); + VERIFY(res_wkl <= 31); spurs->wklState(wnum).exchange(2); spurs->sysSrvMsgUpdateWorkload.exchange(0xff); spurs->sysSrvMessage.exchange(0xff); diff --git a/rpcs3/Emu/Cell/Modules/cellSpursJq.cpp b/rpcs3/Emu/Cell/Modules/cellSpursJq.cpp index b5d85f2d5c..5be8826002 100644 --- a/rpcs3/Emu/Cell/Modules/cellSpursJq.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSpursJq.cpp @@ -8,7 +8,7 @@ #include "cellSpurs.h" #include "cellSpursJq.h" -LOG_CHANNEL(cellSpursJq); +logs::channel cellSpursJq("cellSpursJq", logs::level::notice); s32 cellSpursJobQueueAttributeInitialize() { diff --git a/rpcs3/Emu/Cell/Modules/cellSpursSpu.cpp b/rpcs3/Emu/Cell/Modules/cellSpursSpu.cpp index 7739b1efc3..26ef8ba13c 100644 --- a/rpcs3/Emu/Cell/Modules/cellSpursSpu.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSpursSpu.cpp @@ -9,11 +9,15 @@ #include "Emu/Cell/lv2/sys_spu.h" #include "cellSpurs.h" +#include + //---------------------------------------------------------------------------- // Externs //---------------------------------------------------------------------------- -extern _log::channel cellSpurs; +extern logs::channel cellSpurs; + +extern std::mutex& get_current_thread_mutex(); //---------------------------------------------------------------------------- // Function prototypes @@ -685,7 +689,7 @@ bool spursKernelEntry(SPUThread& spu) { while (true) { - std::this_thread::sleep_for(std::chrono::milliseconds(100)); + std::this_thread::sleep_for(100ms); CHECK_EMU_STATUS; } @@ -861,7 +865,7 @@ void spursSysServiceIdleHandler(SPUThread& spu, SpursKernelContext* ctxt) // The system service blocks by making a reservation and waiting on the lock line reservation lost event. CHECK_EMU_STATUS; if (!lock) lock.lock(); - get_current_thread_cv().wait_for(lock, std::chrono::milliseconds(1)); + get_current_thread_cv().wait_for(lock, 1ms); continue; } diff --git a/rpcs3/Emu/Cell/Modules/cellSsl.cpp b/rpcs3/Emu/Cell/Modules/cellSsl.cpp index ab14c7fedd..daa0707378 100644 --- a/rpcs3/Emu/Cell/Modules/cellSsl.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSsl.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellSsl); +logs::channel cellSsl("cellSsl", logs::level::notice); s32 cellSslInit() { diff --git a/rpcs3/Emu/Cell/Modules/cellStorage.cpp b/rpcs3/Emu/Cell/Modules/cellStorage.cpp index 894f33cf4a..cc498d6471 100644 --- a/rpcs3/Emu/Cell/Modules/cellStorage.cpp +++ b/rpcs3/Emu/Cell/Modules/cellStorage.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -extern _log::channel cellSysutil; +extern logs::channel cellSysutil; s32 cellStorageDataImportMove() { diff --git a/rpcs3/Emu/Cell/Modules/cellSubdisplay.cpp b/rpcs3/Emu/Cell/Modules/cellSubdisplay.cpp index 6f971a4923..3e978e0dcc 100644 --- a/rpcs3/Emu/Cell/Modules/cellSubdisplay.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSubdisplay.cpp @@ -3,7 +3,7 @@ #include "cellSubdisplay.h" -LOG_CHANNEL(cellSubdisplay); +logs::channel cellSubdisplay("cellSubdisplay", logs::level::notice); s32 cellSubDisplayInit() { diff --git a/rpcs3/Emu/Cell/Modules/cellSync.cpp b/rpcs3/Emu/Cell/Modules/cellSync.cpp index eb1f4fc716..1dc29dfb85 100644 --- a/rpcs3/Emu/Cell/Modules/cellSync.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSync.cpp @@ -8,7 +8,9 @@ #include "Emu/Memory/wait_engine.h" -LOG_CHANNEL(cellSync); +#include + +logs::channel cellSync("cellSync", logs::level::notice); namespace _sync { @@ -32,12 +34,12 @@ ppu_error_code cellSyncMutexInitialize(vm::ptr mutex) { cellSync.trace("cellSyncMutexInitialize(mutex=*0x%x)", mutex); - if (!mutex) + if (UNLIKELY(!mutex)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!mutex.aligned()) + if (UNLIKELY(!mutex.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -51,12 +53,12 @@ ppu_error_code cellSyncMutexLock(vm::ptr mutex) { cellSync.trace("cellSyncMutexLock(mutex=*0x%x)", mutex); - if (!mutex) + if (UNLIKELY(!mutex)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!mutex.aligned()) + if (UNLIKELY(!mutex.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -76,12 +78,12 @@ ppu_error_code cellSyncMutexTryLock(vm::ptr mutex) { cellSync.trace("cellSyncMutexTryLock(mutex=*0x%x)", mutex); - if (!mutex) + if (UNLIKELY(!mutex)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!mutex.aligned()) + if (UNLIKELY(!mutex.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -98,12 +100,12 @@ ppu_error_code cellSyncMutexUnlock(vm::ptr mutex) { cellSync.trace("cellSyncMutexUnlock(mutex=*0x%x)", mutex); - if (!mutex) + if (UNLIKELY(!mutex)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!mutex.aligned()) + if (UNLIKELY(!mutex.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -119,17 +121,17 @@ ppu_error_code cellSyncBarrierInitialize(vm::ptr barrier, u16 t { cellSync.trace("cellSyncBarrierInitialize(barrier=*0x%x, total_count=%d)", barrier, total_count); - if (!barrier) + if (UNLIKELY(!barrier)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!barrier.aligned()) + if (UNLIKELY(!barrier.aligned())) { return CELL_SYNC_ERROR_ALIGN; } - if (!total_count || total_count > 32767) + if (UNLIKELY(!total_count || total_count > 32767)) { return CELL_SYNC_ERROR_INVAL; } @@ -144,12 +146,12 @@ ppu_error_code cellSyncBarrierNotify(vm::ptr barrier) { cellSync.trace("cellSyncBarrierNotify(barrier=*0x%x)", barrier); - if (!barrier) + if (UNLIKELY(!barrier)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!barrier.aligned()) + if (UNLIKELY(!barrier.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -165,12 +167,12 @@ ppu_error_code cellSyncBarrierTryNotify(vm::ptr barrier) { cellSync.trace("cellSyncBarrierTryNotify(barrier=*0x%x)", barrier); - if (!barrier) + if (UNLIKELY(!barrier)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!barrier.aligned()) + if (UNLIKELY(!barrier.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -191,12 +193,12 @@ ppu_error_code cellSyncBarrierWait(vm::ptr barrier) { cellSync.trace("cellSyncBarrierWait(barrier=*0x%x)", barrier); - if (!barrier) + if (UNLIKELY(!barrier)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!barrier.aligned()) + if (UNLIKELY(!barrier.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -214,12 +216,12 @@ ppu_error_code cellSyncBarrierTryWait(vm::ptr barrier) { cellSync.trace("cellSyncBarrierTryWait(barrier=*0x%x)", barrier); - if (!barrier) + if (UNLIKELY(!barrier)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!barrier.aligned()) + if (UNLIKELY(!barrier.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -240,17 +242,17 @@ ppu_error_code cellSyncRwmInitialize(vm::ptr rwm, vm::ptr buf { cellSync.trace("cellSyncRwmInitialize(rwm=*0x%x, buffer=*0x%x, buffer_size=0x%x)", rwm, buffer, buffer_size); - if (!rwm || !buffer) + if (UNLIKELY(!rwm || !buffer)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!rwm.aligned() || buffer % 128) + if (UNLIKELY(!rwm.aligned() || buffer % 128)) { return CELL_SYNC_ERROR_ALIGN; } - if (buffer_size % 128 || buffer_size > 0x4000) + if (UNLIKELY(buffer_size % 128 || buffer_size > 0x4000)) { return CELL_SYNC_ERROR_INVAL; } @@ -269,12 +271,12 @@ ppu_error_code cellSyncRwmRead(vm::ptr rwm, vm::ptr buffer) { cellSync.trace("cellSyncRwmRead(rwm=*0x%x, buffer=*0x%x)", rwm, buffer); - if (!rwm || !buffer) + if (UNLIKELY(!rwm || !buffer)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!rwm.aligned()) + if (UNLIKELY(!rwm.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -300,12 +302,12 @@ ppu_error_code cellSyncRwmTryRead(vm::ptr rwm, vm::ptr buffer { cellSync.trace("cellSyncRwmTryRead(rwm=*0x%x, buffer=*0x%x)", rwm, buffer); - if (!rwm || !buffer) + if (UNLIKELY(!rwm || !buffer)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!rwm.aligned()) + if (UNLIKELY(!rwm.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -334,12 +336,12 @@ ppu_error_code cellSyncRwmWrite(vm::ptr rwm, vm::cptr buffer) { cellSync.trace("cellSyncRwmWrite(rwm=*0x%x, buffer=*0x%x)", rwm, buffer); - if (!rwm || !buffer) + if (UNLIKELY(!rwm || !buffer)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!rwm.aligned()) + if (UNLIKELY(!rwm.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -365,12 +367,12 @@ ppu_error_code cellSyncRwmTryWrite(vm::ptr rwm, vm::cptr buff { cellSync.trace("cellSyncRwmTryWrite(rwm=*0x%x, buffer=*0x%x)", rwm, buffer); - if (!rwm || !buffer) + if (UNLIKELY(!rwm || !buffer)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!rwm.aligned()) + if (UNLIKELY(!rwm.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -396,22 +398,22 @@ ppu_error_code cellSyncQueueInitialize(vm::ptr queue, vm::ptr { cellSync.trace("cellSyncQueueInitialize(queue=*0x%x, buffer=*0x%x, size=0x%x, depth=0x%x)", queue, buffer, size, depth); - if (!queue) + if (UNLIKELY(!queue)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (size && !buffer) + if (UNLIKELY(size && !buffer)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!queue.aligned() || buffer % 16) + if (UNLIKELY(!queue.aligned() || buffer % 16)) { return CELL_SYNC_ERROR_ALIGN; } - if (!depth || size % 16) + if (UNLIKELY(!depth || size % 16)) { return CELL_SYNC_ERROR_INVAL; } @@ -431,12 +433,12 @@ ppu_error_code cellSyncQueuePush(vm::ptr queue, vm::cptr bu { cellSync.trace("cellSyncQueuePush(queue=*0x%x, buffer=*0x%x)", queue, buffer); - if (!queue || !buffer) + if (UNLIKELY(!queue || !buffer)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!queue.aligned()) + if (UNLIKELY(!queue.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -462,12 +464,12 @@ ppu_error_code cellSyncQueueTryPush(vm::ptr queue, vm::cptr { cellSync.trace("cellSyncQueueTryPush(queue=*0x%x, buffer=*0x%x)", queue, buffer); - if (!queue || !buffer) + if (UNLIKELY(!queue || !buffer)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!queue.aligned()) + if (UNLIKELY(!queue.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -496,12 +498,12 @@ ppu_error_code cellSyncQueuePop(vm::ptr queue, vm::ptr buff { cellSync.trace("cellSyncQueuePop(queue=*0x%x, buffer=*0x%x)", queue, buffer); - if (!queue || !buffer) + if (UNLIKELY(!queue || !buffer)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!queue.aligned()) + if (UNLIKELY(!queue.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -527,12 +529,12 @@ ppu_error_code cellSyncQueueTryPop(vm::ptr queue, vm::ptr b { cellSync.trace("cellSyncQueueTryPop(queue=*0x%x, buffer=*0x%x)", queue, buffer); - if (!queue || !buffer) + if (UNLIKELY(!queue || !buffer)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!queue.aligned()) + if (UNLIKELY(!queue.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -561,12 +563,12 @@ ppu_error_code cellSyncQueuePeek(vm::ptr queue, vm::ptr buf { cellSync.trace("cellSyncQueuePeek(queue=*0x%x, buffer=*0x%x)", queue, buffer); - if (!queue || !buffer) + if (UNLIKELY(!queue || !buffer)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!queue.aligned()) + if (UNLIKELY(!queue.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -592,12 +594,12 @@ ppu_error_code cellSyncQueueTryPeek(vm::ptr queue, vm::ptr { cellSync.trace("cellSyncQueueTryPeek(queue=*0x%x, buffer=*0x%x)", queue, buffer); - if (!queue || !buffer) + if (UNLIKELY(!queue || !buffer)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!queue.aligned()) + if (UNLIKELY(!queue.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -626,12 +628,12 @@ ppu_error_code cellSyncQueueSize(vm::ptr queue) { cellSync.trace("cellSyncQueueSize(queue=*0x%x)", queue); - if (!queue) + if (UNLIKELY(!queue)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!queue.aligned()) + if (UNLIKELY(!queue.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -645,12 +647,12 @@ ppu_error_code cellSyncQueueClear(vm::ptr queue) { cellSync.trace("cellSyncQueueClear(queue=*0x%x)", queue); - if (!queue) + if (UNLIKELY(!queue)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!queue.aligned()) + if (UNLIKELY(!queue.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -713,30 +715,30 @@ ppu_error_code cellSyncLFQueueInitialize(vm::ptr queue, vm::cpt { cellSync.warning("cellSyncLFQueueInitialize(queue=*0x%x, buffer=*0x%x, size=0x%x, depth=0x%x, direction=%d, eaSignal=*0x%x)", queue, buffer, size, depth, direction, eaSignal); - if (!queue) + if (UNLIKELY(!queue)) { return CELL_SYNC_ERROR_NULL_POINTER; } if (size) { - if (!buffer) + if (UNLIKELY(!buffer)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (size > 0x4000 || size % 16) + if (UNLIKELY(size > 0x4000 || size % 16)) { return CELL_SYNC_ERROR_INVAL; } } - if (!depth || depth > 0x7fff || direction > 3) + if (UNLIKELY(!depth || depth > 0x7fff || direction > 3)) { return CELL_SYNC_ERROR_INVAL; } - if (!queue.aligned() || buffer % 16) + if (UNLIKELY(!queue.aligned() || buffer % 16)) { return CELL_SYNC_ERROR_ALIGN; } @@ -764,7 +766,7 @@ ppu_error_code cellSyncLFQueueInitialize(vm::ptr queue, vm::cpt if (old) { - if (sdk_ver > 0x17ffff && old != 2) + if (UNLIKELY(sdk_ver > 0x17ffff && old != 2)) { return CELL_SYNC_ERROR_STAT; } @@ -777,7 +779,7 @@ ppu_error_code cellSyncLFQueueInitialize(vm::ptr queue, vm::cpt { for (const auto& data : vm::_ref(queue.addr())) { - if (data) + if (UNLIKELY(data)) { return CELL_SYNC_ERROR_STAT; } @@ -793,14 +795,14 @@ ppu_error_code cellSyncLFQueueInitialize(vm::ptr queue, vm::cpt if (old_value == 2) { - if (queue->m_size != size || queue->m_depth != depth || queue->m_buffer != buffer) + if (UNLIKELY(queue->m_size != size || queue->m_depth != depth || queue->m_buffer != buffer)) { return CELL_SYNC_ERROR_INVAL; } if (sdk_ver > 0x17ffff) { - if (queue->m_eaSignal != eaSignal || queue->m_direction != direction) + if (UNLIKELY(queue->m_eaSignal != eaSignal || queue->m_direction != direction)) { return CELL_SYNC_ERROR_INVAL; } @@ -822,7 +824,7 @@ ppu_error_code _cellSyncLFQueueGetPushPointer(PPUThread& ppu, vm::ptrm_direction != CELL_SYNC_QUEUE_PPU2SPU) + if (UNLIKELY(queue->m_direction != CELL_SYNC_QUEUE_PPU2SPU)) { return CELL_SYNC_ERROR_PERM; } @@ -906,7 +908,7 @@ ppu_error_code _cellSyncLFQueueGetPushPointer(PPUThread& ppu, vm::ptrm_eq_id, vm::null, 0) == CELL_OK); + VERIFY(sys_event_queue_receive(ppu, queue->m_eq_id, vm::null, 0) == CELL_OK); var1 = 1; } } @@ -923,7 +925,7 @@ ppu_error_code _cellSyncLFQueueCompletePushPointer(PPUThread& ppu, vm::ptrm_direction != CELL_SYNC_QUEUE_PPU2SPU) + if (UNLIKELY(queue->m_direction != CELL_SYNC_QUEUE_PPU2SPU)) { return CELL_SYNC_ERROR_PERM; } @@ -997,7 +999,7 @@ ppu_error_code _cellSyncLFQueueCompletePushPointer(PPUThread& ppu, vm::ptr 1 && (u32)var8 > 1) { - ASSERT(16 - var2 <= 1); + VERIFY(16 - var2 <= 1); } s32 var11 = (pack >> 10) & 0x1f; @@ -1029,11 +1031,11 @@ ppu_error_code _cellSyncLFQueueCompletePushPointer(PPUThread& ppu, vm::ptrpush2.compare_and_swap_test(old, push2)) { - ASSERT(var2 + var4 < 16); + VERIFY(var2 + var4 < 16); if (var6 != -1) { - ASSERT(queue->push3.compare_and_swap_test(old2, push3)); - ASSERT(fpSendSignal); + VERIFY(queue->push3.compare_and_swap_test(old2, push3)); + VERIFY(fpSendSignal); return NOT_AN_ERROR(fpSendSignal(ppu, (u32)queue->m_eaSignal.addr(), var6)); } else @@ -1064,12 +1066,12 @@ ppu_error_code _cellSyncLFQueuePushBody(PPUThread& ppu, vm::ptr // cellSyncLFQueuePush has 1 in isBlocking param, cellSyncLFQueueTryPush has 0 cellSync.warning("_cellSyncLFQueuePushBody(queue=*0x%x, buffer=*0x%x, isBlocking=%d)", queue, buffer, isBlocking); - if (!queue || !buffer) + if (UNLIKELY(!queue || !buffer)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!queue.aligned() || buffer % 16) + if (UNLIKELY(!queue.aligned() || buffer % 16)) { return CELL_SYNC_ERROR_ALIGN; } @@ -1098,7 +1100,7 @@ ppu_error_code _cellSyncLFQueuePushBody(PPUThread& ppu, vm::ptr break; } - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + std::this_thread::sleep_for(1ms); // hack } const s32 depth = queue->m_depth; @@ -1121,7 +1123,7 @@ ppu_error_code _cellSyncLFQueueGetPopPointer(PPUThread& ppu, vm::ptrm_direction != CELL_SYNC_QUEUE_SPU2PPU) + if (UNLIKELY(queue->m_direction != CELL_SYNC_QUEUE_SPU2PPU)) { return CELL_SYNC_ERROR_PERM; } @@ -1205,7 +1207,7 @@ ppu_error_code _cellSyncLFQueueGetPopPointer(PPUThread& ppu, vm::ptrm_eq_id, vm::null, 0) == CELL_OK); + VERIFY(sys_event_queue_receive(ppu, queue->m_eq_id, vm::null, 0) == CELL_OK); var1 = 1; } } @@ -1223,7 +1225,7 @@ ppu_error_code _cellSyncLFQueueCompletePopPointer(PPUThread& ppu, vm::ptrm_direction != CELL_SYNC_QUEUE_SPU2PPU) + if (UNLIKELY(queue->m_direction != CELL_SYNC_QUEUE_SPU2PPU)) { return CELL_SYNC_ERROR_PERM; } @@ -1301,7 +1303,7 @@ ppu_error_code _cellSyncLFQueueCompletePopPointer(PPUThread& ppu, vm::ptr 1 && (u32)var8 > 1) { - ASSERT(16 - var2 <= 1); + VERIFY(16 - var2 <= 1); } s32 var11 = (pack >> 10) & 0x1f; @@ -1331,8 +1333,8 @@ ppu_error_code _cellSyncLFQueueCompletePopPointer(PPUThread& ppu, vm::ptrpop3.compare_and_swap_test(old2, pop3)); - ASSERT(fpSendSignal); + VERIFY(queue->pop3.compare_and_swap_test(old2, pop3)); + VERIFY(fpSendSignal); return NOT_AN_ERROR(fpSendSignal(ppu, (u32)queue->m_eaSignal.addr(), var6)); } else @@ -1363,12 +1365,12 @@ ppu_error_code _cellSyncLFQueuePopBody(PPUThread& ppu, vm::ptr // cellSyncLFQueuePop has 1 in isBlocking param, cellSyncLFQueueTryPop has 0 cellSync.warning("_cellSyncLFQueuePopBody(queue=*0x%x, buffer=*0x%x, isBlocking=%d)", queue, buffer, isBlocking); - if (!queue || !buffer) + if (UNLIKELY(!queue || !buffer)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!queue.aligned() || buffer % 16) + if (UNLIKELY(!queue.aligned() || buffer % 16)) { return CELL_SYNC_ERROR_ALIGN; } @@ -1397,7 +1399,7 @@ ppu_error_code _cellSyncLFQueuePopBody(PPUThread& ppu, vm::ptr break; } - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + std::this_thread::sleep_for(1ms); // hack } const s32 depth = queue->m_depth; @@ -1420,12 +1422,12 @@ ppu_error_code cellSyncLFQueueClear(vm::ptr queue) { cellSync.warning("cellSyncLFQueueClear(queue=*0x%x)", queue); - if (!queue) + if (UNLIKELY(!queue)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!queue.aligned()) + if (UNLIKELY(!queue.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -1471,12 +1473,12 @@ ppu_error_code cellSyncLFQueueSize(vm::ptr queue, vm::ptr { cellSync.warning("cellSyncLFQueueSize(queue=*0x%x, size=*0x%x)", queue, size); - if (!queue || !size) + if (UNLIKELY(!queue || !size)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!queue.aligned()) + if (UNLIKELY(!queue.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -1508,12 +1510,12 @@ ppu_error_code cellSyncLFQueueDepth(vm::ptr queue, vm::ptr { cellSync.trace("cellSyncLFQueueDepth(queue=*0x%x, depth=*0x%x)", queue, depth); - if (!queue || !depth) + if (UNLIKELY(!queue || !depth)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!queue.aligned()) + if (UNLIKELY(!queue.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -1527,12 +1529,12 @@ ppu_error_code _cellSyncLFQueueGetSignalAddress(vm::cptr queue, { cellSync.trace("_cellSyncLFQueueGetSignalAddress(queue=*0x%x, ppSignal=**0x%x)", queue, ppSignal); - if (!queue || !ppSignal) + if (UNLIKELY(!queue || !ppSignal)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!queue.aligned()) + if (UNLIKELY(!queue.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -1546,12 +1548,12 @@ ppu_error_code cellSyncLFQueueGetDirection(vm::cptr queue, vm:: { cellSync.trace("cellSyncLFQueueGetDirection(queue=*0x%x, direction=*0x%x)", queue, direction); - if (!queue || !direction) + if (UNLIKELY(!queue || !direction)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!queue.aligned()) + if (UNLIKELY(!queue.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -1565,12 +1567,12 @@ ppu_error_code cellSyncLFQueueGetEntrySize(vm::cptr queue, vm:: { cellSync.trace("cellSyncLFQueueGetEntrySize(queue=*0x%x, entry_size=*0x%x)", queue, entry_size); - if (!queue || !entry_size) + if (UNLIKELY(!queue || !entry_size)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!queue.aligned()) + if (UNLIKELY(!queue.aligned())) { return CELL_SYNC_ERROR_ALIGN; } diff --git a/rpcs3/Emu/Cell/Modules/cellSync2.cpp b/rpcs3/Emu/Cell/Modules/cellSync2.cpp index 21673c5012..27e28faff9 100644 --- a/rpcs3/Emu/Cell/Modules/cellSync2.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSync2.cpp @@ -6,7 +6,7 @@ #include "Utilities/StrUtil.h" -LOG_CHANNEL(cellSync2); +logs::channel cellSync2("cellSync2", logs::level::notice); vm::gvar gCellSync2CallerThreadTypePpuThread; vm::gvar gCellSync2NotifierPpuThread; diff --git a/rpcs3/Emu/Cell/Modules/cellSysconf.cpp b/rpcs3/Emu/Cell/Modules/cellSysconf.cpp index 3685f8f1ef..c43d66f9eb 100644 --- a/rpcs3/Emu/Cell/Modules/cellSysconf.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSysconf.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellSysconf); +logs::channel cellSysconf("cellSysconf", logs::level::notice); s32 cellSysconfAbort() { diff --git a/rpcs3/Emu/Cell/Modules/cellSysmodule.cpp b/rpcs3/Emu/Cell/Modules/cellSysmodule.cpp index b4718e11dc..99be319178 100644 --- a/rpcs3/Emu/Cell/Modules/cellSysmodule.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSysmodule.cpp @@ -2,7 +2,7 @@ #include "Emu/System.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellSysmodule); +logs::channel cellSysmodule("cellSysmodule", logs::level::notice); enum { diff --git a/rpcs3/Emu/Cell/Modules/cellSysutil.cpp b/rpcs3/Emu/Cell/Modules/cellSysutil.cpp index 1e92f757ae..ce21bcb7dc 100644 --- a/rpcs3/Emu/Cell/Modules/cellSysutil.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSysutil.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Emu/System.h" #include "Emu/IdManager.h" #include "Emu/Cell/PPUModule.h" @@ -7,7 +8,7 @@ #include "Utilities/StrUtil.h" -LOG_CHANNEL(cellSysutil); +logs::channel cellSysutil("cellSysutil", logs::level::notice); // Temporarily using sys_callbacks_t = std::array, vm::ptr>, 4>; @@ -53,43 +54,47 @@ cfg::map_entry g_cfg_sys_language(cfg::root.sys, "Language", { "English (UK)", CELL_SYSUTIL_LANG_ENGLISH_GB }, }); -static const char* get_systemparam_id_name(s32 id) -{ - static thread_local char tls_id_name[16]; // for test - - switch (id) - { - case CELL_SYSUTIL_SYSTEMPARAM_ID_LANG: return "ID_LANG"; - case CELL_SYSUTIL_SYSTEMPARAM_ID_ENTER_BUTTON_ASSIGN: return "ID_ENTER_BUTTON_ASSIGN"; - case CELL_SYSUTIL_SYSTEMPARAM_ID_DATE_FORMAT: return "ID_DATE_FORMAT"; - case CELL_SYSUTIL_SYSTEMPARAM_ID_TIME_FORMAT: return "ID_TIME_FORMAT"; - case CELL_SYSUTIL_SYSTEMPARAM_ID_TIMEZONE: return "ID_TIMEZONE"; - case CELL_SYSUTIL_SYSTEMPARAM_ID_SUMMERTIME: return "ID_SUMMERTIME"; - case CELL_SYSUTIL_SYSTEMPARAM_ID_GAME_PARENTAL_LEVEL: return "ID_GAME_PARENTAL_LEVEL"; - case CELL_SYSUTIL_SYSTEMPARAM_ID_GAME_PARENTAL_LEVEL0_RESTRICT: return "ID_GAME_PARENTAL_LEVEL0_RESTRICT"; - case CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USER_HAS_NP_ACCOUNT: return "ID_CURRENT_USER_HAS_NP_ACCOUNT"; - case CELL_SYSUTIL_SYSTEMPARAM_ID_CAMERA_PLFREQ: return "ID_CAMERA_PLFREQ"; - case CELL_SYSUTIL_SYSTEMPARAM_ID_PAD_RUMBLE: return "ID_PAD_RUMBLE"; - case CELL_SYSUTIL_SYSTEMPARAM_ID_KEYBOARD_TYPE: return "ID_KEYBOARD_TYPE"; - case CELL_SYSUTIL_SYSTEMPARAM_ID_JAPANESE_KEYBOARD_ENTRY_METHOD: return "ID_JAPANESE_KEYBOARD_ENTRY_METHOD"; - case CELL_SYSUTIL_SYSTEMPARAM_ID_CHINESE_KEYBOARD_ENTRY_METHOD: return "ID_CHINESE_KEYBOARD_ENTRY_METHOD"; - case CELL_SYSUTIL_SYSTEMPARAM_ID_PAD_AUTOOFF: return "ID_PAD_AUTOOFF"; - case CELL_SYSUTIL_SYSTEMPARAM_ID_NICKNAME: return "ID_NICKNAME"; - case CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USERNAME: return "ID_CURRENT_USERNAME"; - } - - std::snprintf(tls_id_name, sizeof(tls_id_name), "0x%04X", id); - return tls_id_name; -} - enum class systemparam_id_name : s32 {}; template<> struct unveil { - static inline const char* get(systemparam_id_name arg) + struct temp { - return get_systemparam_id_name((s32)arg); + s32 value; + char buf[12]; + + temp(systemparam_id_name value) + : value(s32(value)) + { + } + }; + + static inline const char* get(temp&& in) + { + switch (in.value) + { + case CELL_SYSUTIL_SYSTEMPARAM_ID_LANG: return "ID_LANG"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_ENTER_BUTTON_ASSIGN: return "ID_ENTER_BUTTON_ASSIGN"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_DATE_FORMAT: return "ID_DATE_FORMAT"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_TIME_FORMAT: return "ID_TIME_FORMAT"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_TIMEZONE: return "ID_TIMEZONE"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_SUMMERTIME: return "ID_SUMMERTIME"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_GAME_PARENTAL_LEVEL: return "ID_GAME_PARENTAL_LEVEL"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_GAME_PARENTAL_LEVEL0_RESTRICT: return "ID_GAME_PARENTAL_LEVEL0_RESTRICT"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USER_HAS_NP_ACCOUNT: return "ID_CURRENT_USER_HAS_NP_ACCOUNT"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_CAMERA_PLFREQ: return "ID_CAMERA_PLFREQ"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_PAD_RUMBLE: return "ID_PAD_RUMBLE"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_KEYBOARD_TYPE: return "ID_KEYBOARD_TYPE"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_JAPANESE_KEYBOARD_ENTRY_METHOD: return "ID_JAPANESE_KEYBOARD_ENTRY_METHOD"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_CHINESE_KEYBOARD_ENTRY_METHOD: return "ID_CHINESE_KEYBOARD_ENTRY_METHOD"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_PAD_AUTOOFF: return "ID_PAD_AUTOOFF"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_NICKNAME: return "ID_NICKNAME"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USERNAME: return "ID_CURRENT_USERNAME"; + } + + std::snprintf(in.buf, sizeof(in.buf), "!0x%04X", in.value); + return in.buf; } }; @@ -170,7 +175,7 @@ s32 cellSysutilGetSystemParamInt(s32 id, vm::ptr value) s32 cellSysutilGetSystemParamString(s32 id, vm::ptr buf, u32 bufsize) { - cellSysutil.trace("cellSysutilGetSystemParamString(id=0x%x(%s), buf=*0x%x, bufsize=%d)", id, get_systemparam_id_name(id), buf, bufsize); + cellSysutil.trace("cellSysutilGetSystemParamString(id=0x%x(%s), buf=*0x%x, bufsize=%d)", id, systemparam_id_name(id), buf, bufsize); memset(buf.get_ptr(), 0, bufsize); @@ -255,7 +260,7 @@ s32 cellSysCacheMount(vm::ptr param) cellSysutil.warning("cellSysCacheMount(param=*0x%x)", param); const std::string& cache_id = param->cacheId; - ASSERT(cache_id.size() < sizeof(param->cacheId)); + VERIFY(cache_id.size() < sizeof(param->cacheId)); const std::string& cache_path = "/dev_hdd1/cache/" + cache_id + '/'; strcpy_trunc(param->getCachePath, cache_path); diff --git a/rpcs3/Emu/Cell/Modules/cellSysutilAp.cpp b/rpcs3/Emu/Cell/Modules/cellSysutilAp.cpp index f8c6d1668f..d989ceb55d 100644 --- a/rpcs3/Emu/Cell/Modules/cellSysutilAp.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSysutilAp.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellSysutilAp); +logs::channel cellSysutilAp("cellSysutilAp", logs::level::notice); // Return Codes enum diff --git a/rpcs3/Emu/Cell/Modules/cellSysutilAvc.cpp b/rpcs3/Emu/Cell/Modules/cellSysutilAvc.cpp index 24b78da7b4..fee4207eee 100644 --- a/rpcs3/Emu/Cell/Modules/cellSysutilAvc.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSysutilAvc.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellSysutilAvc); +logs::channel cellSysutilAvc("cellSysutilAvc", logs::level::notice); s32 cellSysutilAvcByeRequest() { diff --git a/rpcs3/Emu/Cell/Modules/cellSysutilAvc2.cpp b/rpcs3/Emu/Cell/Modules/cellSysutilAvc2.cpp index c88ffd32d5..1acf10e32d 100644 --- a/rpcs3/Emu/Cell/Modules/cellSysutilAvc2.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSysutilAvc2.cpp @@ -5,7 +5,7 @@ #include "sceNp2.h" #include "cellSysutilAvc2.h" -LOG_CHANNEL(cellSysutilAvc2); +logs::channel cellSysutilAvc2("cellSysutilAvc2", logs::level::notice); s32 cellSysutilAvc2GetPlayerInfo() { diff --git a/rpcs3/Emu/Cell/Modules/cellSysutilMisc.cpp b/rpcs3/Emu/Cell/Modules/cellSysutilMisc.cpp index e009f8e0bc..109e7a817a 100644 --- a/rpcs3/Emu/Cell/Modules/cellSysutilMisc.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSysutilMisc.cpp @@ -2,7 +2,7 @@ #include "Emu/System.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellSysutilMisc); +logs::channel cellSysutilMisc("cellSysutilMisc", logs::level::notice); // License areas enum diff --git a/rpcs3/Emu/Cell/Modules/cellUsbd.cpp b/rpcs3/Emu/Cell/Modules/cellUsbd.cpp index 607277c74e..d998d9387c 100644 --- a/rpcs3/Emu/Cell/Modules/cellUsbd.cpp +++ b/rpcs3/Emu/Cell/Modules/cellUsbd.cpp @@ -3,7 +3,7 @@ #include "Emu/Cell/PPUModule.h" #include "cellUsbd.h" -LOG_CHANNEL(cellUsbd); +logs::channel cellUsbd("cellUsbd", logs::level::notice); s32 cellUsbdInit() { diff --git a/rpcs3/Emu/Cell/Modules/cellUsbpspcm.cpp b/rpcs3/Emu/Cell/Modules/cellUsbpspcm.cpp index ccd4cae8bb..88267a3468 100644 --- a/rpcs3/Emu/Cell/Modules/cellUsbpspcm.cpp +++ b/rpcs3/Emu/Cell/Modules/cellUsbpspcm.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellUsbPspcm); +logs::channel cellUsbPspcm("cellUsbPspcm", logs::level::notice); // Return Codes enum diff --git a/rpcs3/Emu/Cell/Modules/cellUserInfo.cpp b/rpcs3/Emu/Cell/Modules/cellUserInfo.cpp index 790d6b9eab..9c6e3f0d85 100644 --- a/rpcs3/Emu/Cell/Modules/cellUserInfo.cpp +++ b/rpcs3/Emu/Cell/Modules/cellUserInfo.cpp @@ -6,7 +6,7 @@ #include "Utilities/StrUtil.h" -LOG_CHANNEL(cellUserInfo); +logs::channel cellUserInfo("cellUserInfo", logs::level::notice); s32 cellUserInfoGetStat(u32 id, vm::ptr stat) { diff --git a/rpcs3/Emu/Cell/Modules/cellVdec.cpp b/rpcs3/Emu/Cell/Modules/cellVdec.cpp index 2192d6f4c9..47bc12d9ca 100644 --- a/rpcs3/Emu/Cell/Modules/cellVdec.cpp +++ b/rpcs3/Emu/Cell/Modules/cellVdec.cpp @@ -16,7 +16,9 @@ extern "C" #include "cellPamf.h" #include "cellVdec.h" -LOG_CHANNEL(cellVdec); +#include + +logs::channel cellVdec("cellVdec", logs::level::notice); vm::gvar _cell_vdec_prx_ver; // ??? @@ -541,7 +543,7 @@ void vdecOpen(u32 vdec_id) // TODO: call from the constructor vdec.vdecCb->cpu_init(); vdec.vdecCb->state -= cpu_state::stop; - vdec.vdecCb->lock_notify(); + (*vdec.vdecCb)->lock_notify(); } s32 cellVdecQueryAttr(vm::cptr type, vm::ptr attr) @@ -594,7 +596,7 @@ s32 cellVdecClose(u32 handle) { CHECK_EMU_STATUS; - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + std::this_thread::sleep_for(1ms); // hack } idm::remove(vdec->vdecCb->id); @@ -676,7 +678,7 @@ s32 cellVdecGetPicture(u32 handle, vm::cptr format, vm::ptrframes.try_pop(vf)) { - //std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + //std::this_thread::sleep_for(1ms); // hack return CELL_VDEC_ERROR_EMPTY; } @@ -800,13 +802,13 @@ s32 cellVdecGetPicItem(u32 handle, vm::pptr picItem) VdecFrame vf; if (!vdec->frames.try_peek(vf)) { - //std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + //std::this_thread::sleep_for(1ms); // hack return CELL_VDEC_ERROR_EMPTY; } AVFrame& frame = *vf.data; - const vm::ptr info{ vdec->memAddr + vdec->memBias, vm::addr }; + const vm::ptr info = vm::cast(vdec->memAddr + vdec->memBias); vdec->memBias += 512; if (vdec->memBias + 512 > vdec->memSize) @@ -834,7 +836,7 @@ s32 cellVdecGetPicItem(u32 handle, vm::pptr picItem) if (vdec->type == CELL_VDEC_CODEC_TYPE_AVC) { - const vm::ptr avc{ info.addr() + SIZE_32(CellVdecPicItem), vm::addr }; + const vm::ptr avc = vm::cast(info.addr() + SIZE_32(CellVdecPicItem)); avc->horizontalSize = frame.width; avc->verticalSize = frame.height; diff --git a/rpcs3/Emu/Cell/Modules/cellVideoExport.cpp b/rpcs3/Emu/Cell/Modules/cellVideoExport.cpp index 266d8abc45..90034a357f 100644 --- a/rpcs3/Emu/Cell/Modules/cellVideoExport.cpp +++ b/rpcs3/Emu/Cell/Modules/cellVideoExport.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellVideoExport); +logs::channel cellVideoExport("cellVideoExport", logs::level::notice); s32 cellVideoExportProgress() { diff --git a/rpcs3/Emu/Cell/Modules/cellVideoOut.cpp b/rpcs3/Emu/Cell/Modules/cellVideoOut.cpp index a3a2ba826c..27aa431d0b 100644 --- a/rpcs3/Emu/Cell/Modules/cellVideoOut.cpp +++ b/rpcs3/Emu/Cell/Modules/cellVideoOut.cpp @@ -1,10 +1,11 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Emu/System.h" #include "Emu/Cell/PPUModule.h" #include "cellVideoOut.h" -extern _log::channel cellSysutil; +extern logs::channel cellSysutil; cfg::map_entry g_cfg_video_out_resolution(cfg::root.video, "Resolution", "1280x720", { diff --git a/rpcs3/Emu/Cell/Modules/cellVideoUpload.cpp b/rpcs3/Emu/Cell/Modules/cellVideoUpload.cpp index f41f52a573..5ab0c7ba5c 100644 --- a/rpcs3/Emu/Cell/Modules/cellVideoUpload.cpp +++ b/rpcs3/Emu/Cell/Modules/cellVideoUpload.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellVideoUpload); +logs::channel cellVideoUpload("cellVideoUpload", logs::level::notice); s32 cellVideoUploadInitialize() { diff --git a/rpcs3/Emu/Cell/Modules/cellVoice.cpp b/rpcs3/Emu/Cell/Modules/cellVoice.cpp index 83c227faa9..b9ae6d2331 100644 --- a/rpcs3/Emu/Cell/Modules/cellVoice.cpp +++ b/rpcs3/Emu/Cell/Modules/cellVoice.cpp @@ -2,7 +2,7 @@ #include "Emu/System.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellVoice); +logs::channel cellVoice("cellVoice", logs::level::notice); // Error Codes enum diff --git a/rpcs3/Emu/Cell/Modules/cellVpost.cpp b/rpcs3/Emu/Cell/Modules/cellVpost.cpp index d42d4febbc..a8bdcbef42 100644 --- a/rpcs3/Emu/Cell/Modules/cellVpost.cpp +++ b/rpcs3/Emu/Cell/Modules/cellVpost.cpp @@ -10,7 +10,7 @@ extern "C" #include "cellVpost.h" -LOG_CHANNEL(cellVpost); +logs::channel cellVpost("cellVpost", logs::level::notice); s32 cellVpostQueryAttr(vm::cptr cfgParam, vm::ptr attr) { diff --git a/rpcs3/Emu/Cell/Modules/cellWebBrowser.cpp b/rpcs3/Emu/Cell/Modules/cellWebBrowser.cpp index 4f0877a095..999056a52d 100644 --- a/rpcs3/Emu/Cell/Modules/cellWebBrowser.cpp +++ b/rpcs3/Emu/Cell/Modules/cellWebBrowser.cpp @@ -3,7 +3,7 @@ #include "cellWebBrowser.h" -extern _log::channel cellSysutil; +extern logs::channel cellSysutil; s32 cellWebBrowserActivate() { diff --git a/rpcs3/Emu/Cell/Modules/libmixer.cpp b/rpcs3/Emu/Cell/Modules/libmixer.cpp index 2813a039bb..932d20e67e 100644 --- a/rpcs3/Emu/Cell/Modules/libmixer.cpp +++ b/rpcs3/Emu/Cell/Modules/libmixer.cpp @@ -5,9 +5,11 @@ #include "cellAudio.h" #include "libmixer.h" -#include -LOG_CHANNEL(libmixer); +#include +#include + +logs::channel libmixer("libmixer", logs::level::notice); // TODO: use fxm SurMixerConfig g_surmx; @@ -332,7 +334,7 @@ s32 cellSurMixerCreate(vm::cptr config) if (g_surmx.mixcount > (port.tag + 0)) // adding positive value (1-15): preemptive buffer filling (hack) { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + std::this_thread::sleep_for(1ms); // hack continue; } @@ -448,7 +450,7 @@ s32 cellSurMixerCreate(vm::cptr config) ppu->cpu_init(); ppu->state -= cpu_state::stop; - ppu->lock_notify(); + (*ppu)->lock_notify(); return CELL_OK; } diff --git a/rpcs3/Emu/Cell/Modules/libsnd3.cpp b/rpcs3/Emu/Cell/Modules/libsnd3.cpp index 861039754d..f76ffdc839 100644 --- a/rpcs3/Emu/Cell/Modules/libsnd3.cpp +++ b/rpcs3/Emu/Cell/Modules/libsnd3.cpp @@ -3,7 +3,7 @@ #include "libsnd3.h" -LOG_CHANNEL(libsnd3); +logs::channel libsnd3("libsnd3", logs::level::notice); s32 cellSnd3Init(u32 maxVoice, u32 samples, vm::ptr queue) { diff --git a/rpcs3/Emu/Cell/Modules/libsynth2.cpp b/rpcs3/Emu/Cell/Modules/libsynth2.cpp index 532932a2d7..98d123487e 100644 --- a/rpcs3/Emu/Cell/Modules/libsynth2.cpp +++ b/rpcs3/Emu/Cell/Modules/libsynth2.cpp @@ -3,7 +3,7 @@ #include "libsynth2.h" -LOG_CHANNEL(libsynth2); +logs::channel libsynth2("libsynth2", logs::level::notice); s32 cellSoundSynth2Config(s16 param, s32 value) { diff --git a/rpcs3/Emu/Cell/Modules/sceNp.cpp b/rpcs3/Emu/Cell/Modules/sceNp.cpp index 80c682eeed..a1cd7c7ede 100644 --- a/rpcs3/Emu/Cell/Modules/sceNp.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNp.cpp @@ -6,7 +6,7 @@ #include "Crypto/unedat.h" #include "sceNp.h" -LOG_CHANNEL(sceNp); +logs::channel sceNp("sceNp", logs::level::notice); s32 sceNpInit(u32 poolsize, vm::ptr poolptr) { diff --git a/rpcs3/Emu/Cell/Modules/sceNp2.cpp b/rpcs3/Emu/Cell/Modules/sceNp2.cpp index c424aaf877..653c4a5295 100644 --- a/rpcs3/Emu/Cell/Modules/sceNp2.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNp2.cpp @@ -4,7 +4,7 @@ #include "sceNp.h" #include "sceNp2.h" -LOG_CHANNEL(sceNp2); +logs::channel sceNp2("sceNp2", logs::level::notice); s32 sceNp2Init(u32 poolsize, vm::ptr poolptr) { diff --git a/rpcs3/Emu/Cell/Modules/sceNpClans.cpp b/rpcs3/Emu/Cell/Modules/sceNpClans.cpp index e3d7daca27..eb3e3bed8a 100644 --- a/rpcs3/Emu/Cell/Modules/sceNpClans.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNpClans.cpp @@ -5,7 +5,7 @@ #include "sceNp.h" #include "sceNpClans.h" -LOG_CHANNEL(sceNpClans); +logs::channel sceNpClans("sceNpClans", logs::level::notice); s32 sceNpClansInit(vm::ptr commId, vm::ptr passphrase, vm::ptr pool, vm::ptr poolSize, u32 flags) { diff --git a/rpcs3/Emu/Cell/Modules/sceNpCommerce2.cpp b/rpcs3/Emu/Cell/Modules/sceNpCommerce2.cpp index ba8f47ce7e..5b9b9e50d0 100644 --- a/rpcs3/Emu/Cell/Modules/sceNpCommerce2.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNpCommerce2.cpp @@ -3,7 +3,7 @@ #include "sceNpCommerce2.h" -LOG_CHANNEL(sceNpCommerce2); +logs::channel sceNpCommerce2("sceNpCommerce2", logs::level::notice); s32 sceNpCommerce2ExecuteStoreBrowse() { diff --git a/rpcs3/Emu/Cell/Modules/sceNpSns.cpp b/rpcs3/Emu/Cell/Modules/sceNpSns.cpp index 15dc2c7153..552b69807a 100644 --- a/rpcs3/Emu/Cell/Modules/sceNpSns.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNpSns.cpp @@ -3,7 +3,7 @@ #include "sceNpSns.h" -LOG_CHANNEL(sceNpSns); +logs::channel sceNpSns("sceNpSns", logs::level::notice); s32 sceNpSnsFbInit(vm::ptr params) { diff --git a/rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp b/rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp index f81d2b535d..1f011f2b2b 100644 --- a/rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp @@ -12,7 +12,7 @@ #include "Utilities/StrUtil.h" -LOG_CHANNEL(sceNpTrophy); +logs::channel sceNpTrophy("sceNpTrophy", logs::level::notice); struct trophy_context_t { @@ -269,7 +269,7 @@ s32 sceNpTrophyGetGameInfo(u32 context, u32 handle, vm::ptrtrp_name + "/TROPCONF.SFM"); // TODO: rXmlDocument can open only real file - ASSERT(!fs::get_virtual_device(path)); + VERIFY(!fs::get_virtual_device(path)); rXmlDocument doc; doc.Load(path); @@ -399,7 +399,7 @@ s32 sceNpTrophyGetTrophyInfo(u32 context, u32 handle, s32 trophyId, vm::ptrtrp_name + "/TROPCONF.SFM"); // TODO: rXmlDocument can open only real file - ASSERT(!fs::get_virtual_device(path)); + VERIFY(!fs::get_virtual_device(path)); rXmlDocument doc; doc.Load(path); diff --git a/rpcs3/Emu/Cell/Modules/sceNpTus.cpp b/rpcs3/Emu/Cell/Modules/sceNpTus.cpp index 1ee55bf9f6..932f667f51 100644 --- a/rpcs3/Emu/Cell/Modules/sceNpTus.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNpTus.cpp @@ -4,7 +4,7 @@ #include "sceNp.h" #include "sceNpTus.h" -LOG_CHANNEL(sceNpTus); +logs::channel sceNpTus("sceNpTus", logs::level::notice); s32 sceNpTusInit() { diff --git a/rpcs3/Emu/Cell/Modules/sceNpUtil.cpp b/rpcs3/Emu/Cell/Modules/sceNpUtil.cpp index 0dc924f80a..0d99b7e843 100644 --- a/rpcs3/Emu/Cell/Modules/sceNpUtil.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNpUtil.cpp @@ -4,7 +4,7 @@ #include "sceNp.h" #include "sceNpUtil.h" -LOG_CHANNEL(sceNpUtil); +logs::channel sceNpUtil("sceNpUtil", logs::level::notice); s32 sceNpUtilBandwidthTestInitStart(u32 prio, size_t stack) { diff --git a/rpcs3/Emu/Cell/Modules/sysPrxForUser.cpp b/rpcs3/Emu/Cell/Modules/sysPrxForUser.cpp index b531810687..d82f10ac30 100644 --- a/rpcs3/Emu/Cell/Modules/sysPrxForUser.cpp +++ b/rpcs3/Emu/Cell/Modules/sysPrxForUser.cpp @@ -6,7 +6,7 @@ #include "Emu/Cell/lv2/sys_process.h" #include "sysPrxForUser.h" -LOG_CHANNEL(sysPrxForUser); +logs::channel sysPrxForUser("sysPrxForUser", logs::level::notice); extern u64 get_system_time(); diff --git a/rpcs3/Emu/Cell/Modules/sys_game.cpp b/rpcs3/Emu/Cell/Modules/sys_game.cpp index 1c2d47b368..974ad7d3ee 100644 --- a/rpcs3/Emu/Cell/Modules/sys_game.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_game.cpp @@ -4,7 +4,7 @@ #include "sysPrxForUser.h" -extern _log::channel sysPrxForUser; +extern logs::channel sysPrxForUser; void sys_game_process_exitspawn(vm::cptr path, u32 argv_addr, u32 envp_addr, u32 data_addr, u32 data_size, u32 prio, u64 flags) { diff --git a/rpcs3/Emu/Cell/Modules/sys_heap.cpp b/rpcs3/Emu/Cell/Modules/sys_heap.cpp index 13b344fd2f..7d711f0f22 100644 --- a/rpcs3/Emu/Cell/Modules/sys_heap.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_heap.cpp @@ -5,7 +5,7 @@ #include "sysPrxForUser.h" -extern _log::channel sysPrxForUser; +extern logs::channel sysPrxForUser; struct HeapInfo { diff --git a/rpcs3/Emu/Cell/Modules/sys_io.cpp b/rpcs3/Emu/Cell/Modules/sys_io.cpp index 11d2202e5d..7a5dad63b0 100644 --- a/rpcs3/Emu/Cell/Modules/sys_io.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_io.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(sys_io); +logs::channel sys_io("sys_io", logs::level::notice); extern void cellPad_init(); extern void cellKb_init(); diff --git a/rpcs3/Emu/Cell/Modules/sys_libc.cpp b/rpcs3/Emu/Cell/Modules/sys_libc.cpp index 74fabd32b0..38195675d8 100644 --- a/rpcs3/Emu/Cell/Modules/sys_libc.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_libc.cpp @@ -3,7 +3,7 @@ #include "Emu/Cell/PPUModule.h" #include "Emu/Cell/PPUOpcodes.h" -LOG_CHANNEL(sys_libc); +logs::channel sys_libc("sys_libc", logs::level::notice); namespace sys_libc_func { diff --git a/rpcs3/Emu/Cell/Modules/sys_libc_.cpp b/rpcs3/Emu/Cell/Modules/sys_libc_.cpp index 15be5a9f46..97b1045823 100644 --- a/rpcs3/Emu/Cell/Modules/sys_libc_.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_libc_.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -extern _log::channel sysPrxForUser; +extern logs::channel sysPrxForUser; extern fs::file g_tty; diff --git a/rpcs3/Emu/Cell/Modules/sys_lv2dbg.cpp b/rpcs3/Emu/Cell/Modules/sys_lv2dbg.cpp index 791e29ceed..eaa1c38f26 100644 --- a/rpcs3/Emu/Cell/Modules/sys_lv2dbg.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_lv2dbg.cpp @@ -5,7 +5,7 @@ #include "sys_lv2dbg.h" -LOG_CHANNEL(sys_lv2dbg); +logs::channel sys_lv2dbg("sys_lv2dbg", logs::level::notice); s32 sys_dbg_read_ppu_thread_context(u64 id, vm::ptr ppu_context) { diff --git a/rpcs3/Emu/Cell/Modules/sys_lwcond_.cpp b/rpcs3/Emu/Cell/Modules/sys_lwcond_.cpp index 7b4b019a8d..4d3e0e5518 100644 --- a/rpcs3/Emu/Cell/Modules/sys_lwcond_.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_lwcond_.cpp @@ -7,7 +7,7 @@ #include "Emu/Cell/lv2/sys_lwcond.h" #include "sysPrxForUser.h" -extern _log::channel sysPrxForUser; +extern logs::channel sysPrxForUser; s32 sys_lwcond_create(vm::ptr lwcond, vm::ptr lwmutex, vm::ptr attr) { diff --git a/rpcs3/Emu/Cell/Modules/sys_lwmutex_.cpp b/rpcs3/Emu/Cell/Modules/sys_lwmutex_.cpp index 7cbaab6dba..7050e97aa5 100644 --- a/rpcs3/Emu/Cell/Modules/sys_lwmutex_.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_lwmutex_.cpp @@ -7,7 +7,7 @@ #include "Emu/Cell/lv2/sys_lwmutex.h" #include "sysPrxForUser.h" -extern _log::channel sysPrxForUser; +extern logs::channel sysPrxForUser; s32 sys_lwmutex_create(vm::ptr lwmutex, vm::ptr attr) { diff --git a/rpcs3/Emu/Cell/Modules/sys_mempool.cpp b/rpcs3/Emu/Cell/Modules/sys_mempool.cpp index 99763b4b1f..b4f748485b 100644 --- a/rpcs3/Emu/Cell/Modules/sys_mempool.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_mempool.cpp @@ -5,7 +5,7 @@ #include "sysPrxForUser.h" -extern _log::channel sysPrxForUser; +extern logs::channel sysPrxForUser; using sys_mempool_t = u32; diff --git a/rpcs3/Emu/Cell/Modules/sys_mmapper_.cpp b/rpcs3/Emu/Cell/Modules/sys_mmapper_.cpp index 37830aea71..e07618022e 100644 --- a/rpcs3/Emu/Cell/Modules/sys_mmapper_.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_mmapper_.cpp @@ -5,7 +5,7 @@ #include "Emu/Cell/lv2/sys_mmapper.h" #include "sysPrxForUser.h" -extern _log::channel sysPrxForUser; +extern logs::channel sysPrxForUser; void sysPrxForUser_sys_mmapper_init() { diff --git a/rpcs3/Emu/Cell/Modules/sys_net.cpp b/rpcs3/Emu/Cell/Modules/sys_net.cpp index abe038f6c4..126dfd515c 100644 --- a/rpcs3/Emu/Cell/Modules/sys_net.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_net.cpp @@ -14,7 +14,7 @@ #include #endif -LOG_CHANNEL(libnet); +logs::channel libnet("libnet", logs::level::notice); // We map host sockets to sequential IDs to return as FDs because syscalls using // socketselect(), etc. expect socket FDs to be under 1024. @@ -127,7 +127,7 @@ namespace sys_net { g_tls_net_data.set(vm::alloc(sizeof(decltype(g_tls_net_data)::type), vm::main)); - thread_ctrl::at_exit([addr = g_tls_net_data.addr()] + thread_ctrl::atexit([addr = g_tls_net_data.addr()] { vm::dealloc_verbose_nothrow(addr, vm::main); }); diff --git a/rpcs3/Emu/Cell/Modules/sys_ppu_thread_.cpp b/rpcs3/Emu/Cell/Modules/sys_ppu_thread_.cpp index f339fa8407..b37289ec3f 100644 --- a/rpcs3/Emu/Cell/Modules/sys_ppu_thread_.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_ppu_thread_.cpp @@ -5,7 +5,7 @@ #include "Emu/Cell/lv2/sys_ppu_thread.h" #include "sysPrxForUser.h" -extern _log::channel sysPrxForUser; +extern logs::channel sysPrxForUser; extern u32 ppu_alloc_tls(); extern void ppu_free_tls(u32 addr); diff --git a/rpcs3/Emu/Cell/Modules/sys_prx_.cpp b/rpcs3/Emu/Cell/Modules/sys_prx_.cpp index 1b2fac8523..70ba08027c 100644 --- a/rpcs3/Emu/Cell/Modules/sys_prx_.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_prx_.cpp @@ -5,7 +5,7 @@ #include "Emu/Cell/lv2/sys_prx.h" #include "sysPrxForUser.h" -extern _log::channel sysPrxForUser; +extern logs::channel sysPrxForUser; s64 sys_prx_exitspawn_with_level() { diff --git a/rpcs3/Emu/Cell/Modules/sys_spinlock.cpp b/rpcs3/Emu/Cell/Modules/sys_spinlock.cpp index 9ec0c65ff8..47a5986fe1 100644 --- a/rpcs3/Emu/Cell/Modules/sys_spinlock.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_spinlock.cpp @@ -6,7 +6,7 @@ #include "Emu/Memory/wait_engine.h" -extern _log::channel sysPrxForUser; +extern logs::channel sysPrxForUser; void sys_spinlock_initialize(vm::ptr> lock) { diff --git a/rpcs3/Emu/Cell/Modules/sys_spu_.cpp b/rpcs3/Emu/Cell/Modules/sys_spu_.cpp index 3d2c0e6863..111ce221de 100644 --- a/rpcs3/Emu/Cell/Modules/sys_spu_.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_spu_.cpp @@ -7,7 +7,7 @@ #include "Crypto/unself.h" #include "sysPrxForUser.h" -extern _log::channel sysPrxForUser; +extern logs::channel sysPrxForUser; extern u64 get_system_time(); @@ -59,7 +59,7 @@ s32 sys_spu_image_close(vm::ptr img) return CELL_EINVAL; } - ASSERT(vm::dealloc(img->segs.addr(), vm::main)); // Current rough implementation + VERIFY(vm::dealloc(img->segs.addr(), vm::main)); // Current rough implementation return CELL_OK; } diff --git a/rpcs3/Emu/Cell/PPUCallback.cpp b/rpcs3/Emu/Cell/PPUCallback.cpp index f1652f4d66..3f29de1945 100644 --- a/rpcs3/Emu/Cell/PPUCallback.cpp +++ b/rpcs3/Emu/Cell/PPUCallback.cpp @@ -6,6 +6,8 @@ #include "PPUThread.h" #include "PPUCallback.h" +#include + void CallbackManager::Register(check_cb_t func) { std::lock_guard lock(m_mutex); @@ -24,9 +26,11 @@ void CallbackManager::Async(async_cb_t func) m_async_cb.emplace(std::move(func)); - m_cb_thread->notify(); + (*m_cb_thread)->notify(); } +extern std::condition_variable& get_current_thread_cv(); + CallbackManager::check_cb_t CallbackManager::Check() { std::lock_guard lock(m_mutex); diff --git a/rpcs3/Emu/Cell/PPUCallback.h b/rpcs3/Emu/Cell/PPUCallback.h index 66b3ce2449..42fe061830 100644 --- a/rpcs3/Emu/Cell/PPUCallback.h +++ b/rpcs3/Emu/Cell/PPUCallback.h @@ -193,6 +193,7 @@ template inline RT cb_call(PPUThread& CPU, u32 pc, u } #include +#include class CallbackManager { diff --git a/rpcs3/Emu/Cell/PPUDisAsm.cpp b/rpcs3/Emu/Cell/PPUDisAsm.cpp index 31a1cfa48d..2d2f93e8d9 100644 --- a/rpcs3/Emu/Cell/PPUDisAsm.cpp +++ b/rpcs3/Emu/Cell/PPUDisAsm.cpp @@ -10,16 +10,6 @@ u32 PPUDisAsm::disasm(u32 pc) return 4; } -void PPUDisAsm::TDI(ppu_opcode_t op) -{ - DisAsm_INT1_R1_IMM("tdi", op.bo, op.ra, op.simm16); -} - -void PPUDisAsm::TWI(ppu_opcode_t op) -{ - DisAsm_INT1_R1_IMM("twi", op.bo, op.ra, op.simm16); -} - void PPUDisAsm::MFVSCR(ppu_opcode_t op) { DisAsm_V1("mfvscr", op.vd); @@ -740,6 +730,16 @@ void PPUDisAsm::VXOR(ppu_opcode_t op) DisAsm_V3("vxor", op.vd, op.va, op.vb); } +void PPUDisAsm::TDI(ppu_opcode_t op) +{ + DisAsm_INT1_R1_IMM("tdi", op.bo, op.ra, op.simm16); +} + +void PPUDisAsm::TWI(ppu_opcode_t op) +{ + DisAsm_INT1_R1_IMM("twi", op.bo, op.ra, op.simm16); +} + void PPUDisAsm::MULLI(ppu_opcode_t op) { DisAsm_R2_IMM("mulli", op.rd, op.ra, op.simm16); @@ -1949,6 +1949,16 @@ void PPUDisAsm::LWA(ppu_opcode_t op) DisAsm_R2_IMM("lwa", op.rd, op.ra, op.ds * 4); } +void PPUDisAsm::STD(ppu_opcode_t op) +{ + DisAsm_R2_IMM("std", op.rs, op.ra, op.ds * 4); +} + +void PPUDisAsm::STDU(ppu_opcode_t op) +{ + DisAsm_R2_IMM("stdu", op.rs, op.ra, op.ds * 4); +} + void PPUDisAsm::FDIVS(ppu_opcode_t op) { DisAsm_F3_RC("fdivs", op.frd, op.fra, op.frb, op.rc); @@ -1999,16 +2009,6 @@ void PPUDisAsm::FNMADDS(ppu_opcode_t op) DisAsm_F4_RC("fnmadds", op.frd, op.fra, op.frc, op.frb, op.rc); } -void PPUDisAsm::STD(ppu_opcode_t op) -{ - DisAsm_R2_IMM("std", op.rs, op.ra, op.ds * 4); -} - -void PPUDisAsm::STDU(ppu_opcode_t op) -{ - DisAsm_R2_IMM("stdu", op.rs, op.ra, op.ds * 4); -} - void PPUDisAsm::MTFSB1(ppu_opcode_t op) { Write(fmt::format("mtfsb1%s %d", op.rc ? "." : "", op.crbd)); diff --git a/rpcs3/Emu/Cell/PPUDisAsm.h b/rpcs3/Emu/Cell/PPUDisAsm.h index 7138bfe519..37d969a728 100644 --- a/rpcs3/Emu/Cell/PPUDisAsm.h +++ b/rpcs3/Emu/Cell/PPUDisAsm.h @@ -243,8 +243,6 @@ private: public: u32 disasm(u32 pc) override; - void TDI(ppu_opcode_t op); - void TWI(ppu_opcode_t op); void MFVSCR(ppu_opcode_t op); void MTVSCR(ppu_opcode_t op); void VADDCUW(ppu_opcode_t op); @@ -389,6 +387,8 @@ public: void VUPKLSB(ppu_opcode_t op); void VUPKLSH(ppu_opcode_t op); void VXOR(ppu_opcode_t op); + void TDI(ppu_opcode_t op); + void TWI(ppu_opcode_t op); void MULLI(ppu_opcode_t op); void SUBFIC(ppu_opcode_t op); void CMPLI(ppu_opcode_t op); @@ -582,6 +582,8 @@ public: void LD(ppu_opcode_t op); void LDU(ppu_opcode_t op); void LWA(ppu_opcode_t op); + void STD(ppu_opcode_t op); + void STDU(ppu_opcode_t op); void FDIVS(ppu_opcode_t op); void FSUBS(ppu_opcode_t op); void FADDS(ppu_opcode_t op); @@ -592,8 +594,6 @@ public: void FMSUBS(ppu_opcode_t op); void FNMSUBS(ppu_opcode_t op); void FNMADDS(ppu_opcode_t op); - void STD(ppu_opcode_t op); - void STDU(ppu_opcode_t op); void MTFSB1(ppu_opcode_t op); void MCRFS(ppu_opcode_t op); void MTFSB0(ppu_opcode_t op); diff --git a/rpcs3/Emu/Cell/PPUInterpreter.cpp b/rpcs3/Emu/Cell/PPUInterpreter.cpp index 5601971adf..c15b27762d 100644 --- a/rpcs3/Emu/Cell/PPUInterpreter.cpp +++ b/rpcs3/Emu/Cell/PPUInterpreter.cpp @@ -2,6 +2,7 @@ #include "Emu/System.h" #include "PPUThread.h" #include "PPUInterpreter.h" + #include // TODO: fix rol8 and rol16 for __GNUG__ (probably with __asm__) @@ -147,70 +148,44 @@ public: } const g_ppu_scale_table; -void ppu_interpreter::TDI(PPUThread& ppu, ppu_opcode_t op) -{ - const s64 a = ppu.GPR[op.ra], b = op.simm16; - const u64 a_ = a, b_ = b; - - if (((op.bo & 0x10) && a < b) || - ((op.bo & 0x8) && a > b) || - ((op.bo & 0x4) && a == b) || - ((op.bo & 0x2) && a_ < b_) || - ((op.bo & 0x1) && a_ > b_)) - { - throw std::runtime_error("Trap!" HERE); - } -} - -void ppu_interpreter::TWI(PPUThread& ppu, ppu_opcode_t op) -{ - const s32 a = u32(ppu.GPR[op.ra]), b = op.simm16; - const u32 a_ = a, b_ = b; - - if (((op.bo & 0x10) && a < b) || - ((op.bo & 0x8) && a > b) || - ((op.bo & 0x4) && a == b) || - ((op.bo & 0x2) && a_ < b_) || - ((op.bo & 0x1) && a_ > b_)) - { - throw std::runtime_error("Trap!" HERE); - } -} - - -void ppu_interpreter::MFVSCR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MFVSCR(PPUThread& ppu, ppu_opcode_t op) { throw std::runtime_error("MFVSCR" HERE); } -void ppu_interpreter::MTVSCR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MTVSCR(PPUThread& ppu, ppu_opcode_t op) { LOG_WARNING(PPU, "MTVSCR"); + return true; } -void ppu_interpreter::VADDCUW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VADDCUW(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va].vi; const auto b = ppu.VR[op.vb].vi; ppu.VR[op.vd].vi = _mm_srli_epi32(_mm_cmpgt_epi32(_mm_xor_si128(b, _mm_set1_epi32(0x80000000)), _mm_xor_si128(a, _mm_set1_epi32(0x7fffffff))), 31); + return true; } -void ppu_interpreter::VADDFP(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VADDFP(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd] = v128::addfs(ppu.VR[op.va], ppu.VR[op.vb]); + return true; } -void ppu_interpreter::VADDSBS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VADDSBS(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_adds_epi8(ppu.VR[op.va].vi, ppu.VR[op.vb].vi); + return true; } -void ppu_interpreter::VADDSHS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VADDSHS(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_adds_epi16(ppu.VR[op.va].vi, ppu.VR[op.vb].vi); + return true; } -void ppu_interpreter::VADDSWS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VADDSWS(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va]; const auto b = ppu.VR[op.vb]; @@ -219,51 +194,60 @@ void ppu_interpreter::VADDSWS(PPUThread& ppu, ppu_opcode_t op) const auto x = _mm_srai_epi32(m.vi, 31); // saturation mask const auto y = _mm_srai_epi32(_mm_and_si128(s.vi, m.vi), 31); // positive saturation mask ppu.VR[op.vd].vi = _mm_xor_si128(_mm_xor_si128(_mm_srli_epi32(x, 1), y), _mm_or_si128(s.vi, x)); + return true; } -void ppu_interpreter::VADDUBM(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VADDUBM(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd] = v128::add8(ppu.VR[op.va], ppu.VR[op.vb]); + return true; } -void ppu_interpreter::VADDUBS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VADDUBS(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_adds_epu8(ppu.VR[op.va].vi, ppu.VR[op.vb].vi); + return true; } -void ppu_interpreter::VADDUHM(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VADDUHM(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd] = v128::add16(ppu.VR[op.va], ppu.VR[op.vb]); + return true; } -void ppu_interpreter::VADDUHS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VADDUHS(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_adds_epu16(ppu.VR[op.va].vi, ppu.VR[op.vb].vi); + return true; } -void ppu_interpreter::VADDUWM(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VADDUWM(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd] = v128::add32(ppu.VR[op.va], ppu.VR[op.vb]); + return true; } -void ppu_interpreter::VADDUWS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VADDUWS(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va].vi; const auto b = ppu.VR[op.vb].vi; ppu.VR[op.vd].vi = _mm_or_si128(_mm_add_epi32(a, b), _mm_cmpgt_epi32(_mm_xor_si128(b, _mm_set1_epi32(0x80000000)), _mm_xor_si128(a, _mm_set1_epi32(0x7fffffff)))); + return true; } -void ppu_interpreter::VAND(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VAND(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd] = ppu.VR[op.va] & ppu.VR[op.vb]; + return true; } -void ppu_interpreter::VANDC(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VANDC(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd] = v128::andnot(ppu.VR[op.vb], ppu.VR[op.va]); + return true; } -void ppu_interpreter::VAVGSB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VAVGSB(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va]; const auto b = v128::add8(ppu.VR[op.vb], v128::from8p(1)); // add 1 @@ -271,9 +255,10 @@ void ppu_interpreter::VAVGSB(PPUThread& ppu, ppu_opcode_t op) const auto sign = v128::from8p(0x80); const auto overflow = (((a ^ summ) & (b ^ summ)) ^ summ ^ v128::eq8(b, sign)) & sign; // calculate msb ppu.VR[op.vd].vi = _mm_or_si128(overflow.vi, _mm_srli_epi64(summ.vi, 1)); + return true; } -void ppu_interpreter::VAVGSH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VAVGSH(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va]; const auto b = v128::add16(ppu.VR[op.vb], v128::from16p(1)); // add 1 @@ -281,9 +266,10 @@ void ppu_interpreter::VAVGSH(PPUThread& ppu, ppu_opcode_t op) const auto sign = v128::from16p(0x8000); const auto overflow = (((a ^ summ) & (b ^ summ)) ^ summ ^ v128::eq16(b, sign)) & sign; // calculate msb ppu.VR[op.vd].vi = _mm_or_si128(overflow.vi, _mm_srli_epi16(summ.vi, 1)); + return true; } -void ppu_interpreter::VAVGSW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VAVGSW(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va]; const auto b = v128::add32(ppu.VR[op.vb], v128::from32p(1)); // add 1 @@ -291,40 +277,46 @@ void ppu_interpreter::VAVGSW(PPUThread& ppu, ppu_opcode_t op) const auto sign = v128::from32p(0x80000000); const auto overflow = (((a ^ summ) & (b ^ summ)) ^ summ ^ v128::eq32(b, sign)) & sign; // calculate msb ppu.VR[op.vd].vi = _mm_or_si128(overflow.vi, _mm_srli_epi32(summ.vi, 1)); + return true; } -void ppu_interpreter::VAVGUB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VAVGUB(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_avg_epu8(ppu.VR[op.va].vi, ppu.VR[op.vb].vi); + return true; } -void ppu_interpreter::VAVGUH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VAVGUH(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_avg_epu16(ppu.VR[op.va].vi, ppu.VR[op.vb].vi); + return true; } -void ppu_interpreter::VAVGUW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VAVGUW(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va]; const auto b = ppu.VR[op.vb]; const auto summ = v128::add32(v128::add32(a, b), v128::from32p(1)); const auto carry = _mm_xor_si128(_mm_slli_epi32(sse_cmpgt_epu32(summ.vi, a.vi), 31), _mm_set1_epi32(0x80000000)); ppu.VR[op.vd].vi = _mm_or_si128(carry, _mm_srli_epi32(summ.vi, 1)); + return true; } -void ppu_interpreter::VCFSX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VCFSX(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vf = _mm_mul_ps(_mm_cvtepi32_ps(ppu.VR[op.vb].vi), g_ppu_scale_table[0 - op.vuimm]); + return true; } -void ppu_interpreter::VCFUX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VCFUX(PPUThread& ppu, ppu_opcode_t op) { const auto b = ppu.VR[op.vb].vi; const auto fix = _mm_and_ps(_mm_castsi128_ps(_mm_srai_epi32(b, 31)), _mm_set1_ps(0x80000000)); ppu.VR[op.vd].vf = _mm_mul_ps(_mm_add_ps(_mm_cvtepi32_ps(_mm_and_si128(b, _mm_set1_epi32(0x7fffffff))), fix), g_ppu_scale_table[0 - op.vuimm]); + return true; } -void ppu_interpreter::VCMPBFP(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VCMPBFP(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va].vf; const auto b = ppu.VR[op.vb].vf; @@ -333,154 +325,179 @@ void ppu_interpreter::VCMPBFP(PPUThread& ppu, ppu_opcode_t op) const auto cmp2 = _mm_cmpnge_ps(a, _mm_xor_ps(b, sign)); ppu.VR[op.vd].vf = _mm_or_ps(_mm_and_ps(cmp1, sign), _mm_and_ps(cmp2, _mm_castsi128_ps(_mm_set1_epi32(0x40000000)))); if (UNLIKELY(op.oe)) ppu.SetCR(6, false, false, _mm_movemask_ps(_mm_or_ps(cmp1, cmp2)) == 0, false); + return true; } -void ppu_interpreter::VCMPEQFP(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VCMPEQFP(PPUThread& ppu, ppu_opcode_t op) { const auto rmask = _mm_movemask_ps(ppu.VR[op.vd].vf = _mm_cmpeq_ps(ppu.VR[op.va].vf, ppu.VR[op.vb].vf)); if (UNLIKELY(op.oe)) ppu.SetCR(6, rmask == 0xf, false, rmask == 0, false); + return true; } -void ppu_interpreter::VCMPEQUB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VCMPEQUB(PPUThread& ppu, ppu_opcode_t op) { const auto rmask = _mm_movemask_epi8((ppu.VR[op.vd] = v128::eq8(ppu.VR[op.va], ppu.VR[op.vb])).vi); if (UNLIKELY(op.oe)) ppu.SetCR(6, rmask == 0xffff, false, rmask == 0, false); + return true; } -void ppu_interpreter::VCMPEQUH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VCMPEQUH(PPUThread& ppu, ppu_opcode_t op) { const auto rmask = _mm_movemask_epi8((ppu.VR[op.vd] = v128::eq16(ppu.VR[op.va], ppu.VR[op.vb])).vi); if (UNLIKELY(op.oe)) ppu.SetCR(6, rmask == 0xffff, false, rmask == 0, false); + return true; } -void ppu_interpreter::VCMPEQUW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VCMPEQUW(PPUThread& ppu, ppu_opcode_t op) { const auto rmask = _mm_movemask_epi8((ppu.VR[op.vd] = v128::eq32(ppu.VR[op.va], ppu.VR[op.vb])).vi); if (UNLIKELY(op.oe)) ppu.SetCR(6, rmask == 0xffff, false, rmask == 0, false); + return true; } -void ppu_interpreter::VCMPGEFP(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VCMPGEFP(PPUThread& ppu, ppu_opcode_t op) { const auto rmask = _mm_movemask_ps(ppu.VR[op.vd].vf = _mm_cmpge_ps(ppu.VR[op.va].vf, ppu.VR[op.vb].vf)); if (UNLIKELY(op.oe)) ppu.SetCR(6, rmask == 0xf, false, rmask == 0, false); + return true; } -void ppu_interpreter::VCMPGTFP(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VCMPGTFP(PPUThread& ppu, ppu_opcode_t op) { const auto rmask = _mm_movemask_ps(ppu.VR[op.vd].vf = _mm_cmpgt_ps(ppu.VR[op.va].vf, ppu.VR[op.vb].vf)); if (UNLIKELY(op.oe)) ppu.SetCR(6, rmask == 0xf, false, rmask == 0, false); + return true; } -void ppu_interpreter::VCMPGTSB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VCMPGTSB(PPUThread& ppu, ppu_opcode_t op) { const auto rmask = _mm_movemask_epi8(ppu.VR[op.vd].vi = _mm_cmpgt_epi8(ppu.VR[op.va].vi, ppu.VR[op.vb].vi)); if (UNLIKELY(op.oe)) ppu.SetCR(6, rmask == 0xffff, false, rmask == 0, false); + return true; } -void ppu_interpreter::VCMPGTSH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VCMPGTSH(PPUThread& ppu, ppu_opcode_t op) { const auto rmask = _mm_movemask_epi8(ppu.VR[op.vd].vi = _mm_cmpgt_epi16(ppu.VR[op.va].vi, ppu.VR[op.vb].vi)); if (UNLIKELY(op.oe)) ppu.SetCR(6, rmask == 0xffff, false, rmask == 0, false); + return true; } -void ppu_interpreter::VCMPGTSW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VCMPGTSW(PPUThread& ppu, ppu_opcode_t op) { const auto rmask = _mm_movemask_epi8(ppu.VR[op.vd].vi = _mm_cmpgt_epi32(ppu.VR[op.va].vi, ppu.VR[op.vb].vi)); if (UNLIKELY(op.oe)) ppu.SetCR(6, rmask == 0xffff, false, rmask == 0, false); + return true; } -void ppu_interpreter::VCMPGTUB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VCMPGTUB(PPUThread& ppu, ppu_opcode_t op) { const auto rmask = _mm_movemask_epi8(ppu.VR[op.vd].vi = sse_cmpgt_epu8(ppu.VR[op.va].vi, ppu.VR[op.vb].vi)); if (UNLIKELY(op.oe)) ppu.SetCR(6, rmask == 0xffff, false, rmask == 0, false); + return true; } -void ppu_interpreter::VCMPGTUH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VCMPGTUH(PPUThread& ppu, ppu_opcode_t op) { const auto rmask = _mm_movemask_epi8(ppu.VR[op.vd].vi = sse_cmpgt_epu16(ppu.VR[op.va].vi, ppu.VR[op.vb].vi)); if (UNLIKELY(op.oe)) ppu.SetCR(6, rmask == 0xffff, false, rmask == 0, false); + return true; } -void ppu_interpreter::VCMPGTUW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VCMPGTUW(PPUThread& ppu, ppu_opcode_t op) { const auto rmask = _mm_movemask_epi8(ppu.VR[op.vd].vi = sse_cmpgt_epu32(ppu.VR[op.va].vi, ppu.VR[op.vb].vi)); if (UNLIKELY(op.oe)) ppu.SetCR(6, rmask == 0xffff, false, rmask == 0, false); + return true; } -void ppu_interpreter::VCTSXS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VCTSXS(PPUThread& ppu, ppu_opcode_t op) { const auto scaled = _mm_mul_ps(ppu.VR[op.vb].vf, g_ppu_scale_table[op.vuimm]); ppu.VR[op.vd].vi = _mm_xor_si128(_mm_cvttps_epi32(scaled), _mm_castps_si128(_mm_cmpge_ps(scaled, _mm_set1_ps(0x80000000)))); + return true; } -void ppu_interpreter::VCTUXS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VCTUXS(PPUThread& ppu, ppu_opcode_t op) { const auto scaled1 = _mm_max_ps(_mm_mul_ps(ppu.VR[op.vb].vf, g_ppu_scale_table[op.vuimm]), _mm_set1_ps(0.0f)); const auto scaled2 = _mm_and_ps(_mm_sub_ps(scaled1, _mm_set1_ps(0x80000000)), _mm_cmpge_ps(scaled1, _mm_set1_ps(0x80000000))); ppu.VR[op.vd].vi = _mm_or_si128(_mm_or_si128(_mm_cvttps_epi32(scaled1), _mm_cvttps_epi32(scaled2)), _mm_castps_si128(_mm_cmpge_ps(scaled1, _mm_set1_ps(0x100000000)))); + return true; } -void ppu_interpreter::VEXPTEFP(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VEXPTEFP(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vf = sse_exp2_ps(ppu.VR[op.vb].vf); + return true; } -void ppu_interpreter::VLOGEFP(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VLOGEFP(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vf = sse_log2_ps(ppu.VR[op.vb].vf); + return true; } -void ppu_interpreter::VMADDFP(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMADDFP(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vf = _mm_add_ps(_mm_mul_ps(ppu.VR[op.va].vf, ppu.VR[op.vc].vf), ppu.VR[op.vb].vf); + return true; } -void ppu_interpreter::VMAXFP(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMAXFP(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vf = _mm_max_ps(ppu.VR[op.va].vf, ppu.VR[op.vb].vf); + return true; } -void ppu_interpreter::VMAXSB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMAXSB(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va].vi; const auto b = ppu.VR[op.vb].vi; const auto m = _mm_cmpgt_epi8(a, b); ppu.VR[op.vd].vi = _mm_or_si128(_mm_and_si128(m, a), _mm_andnot_si128(m, b)); + return true; } -void ppu_interpreter::VMAXSH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMAXSH(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_max_epi16(ppu.VR[op.va].vi, ppu.VR[op.vb].vi); + return true; } -void ppu_interpreter::VMAXSW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMAXSW(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va].vi; const auto b = ppu.VR[op.vb].vi; const auto m = _mm_cmpgt_epi32(a, b); ppu.VR[op.vd].vi = _mm_or_si128(_mm_and_si128(m, a), _mm_andnot_si128(m, b)); + return true; } -void ppu_interpreter::VMAXUB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMAXUB(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_max_epu8(ppu.VR[op.va].vi, ppu.VR[op.vb].vi); + return true; } -void ppu_interpreter::VMAXUH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMAXUH(PPUThread& ppu, ppu_opcode_t op) { const auto mask = _mm_set1_epi32(0x80008000); ppu.VR[op.vd].vi = _mm_xor_si128(_mm_max_epi16(_mm_xor_si128(ppu.VR[op.va].vi, mask), _mm_xor_si128(ppu.VR[op.vb].vi, mask)), mask); + return true; } -void ppu_interpreter::VMAXUW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMAXUW(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va].vi; const auto b = ppu.VR[op.vb].vi; const auto m = sse_cmpgt_epu32(a, b); ppu.VR[op.vd].vi = _mm_or_si128(_mm_and_si128(m, a), _mm_andnot_si128(m, b)); + return true; } -void ppu_interpreter::VMHADDSHS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMHADDSHS(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va].vi; const auto b = ppu.VR[op.vb].vi; @@ -488,9 +505,10 @@ void ppu_interpreter::VMHADDSHS(PPUThread& ppu, ppu_opcode_t op) const auto m = _mm_or_si128(_mm_srli_epi16(_mm_mullo_epi16(a, b), 15), _mm_slli_epi16(_mm_mulhi_epi16(a, b), 1)); const auto s = _mm_cmpeq_epi16(m, _mm_set1_epi16(-0x8000)); // detect special case (positive 0x8000) ppu.VR[op.vd].vi = _mm_adds_epi16(_mm_adds_epi16(_mm_xor_si128(m, s), c), _mm_srli_epi16(s, 15)); + return true; } -void ppu_interpreter::VMHRADDSHS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMHRADDSHS(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va].vi; const auto b = ppu.VR[op.vb].vi; @@ -498,89 +516,104 @@ void ppu_interpreter::VMHRADDSHS(PPUThread& ppu, ppu_opcode_t op) const auto m = _mm_mulhrs_epi16(a, b); const auto s = _mm_cmpeq_epi16(m, _mm_set1_epi16(-0x8000)); // detect special case (positive 0x8000) ppu.VR[op.vd].vi = _mm_adds_epi16(_mm_adds_epi16(_mm_xor_si128(m, s), c), _mm_srli_epi16(s, 15)); + return true; } -void ppu_interpreter::VMINFP(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMINFP(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vf = _mm_min_ps(ppu.VR[op.va].vf, ppu.VR[op.vb].vf); + return true; } -void ppu_interpreter::VMINSB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMINSB(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va].vi; const auto b = ppu.VR[op.vb].vi; const auto m = _mm_cmpgt_epi8(a, b); ppu.VR[op.vd].vi = _mm_or_si128(_mm_andnot_si128(m, a), _mm_and_si128(m, b)); + return true; } -void ppu_interpreter::VMINSH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMINSH(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_min_epi16(ppu.VR[op.va].vi, ppu.VR[op.vb].vi); + return true; } -void ppu_interpreter::VMINSW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMINSW(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va].vi; const auto b = ppu.VR[op.vb].vi; const auto m = _mm_cmpgt_epi32(a, b); ppu.VR[op.vd].vi = _mm_or_si128(_mm_andnot_si128(m, a), _mm_and_si128(m, b)); + return true; } -void ppu_interpreter::VMINUB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMINUB(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_min_epu8(ppu.VR[op.va].vi, ppu.VR[op.vb].vi); + return true; } -void ppu_interpreter::VMINUH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMINUH(PPUThread& ppu, ppu_opcode_t op) { const auto mask = _mm_set1_epi32(0x80008000); ppu.VR[op.vd].vi = _mm_xor_si128(_mm_min_epi16(_mm_xor_si128(ppu.VR[op.va].vi, mask), _mm_xor_si128(ppu.VR[op.vb].vi, mask)), mask); + return true; } -void ppu_interpreter::VMINUW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMINUW(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va].vi; const auto b = ppu.VR[op.vb].vi; const auto m = sse_cmpgt_epu32(a, b); ppu.VR[op.vd].vi = _mm_or_si128(_mm_andnot_si128(m, a), _mm_and_si128(m, b)); + return true; } -void ppu_interpreter::VMLADDUHM(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMLADDUHM(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_add_epi16(_mm_mullo_epi16(ppu.VR[op.va].vi, ppu.VR[op.vb].vi), ppu.VR[op.vc].vi); + return true; } -void ppu_interpreter::VMRGHB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMRGHB(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_unpackhi_epi8(ppu.VR[op.vb].vi, ppu.VR[op.va].vi); + return true; } -void ppu_interpreter::VMRGHH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMRGHH(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_unpackhi_epi16(ppu.VR[op.vb].vi, ppu.VR[op.va].vi); + return true; } -void ppu_interpreter::VMRGHW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMRGHW(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_unpackhi_epi32(ppu.VR[op.vb].vi, ppu.VR[op.va].vi); + return true; } -void ppu_interpreter::VMRGLB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMRGLB(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_unpacklo_epi8(ppu.VR[op.vb].vi, ppu.VR[op.va].vi); + return true; } -void ppu_interpreter::VMRGLH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMRGLH(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_unpacklo_epi16(ppu.VR[op.vb].vi, ppu.VR[op.va].vi); + return true; } -void ppu_interpreter::VMRGLW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMRGLW(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_unpacklo_epi32(ppu.VR[op.vb].vi, ppu.VR[op.va].vi); + return true; } -void ppu_interpreter::VMSUMMBM(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMSUMMBM(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va].vi; // signed bytes const auto b = ppu.VR[op.vb].vi; // unsigned bytes @@ -592,14 +625,16 @@ void ppu_interpreter::VMSUMMBM(PPUThread& ppu, ppu_opcode_t op) const auto sh = _mm_madd_epi16(ah, bh); const auto sl = _mm_madd_epi16(al, bl); ppu.VR[op.vd].vi = _mm_add_epi32(_mm_add_epi32(c, sh), sl); + return true; } -void ppu_interpreter::VMSUMSHM(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMSUMSHM(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_add_epi32(_mm_madd_epi16(ppu.VR[op.va].vi, ppu.VR[op.vb].vi), ppu.VR[op.vc].vi); + return true; } -void ppu_interpreter::VMSUMSHS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMSUMSHS(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -631,9 +666,10 @@ void ppu_interpreter::VMSUMSHS(PPUThread& ppu, ppu_opcode_t op) d._s32[w] = saturated; } + return true; } -void ppu_interpreter::VMSUMUBM(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMSUMUBM(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va].vi; const auto b = ppu.VR[op.vb].vi; @@ -646,9 +682,10 @@ void ppu_interpreter::VMSUMUBM(PPUThread& ppu, ppu_opcode_t op) const auto sh = _mm_madd_epi16(ah, bh); const auto sl = _mm_madd_epi16(al, bl); ppu.VR[op.vd].vi = _mm_add_epi32(_mm_add_epi32(c, sh), sl); + return true; } -void ppu_interpreter::VMSUMUHM(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMSUMUHM(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va].vi; const auto b = ppu.VR[op.vb].vi; @@ -658,9 +695,10 @@ void ppu_interpreter::VMSUMUHM(PPUThread& ppu, ppu_opcode_t op) const auto ls = _mm_add_epi32(_mm_srli_epi32(ml, 16), _mm_and_si128(ml, _mm_set1_epi32(0x0000ffff))); const auto hs = _mm_add_epi32(_mm_slli_epi32(mh, 16), _mm_and_si128(mh, _mm_set1_epi32(0xffff0000))); ppu.VR[op.vd].vi = _mm_add_epi32(_mm_add_epi32(c, ls), hs); + return true; } -void ppu_interpreter::VMSUMUHS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMSUMUHS(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -688,83 +726,96 @@ void ppu_interpreter::VMSUMUHS(PPUThread& ppu, ppu_opcode_t op) d._u32[w] = saturated; } + return true; } -void ppu_interpreter::VMULESB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMULESB(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_mullo_epi16(_mm_srai_epi16(ppu.VR[op.va].vi, 8), _mm_srai_epi16(ppu.VR[op.vb].vi, 8)); + return true; } -void ppu_interpreter::VMULESH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMULESH(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_madd_epi16(_mm_srli_epi32(ppu.VR[op.va].vi, 16), _mm_srli_epi32(ppu.VR[op.vb].vi, 16)); + return true; } -void ppu_interpreter::VMULEUB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMULEUB(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_mullo_epi16(_mm_srli_epi16(ppu.VR[op.va].vi, 8), _mm_srli_epi16(ppu.VR[op.vb].vi, 8)); + return true; } -void ppu_interpreter::VMULEUH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMULEUH(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va].vi; const auto b = ppu.VR[op.vb].vi; const auto ml = _mm_mullo_epi16(a, b); const auto mh = _mm_mulhi_epu16(a, b); ppu.VR[op.vd].vi = _mm_or_si128(_mm_srli_epi32(ml, 16), _mm_and_si128(mh, _mm_set1_epi32(0xffff0000))); + return true; } -void ppu_interpreter::VMULOSB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMULOSB(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_mullo_epi16(_mm_srai_epi16(_mm_slli_epi16(ppu.VR[op.va].vi, 8), 8), _mm_srai_epi16(_mm_slli_epi16(ppu.VR[op.vb].vi, 8), 8)); + return true; } -void ppu_interpreter::VMULOSH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMULOSH(PPUThread& ppu, ppu_opcode_t op) { const auto mask = _mm_set1_epi32(0x0000ffff); ppu.VR[op.vd].vi = _mm_madd_epi16(_mm_and_si128(ppu.VR[op.va].vi, mask), _mm_and_si128(ppu.VR[op.vb].vi, mask)); + return true; } -void ppu_interpreter::VMULOUB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMULOUB(PPUThread& ppu, ppu_opcode_t op) { const auto mask = _mm_set1_epi16(0x00ff); ppu.VR[op.vd].vi = _mm_mullo_epi16(_mm_and_si128(ppu.VR[op.va].vi, mask), _mm_and_si128(ppu.VR[op.vb].vi, mask)); + return true; } -void ppu_interpreter::VMULOUH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMULOUH(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va].vi; const auto b = ppu.VR[op.vb].vi; const auto ml = _mm_mullo_epi16(a, b); const auto mh = _mm_mulhi_epu16(a, b); ppu.VR[op.vd].vi = _mm_or_si128(_mm_slli_epi32(mh, 16), _mm_and_si128(ml, _mm_set1_epi32(0x0000ffff))); + return true; } -void ppu_interpreter::VNMSUBFP(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VNMSUBFP(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vf = _mm_sub_ps(ppu.VR[op.vb].vf, _mm_mul_ps(ppu.VR[op.va].vf, ppu.VR[op.vc].vf)); + return true; } -void ppu_interpreter::VNOR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VNOR(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd] = ~(ppu.VR[op.va] | ppu.VR[op.vb]); + return true; } -void ppu_interpreter::VOR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VOR(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd] = ppu.VR[op.va] | ppu.VR[op.vb]; + return true; } -void ppu_interpreter::VPERM(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VPERM(PPUThread& ppu, ppu_opcode_t op) { const auto index = _mm_andnot_si128(ppu.VR[op.vc].vi, _mm_set1_epi8(0x1f)); const auto mask = _mm_cmpgt_epi8(index, _mm_set1_epi8(0xf)); const auto sa = _mm_shuffle_epi8(ppu.VR[op.va].vi, index); const auto sb = _mm_shuffle_epi8(ppu.VR[op.vb].vi, index); ppu.VR[op.vd].vi = _mm_or_si128(_mm_and_si128(mask, sa), _mm_andnot_si128(mask, sb)); + return true; } -void ppu_interpreter::VPKPX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VPKPX(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; v128 VA = ppu.VR[op.va]; @@ -783,24 +834,28 @@ void ppu_interpreter::VPKPX(PPUThread& ppu, ppu_opcode_t op) d._u16[3 - h] = (bb7 << 15) | (bb8 << 10) | (bb16 << 5) | bb24; d._u16[4 + (3 - h)] = (ab7 << 15) | (ab8 << 10) | (ab16 << 5) | ab24; } + return true; } -void ppu_interpreter::VPKSHSS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VPKSHSS(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_packs_epi16(ppu.VR[op.vb].vi, ppu.VR[op.va].vi); + return true; } -void ppu_interpreter::VPKSHUS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VPKSHUS(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_packus_epi16(ppu.VR[op.vb].vi, ppu.VR[op.va].vi); + return true; } -void ppu_interpreter::VPKSWSS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VPKSWSS(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_packs_epi32(ppu.VR[op.vb].vi, ppu.VR[op.va].vi); + return true; } -void ppu_interpreter::VPKSWUS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VPKSWUS(PPUThread& ppu, ppu_opcode_t op) { //ppu.VR[op.vd].vi = _mm_packus_epi32(ppu.VR[op.vb].vi, ppu.VR[op.va].vi); auto& d = ppu.VR[op.vd]; @@ -834,9 +889,10 @@ void ppu_interpreter::VPKSWUS(PPUThread& ppu, ppu_opcode_t op) d._u16[h] = result; } + return true; } -void ppu_interpreter::VPKUHUM(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VPKUHUM(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; v128 VA = ppu.VR[op.va]; @@ -846,9 +902,10 @@ void ppu_interpreter::VPKUHUM(PPUThread& ppu, ppu_opcode_t op) d._u8[b + 8] = VA._u8[b * 2]; d._u8[b] = VB._u8[b * 2]; } + return true; } -void ppu_interpreter::VPKUHUS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VPKUHUS(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; v128 VA = ppu.VR[op.va]; @@ -873,9 +930,10 @@ void ppu_interpreter::VPKUHUS(PPUThread& ppu, ppu_opcode_t op) d._u8[b] = (u8)result; } + return true; } -void ppu_interpreter::VPKUWUM(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VPKUWUM(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; v128 VA = ppu.VR[op.va]; @@ -885,9 +943,10 @@ void ppu_interpreter::VPKUWUM(PPUThread& ppu, ppu_opcode_t op) d._u16[h + 4] = VA._u16[h * 2]; d._u16[h] = VB._u16[h * 2]; } + return true; } -void ppu_interpreter::VPKUWUS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VPKUWUS(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; v128 VA = ppu.VR[op.va]; @@ -912,58 +971,64 @@ void ppu_interpreter::VPKUWUS(PPUThread& ppu, ppu_opcode_t op) d._u16[h] = result; } + return true; } -void ppu_interpreter::VREFP(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VREFP(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vf = _mm_rcp_ps(ppu.VR[op.vb].vf); + return true; } -void ppu_interpreter::VRFIM(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VRFIM(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& b = ppu.VR[op.vb]; for (uint w = 0; w < 4; w++) { - d._f[w] = floorf(b._f[w]); + d._f[w] = std::floor(b._f[w]); } + return true; } -void ppu_interpreter::VRFIN(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VRFIN(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& b = ppu.VR[op.vb]; for (uint w = 0; w < 4; w++) { - d._f[w] = nearbyintf(b._f[w]); + d._f[w] = std::nearbyint(b._f[w]); } + return true; } -void ppu_interpreter::VRFIP(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VRFIP(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& b = ppu.VR[op.vb]; for (uint w = 0; w < 4; w++) { - d._f[w] = ceilf(b._f[w]); + d._f[w] = std::ceil(b._f[w]); } + return true; } -void ppu_interpreter::VRFIZ(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VRFIZ(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& b = ppu.VR[op.vb]; for (uint w = 0; w < 4; w++) { - d._f[w] = truncf(b._f[w]); + d._f[w] = std::truncf(b._f[w]); } + return true; } -void ppu_interpreter::VRLB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VRLB(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -973,9 +1038,10 @@ void ppu_interpreter::VRLB(PPUThread& ppu, ppu_opcode_t op) { d._u8[i] = rol8(a._u8[i], b._u8[i] & 0x7); } + return true; } -void ppu_interpreter::VRLH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VRLH(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -985,9 +1051,10 @@ void ppu_interpreter::VRLH(PPUThread& ppu, ppu_opcode_t op) { d._u16[i] = rol16(a._u16[i], b._u8[i * 2] & 0xf); } + return true; } -void ppu_interpreter::VRLW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VRLW(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -997,14 +1064,16 @@ void ppu_interpreter::VRLW(PPUThread& ppu, ppu_opcode_t op) { d._u32[w] = rol32(a._u32[w], b._u8[w * 4] & 0x1f); } + return true; } -void ppu_interpreter::VRSQRTEFP(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VRSQRTEFP(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vf = _mm_rsqrt_ps(ppu.VR[op.vb].vf); + return true; } -void ppu_interpreter::VSEL(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSEL(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -1012,9 +1081,10 @@ void ppu_interpreter::VSEL(PPUThread& ppu, ppu_opcode_t op) const auto& c = ppu.VR[op.vc]; d = (b & c) | v128::andnot(c, a); + return true; } -void ppu_interpreter::VSL(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSL(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; v128 VA = ppu.VR[op.va]; @@ -1025,9 +1095,10 @@ void ppu_interpreter::VSL(PPUThread& ppu, ppu_opcode_t op) { d._u8[b] = (VA._u8[b] << sh) | (VA._u8[b - 1] >> (8 - sh)); } + return true; } -void ppu_interpreter::VSLB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSLB(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -1037,9 +1108,10 @@ void ppu_interpreter::VSLB(PPUThread& ppu, ppu_opcode_t op) { d._u8[i] = a._u8[i] << (b._u8[i] & 0x7); } + return true; } -void ppu_interpreter::VSLDOI(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSLDOI(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; u8 tmpSRC[32]; @@ -1050,9 +1122,10 @@ void ppu_interpreter::VSLDOI(PPUThread& ppu, ppu_opcode_t op) { d._u8[15 - b] = tmpSRC[31 - (b + op.vsh)]; } + return true; } -void ppu_interpreter::VSLH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSLH(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -1062,9 +1135,10 @@ void ppu_interpreter::VSLH(PPUThread& ppu, ppu_opcode_t op) { d._u16[h] = a._u16[h] << (b._u16[h] & 0xf); } + return true; } -void ppu_interpreter::VSLO(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSLO(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; v128 VA = ppu.VR[op.va]; @@ -1076,9 +1150,10 @@ void ppu_interpreter::VSLO(PPUThread& ppu, ppu_opcode_t op) { d._u8[15 - b] = VA._u8[15 - (b + nShift)]; } + return true; } -void ppu_interpreter::VSLW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSLW(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -1088,9 +1163,10 @@ void ppu_interpreter::VSLW(PPUThread& ppu, ppu_opcode_t op) { d._u32[w] = a._u32[w] << (b._u32[w] & 0x1f); } + return true; } -void ppu_interpreter::VSPLTB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSPLTB(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; u8 byte = ppu.VR[op.vb]._u8[15 - op.vuimm]; @@ -1099,12 +1175,13 @@ void ppu_interpreter::VSPLTB(PPUThread& ppu, ppu_opcode_t op) { d._u8[b] = byte; } + return true; } -void ppu_interpreter::VSPLTH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSPLTH(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; - Expects(op.vuimm < 8); + EXPECTS(op.vuimm < 8); u16 hword = ppu.VR[op.vb]._u16[7 - op.vuimm]; @@ -1112,9 +1189,10 @@ void ppu_interpreter::VSPLTH(PPUThread& ppu, ppu_opcode_t op) { d._u16[h] = hword; } + return true; } -void ppu_interpreter::VSPLTISB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSPLTISB(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const s8 imm = op.vsimm; @@ -1123,9 +1201,10 @@ void ppu_interpreter::VSPLTISB(PPUThread& ppu, ppu_opcode_t op) { d._u8[b] = imm; } + return true; } -void ppu_interpreter::VSPLTISH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSPLTISH(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const s16 imm = op.vsimm; @@ -1134,9 +1213,10 @@ void ppu_interpreter::VSPLTISH(PPUThread& ppu, ppu_opcode_t op) { d._u16[h] = imm; } + return true; } -void ppu_interpreter::VSPLTISW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSPLTISW(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const s32 imm = op.vsimm; @@ -1145,12 +1225,13 @@ void ppu_interpreter::VSPLTISW(PPUThread& ppu, ppu_opcode_t op) { d._u32[w] = imm; } + return true; } -void ppu_interpreter::VSPLTW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSPLTW(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; - Expects(op.vuimm < 4); + EXPECTS(op.vuimm < 4); u32 word = ppu.VR[op.vb]._u32[3 - op.vuimm]; @@ -1158,9 +1239,10 @@ void ppu_interpreter::VSPLTW(PPUThread& ppu, ppu_opcode_t op) { d._u32[w] = word; } + return true; } -void ppu_interpreter::VSR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSR(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; v128 VA = ppu.VR[op.va]; @@ -1171,9 +1253,10 @@ void ppu_interpreter::VSR(PPUThread& ppu, ppu_opcode_t op) { d._u8[b] = (VA._u8[b] >> sh) | (VA._u8[b + 1] << (8 - sh)); } + return true; } -void ppu_interpreter::VSRAB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSRAB(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -1183,9 +1266,10 @@ void ppu_interpreter::VSRAB(PPUThread& ppu, ppu_opcode_t op) { d._s8[i] = a._s8[i] >> (b._u8[i] & 0x7); } + return true; } -void ppu_interpreter::VSRAH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSRAH(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -1195,9 +1279,10 @@ void ppu_interpreter::VSRAH(PPUThread& ppu, ppu_opcode_t op) { d._s16[h] = a._s16[h] >> (b._u16[h] & 0xf); } + return true; } -void ppu_interpreter::VSRAW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSRAW(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -1207,9 +1292,10 @@ void ppu_interpreter::VSRAW(PPUThread& ppu, ppu_opcode_t op) { d._s32[w] = a._s32[w] >> (b._u32[w] & 0x1f); } + return true; } -void ppu_interpreter::VSRB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSRB(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -1219,9 +1305,10 @@ void ppu_interpreter::VSRB(PPUThread& ppu, ppu_opcode_t op) { d._u8[i] = a._u8[i] >> (b._u8[i] & 0x7); } + return true; } -void ppu_interpreter::VSRH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSRH(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -1231,9 +1318,10 @@ void ppu_interpreter::VSRH(PPUThread& ppu, ppu_opcode_t op) { d._u16[h] = a._u16[h] >> (b._u16[h] & 0xf); } + return true; } -void ppu_interpreter::VSRO(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSRO(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; v128 VA = ppu.VR[op.va]; @@ -1245,9 +1333,10 @@ void ppu_interpreter::VSRO(PPUThread& ppu, ppu_opcode_t op) { d._u8[b] = VA._u8[b + nShift]; } + return true; } -void ppu_interpreter::VSRW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSRW(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -1257,9 +1346,10 @@ void ppu_interpreter::VSRW(PPUThread& ppu, ppu_opcode_t op) { d._u32[w] = a._u32[w] >> (b._u32[w] & 0x1f); } + return true; } -void ppu_interpreter::VSUBCUW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSUBCUW(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -1269,24 +1359,28 @@ void ppu_interpreter::VSUBCUW(PPUThread& ppu, ppu_opcode_t op) { d._u32[w] = a._u32[w] < b._u32[w] ? 0 : 1; } + return true; } -void ppu_interpreter::VSUBFP(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSUBFP(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd] = v128::subfs(ppu.VR[op.va], ppu.VR[op.vb]); + return true; } -void ppu_interpreter::VSUBSBS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSUBSBS(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_subs_epi8(ppu.VR[op.va].vi, ppu.VR[op.vb].vi); + return true; } -void ppu_interpreter::VSUBSHS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSUBSHS(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_subs_epi16(ppu.VR[op.va].vi, ppu.VR[op.vb].vi); + return true; } -void ppu_interpreter::VSUBSWS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSUBSWS(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -1307,34 +1401,40 @@ void ppu_interpreter::VSUBSWS(PPUThread& ppu, ppu_opcode_t op) else d._s32[w] = (s32)result; } + return true; } -void ppu_interpreter::VSUBUBM(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSUBUBM(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd] = v128::sub8(ppu.VR[op.va], ppu.VR[op.vb]); + return true; } -void ppu_interpreter::VSUBUBS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSUBUBS(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_subs_epu8(ppu.VR[op.va].vi, ppu.VR[op.vb].vi); + return true; } -void ppu_interpreter::VSUBUHM(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSUBUHM(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd] = v128::sub16(ppu.VR[op.va], ppu.VR[op.vb]); + return true; } -void ppu_interpreter::VSUBUHS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSUBUHS(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_subs_epu16(ppu.VR[op.va].vi, ppu.VR[op.vb].vi); + return true; } -void ppu_interpreter::VSUBUWM(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSUBUWM(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd] = v128::sub32(ppu.VR[op.va], ppu.VR[op.vb]); + return true; } -void ppu_interpreter::VSUBUWS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSUBUWS(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -1351,9 +1451,10 @@ void ppu_interpreter::VSUBUWS(PPUThread& ppu, ppu_opcode_t op) else d._u32[w] = (u32)result; } + return true; } -void ppu_interpreter::VSUMSWS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSUMSWS(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -1377,9 +1478,10 @@ void ppu_interpreter::VSUMSWS(PPUThread& ppu, ppu_opcode_t op) } else d._s32[0] = (s32)sum; + return true; } -void ppu_interpreter::VSUM2SWS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSUM2SWS(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -1402,9 +1504,10 @@ void ppu_interpreter::VSUM2SWS(PPUThread& ppu, ppu_opcode_t op) } d._s32[1] = 0; d._s32[3] = 0; + return true; } -void ppu_interpreter::VSUM4SBS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSUM4SBS(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -1430,9 +1533,10 @@ void ppu_interpreter::VSUM4SBS(PPUThread& ppu, ppu_opcode_t op) else d._s32[w] = (s32)sum; } + return true; } -void ppu_interpreter::VSUM4SHS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSUM4SHS(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -1458,9 +1562,10 @@ void ppu_interpreter::VSUM4SHS(PPUThread& ppu, ppu_opcode_t op) else d._s32[w] = (s32)sum; } + return true; } -void ppu_interpreter::VSUM4UBS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSUM4UBS(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -1482,9 +1587,10 @@ void ppu_interpreter::VSUM4UBS(PPUThread& ppu, ppu_opcode_t op) else d._u32[w] = (u32)sum; } + return true; } -void ppu_interpreter::VUPKHPX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VUPKHPX(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; v128 VB = ppu.VR[op.vb]; @@ -1495,9 +1601,10 @@ void ppu_interpreter::VUPKHPX(PPUThread& ppu, ppu_opcode_t op) d._u8[w * 4 + 1] = ((VB._u8[8 + w * 2 + 1] & 0x3) << 3) | ((VB._u8[8 + w * 2 + 0] >> 5) & 0x7); d._u8[w * 4 + 0] = VB._u8[8 + w * 2 + 0] & 0x1f; } + return true; } -void ppu_interpreter::VUPKHSB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VUPKHSB(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; v128 VB = ppu.VR[op.vb]; @@ -1505,9 +1612,10 @@ void ppu_interpreter::VUPKHSB(PPUThread& ppu, ppu_opcode_t op) { d._s16[h] = VB._s8[8 + h]; } + return true; } -void ppu_interpreter::VUPKHSH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VUPKHSH(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; v128 VB = ppu.VR[op.vb]; @@ -1515,9 +1623,10 @@ void ppu_interpreter::VUPKHSH(PPUThread& ppu, ppu_opcode_t op) { d._s32[w] = VB._s16[4 + w]; } + return true; } -void ppu_interpreter::VUPKLPX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VUPKLPX(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; v128 VB = ppu.VR[op.vb]; @@ -1528,9 +1637,10 @@ void ppu_interpreter::VUPKLPX(PPUThread& ppu, ppu_opcode_t op) d._u8[w * 4 + 1] = ((VB._u8[w * 2 + 1] & 0x3) << 3) | ((VB._u8[w * 2 + 0] >> 5) & 0x7); d._u8[w * 4 + 0] = VB._u8[w * 2 + 0] & 0x1f; } + return true; } -void ppu_interpreter::VUPKLSB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VUPKLSB(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; v128 VB = ppu.VR[op.vb]; @@ -1538,9 +1648,10 @@ void ppu_interpreter::VUPKLSB(PPUThread& ppu, ppu_opcode_t op) { d._s16[h] = VB._s8[h]; } + return true; } -void ppu_interpreter::VUPKLSH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VUPKLSH(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; v128 VB = ppu.VR[op.vb]; @@ -1548,28 +1659,66 @@ void ppu_interpreter::VUPKLSH(PPUThread& ppu, ppu_opcode_t op) { d._s32[w] = VB._s16[w]; } + return true; } -void ppu_interpreter::VXOR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VXOR(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd] = ppu.VR[op.va] ^ ppu.VR[op.vb]; + return true; } -void ppu_interpreter::MULLI(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::TDI(PPUThread& ppu, ppu_opcode_t op) +{ + const s64 a = ppu.GPR[op.ra], b = op.simm16; + const u64 a_ = a, b_ = b; + + if (((op.bo & 0x10) && a < b) || + ((op.bo & 0x8) && a > b) || + ((op.bo & 0x4) && a == b) || + ((op.bo & 0x2) && a_ < b_) || + ((op.bo & 0x1) && a_ > b_)) + { + throw std::runtime_error("Trap!" HERE); + } + + return true; +} + +bool ppu_interpreter::TWI(PPUThread& ppu, ppu_opcode_t op) +{ + const s32 a = u32(ppu.GPR[op.ra]), b = op.simm16; + const u32 a_ = a, b_ = b; + + if (((op.bo & 0x10) && a < b) || + ((op.bo & 0x8) && a > b) || + ((op.bo & 0x4) && a == b) || + ((op.bo & 0x2) && a_ < b_) || + ((op.bo & 0x1) && a_ > b_)) + { + throw std::runtime_error("Trap!" HERE); + } + + return true; +} + +bool ppu_interpreter::MULLI(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.rd] = (s64)ppu.GPR[op.ra] * op.simm16; + return true; } -void ppu_interpreter::SUBFIC(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::SUBFIC(PPUThread& ppu, ppu_opcode_t op) { const u64 a = ppu.GPR[op.ra]; const s64 i = op.simm16; const auto r = add64_flags(~a, i, 1); ppu.GPR[op.rd] = r.result; ppu.CA = r.carry; + return true; } -void ppu_interpreter::CMPLI(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::CMPLI(PPUThread& ppu, ppu_opcode_t op) { if (op.l10) { @@ -1579,9 +1728,10 @@ void ppu_interpreter::CMPLI(PPUThread& ppu, ppu_opcode_t op) { ppu.SetCR(op.crfd, u32(ppu.GPR[op.ra]), op.uimm16); } + return true; } -void ppu_interpreter::CMPI(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::CMPI(PPUThread& ppu, ppu_opcode_t op) { if (op.l10) { @@ -1591,9 +1741,10 @@ void ppu_interpreter::CMPI(PPUThread& ppu, ppu_opcode_t op) { ppu.SetCR(op.crfd, u32(ppu.GPR[op.ra]), op.simm16); } + return true; } -void ppu_interpreter::ADDIC(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::ADDIC(PPUThread& ppu, ppu_opcode_t op) { const s64 a = ppu.GPR[op.ra]; const s64 i = op.simm16; @@ -1601,19 +1752,22 @@ void ppu_interpreter::ADDIC(PPUThread& ppu, ppu_opcode_t op) ppu.GPR[op.rd] = r.result; ppu.CA = r.carry; if (UNLIKELY(op.main & 1)) ppu.SetCR(0, r.result, 0); + return true; } -void ppu_interpreter::ADDI(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::ADDI(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.rd] = op.ra ? ((s64)ppu.GPR[op.ra] + op.simm16) : op.simm16; + return true; } -void ppu_interpreter::ADDIS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::ADDIS(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.rd] = op.ra ? ((s64)ppu.GPR[op.ra] + (op.simm16 << 16)) : (op.simm16 << 16); + return true; } -void ppu_interpreter::BC(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::BC(PPUThread& ppu, ppu_opcode_t op) { const bool bo0 = (op.bo & 0x10) != 0; const bool bo1 = (op.bo & 0x08) != 0; @@ -1627,40 +1781,50 @@ void ppu_interpreter::BC(PPUThread& ppu, ppu_opcode_t op) if (ctr_ok && cond_ok) { - const u32 nextLR = ppu.PC + 4; - ppu.PC = ppu_branch_target((op.aa ? 0 : ppu.PC), op.simm16) - 4; + const u32 nextLR = ppu.pc + 4; + ppu.pc = ppu_branch_target((op.aa ? 0 : ppu.pc), op.simm16); if (op.lk) ppu.LR = nextLR; + return false; + } + else + { + return true; } } -void ppu_interpreter::HACK(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::HACK(PPUThread& ppu, ppu_opcode_t op) { ppu_execute_function(ppu, op.opcode & 0x3ffffff); + return true; } -void ppu_interpreter::SC(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::SC(PPUThread& ppu, ppu_opcode_t op) { switch (u32 lv = op.lev) { case 0x0: ppu_execute_syscall(ppu, ppu.GPR[11]); break; default: throw fmt::exception("SC lv%u", lv); } + + return true; } -void ppu_interpreter::B(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::B(PPUThread& ppu, ppu_opcode_t op) { - const u32 nextLR = ppu.PC + 4; - ppu.PC = ppu_branch_target(op.aa ? 0 : ppu.PC, op.ll) - 4; + const u32 nextLR = ppu.pc + 4; + ppu.pc = ppu_branch_target(op.aa ? 0 : ppu.pc, op.ll); if (op.lk) ppu.LR = nextLR; + return false; } -void ppu_interpreter::MCRF(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MCRF(PPUThread& ppu, ppu_opcode_t op) { CHECK_SIZE(PPUThread::CR, 32); reinterpret_cast(ppu.CR)[op.crfd] = reinterpret_cast(ppu.CR)[op.crfs]; + return true; } -void ppu_interpreter::BCLR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::BCLR(PPUThread& ppu, ppu_opcode_t op) { const bool bo0 = (op.bo & 0x10) != 0; const bool bo1 = (op.bo & 0x08) != 0; @@ -1674,156 +1838,188 @@ void ppu_interpreter::BCLR(PPUThread& ppu, ppu_opcode_t op) if (ctr_ok && cond_ok) { - const u32 nextLR = ppu.PC + 4; - ppu.PC = ppu_branch_target(0, (u32)ppu.LR) - 4; + const u32 nextLR = ppu.pc + 4; + ppu.pc = ppu_branch_target(0, (u32)ppu.LR); if (op.lk) ppu.LR = nextLR; + return false; + } + else + { + return true; } } -void ppu_interpreter::CRNOR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::CRNOR(PPUThread& ppu, ppu_opcode_t op) { ppu.CR[op.crbd] = (ppu.CR[op.crba] | ppu.CR[op.crbb]) ^ true; + return true; } -void ppu_interpreter::CRANDC(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::CRANDC(PPUThread& ppu, ppu_opcode_t op) { ppu.CR[op.crbd] = ppu.CR[op.crba] & (ppu.CR[op.crbb] ^ true); + return true; } -void ppu_interpreter::ISYNC(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::ISYNC(PPUThread& ppu, ppu_opcode_t op) { _mm_mfence(); + return true; } -void ppu_interpreter::CRXOR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::CRXOR(PPUThread& ppu, ppu_opcode_t op) { ppu.CR[op.crbd] = ppu.CR[op.crba] ^ ppu.CR[op.crbb]; + return true; } -void ppu_interpreter::CRNAND(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::CRNAND(PPUThread& ppu, ppu_opcode_t op) { ppu.CR[op.crbd] = (ppu.CR[op.crba] & ppu.CR[op.crbb]) ^ true; + return true; } -void ppu_interpreter::CRAND(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::CRAND(PPUThread& ppu, ppu_opcode_t op) { ppu.CR[op.crbd] = ppu.CR[op.crba] & ppu.CR[op.crbb]; + return true; } -void ppu_interpreter::CREQV(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::CREQV(PPUThread& ppu, ppu_opcode_t op) { ppu.CR[op.crbd] = (ppu.CR[op.crba] ^ ppu.CR[op.crbb]) ^ true; + return true; } -void ppu_interpreter::CRORC(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::CRORC(PPUThread& ppu, ppu_opcode_t op) { ppu.CR[op.crbd] = ppu.CR[op.crba] | (ppu.CR[op.crbb] ^ true); + return true; } -void ppu_interpreter::CROR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::CROR(PPUThread& ppu, ppu_opcode_t op) { ppu.CR[op.crbd] = ppu.CR[op.crba] | ppu.CR[op.crbb]; + return true; } -void ppu_interpreter::BCCTR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::BCCTR(PPUThread& ppu, ppu_opcode_t op) { if (op.bo & 0x10 || ppu.CR[op.bi] == ((op.bo & 0x8) != 0)) { - const u32 nextLR = ppu.PC + 4; - ppu.PC = ppu_branch_target(0, (u32)ppu.CTR) - 4; + const u32 nextLR = ppu.pc + 4; + ppu.pc = ppu_branch_target(0, (u32)ppu.CTR); if (op.lk) ppu.LR = nextLR; + return false; } + + return true; } -void ppu_interpreter::RLWIMI(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::RLWIMI(PPUThread& ppu, ppu_opcode_t op) { const u64 mask = ppu_rotate_mask(32 + op.mb32, 32 + op.me32); ppu.GPR[op.ra] = (ppu.GPR[op.ra] & ~mask) | (dup32(rol32(u32(ppu.GPR[op.rs]), op.sh32)) & mask); if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::RLWINM(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::RLWINM(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = dup32(rol32(u32(ppu.GPR[op.rs]), op.sh32)) & ppu_rotate_mask(32 + op.mb32, 32 + op.me32); if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::RLWNM(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::RLWNM(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = dup32(rol32(u32(ppu.GPR[op.rs]), ppu.GPR[op.rb] & 0x1f)) & ppu_rotate_mask(32 + op.mb32, 32 + op.me32); if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::ORI(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::ORI(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = ppu.GPR[op.rs] | op.uimm16; + return true; } -void ppu_interpreter::ORIS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::ORIS(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = ppu.GPR[op.rs] | ((u64)op.uimm16 << 16); + return true; } -void ppu_interpreter::XORI(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::XORI(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = ppu.GPR[op.rs] ^ op.uimm16; + return true; } -void ppu_interpreter::XORIS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::XORIS(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = ppu.GPR[op.rs] ^ ((u64)op.uimm16 << 16); + return true; } -void ppu_interpreter::ANDI(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::ANDI(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = ppu.GPR[op.rs] & op.uimm16; ppu.SetCR(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::ANDIS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::ANDIS(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = ppu.GPR[op.rs] & ((u64)op.uimm16 << 16); ppu.SetCR(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::RLDICL(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::RLDICL(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = rol64(ppu.GPR[op.rs], op.sh64) & (~0ull >> op.mbe64); if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::RLDICR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::RLDICR(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = rol64(ppu.GPR[op.rs], op.sh64) & (~0ull << (op.mbe64 ^ 63)); if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::RLDIC(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::RLDIC(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = rol64(ppu.GPR[op.rs], op.sh64) & ppu_rotate_mask(op.mbe64, op.sh64 ^ 63); if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::RLDIMI(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::RLDIMI(PPUThread& ppu, ppu_opcode_t op) { const u64 mask = ppu_rotate_mask(op.mbe64, op.sh64 ^ 63); ppu.GPR[op.ra] = (ppu.GPR[op.ra] & ~mask) | (rol64(ppu.GPR[op.rs], op.sh64) & mask); if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::RLDCL(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::RLDCL(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = rol64(ppu.GPR[op.rs], ppu.GPR[op.rb] & 0x3f) & (~0ull >> op.mbe64); if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::RLDCR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::RLDCR(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = rol64(ppu.GPR[op.rs], ppu.GPR[op.rb] & 0x3f) & (~0ull << (op.mbe64 ^ 63)); if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::CMP(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::CMP(PPUThread& ppu, ppu_opcode_t op) { if (op.l10) { @@ -1833,9 +2029,10 @@ void ppu_interpreter::CMP(PPUThread& ppu, ppu_opcode_t op) { ppu.SetCR(op.crfd, u32(ppu.GPR[op.ra]), u32(ppu.GPR[op.rb])); } + return true; } -void ppu_interpreter::TW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::TW(PPUThread& ppu, ppu_opcode_t op) { s32 a = (s32)ppu.GPR[op.ra]; s32 b = (s32)ppu.GPR[op.rb]; @@ -1848,9 +2045,11 @@ void ppu_interpreter::TW(PPUThread& ppu, ppu_opcode_t op) { throw std::runtime_error("Trap!" HERE); } + + return true; } -void ppu_interpreter::LVSL(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LVSL(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; @@ -1876,15 +2075,17 @@ void ppu_interpreter::LVSL(PPUThread& ppu, ppu_opcode_t op) ppu.VR[op.vd]._u64[0] = lvsl_values[addr & 0xf][0]; ppu.VR[op.vd]._u64[1] = lvsl_values[addr & 0xf][1]; + return true; } -void ppu_interpreter::LVEBX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LVEBX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; ppu.VR[op.vd]._u8[15 - (addr & 0xf)] = vm::read8(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::SUBFC(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::SUBFC(PPUThread& ppu, ppu_opcode_t op) { const u64 RA = ppu.GPR[op.ra]; const u64 RB = ppu.GPR[op.rb]; @@ -1893,15 +2094,17 @@ void ppu_interpreter::SUBFC(PPUThread& ppu, ppu_opcode_t op) ppu.CA = r.carry; if (UNLIKELY(op.oe)) ppu.SetOV((~RA >> 63 == RB >> 63) && (~RA >> 63 != ppu.GPR[op.rd] >> 63)); if (UNLIKELY(op.rc)) ppu.SetCR(0, r.result, 0); + return true; } -void ppu_interpreter::MULHDU(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MULHDU(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.rd] = UMULH64(ppu.GPR[op.ra], ppu.GPR[op.rb]); if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.rd], 0); + return true; } -void ppu_interpreter::ADDC(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::ADDC(PPUThread& ppu, ppu_opcode_t op) { const u64 RA = ppu.GPR[op.ra]; const u64 RB = ppu.GPR[op.rb]; @@ -1910,17 +2113,19 @@ void ppu_interpreter::ADDC(PPUThread& ppu, ppu_opcode_t op) ppu.CA = r.carry; if (UNLIKELY(op.oe)) ppu.SetOV((RA >> 63 == RB >> 63) && (RA >> 63 != ppu.GPR[op.rd] >> 63)); if (UNLIKELY(op.rc)) ppu.SetCR(0, r.result, 0); + return true; } -void ppu_interpreter::MULHWU(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MULHWU(PPUThread& ppu, ppu_opcode_t op) { u32 a = (u32)ppu.GPR[op.ra]; u32 b = (u32)ppu.GPR[op.rb]; ppu.GPR[op.rd] = ((u64)a * (u64)b) >> 32; if (UNLIKELY(op.rc)) ppu.SetCR(0, false, false, false, ppu.SO); + return true; } -void ppu_interpreter::MFOCRF(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MFOCRF(PPUThread& ppu, ppu_opcode_t op) { if (op.l11) { @@ -1940,9 +2145,10 @@ void ppu_interpreter::MFOCRF(PPUThread& ppu, ppu_opcode_t op) ppu.GPR[op.rd] = (mh << 16) | ml; } + return true; } -void ppu_interpreter::LWARX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LWARX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; @@ -1950,46 +2156,53 @@ void ppu_interpreter::LWARX(PPUThread& ppu, ppu_opcode_t op) vm::reservation_acquire(&value, vm::cast(addr, HERE), SIZE_32(value)); ppu.GPR[op.rd] = value; + return true; } -void ppu_interpreter::LDX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LDX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; ppu.GPR[op.rd] = vm::read64(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::LWZX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LWZX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; ppu.GPR[op.rd] = vm::read32(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::SLW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::SLW(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = u32(ppu.GPR[op.rs] << (ppu.GPR[op.rb] & 0x3f)); if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::CNTLZW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::CNTLZW(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = cntlz32(u32(ppu.GPR[op.rs])); if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::SLD(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::SLD(PPUThread& ppu, ppu_opcode_t op) { const u32 n = ppu.GPR[op.rb]; ppu.GPR[op.ra] = UNLIKELY(n & 0x40) ? 0 : ppu.GPR[op.rs] << n; if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::AND(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::AND(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = ppu.GPR[op.rs] & ppu.GPR[op.rb]; if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::CMPL(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::CMPL(PPUThread& ppu, ppu_opcode_t op) { if (op.l10) { @@ -1999,9 +2212,10 @@ void ppu_interpreter::CMPL(PPUThread& ppu, ppu_opcode_t op) { ppu.SetCR(op.crfd, u32(ppu.GPR[op.ra]), u32(ppu.GPR[op.rb])); } + return true; } -void ppu_interpreter::LVSR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LVSR(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; @@ -2027,54 +2241,62 @@ void ppu_interpreter::LVSR(PPUThread& ppu, ppu_opcode_t op) ppu.VR[op.vd]._u64[0] = lvsr_values[addr & 0xf][0]; ppu.VR[op.vd]._u64[1] = lvsr_values[addr & 0xf][1]; + return true; } -void ppu_interpreter::LVEHX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LVEHX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = (op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]) & ~1ULL; ppu.VR[op.vd]._u16[7 - ((addr >> 1) & 0x7)] = vm::read16(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::SUBF(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::SUBF(PPUThread& ppu, ppu_opcode_t op) { const u64 RA = ppu.GPR[op.ra]; const u64 RB = ppu.GPR[op.rb]; ppu.GPR[op.rd] = RB - RA; if (UNLIKELY(op.oe)) ppu.SetOV((~RA >> 63 == RB >> 63) && (~RA >> 63 != ppu.GPR[op.rd] >> 63)); if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.rd], 0); + return true; } -void ppu_interpreter::LDUX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LDUX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + ppu.GPR[op.rb]; ppu.GPR[op.rd] = vm::read64(vm::cast(addr, HERE)); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::DCBST(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::DCBST(PPUThread& ppu, ppu_opcode_t op) { + return true; } -void ppu_interpreter::LWZUX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LWZUX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + ppu.GPR[op.rb]; ppu.GPR[op.rd] = vm::read32(vm::cast(addr, HERE)); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::CNTLZD(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::CNTLZD(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = cntlz64(ppu.GPR[op.rs]); if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::ANDC(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::ANDC(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = ppu.GPR[op.rs] & ~ppu.GPR[op.rb]; if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::TD(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::TD(PPUThread& ppu, ppu_opcode_t op) { const s64 a = ppu.GPR[op.ra], b = ppu.GPR[op.rb]; const u64 a_ = a, b_ = b; @@ -2087,29 +2309,34 @@ void ppu_interpreter::TD(PPUThread& ppu, ppu_opcode_t op) { throw std::runtime_error("Trap!" HERE); } + + return true; } -void ppu_interpreter::LVEWX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LVEWX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = (op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]) & ~3ULL; ppu.VR[op.vd]._u32[3 - ((addr >> 2) & 0x3)] = vm::read32(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::MULHD(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MULHD(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.rd] = MULH64(ppu.GPR[op.ra], ppu.GPR[op.rb]); if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.rd], 0); + return true; } -void ppu_interpreter::MULHW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MULHW(PPUThread& ppu, ppu_opcode_t op) { s32 a = (s32)ppu.GPR[op.ra]; s32 b = (s32)ppu.GPR[op.rb]; ppu.GPR[op.rd] = ((s64)a * (s64)b) >> 32; if (UNLIKELY(op.rc)) ppu.SetCR(0, false, false, false, ppu.SO); + return true; } -void ppu_interpreter::LDARX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LDARX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; @@ -2117,53 +2344,61 @@ void ppu_interpreter::LDARX(PPUThread& ppu, ppu_opcode_t op) vm::reservation_acquire(&value, vm::cast(addr, HERE), SIZE_32(value)); ppu.GPR[op.rd] = value; + return true; } -void ppu_interpreter::DCBF(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::DCBF(PPUThread& ppu, ppu_opcode_t op) { + return true; } -void ppu_interpreter::LBZX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LBZX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; ppu.GPR[op.rd] = vm::read8(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::LVX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LVX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = (op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]) & ~0xfull; ppu.VR[op.vd] = vm::_ref(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::NEG(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::NEG(PPUThread& ppu, ppu_opcode_t op) { const u64 RA = ppu.GPR[op.ra]; ppu.GPR[op.rd] = 0 - RA; if (UNLIKELY(op.oe)) ppu.SetOV((~RA >> 63 == 0) && (~RA >> 63 != ppu.GPR[op.rd] >> 63)); if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.rd], 0); + return true; } -void ppu_interpreter::LBZUX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LBZUX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + ppu.GPR[op.rb]; ppu.GPR[op.rd] = vm::read8(vm::cast(addr, HERE)); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::NOR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::NOR(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = ~(ppu.GPR[op.rs] | ppu.GPR[op.rb]); if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::STVEBX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STVEBX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; const u8 eb = addr & 0xf; vm::write8(vm::cast(addr, HERE), ppu.VR[op.vs]._u8[15 - eb]); + return true; } -void ppu_interpreter::SUBFE(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::SUBFE(PPUThread& ppu, ppu_opcode_t op) { const u64 RA = ppu.GPR[op.ra]; const u64 RB = ppu.GPR[op.rb]; @@ -2172,9 +2407,10 @@ void ppu_interpreter::SUBFE(PPUThread& ppu, ppu_opcode_t op) ppu.CA = r.carry; if (UNLIKELY(op.oe)) ppu.SetOV((~RA >> 63 == RB >> 63) && (~RA >> 63 != ppu.GPR[op.rd] >> 63)); if (UNLIKELY(op.rc)) ppu.SetCR(0, r.result, 0); + return true; } -void ppu_interpreter::ADDE(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::ADDE(PPUThread& ppu, ppu_opcode_t op) { const u64 RA = ppu.GPR[op.ra]; const u64 RB = ppu.GPR[op.rb]; @@ -2183,9 +2419,10 @@ void ppu_interpreter::ADDE(PPUThread& ppu, ppu_opcode_t op) ppu.CA = r.carry; if (UNLIKELY(op.oe)) ppu.SetOV((RA >> 63 == RB >> 63) && (RA >> 63 != ppu.GPR[op.rd] >> 63)); if (UNLIKELY(op.rc)) ppu.SetCR(0, r.result, 0); + return true; } -void ppu_interpreter::MTOCRF(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MTOCRF(PPUThread& ppu, ppu_opcode_t op) { const u64 s = ppu.GPR[op.rs]; @@ -2219,57 +2456,65 @@ void ppu_interpreter::MTOCRF(PPUThread& ppu, ppu_opcode_t op) } } } + return true; } -void ppu_interpreter::STDX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STDX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; vm::write64(vm::cast(addr, HERE), ppu.GPR[op.rs]); + return true; } -void ppu_interpreter::STWCX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STWCX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; const be_t value = (u32)ppu.GPR[op.rs]; ppu.SetCR(0, false, false, vm::reservation_update(vm::cast(addr, HERE), &value, SIZE_32(value)), ppu.SO); + return true; } -void ppu_interpreter::STWX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STWX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; vm::write32(vm::cast(addr, HERE), (u32)ppu.GPR[op.rs]); + return true; } -void ppu_interpreter::STVEHX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STVEHX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = (op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]) & ~1ULL; const u8 eb = (addr & 0xf) >> 1; vm::write16(vm::cast(addr, HERE), ppu.VR[op.vs]._u16[7 - eb]); + return true; } -void ppu_interpreter::STDUX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STDUX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + ppu.GPR[op.rb]; vm::write64(vm::cast(addr, HERE), ppu.GPR[op.rs]); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::STWUX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STWUX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + ppu.GPR[op.rb]; vm::write32(vm::cast(addr, HERE), (u32)ppu.GPR[op.rs]); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::STVEWX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STVEWX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = (op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]) & ~3ULL; const u8 eb = (addr & 0xf) >> 2; vm::write32(vm::cast(addr, HERE), ppu.VR[op.vs]._u32[3 - eb]); + return true; } -void ppu_interpreter::SUBFZE(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::SUBFZE(PPUThread& ppu, ppu_opcode_t op) { const u64 RA = ppu.GPR[op.ra]; const auto r = add64_flags(~RA, 0, ppu.CA); @@ -2277,9 +2522,10 @@ void ppu_interpreter::SUBFZE(PPUThread& ppu, ppu_opcode_t op) ppu.CA = r.carry; if (UNLIKELY(op.oe)) ppu.SetOV((~RA >> 63 == 0) && (~RA >> 63 != ppu.GPR[op.rd] >> 63)); if (UNLIKELY(op.rc)) ppu.SetCR(0, r.result, 0); + return true; } -void ppu_interpreter::ADDZE(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::ADDZE(PPUThread& ppu, ppu_opcode_t op) { const u64 RA = ppu.GPR[op.ra]; const auto r = add64_flags(RA, 0, ppu.CA); @@ -2287,29 +2533,33 @@ void ppu_interpreter::ADDZE(PPUThread& ppu, ppu_opcode_t op) ppu.CA = r.carry; if (UNLIKELY(op.oe)) ppu.SetOV((RA >> 63 == 0) && (RA >> 63 != ppu.GPR[op.rd] >> 63)); if (UNLIKELY(op.rc)) ppu.SetCR(0, r.result, 0); + return true; } -void ppu_interpreter::STDCX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STDCX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; const be_t value = ppu.GPR[op.rs]; ppu.SetCR(0, false, false, vm::reservation_update(vm::cast(addr, HERE), &value, SIZE_32(value)), ppu.SO); + return true; } -void ppu_interpreter::STBX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STBX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; vm::write8(vm::cast(addr, HERE), (u8)ppu.GPR[op.rs]); + return true; } -void ppu_interpreter::STVX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STVX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = (op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]) & ~0xfull; vm::_ref(vm::cast(addr, HERE)) = ppu.VR[op.vs]; + return true; } -void ppu_interpreter::MULLD(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MULLD(PPUThread& ppu, ppu_opcode_t op) { const s64 RA = ppu.GPR[op.ra]; const s64 RB = ppu.GPR[op.rb]; @@ -2320,9 +2570,10 @@ void ppu_interpreter::MULLD(PPUThread& ppu, ppu_opcode_t op) ppu.SetOV(high != s64(ppu.GPR[op.rd]) >> 63); } if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.rd], 0); + return true; } -void ppu_interpreter::SUBFME(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::SUBFME(PPUThread& ppu, ppu_opcode_t op) { const u64 RA = ppu.GPR[op.ra]; const auto r = add64_flags(~RA, ~0ull, ppu.CA); @@ -2330,9 +2581,10 @@ void ppu_interpreter::SUBFME(PPUThread& ppu, ppu_opcode_t op) ppu.CA = r.carry; if (UNLIKELY(op.oe)) ppu.SetOV((~RA >> 63 == 1) && (~RA >> 63 != ppu.GPR[op.rd] >> 63)); if (UNLIKELY(op.rc)) ppu.SetCR(0, r.result, 0); + return true; } -void ppu_interpreter::ADDME(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::ADDME(PPUThread& ppu, ppu_opcode_t op) { const s64 RA = ppu.GPR[op.ra]; const auto r = add64_flags(RA, ~0ull, ppu.CA); @@ -2340,110 +2592,125 @@ void ppu_interpreter::ADDME(PPUThread& ppu, ppu_opcode_t op) ppu.CA = r.carry; if (UNLIKELY(op.oe)) ppu.SetOV((u64(RA) >> 63 == 1) && (u64(RA) >> 63 != ppu.GPR[op.rd] >> 63)); if (UNLIKELY(op.rc)) ppu.SetCR(0, r.result, 0); + return true; } -void ppu_interpreter::MULLW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MULLW(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.rd] = (s64)((s64)(s32)ppu.GPR[op.ra] * (s64)(s32)ppu.GPR[op.rb]); if (UNLIKELY(op.oe)) ppu.SetOV(s64(ppu.GPR[op.rd]) < s64(-1) << 31 || s64(ppu.GPR[op.rd]) >= s64(1) << 31); if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::DCBTST(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::DCBTST(PPUThread& ppu, ppu_opcode_t op) { + return true; } -void ppu_interpreter::STBUX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STBUX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + ppu.GPR[op.rb]; vm::write8(vm::cast(addr, HERE), (u8)ppu.GPR[op.rs]); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::ADD(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::ADD(PPUThread& ppu, ppu_opcode_t op) { const u64 RA = ppu.GPR[op.ra]; const u64 RB = ppu.GPR[op.rb]; ppu.GPR[op.rd] = RA + RB; if (UNLIKELY(op.oe)) ppu.SetOV((RA >> 63 == RB >> 63) && (RA >> 63 != ppu.GPR[op.rd] >> 63)); if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.rd], 0); + return true; } -void ppu_interpreter::DCBT(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::DCBT(PPUThread& ppu, ppu_opcode_t op) { + return true; } -void ppu_interpreter::LHZX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LHZX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; ppu.GPR[op.rd] = vm::read16(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::EQV(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::EQV(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = ~(ppu.GPR[op.rs] ^ ppu.GPR[op.rb]); if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::ECIWX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::ECIWX(PPUThread& ppu, ppu_opcode_t op) { throw std::runtime_error("ECIWX" HERE); } -void ppu_interpreter::LHZUX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LHZUX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; ppu.GPR[op.rd] = vm::read16(vm::cast(addr, HERE)); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::XOR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::XOR(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = ppu.GPR[op.rs] ^ ppu.GPR[op.rb]; if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::MFSPR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MFSPR(PPUThread& ppu, ppu_opcode_t op) { const u32 n = (op.spr >> 5) | ((op.spr & 0x1f) << 5); switch (n) { - case 0x001: ppu.GPR[op.rd] = u32{ ppu.SO } << 31 | ppu.OV << 30 | ppu.CA << 29 | ppu.XCNT; return; - case 0x008: ppu.GPR[op.rd] = ppu.LR; return; - case 0x009: ppu.GPR[op.rd] = ppu.CTR; return; - case 0x100: ppu.GPR[op.rd] = ppu.VRSAVE; return; + case 0x001: ppu.GPR[op.rd] = u32{ ppu.SO } << 31 | ppu.OV << 30 | ppu.CA << 29 | ppu.XCNT; break; + case 0x008: ppu.GPR[op.rd] = ppu.LR; break; + case 0x009: ppu.GPR[op.rd] = ppu.CTR; break; + case 0x100: ppu.GPR[op.rd] = ppu.VRSAVE; break; - case 0x10C: ppu.GPR[op.rd] = get_timebased_time() & 0xffffffff; return; - case 0x10D: ppu.GPR[op.rd] = get_timebased_time() >> 32; return; + case 0x10C: ppu.GPR[op.rd] = get_timebased_time() & 0xffffffff; break; + case 0x10D: ppu.GPR[op.rd] = get_timebased_time() >> 32; break; + default: throw fmt::exception("MFSPR 0x%x" HERE, n); } - throw fmt::exception("MFSPR 0x%x" HERE, n); + return true; } -void ppu_interpreter::LWAX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LWAX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; ppu.GPR[op.rd] = (s64)(s32)vm::read32(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::DST(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::DST(PPUThread& ppu, ppu_opcode_t op) { + return true; } -void ppu_interpreter::LHAX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LHAX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; ppu.GPR[op.rd] = (s64)(s16)vm::read16(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::LVXL(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LVXL(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = (op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]) & ~0xfull; ppu.VR[op.vd] = vm::_ref(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::MFTB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MFTB(PPUThread& ppu, ppu_opcode_t op) { const u32 n = (op.spr >> 5) | ((op.spr & 0x1f) << 5); @@ -2453,75 +2720,86 @@ void ppu_interpreter::MFTB(PPUThread& ppu, ppu_opcode_t op) case 0x10D: ppu.GPR[op.rd] = get_timebased_time() >> 32; break; default: throw fmt::exception("MFSPR 0x%x" HERE, n); } + + return true; } -void ppu_interpreter::LWAUX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LWAUX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; ppu.GPR[op.rd] = (s64)(s32)vm::read32(vm::cast(addr, HERE)); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::DSTST(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::DSTST(PPUThread& ppu, ppu_opcode_t op) { + return true; } -void ppu_interpreter::LHAUX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LHAUX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; ppu.GPR[op.rd] = (s64)(s16)vm::read16(vm::cast(addr, HERE)); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::STHX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STHX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; vm::write16(vm::cast(addr, HERE), (u16)ppu.GPR[op.rs]); + return true; } -void ppu_interpreter::ORC(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::ORC(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = ppu.GPR[op.rs] | ~ppu.GPR[op.rb]; if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::ECOWX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::ECOWX(PPUThread& ppu, ppu_opcode_t op) { throw std::runtime_error("ECOWX" HERE); } -void ppu_interpreter::STHUX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STHUX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + ppu.GPR[op.rb]; vm::write16(vm::cast(addr, HERE), (u16)ppu.GPR[op.rs]); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::OR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::OR(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = ppu.GPR[op.rs] | ppu.GPR[op.rb]; if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::DIVDU(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::DIVDU(PPUThread& ppu, ppu_opcode_t op) { const u64 RA = ppu.GPR[op.ra]; const u64 RB = ppu.GPR[op.rb]; ppu.GPR[op.rd] = RB == 0 ? 0 : RA / RB; if (UNLIKELY(op.oe)) ppu.SetOV(RB == 0); if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.rd], 0); + return true; } -void ppu_interpreter::DIVWU(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::DIVWU(PPUThread& ppu, ppu_opcode_t op) { const u32 RA = (u32)ppu.GPR[op.ra]; const u32 RB = (u32)ppu.GPR[op.rb]; ppu.GPR[op.rd] = RB == 0 ? 0 : RA / RB; if (UNLIKELY(op.oe)) ppu.SetOV(RB == 0); if (UNLIKELY(op.rc)) ppu.SetCR(0, false, false, false, ppu.SO); + return true; } -void ppu_interpreter::MTSPR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MTSPR(PPUThread& ppu, ppu_opcode_t op) { const u32 n = (op.spr >> 5) | ((op.spr & 0x1f) << 5); @@ -2534,33 +2812,37 @@ void ppu_interpreter::MTSPR(PPUThread& ppu, ppu_opcode_t op) ppu.OV = (value & 0x40000000) != 0; ppu.CA = (value & 0x20000000) != 0; ppu.XCNT = value & 0x7f; - return; + break; } - case 0x008: ppu.LR = ppu.GPR[op.rs]; return; - case 0x009: ppu.CTR = ppu.GPR[op.rs]; return; - case 0x100: ppu.VRSAVE = (u32)ppu.GPR[op.rs]; return; + case 0x008: ppu.LR = ppu.GPR[op.rs]; break; + case 0x009: ppu.CTR = ppu.GPR[op.rs]; break; + case 0x100: ppu.VRSAVE = (u32)ppu.GPR[op.rs]; break; + default: throw fmt::exception("MTSPR 0x%x" HERE, n); } - throw fmt::exception("MTSPR 0x%x" HERE, n); + return true; } -void ppu_interpreter::DCBI(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::DCBI(PPUThread& ppu, ppu_opcode_t op) { + return true; } -void ppu_interpreter::NAND(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::NAND(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = ~(ppu.GPR[op.rs] & ppu.GPR[op.rb]); if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::STVXL(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STVXL(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = (op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]) & ~0xfull; vm::_ref(vm::cast(addr, HERE)) = ppu.VR[op.vs]; + return true; } -void ppu_interpreter::DIVD(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::DIVD(PPUThread& ppu, ppu_opcode_t op) { const s64 RA = ppu.GPR[op.ra]; const s64 RB = ppu.GPR[op.rb]; @@ -2568,9 +2850,10 @@ void ppu_interpreter::DIVD(PPUThread& ppu, ppu_opcode_t op) ppu.GPR[op.rd] = o ? 0 : RA / RB; if (UNLIKELY(op.oe)) ppu.SetOV(o); if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.rd], 0); + return true; } -void ppu_interpreter::DIVW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::DIVW(PPUThread& ppu, ppu_opcode_t op) { const s32 RA = (s32)ppu.GPR[op.ra]; const s32 RB = (s32)ppu.GPR[op.rb]; @@ -2578,24 +2861,27 @@ void ppu_interpreter::DIVW(PPUThread& ppu, ppu_opcode_t op) ppu.GPR[op.rd] = o ? 0 : u32(RA / RB); if (UNLIKELY(op.oe)) ppu.SetOV(o); if (UNLIKELY(op.rc)) ppu.SetCR(0, false, false, false, ppu.SO); + return true; } -void ppu_interpreter::LVLX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LVLX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; const u32 eb = addr & 0xf; ppu.VR[op.vd].clear(); for (u32 i = 0; i < 16u - eb; ++i) ppu.VR[op.vd]._u8[15 - i] = vm::read8(vm::cast(addr + i, HERE)); + return true; } -void ppu_interpreter::LDBRX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LDBRX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; ppu.GPR[op.rd] = vm::_ref>(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::LSWX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LSWX(PPUThread& ppu, ppu_opcode_t op) { u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; u32 count = ppu.XCNT & 0x7f; @@ -2613,43 +2899,49 @@ void ppu_interpreter::LSWX(PPUThread& ppu, ppu_opcode_t op) } ppu.GPR[op.rd] = value; } + return true; } -void ppu_interpreter::LWBRX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LWBRX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; ppu.GPR[op.rd] = vm::_ref>(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::LFSX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LFSX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; ppu.FPR[op.frd] = vm::_ref(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::SRW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::SRW(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = (ppu.GPR[op.rs] & 0xffffffff) >> (ppu.GPR[op.rb] & 0x3f); if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::SRD(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::SRD(PPUThread& ppu, ppu_opcode_t op) { const u32 n = ppu.GPR[op.rb]; ppu.GPR[op.ra] = UNLIKELY(n & 0x40) ? 0 : ppu.GPR[op.rs] >> n; if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::LVRX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LVRX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; const u8 eb = addr & 0xf; ppu.VR[op.vd].clear(); for (u32 i = 16 - eb; i < 16; ++i) ppu.VR[op.vd]._u8[15 - i] = vm::read8(vm::cast(addr + i - 16, HERE)); + return true; } -void ppu_interpreter::LSWI(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LSWI(PPUThread& ppu, ppu_opcode_t op) { u64 addr = op.ra ? ppu.GPR[op.ra] : 0; u64 N = op.rb ? op.rb : 32; @@ -2678,48 +2970,55 @@ void ppu_interpreter::LSWI(PPUThread& ppu, ppu_opcode_t op) } reg = (reg + 1) % 32; } + return true; } -void ppu_interpreter::LFSUX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LFSUX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + ppu.GPR[op.rb]; ppu.FPR[op.frd] = vm::_ref(vm::cast(addr, HERE)); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::SYNC(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::SYNC(PPUThread& ppu, ppu_opcode_t op) { _mm_mfence(); + return true; } -void ppu_interpreter::LFDX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LFDX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; ppu.FPR[op.frd] = vm::_ref(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::LFDUX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LFDUX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + ppu.GPR[op.rb]; ppu.FPR[op.frd] = vm::_ref(vm::cast(addr, HERE)); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::STVLX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STVLX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; const u32 eb = addr & 0xf; for (u32 i = 0; i < 16u - eb; ++i) vm::write8(vm::cast(addr + i, HERE), ppu.VR[op.vs]._u8[15 - i]); + return true; } -void ppu_interpreter::STDBRX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STDBRX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; vm::_ref>(vm::cast(addr, HERE)) = ppu.GPR[op.rs]; + return true; } -void ppu_interpreter::STSWX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STSWX(PPUThread& ppu, ppu_opcode_t op) { u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; u32 count = ppu.XCNT & 0x7F; @@ -2736,36 +3035,41 @@ void ppu_interpreter::STSWX(PPUThread& ppu, ppu_opcode_t op) vm::write8(vm::cast(addr + byte, HERE), byte_value); } } + return true; } -void ppu_interpreter::STWBRX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STWBRX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; vm::_ref>(vm::cast(addr, HERE)) = (u32)ppu.GPR[op.rs]; + return true; } -void ppu_interpreter::STFSX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STFSX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; vm::_ref(vm::cast(addr, HERE)) = static_cast(ppu.FPR[op.frs]); + return true; } -void ppu_interpreter::STVRX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STVRX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; const u8 eb = addr & 0xf; for (u32 i = 16 - eb; i < 16; ++i) vm::write8(vm::cast(addr + i - 16, HERE), ppu.VR[op.vs]._u8[15 - i]); + return true; } -void ppu_interpreter::STFSUX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STFSUX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + ppu.GPR[op.rb]; vm::_ref(vm::cast(addr, HERE)) = static_cast(ppu.FPR[op.frs]); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::STSWI(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STSWI(PPUThread& ppu, ppu_opcode_t op) { u64 addr = op.ra ? ppu.GPR[op.ra] : 0; u64 N = op.rb ? op.rb : 32; @@ -2792,37 +3096,42 @@ void ppu_interpreter::STSWI(PPUThread& ppu, ppu_opcode_t op) } reg = (reg + 1) % 32; } + return true; } -void ppu_interpreter::STFDX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STFDX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; vm::_ref(vm::cast(addr, HERE)) = ppu.FPR[op.frs]; + return true; } -void ppu_interpreter::STFDUX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STFDUX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + ppu.GPR[op.rb]; vm::_ref(vm::cast(addr, HERE)) = ppu.FPR[op.frs]; ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::LVLXL(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LVLXL(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; const u32 eb = addr & 0xf; ppu.VR[op.vd].clear(); for (u32 i = 0; i < 16u - eb; ++i) ppu.VR[op.vd]._u8[15 - i] = vm::read8(vm::cast(addr + i, HERE)); + return true; } -void ppu_interpreter::LHBRX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LHBRX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; ppu.GPR[op.rd] = vm::_ref>(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::SRAW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::SRAW(PPUThread& ppu, ppu_opcode_t op) { s32 RS = (s32)ppu.GPR[op.rs]; u8 shift = ppu.GPR[op.rb] & 63; @@ -2838,9 +3147,10 @@ void ppu_interpreter::SRAW(PPUThread& ppu, ppu_opcode_t op) } if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::SRAD(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::SRAD(PPUThread& ppu, ppu_opcode_t op) { s64 RS = ppu.GPR[op.rs]; u8 shift = ppu.GPR[op.rb] & 127; @@ -2856,31 +3166,35 @@ void ppu_interpreter::SRAD(PPUThread& ppu, ppu_opcode_t op) } if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::LVRXL(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LVRXL(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; const u8 eb = addr & 0xf; ppu.VR[op.vd].clear(); for (u32 i = 16 - eb; i < 16; ++i) ppu.VR[op.vd]._u8[15 - i] = vm::read8(vm::cast(addr + i - 16, HERE)); + return true; } -void ppu_interpreter::DSS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::DSS(PPUThread& ppu, ppu_opcode_t op) { + return true; } -void ppu_interpreter::SRAWI(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::SRAWI(PPUThread& ppu, ppu_opcode_t op) { s32 RS = (u32)ppu.GPR[op.rs]; ppu.GPR[op.ra] = RS >> op.sh32; ppu.CA = (RS < 0) && ((u32)(ppu.GPR[op.ra] << op.sh32) != RS); if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::SRADI(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::SRADI(PPUThread& ppu, ppu_opcode_t op) { auto sh = op.sh64; s64 RS = ppu.GPR[op.rs]; @@ -2888,361 +3202,417 @@ void ppu_interpreter::SRADI(PPUThread& ppu, ppu_opcode_t op) ppu.CA = (RS < 0) && ((ppu.GPR[op.ra] << sh) != RS); if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::EIEIO(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::EIEIO(PPUThread& ppu, ppu_opcode_t op) { _mm_mfence(); + return true; } -void ppu_interpreter::STVLXL(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STVLXL(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; const u32 eb = addr & 0xf; for (u32 i = 0; i < 16u - eb; ++i) vm::write8(vm::cast(addr + i, HERE), ppu.VR[op.vs]._u8[15 - i]); + return true; } -void ppu_interpreter::STHBRX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STHBRX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; vm::_ref>(vm::cast(addr, HERE)) = (u16)ppu.GPR[op.rs]; + return true; } -void ppu_interpreter::EXTSH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::EXTSH(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = (s64)(s16)ppu.GPR[op.rs]; if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::STVRXL(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STVRXL(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; const u8 eb = addr & 0xf; for (u32 i = 16 - eb; i < 16; ++i) vm::write8(vm::cast(addr + i - 16, HERE), ppu.VR[op.vs]._u8[15 - i]); + return true; } -void ppu_interpreter::EXTSB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::EXTSB(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = (s64)(s8)ppu.GPR[op.rs]; if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::STFIWX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STFIWX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; vm::write32(vm::cast(addr, HERE), (u32&)ppu.FPR[op.frs]); + return true; } -void ppu_interpreter::EXTSW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::EXTSW(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = (s64)(s32)ppu.GPR[op.rs]; if (UNLIKELY(op.rc)) ppu.SetCR(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::ICBI(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::ICBI(PPUThread& ppu, ppu_opcode_t op) { + return true; } -void ppu_interpreter::DCBZ(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::DCBZ(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; std::memset(vm::base(vm::cast(addr, HERE) & ~127), 0, 128); + return true; } -void ppu_interpreter::LWZ(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LWZ(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + op.simm16 : op.simm16; ppu.GPR[op.rd] = vm::read32(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::LWZU(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LWZU(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + op.simm16; ppu.GPR[op.rd] = vm::read32(vm::cast(addr, HERE)); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::LBZ(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LBZ(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + op.simm16 : op.simm16; ppu.GPR[op.rd] = vm::read8(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::LBZU(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LBZU(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + op.simm16; ppu.GPR[op.rd] = vm::read8(vm::cast(addr, HERE)); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::STW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STW(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + op.simm16 : op.simm16; vm::write32(vm::cast(addr, HERE), (u32)ppu.GPR[op.rs]); + return true; } -void ppu_interpreter::STWU(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STWU(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + op.simm16; vm::write32(vm::cast(addr, HERE), (u32)ppu.GPR[op.rs]); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::STB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STB(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + op.simm16 : op.simm16; vm::write8(vm::cast(addr, HERE), (u8)ppu.GPR[op.rs]); + return true; } -void ppu_interpreter::STBU(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STBU(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + op.simm16; vm::write8(vm::cast(addr, HERE), (u8)ppu.GPR[op.rs]); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::LHZ(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LHZ(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + op.simm16 : op.simm16; ppu.GPR[op.rd] = vm::read16(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::LHZU(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LHZU(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + op.simm16; ppu.GPR[op.rd] = vm::read16(vm::cast(addr, HERE)); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::LHA(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LHA(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + op.simm16 : op.simm16; ppu.GPR[op.rd] = (s64)(s16)vm::read16(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::LHAU(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LHAU(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + op.simm16; ppu.GPR[op.rd] = (s64)(s16)vm::read16(vm::cast(addr, HERE)); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::STH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STH(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + op.simm16 : op.simm16; vm::write16(vm::cast(addr, HERE), (u16)ppu.GPR[op.rs]); + return true; } -void ppu_interpreter::STHU(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STHU(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + op.simm16; vm::write16(vm::cast(addr, HERE), (u16)ppu.GPR[op.rs]); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::LMW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LMW(PPUThread& ppu, ppu_opcode_t op) { u64 addr = op.ra ? ppu.GPR[op.ra] + op.simm16 : op.simm16; for (u32 i = op.rd; i<32; ++i, addr += 4) { ppu.GPR[i] = vm::read32(vm::cast(addr, HERE)); } + return true; } -void ppu_interpreter::STMW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STMW(PPUThread& ppu, ppu_opcode_t op) { u64 addr = op.ra ? ppu.GPR[op.ra] + op.simm16 : op.simm16; for (u32 i = op.rs; i<32; ++i, addr += 4) { vm::write32(vm::cast(addr, HERE), (u32)ppu.GPR[i]); } + return true; } -void ppu_interpreter::LFS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LFS(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + op.simm16 : op.simm16; ppu.FPR[op.frd] = vm::_ref(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::LFSU(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LFSU(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + op.simm16; ppu.FPR[op.frd] = vm::_ref(vm::cast(addr, HERE)); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::LFD(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LFD(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + op.simm16 : op.simm16; ppu.FPR[op.frd] = vm::_ref(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::LFDU(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LFDU(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + op.simm16; ppu.FPR[op.frd] = vm::_ref(vm::cast(addr, HERE)); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::STFS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STFS(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + op.simm16 : op.simm16; vm::_ref(vm::cast(addr, HERE)) = static_cast(ppu.FPR[op.frs]); + return true; } -void ppu_interpreter::STFSU(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STFSU(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + op.simm16; vm::_ref(vm::cast(addr, HERE)) = static_cast(ppu.FPR[op.frs]); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::STFD(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STFD(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + op.simm16 : op.simm16; vm::_ref(vm::cast(addr, HERE)) = ppu.FPR[op.frs]; + return true; } -void ppu_interpreter::STFDU(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STFDU(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + op.simm16; vm::_ref(vm::cast(addr, HERE)) = ppu.FPR[op.frs]; ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::LD(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LD(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = (op.simm16 & ~3) + (op.ra ? ppu.GPR[op.ra] : 0); ppu.GPR[op.rd] = vm::read64(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::LDU(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LDU(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + (op.simm16 & ~3); ppu.GPR[op.rd] = vm::read64(vm::cast(addr, HERE)); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::LWA(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LWA(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = (op.simm16 & ~3) + (op.ra ? ppu.GPR[op.ra] : 0); ppu.GPR[op.rd] = (s64)(s32)vm::read32(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::STD(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STD(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = (op.simm16 & ~3) + (op.ra ? ppu.GPR[op.ra] : 0); vm::write64(vm::cast(addr, HERE), ppu.GPR[op.rs]); + return true; } -void ppu_interpreter::STDU(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STDU(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + (op.simm16 & ~3); vm::write64(vm::cast(addr, HERE), ppu.GPR[op.rs]); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::FDIVS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FDIVS(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = f32(ppu.FPR[op.fra] / ppu.FPR[op.frb]); - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FSUBS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FSUBS(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = f32(ppu.FPR[op.fra] - ppu.FPR[op.frb]); - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FADDS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FADDS(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = f32(ppu.FPR[op.fra] + ppu.FPR[op.frb]); - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FSQRTS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FSQRTS(PPUThread& ppu, ppu_opcode_t op) { - ppu.FPR[op.frd] = f32(sqrt(ppu.FPR[op.frb])); - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + ppu.FPR[op.frd] = f32(std::sqrt(ppu.FPR[op.frb])); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FRES(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FRES(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = f32(1.0 / ppu.FPR[op.frb]); - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FMULS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FMULS(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = f32(ppu.FPR[op.fra] * ppu.FPR[op.frc]); - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FMADDS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FMADDS(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = f32(ppu.FPR[op.fra] * ppu.FPR[op.frc] + ppu.FPR[op.frb]); - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FMSUBS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FMSUBS(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = f32(ppu.FPR[op.fra] * ppu.FPR[op.frc] - ppu.FPR[op.frb]); - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FNMSUBS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FNMSUBS(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = f32(-(ppu.FPR[op.fra] * ppu.FPR[op.frc]) + ppu.FPR[op.frb]); - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FNMADDS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FNMADDS(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = f32(-(ppu.FPR[op.fra] * ppu.FPR[op.frc]) - ppu.FPR[op.frb]); - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::MTFSB1(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MTFSB1(PPUThread& ppu, ppu_opcode_t op) { LOG_WARNING(PPU, "MTFSB1"); if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::MCRFS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MCRFS(PPUThread& ppu, ppu_opcode_t op) { LOG_WARNING(PPU, "MCRFS"); ppu.SetCR(op.crfd, false, false, false, false); + return true; } -void ppu_interpreter::MTFSB0(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MTFSB0(PPUThread& ppu, ppu_opcode_t op) { LOG_WARNING(PPU, "MTFSB0"); if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::MTFSFI(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MTFSFI(PPUThread& ppu, ppu_opcode_t op) { LOG_WARNING(PPU, "MTFSFI"); if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::MFFS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MFFS(PPUThread& ppu, ppu_opcode_t op) { LOG_WARNING(PPU, "MFFS"); ppu.FPR[op.frd] = 0.0; if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::MTFSF(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MTFSF(PPUThread& ppu, ppu_opcode_t op) { LOG_WARNING(PPU, "MTFSF"); if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FCMPU(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FCMPU(PPUThread& ppu, ppu_opcode_t op) { const f64 a = ppu.FPR[op.fra]; const f64 b = ppu.FPR[op.frb]; @@ -3251,141 +3621,163 @@ void ppu_interpreter::FCMPU(PPUThread& ppu, ppu_opcode_t op) ppu.FE = a == b; //ppu.FU = a != a || b != b; ppu.SetCR(op.crfd, ppu.FL, ppu.FG, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FRSP(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FRSP(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = f32(ppu.FPR[op.frb]); - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FCTIW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FCTIW(PPUThread& ppu, ppu_opcode_t op) { - (s32&)ppu.FPR[op.frd] = lrint(ppu.FPR[op.frb]); - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + (s32&)ppu.FPR[op.frd] = std::lrint(ppu.FPR[op.frb]); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FCTIWZ(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FCTIWZ(PPUThread& ppu, ppu_opcode_t op) { (s32&)ppu.FPR[op.frd] = static_cast(ppu.FPR[op.frb]); - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FDIV(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FDIV(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = ppu.FPR[op.fra] / ppu.FPR[op.frb]; - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FSUB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FSUB(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = ppu.FPR[op.fra] - ppu.FPR[op.frb]; - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FADD(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FADD(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = ppu.FPR[op.fra] + ppu.FPR[op.frb]; - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FSQRT(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FSQRT(PPUThread& ppu, ppu_opcode_t op) { - ppu.FPR[op.frd] = sqrt(ppu.FPR[op.frb]); - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + ppu.FPR[op.frd] = std::sqrt(ppu.FPR[op.frb]); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FSEL(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FSEL(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = ppu.FPR[op.fra] >= 0.0 ? ppu.FPR[op.frc] : ppu.FPR[op.frb]; if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FMUL(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FMUL(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = ppu.FPR[op.fra] * ppu.FPR[op.frc]; - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FRSQRTE(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FRSQRTE(PPUThread& ppu, ppu_opcode_t op) { - ppu.FPR[op.frd] = 1.0 / sqrt(ppu.FPR[op.frb]); - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + ppu.FPR[op.frd] = 1.0 / std::sqrt(ppu.FPR[op.frb]); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FMSUB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FMSUB(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = ppu.FPR[op.fra] * ppu.FPR[op.frc] - ppu.FPR[op.frb]; - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FMADD(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FMADD(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = ppu.FPR[op.fra] * ppu.FPR[op.frc] + ppu.FPR[op.frb]; - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FNMSUB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FNMSUB(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = -(ppu.FPR[op.fra] * ppu.FPR[op.frc]) + ppu.FPR[op.frb]; - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FNMADD(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FNMADD(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = -(ppu.FPR[op.fra] * ppu.FPR[op.frc]) - ppu.FPR[op.frb]; - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FCMPO(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FCMPO(PPUThread& ppu, ppu_opcode_t op) { return FCMPU(ppu, op); + return true; } -void ppu_interpreter::FNEG(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FNEG(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = -ppu.FPR[op.frb]; if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FMR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FMR(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = ppu.FPR[op.frb]; if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FNABS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FNABS(PPUThread& ppu, ppu_opcode_t op) { - ppu.FPR[op.frd] = -fabs(ppu.FPR[op.frb]); + ppu.FPR[op.frd] = -std::fabs(ppu.FPR[op.frb]); if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FABS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FABS(PPUThread& ppu, ppu_opcode_t op) { - ppu.FPR[op.frd] = fabs(ppu.FPR[op.frb]); + ppu.FPR[op.frd] = std::fabs(ppu.FPR[op.frb]); if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FCTID(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FCTID(PPUThread& ppu, ppu_opcode_t op) { - (s64&)ppu.FPR[op.frd] = llrint(ppu.FPR[op.frb]); - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + (s64&)ppu.FPR[op.frd] = std::llrint(ppu.FPR[op.frb]); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FCTIDZ(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FCTIDZ(PPUThread& ppu, ppu_opcode_t op) { (s64&)ppu.FPR[op.frd] = static_cast(ppu.FPR[op.frb]); - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FCFID(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FCFID(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = static_cast((s64&)ppu.FPR[op.frb]); - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } - -void ppu_interpreter::UNK(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::UNK(PPUThread& ppu, ppu_opcode_t op) { throw fmt::exception("Unknown/Illegal opcode: 0x%08x" HERE, op.opcode); } diff --git a/rpcs3/Emu/Cell/PPUInterpreter.h b/rpcs3/Emu/Cell/PPUInterpreter.h index ddca283103..e1c54db3cc 100644 --- a/rpcs3/Emu/Cell/PPUInterpreter.h +++ b/rpcs3/Emu/Cell/PPUInterpreter.h @@ -4,392 +4,390 @@ class PPUThread; -using ppu_inter_func_t = void(*)(PPUThread& ppu, ppu_opcode_t op); - struct ppu_interpreter { - static void TDI(PPUThread&, ppu_opcode_t); - static void TWI(PPUThread&, ppu_opcode_t); - static void MFVSCR(PPUThread&, ppu_opcode_t); - static void MTVSCR(PPUThread&, ppu_opcode_t); - static void VADDCUW(PPUThread&, ppu_opcode_t); - static void VADDFP(PPUThread&, ppu_opcode_t); - static void VADDSBS(PPUThread&, ppu_opcode_t); - static void VADDSHS(PPUThread&, ppu_opcode_t); - static void VADDSWS(PPUThread&, ppu_opcode_t); - static void VADDUBM(PPUThread&, ppu_opcode_t); - static void VADDUBS(PPUThread&, ppu_opcode_t); - static void VADDUHM(PPUThread&, ppu_opcode_t); - static void VADDUHS(PPUThread&, ppu_opcode_t); - static void VADDUWM(PPUThread&, ppu_opcode_t); - static void VADDUWS(PPUThread&, ppu_opcode_t); - static void VAND(PPUThread&, ppu_opcode_t); - static void VANDC(PPUThread&, ppu_opcode_t); - static void VAVGSB(PPUThread&, ppu_opcode_t); - static void VAVGSH(PPUThread&, ppu_opcode_t); - static void VAVGSW(PPUThread&, ppu_opcode_t); - static void VAVGUB(PPUThread&, ppu_opcode_t); - static void VAVGUH(PPUThread&, ppu_opcode_t); - static void VAVGUW(PPUThread&, ppu_opcode_t); - static void VCFSX(PPUThread&, ppu_opcode_t); - static void VCFUX(PPUThread&, ppu_opcode_t); - static void VCMPBFP(PPUThread&, ppu_opcode_t); - static void VCMPEQFP(PPUThread&, ppu_opcode_t); - static void VCMPEQUB(PPUThread&, ppu_opcode_t); - static void VCMPEQUH(PPUThread&, ppu_opcode_t); - static void VCMPEQUW(PPUThread&, ppu_opcode_t); - static void VCMPGEFP(PPUThread&, ppu_opcode_t); - static void VCMPGTFP(PPUThread&, ppu_opcode_t); - static void VCMPGTSB(PPUThread&, ppu_opcode_t); - static void VCMPGTSH(PPUThread&, ppu_opcode_t); - static void VCMPGTSW(PPUThread&, ppu_opcode_t); - static void VCMPGTUB(PPUThread&, ppu_opcode_t); - static void VCMPGTUH(PPUThread&, ppu_opcode_t); - static void VCMPGTUW(PPUThread&, ppu_opcode_t); - static void VCTSXS(PPUThread&, ppu_opcode_t); - static void VCTUXS(PPUThread&, ppu_opcode_t); - static void VEXPTEFP(PPUThread&, ppu_opcode_t); - static void VLOGEFP(PPUThread&, ppu_opcode_t); - static void VMADDFP(PPUThread&, ppu_opcode_t); - static void VMAXFP(PPUThread&, ppu_opcode_t); - static void VMAXSB(PPUThread&, ppu_opcode_t); - static void VMAXSH(PPUThread&, ppu_opcode_t); - static void VMAXSW(PPUThread&, ppu_opcode_t); - static void VMAXUB(PPUThread&, ppu_opcode_t); - static void VMAXUH(PPUThread&, ppu_opcode_t); - static void VMAXUW(PPUThread&, ppu_opcode_t); - static void VMHADDSHS(PPUThread&, ppu_opcode_t); - static void VMHRADDSHS(PPUThread&, ppu_opcode_t); - static void VMINFP(PPUThread&, ppu_opcode_t); - static void VMINSB(PPUThread&, ppu_opcode_t); - static void VMINSH(PPUThread&, ppu_opcode_t); - static void VMINSW(PPUThread&, ppu_opcode_t); - static void VMINUB(PPUThread&, ppu_opcode_t); - static void VMINUH(PPUThread&, ppu_opcode_t); - static void VMINUW(PPUThread&, ppu_opcode_t); - static void VMLADDUHM(PPUThread&, ppu_opcode_t); - static void VMRGHB(PPUThread&, ppu_opcode_t); - static void VMRGHH(PPUThread&, ppu_opcode_t); - static void VMRGHW(PPUThread&, ppu_opcode_t); - static void VMRGLB(PPUThread&, ppu_opcode_t); - static void VMRGLH(PPUThread&, ppu_opcode_t); - static void VMRGLW(PPUThread&, ppu_opcode_t); - static void VMSUMMBM(PPUThread&, ppu_opcode_t); - static void VMSUMSHM(PPUThread&, ppu_opcode_t); - static void VMSUMSHS(PPUThread&, ppu_opcode_t); - static void VMSUMUBM(PPUThread&, ppu_opcode_t); - static void VMSUMUHM(PPUThread&, ppu_opcode_t); - static void VMSUMUHS(PPUThread&, ppu_opcode_t); - static void VMULESB(PPUThread&, ppu_opcode_t); - static void VMULESH(PPUThread&, ppu_opcode_t); - static void VMULEUB(PPUThread&, ppu_opcode_t); - static void VMULEUH(PPUThread&, ppu_opcode_t); - static void VMULOSB(PPUThread&, ppu_opcode_t); - static void VMULOSH(PPUThread&, ppu_opcode_t); - static void VMULOUB(PPUThread&, ppu_opcode_t); - static void VMULOUH(PPUThread&, ppu_opcode_t); - static void VNMSUBFP(PPUThread&, ppu_opcode_t); - static void VNOR(PPUThread&, ppu_opcode_t); - static void VOR(PPUThread&, ppu_opcode_t); - static void VPERM(PPUThread&, ppu_opcode_t); - static void VPKPX(PPUThread&, ppu_opcode_t); - static void VPKSHSS(PPUThread&, ppu_opcode_t); - static void VPKSHUS(PPUThread&, ppu_opcode_t); - static void VPKSWSS(PPUThread&, ppu_opcode_t); - static void VPKSWUS(PPUThread&, ppu_opcode_t); - static void VPKUHUM(PPUThread&, ppu_opcode_t); - static void VPKUHUS(PPUThread&, ppu_opcode_t); - static void VPKUWUM(PPUThread&, ppu_opcode_t); - static void VPKUWUS(PPUThread&, ppu_opcode_t); - static void VREFP(PPUThread&, ppu_opcode_t); - static void VRFIM(PPUThread&, ppu_opcode_t); - static void VRFIN(PPUThread&, ppu_opcode_t); - static void VRFIP(PPUThread&, ppu_opcode_t); - static void VRFIZ(PPUThread&, ppu_opcode_t); - static void VRLB(PPUThread&, ppu_opcode_t); - static void VRLH(PPUThread&, ppu_opcode_t); - static void VRLW(PPUThread&, ppu_opcode_t); - static void VRSQRTEFP(PPUThread&, ppu_opcode_t); - static void VSEL(PPUThread&, ppu_opcode_t); - static void VSL(PPUThread&, ppu_opcode_t); - static void VSLB(PPUThread&, ppu_opcode_t); - static void VSLDOI(PPUThread&, ppu_opcode_t); - static void VSLH(PPUThread&, ppu_opcode_t); - static void VSLO(PPUThread&, ppu_opcode_t); - static void VSLW(PPUThread&, ppu_opcode_t); - static void VSPLTB(PPUThread&, ppu_opcode_t); - static void VSPLTH(PPUThread&, ppu_opcode_t); - static void VSPLTISB(PPUThread&, ppu_opcode_t); - static void VSPLTISH(PPUThread&, ppu_opcode_t); - static void VSPLTISW(PPUThread&, ppu_opcode_t); - static void VSPLTW(PPUThread&, ppu_opcode_t); - static void VSR(PPUThread&, ppu_opcode_t); - static void VSRAB(PPUThread&, ppu_opcode_t); - static void VSRAH(PPUThread&, ppu_opcode_t); - static void VSRAW(PPUThread&, ppu_opcode_t); - static void VSRB(PPUThread&, ppu_opcode_t); - static void VSRH(PPUThread&, ppu_opcode_t); - static void VSRO(PPUThread&, ppu_opcode_t); - static void VSRW(PPUThread&, ppu_opcode_t); - static void VSUBCUW(PPUThread&, ppu_opcode_t); - static void VSUBFP(PPUThread&, ppu_opcode_t); - static void VSUBSBS(PPUThread&, ppu_opcode_t); - static void VSUBSHS(PPUThread&, ppu_opcode_t); - static void VSUBSWS(PPUThread&, ppu_opcode_t); - static void VSUBUBM(PPUThread&, ppu_opcode_t); - static void VSUBUBS(PPUThread&, ppu_opcode_t); - static void VSUBUHM(PPUThread&, ppu_opcode_t); - static void VSUBUHS(PPUThread&, ppu_opcode_t); - static void VSUBUWM(PPUThread&, ppu_opcode_t); - static void VSUBUWS(PPUThread&, ppu_opcode_t); - static void VSUMSWS(PPUThread&, ppu_opcode_t); - static void VSUM2SWS(PPUThread&, ppu_opcode_t); - static void VSUM4SBS(PPUThread&, ppu_opcode_t); - static void VSUM4SHS(PPUThread&, ppu_opcode_t); - static void VSUM4UBS(PPUThread&, ppu_opcode_t); - static void VUPKHPX(PPUThread&, ppu_opcode_t); - static void VUPKHSB(PPUThread&, ppu_opcode_t); - static void VUPKHSH(PPUThread&, ppu_opcode_t); - static void VUPKLPX(PPUThread&, ppu_opcode_t); - static void VUPKLSB(PPUThread&, ppu_opcode_t); - static void VUPKLSH(PPUThread&, ppu_opcode_t); - static void VXOR(PPUThread&, ppu_opcode_t); - static void MULLI(PPUThread&, ppu_opcode_t); - static void SUBFIC(PPUThread&, ppu_opcode_t); - static void CMPLI(PPUThread&, ppu_opcode_t); - static void CMPI(PPUThread&, ppu_opcode_t); - static void ADDIC(PPUThread&, ppu_opcode_t); - static void ADDI(PPUThread&, ppu_opcode_t); - static void ADDIS(PPUThread&, ppu_opcode_t); - static void BC(PPUThread&, ppu_opcode_t); - static void HACK(PPUThread&, ppu_opcode_t); - static void SC(PPUThread&, ppu_opcode_t); - static void B(PPUThread&, ppu_opcode_t); - static void MCRF(PPUThread&, ppu_opcode_t); - static void BCLR(PPUThread&, ppu_opcode_t); - static void CRNOR(PPUThread&, ppu_opcode_t); - static void CRANDC(PPUThread&, ppu_opcode_t); - static void ISYNC(PPUThread&, ppu_opcode_t); - static void CRXOR(PPUThread&, ppu_opcode_t); - static void CRNAND(PPUThread&, ppu_opcode_t); - static void CRAND(PPUThread&, ppu_opcode_t); - static void CREQV(PPUThread&, ppu_opcode_t); - static void CRORC(PPUThread&, ppu_opcode_t); - static void CROR(PPUThread&, ppu_opcode_t); - static void BCCTR(PPUThread&, ppu_opcode_t); - static void RLWIMI(PPUThread&, ppu_opcode_t); - static void RLWINM(PPUThread&, ppu_opcode_t); - static void RLWNM(PPUThread&, ppu_opcode_t); - static void ORI(PPUThread&, ppu_opcode_t); - static void ORIS(PPUThread&, ppu_opcode_t); - static void XORI(PPUThread&, ppu_opcode_t); - static void XORIS(PPUThread&, ppu_opcode_t); - static void ANDI(PPUThread&, ppu_opcode_t); - static void ANDIS(PPUThread&, ppu_opcode_t); - static void RLDICL(PPUThread&, ppu_opcode_t); - static void RLDICR(PPUThread&, ppu_opcode_t); - static void RLDIC(PPUThread&, ppu_opcode_t); - static void RLDIMI(PPUThread&, ppu_opcode_t); - static void RLDCL(PPUThread&, ppu_opcode_t); - static void RLDCR(PPUThread&, ppu_opcode_t); - static void CMP(PPUThread&, ppu_opcode_t); - static void TW(PPUThread&, ppu_opcode_t); - static void LVSL(PPUThread&, ppu_opcode_t); - static void LVEBX(PPUThread&, ppu_opcode_t); - static void SUBFC(PPUThread&, ppu_opcode_t); - static void MULHDU(PPUThread&, ppu_opcode_t); - static void ADDC(PPUThread&, ppu_opcode_t); - static void MULHWU(PPUThread&, ppu_opcode_t); - static void MFOCRF(PPUThread&, ppu_opcode_t); - static void LWARX(PPUThread&, ppu_opcode_t); - static void LDX(PPUThread&, ppu_opcode_t); - static void LWZX(PPUThread&, ppu_opcode_t); - static void SLW(PPUThread&, ppu_opcode_t); - static void CNTLZW(PPUThread&, ppu_opcode_t); - static void SLD(PPUThread&, ppu_opcode_t); - static void AND(PPUThread&, ppu_opcode_t); - static void CMPL(PPUThread&, ppu_opcode_t); - static void LVSR(PPUThread&, ppu_opcode_t); - static void LVEHX(PPUThread&, ppu_opcode_t); - static void SUBF(PPUThread&, ppu_opcode_t); - static void LDUX(PPUThread&, ppu_opcode_t); - static void DCBST(PPUThread&, ppu_opcode_t); - static void LWZUX(PPUThread&, ppu_opcode_t); - static void CNTLZD(PPUThread&, ppu_opcode_t); - static void ANDC(PPUThread&, ppu_opcode_t); - static void TD(PPUThread&, ppu_opcode_t); - static void LVEWX(PPUThread&, ppu_opcode_t); - static void MULHD(PPUThread&, ppu_opcode_t); - static void MULHW(PPUThread&, ppu_opcode_t); - static void LDARX(PPUThread&, ppu_opcode_t); - static void DCBF(PPUThread&, ppu_opcode_t); - static void LBZX(PPUThread&, ppu_opcode_t); - static void LVX(PPUThread&, ppu_opcode_t); - static void NEG(PPUThread&, ppu_opcode_t); - static void LBZUX(PPUThread&, ppu_opcode_t); - static void NOR(PPUThread&, ppu_opcode_t); - static void STVEBX(PPUThread&, ppu_opcode_t); - static void SUBFE(PPUThread&, ppu_opcode_t); - static void ADDE(PPUThread&, ppu_opcode_t); - static void MTOCRF(PPUThread&, ppu_opcode_t); - static void STDX(PPUThread&, ppu_opcode_t); - static void STWCX(PPUThread&, ppu_opcode_t); - static void STWX(PPUThread&, ppu_opcode_t); - static void STVEHX(PPUThread&, ppu_opcode_t); - static void STDUX(PPUThread&, ppu_opcode_t); - static void STWUX(PPUThread&, ppu_opcode_t); - static void STVEWX(PPUThread&, ppu_opcode_t); - static void SUBFZE(PPUThread&, ppu_opcode_t); - static void ADDZE(PPUThread&, ppu_opcode_t); - static void STDCX(PPUThread&, ppu_opcode_t); - static void STBX(PPUThread&, ppu_opcode_t); - static void STVX(PPUThread&, ppu_opcode_t); - static void MULLD(PPUThread&, ppu_opcode_t); - static void SUBFME(PPUThread&, ppu_opcode_t); - static void ADDME(PPUThread&, ppu_opcode_t); - static void MULLW(PPUThread&, ppu_opcode_t); - static void DCBTST(PPUThread&, ppu_opcode_t); - static void STBUX(PPUThread&, ppu_opcode_t); - static void ADD(PPUThread&, ppu_opcode_t); - static void DCBT(PPUThread&, ppu_opcode_t); - static void LHZX(PPUThread&, ppu_opcode_t); - static void EQV(PPUThread&, ppu_opcode_t); - static void ECIWX(PPUThread&, ppu_opcode_t); - static void LHZUX(PPUThread&, ppu_opcode_t); - static void XOR(PPUThread&, ppu_opcode_t); - static void MFSPR(PPUThread&, ppu_opcode_t); - static void LWAX(PPUThread&, ppu_opcode_t); - static void DST(PPUThread&, ppu_opcode_t); - static void LHAX(PPUThread&, ppu_opcode_t); - static void LVXL(PPUThread&, ppu_opcode_t); - static void MFTB(PPUThread&, ppu_opcode_t); - static void LWAUX(PPUThread&, ppu_opcode_t); - static void DSTST(PPUThread&, ppu_opcode_t); - static void LHAUX(PPUThread&, ppu_opcode_t); - static void STHX(PPUThread&, ppu_opcode_t); - static void ORC(PPUThread&, ppu_opcode_t); - static void ECOWX(PPUThread&, ppu_opcode_t); - static void STHUX(PPUThread&, ppu_opcode_t); - static void OR(PPUThread&, ppu_opcode_t); - static void DIVDU(PPUThread&, ppu_opcode_t); - static void DIVWU(PPUThread&, ppu_opcode_t); - static void MTSPR(PPUThread&, ppu_opcode_t); - static void DCBI(PPUThread&, ppu_opcode_t); - static void NAND(PPUThread&, ppu_opcode_t); - static void STVXL(PPUThread&, ppu_opcode_t); - static void DIVD(PPUThread&, ppu_opcode_t); - static void DIVW(PPUThread&, ppu_opcode_t); - static void LVLX(PPUThread&, ppu_opcode_t); - static void LDBRX(PPUThread&, ppu_opcode_t); - static void LSWX(PPUThread&, ppu_opcode_t); - static void LWBRX(PPUThread&, ppu_opcode_t); - static void LFSX(PPUThread&, ppu_opcode_t); - static void SRW(PPUThread&, ppu_opcode_t); - static void SRD(PPUThread&, ppu_opcode_t); - static void LVRX(PPUThread&, ppu_opcode_t); - static void LSWI(PPUThread&, ppu_opcode_t); - static void LFSUX(PPUThread&, ppu_opcode_t); - static void SYNC(PPUThread&, ppu_opcode_t); - static void LFDX(PPUThread&, ppu_opcode_t); - static void LFDUX(PPUThread&, ppu_opcode_t); - static void STVLX(PPUThread&, ppu_opcode_t); - static void STDBRX(PPUThread&, ppu_opcode_t); - static void STSWX(PPUThread&, ppu_opcode_t); - static void STWBRX(PPUThread&, ppu_opcode_t); - static void STFSX(PPUThread&, ppu_opcode_t); - static void STVRX(PPUThread&, ppu_opcode_t); - static void STFSUX(PPUThread&, ppu_opcode_t); - static void STSWI(PPUThread&, ppu_opcode_t); - static void STFDX(PPUThread&, ppu_opcode_t); - static void STFDUX(PPUThread&, ppu_opcode_t); - static void LVLXL(PPUThread&, ppu_opcode_t); - static void LHBRX(PPUThread&, ppu_opcode_t); - static void SRAW(PPUThread&, ppu_opcode_t); - static void SRAD(PPUThread&, ppu_opcode_t); - static void LVRXL(PPUThread&, ppu_opcode_t); - static void DSS(PPUThread&, ppu_opcode_t); - static void SRAWI(PPUThread&, ppu_opcode_t); - static void SRADI(PPUThread&, ppu_opcode_t); - static void EIEIO(PPUThread&, ppu_opcode_t); - static void STVLXL(PPUThread&, ppu_opcode_t); - static void STHBRX(PPUThread&, ppu_opcode_t); - static void EXTSH(PPUThread&, ppu_opcode_t); - static void STVRXL(PPUThread&, ppu_opcode_t); - static void EXTSB(PPUThread&, ppu_opcode_t); - static void STFIWX(PPUThread&, ppu_opcode_t); - static void EXTSW(PPUThread&, ppu_opcode_t); - static void ICBI(PPUThread&, ppu_opcode_t); - static void DCBZ(PPUThread&, ppu_opcode_t); - static void LWZ(PPUThread&, ppu_opcode_t); - static void LWZU(PPUThread&, ppu_opcode_t); - static void LBZ(PPUThread&, ppu_opcode_t); - static void LBZU(PPUThread&, ppu_opcode_t); - static void STW(PPUThread&, ppu_opcode_t); - static void STWU(PPUThread&, ppu_opcode_t); - static void STB(PPUThread&, ppu_opcode_t); - static void STBU(PPUThread&, ppu_opcode_t); - static void LHZ(PPUThread&, ppu_opcode_t); - static void LHZU(PPUThread&, ppu_opcode_t); - static void LHA(PPUThread&, ppu_opcode_t); - static void LHAU(PPUThread&, ppu_opcode_t); - static void STH(PPUThread&, ppu_opcode_t); - static void STHU(PPUThread&, ppu_opcode_t); - static void LMW(PPUThread&, ppu_opcode_t); - static void STMW(PPUThread&, ppu_opcode_t); - static void LFS(PPUThread&, ppu_opcode_t); - static void LFSU(PPUThread&, ppu_opcode_t); - static void LFD(PPUThread&, ppu_opcode_t); - static void LFDU(PPUThread&, ppu_opcode_t); - static void STFS(PPUThread&, ppu_opcode_t); - static void STFSU(PPUThread&, ppu_opcode_t); - static void STFD(PPUThread&, ppu_opcode_t); - static void STFDU(PPUThread&, ppu_opcode_t); - static void LD(PPUThread&, ppu_opcode_t); - static void LDU(PPUThread&, ppu_opcode_t); - static void LWA(PPUThread&, ppu_opcode_t); - static void FDIVS(PPUThread&, ppu_opcode_t); - static void FSUBS(PPUThread&, ppu_opcode_t); - static void FADDS(PPUThread&, ppu_opcode_t); - static void FSQRTS(PPUThread&, ppu_opcode_t); - static void FRES(PPUThread&, ppu_opcode_t); - static void FMULS(PPUThread&, ppu_opcode_t); - static void FMADDS(PPUThread&, ppu_opcode_t); - static void FMSUBS(PPUThread&, ppu_opcode_t); - static void FNMSUBS(PPUThread&, ppu_opcode_t); - static void FNMADDS(PPUThread&, ppu_opcode_t); - static void STD(PPUThread&, ppu_opcode_t); - static void STDU(PPUThread&, ppu_opcode_t); - static void MTFSB1(PPUThread&, ppu_opcode_t); - static void MCRFS(PPUThread&, ppu_opcode_t); - static void MTFSB0(PPUThread&, ppu_opcode_t); - static void MTFSFI(PPUThread&, ppu_opcode_t); - static void MFFS(PPUThread&, ppu_opcode_t); - static void MTFSF(PPUThread&, ppu_opcode_t); - static void FCMPU(PPUThread&, ppu_opcode_t); - static void FRSP(PPUThread&, ppu_opcode_t); - static void FCTIW(PPUThread&, ppu_opcode_t); - static void FCTIWZ(PPUThread&, ppu_opcode_t); - static void FDIV(PPUThread&, ppu_opcode_t); - static void FSUB(PPUThread&, ppu_opcode_t); - static void FADD(PPUThread&, ppu_opcode_t); - static void FSQRT(PPUThread&, ppu_opcode_t); - static void FSEL(PPUThread&, ppu_opcode_t); - static void FMUL(PPUThread&, ppu_opcode_t); - static void FRSQRTE(PPUThread&, ppu_opcode_t); - static void FMSUB(PPUThread&, ppu_opcode_t); - static void FMADD(PPUThread&, ppu_opcode_t); - static void FNMSUB(PPUThread&, ppu_opcode_t); - static void FNMADD(PPUThread&, ppu_opcode_t); - static void FCMPO(PPUThread&, ppu_opcode_t); - static void FNEG(PPUThread&, ppu_opcode_t); - static void FMR(PPUThread&, ppu_opcode_t); - static void FNABS(PPUThread&, ppu_opcode_t); - static void FABS(PPUThread&, ppu_opcode_t); - static void FCTID(PPUThread&, ppu_opcode_t); - static void FCTIDZ(PPUThread&, ppu_opcode_t); - static void FCFID(PPUThread&, ppu_opcode_t); + static bool MFVSCR(PPUThread&, ppu_opcode_t); + static bool MTVSCR(PPUThread&, ppu_opcode_t); + static bool VADDCUW(PPUThread&, ppu_opcode_t); + static bool VADDFP(PPUThread&, ppu_opcode_t); + static bool VADDSBS(PPUThread&, ppu_opcode_t); + static bool VADDSHS(PPUThread&, ppu_opcode_t); + static bool VADDSWS(PPUThread&, ppu_opcode_t); + static bool VADDUBM(PPUThread&, ppu_opcode_t); + static bool VADDUBS(PPUThread&, ppu_opcode_t); + static bool VADDUHM(PPUThread&, ppu_opcode_t); + static bool VADDUHS(PPUThread&, ppu_opcode_t); + static bool VADDUWM(PPUThread&, ppu_opcode_t); + static bool VADDUWS(PPUThread&, ppu_opcode_t); + static bool VAND(PPUThread&, ppu_opcode_t); + static bool VANDC(PPUThread&, ppu_opcode_t); + static bool VAVGSB(PPUThread&, ppu_opcode_t); + static bool VAVGSH(PPUThread&, ppu_opcode_t); + static bool VAVGSW(PPUThread&, ppu_opcode_t); + static bool VAVGUB(PPUThread&, ppu_opcode_t); + static bool VAVGUH(PPUThread&, ppu_opcode_t); + static bool VAVGUW(PPUThread&, ppu_opcode_t); + static bool VCFSX(PPUThread&, ppu_opcode_t); + static bool VCFUX(PPUThread&, ppu_opcode_t); + static bool VCMPBFP(PPUThread&, ppu_opcode_t); + static bool VCMPEQFP(PPUThread&, ppu_opcode_t); + static bool VCMPEQUB(PPUThread&, ppu_opcode_t); + static bool VCMPEQUH(PPUThread&, ppu_opcode_t); + static bool VCMPEQUW(PPUThread&, ppu_opcode_t); + static bool VCMPGEFP(PPUThread&, ppu_opcode_t); + static bool VCMPGTFP(PPUThread&, ppu_opcode_t); + static bool VCMPGTSB(PPUThread&, ppu_opcode_t); + static bool VCMPGTSH(PPUThread&, ppu_opcode_t); + static bool VCMPGTSW(PPUThread&, ppu_opcode_t); + static bool VCMPGTUB(PPUThread&, ppu_opcode_t); + static bool VCMPGTUH(PPUThread&, ppu_opcode_t); + static bool VCMPGTUW(PPUThread&, ppu_opcode_t); + static bool VCTSXS(PPUThread&, ppu_opcode_t); + static bool VCTUXS(PPUThread&, ppu_opcode_t); + static bool VEXPTEFP(PPUThread&, ppu_opcode_t); + static bool VLOGEFP(PPUThread&, ppu_opcode_t); + static bool VMADDFP(PPUThread&, ppu_opcode_t); + static bool VMAXFP(PPUThread&, ppu_opcode_t); + static bool VMAXSB(PPUThread&, ppu_opcode_t); + static bool VMAXSH(PPUThread&, ppu_opcode_t); + static bool VMAXSW(PPUThread&, ppu_opcode_t); + static bool VMAXUB(PPUThread&, ppu_opcode_t); + static bool VMAXUH(PPUThread&, ppu_opcode_t); + static bool VMAXUW(PPUThread&, ppu_opcode_t); + static bool VMHADDSHS(PPUThread&, ppu_opcode_t); + static bool VMHRADDSHS(PPUThread&, ppu_opcode_t); + static bool VMINFP(PPUThread&, ppu_opcode_t); + static bool VMINSB(PPUThread&, ppu_opcode_t); + static bool VMINSH(PPUThread&, ppu_opcode_t); + static bool VMINSW(PPUThread&, ppu_opcode_t); + static bool VMINUB(PPUThread&, ppu_opcode_t); + static bool VMINUH(PPUThread&, ppu_opcode_t); + static bool VMINUW(PPUThread&, ppu_opcode_t); + static bool VMLADDUHM(PPUThread&, ppu_opcode_t); + static bool VMRGHB(PPUThread&, ppu_opcode_t); + static bool VMRGHH(PPUThread&, ppu_opcode_t); + static bool VMRGHW(PPUThread&, ppu_opcode_t); + static bool VMRGLB(PPUThread&, ppu_opcode_t); + static bool VMRGLH(PPUThread&, ppu_opcode_t); + static bool VMRGLW(PPUThread&, ppu_opcode_t); + static bool VMSUMMBM(PPUThread&, ppu_opcode_t); + static bool VMSUMSHM(PPUThread&, ppu_opcode_t); + static bool VMSUMSHS(PPUThread&, ppu_opcode_t); + static bool VMSUMUBM(PPUThread&, ppu_opcode_t); + static bool VMSUMUHM(PPUThread&, ppu_opcode_t); + static bool VMSUMUHS(PPUThread&, ppu_opcode_t); + static bool VMULESB(PPUThread&, ppu_opcode_t); + static bool VMULESH(PPUThread&, ppu_opcode_t); + static bool VMULEUB(PPUThread&, ppu_opcode_t); + static bool VMULEUH(PPUThread&, ppu_opcode_t); + static bool VMULOSB(PPUThread&, ppu_opcode_t); + static bool VMULOSH(PPUThread&, ppu_opcode_t); + static bool VMULOUB(PPUThread&, ppu_opcode_t); + static bool VMULOUH(PPUThread&, ppu_opcode_t); + static bool VNMSUBFP(PPUThread&, ppu_opcode_t); + static bool VNOR(PPUThread&, ppu_opcode_t); + static bool VOR(PPUThread&, ppu_opcode_t); + static bool VPERM(PPUThread&, ppu_opcode_t); + static bool VPKPX(PPUThread&, ppu_opcode_t); + static bool VPKSHSS(PPUThread&, ppu_opcode_t); + static bool VPKSHUS(PPUThread&, ppu_opcode_t); + static bool VPKSWSS(PPUThread&, ppu_opcode_t); + static bool VPKSWUS(PPUThread&, ppu_opcode_t); + static bool VPKUHUM(PPUThread&, ppu_opcode_t); + static bool VPKUHUS(PPUThread&, ppu_opcode_t); + static bool VPKUWUM(PPUThread&, ppu_opcode_t); + static bool VPKUWUS(PPUThread&, ppu_opcode_t); + static bool VREFP(PPUThread&, ppu_opcode_t); + static bool VRFIM(PPUThread&, ppu_opcode_t); + static bool VRFIN(PPUThread&, ppu_opcode_t); + static bool VRFIP(PPUThread&, ppu_opcode_t); + static bool VRFIZ(PPUThread&, ppu_opcode_t); + static bool VRLB(PPUThread&, ppu_opcode_t); + static bool VRLH(PPUThread&, ppu_opcode_t); + static bool VRLW(PPUThread&, ppu_opcode_t); + static bool VRSQRTEFP(PPUThread&, ppu_opcode_t); + static bool VSEL(PPUThread&, ppu_opcode_t); + static bool VSL(PPUThread&, ppu_opcode_t); + static bool VSLB(PPUThread&, ppu_opcode_t); + static bool VSLDOI(PPUThread&, ppu_opcode_t); + static bool VSLH(PPUThread&, ppu_opcode_t); + static bool VSLO(PPUThread&, ppu_opcode_t); + static bool VSLW(PPUThread&, ppu_opcode_t); + static bool VSPLTB(PPUThread&, ppu_opcode_t); + static bool VSPLTH(PPUThread&, ppu_opcode_t); + static bool VSPLTISB(PPUThread&, ppu_opcode_t); + static bool VSPLTISH(PPUThread&, ppu_opcode_t); + static bool VSPLTISW(PPUThread&, ppu_opcode_t); + static bool VSPLTW(PPUThread&, ppu_opcode_t); + static bool VSR(PPUThread&, ppu_opcode_t); + static bool VSRAB(PPUThread&, ppu_opcode_t); + static bool VSRAH(PPUThread&, ppu_opcode_t); + static bool VSRAW(PPUThread&, ppu_opcode_t); + static bool VSRB(PPUThread&, ppu_opcode_t); + static bool VSRH(PPUThread&, ppu_opcode_t); + static bool VSRO(PPUThread&, ppu_opcode_t); + static bool VSRW(PPUThread&, ppu_opcode_t); + static bool VSUBCUW(PPUThread&, ppu_opcode_t); + static bool VSUBFP(PPUThread&, ppu_opcode_t); + static bool VSUBSBS(PPUThread&, ppu_opcode_t); + static bool VSUBSHS(PPUThread&, ppu_opcode_t); + static bool VSUBSWS(PPUThread&, ppu_opcode_t); + static bool VSUBUBM(PPUThread&, ppu_opcode_t); + static bool VSUBUBS(PPUThread&, ppu_opcode_t); + static bool VSUBUHM(PPUThread&, ppu_opcode_t); + static bool VSUBUHS(PPUThread&, ppu_opcode_t); + static bool VSUBUWM(PPUThread&, ppu_opcode_t); + static bool VSUBUWS(PPUThread&, ppu_opcode_t); + static bool VSUMSWS(PPUThread&, ppu_opcode_t); + static bool VSUM2SWS(PPUThread&, ppu_opcode_t); + static bool VSUM4SBS(PPUThread&, ppu_opcode_t); + static bool VSUM4SHS(PPUThread&, ppu_opcode_t); + static bool VSUM4UBS(PPUThread&, ppu_opcode_t); + static bool VUPKHPX(PPUThread&, ppu_opcode_t); + static bool VUPKHSB(PPUThread&, ppu_opcode_t); + static bool VUPKHSH(PPUThread&, ppu_opcode_t); + static bool VUPKLPX(PPUThread&, ppu_opcode_t); + static bool VUPKLSB(PPUThread&, ppu_opcode_t); + static bool VUPKLSH(PPUThread&, ppu_opcode_t); + static bool VXOR(PPUThread&, ppu_opcode_t); + static bool TDI(PPUThread&, ppu_opcode_t); + static bool TWI(PPUThread&, ppu_opcode_t); + static bool MULLI(PPUThread&, ppu_opcode_t); + static bool SUBFIC(PPUThread&, ppu_opcode_t); + static bool CMPLI(PPUThread&, ppu_opcode_t); + static bool CMPI(PPUThread&, ppu_opcode_t); + static bool ADDIC(PPUThread&, ppu_opcode_t); + static bool ADDI(PPUThread&, ppu_opcode_t); + static bool ADDIS(PPUThread&, ppu_opcode_t); + static bool BC(PPUThread&, ppu_opcode_t); + static bool HACK(PPUThread&, ppu_opcode_t); + static bool SC(PPUThread&, ppu_opcode_t); + static bool B(PPUThread&, ppu_opcode_t); + static bool MCRF(PPUThread&, ppu_opcode_t); + static bool BCLR(PPUThread&, ppu_opcode_t); + static bool CRNOR(PPUThread&, ppu_opcode_t); + static bool CRANDC(PPUThread&, ppu_opcode_t); + static bool ISYNC(PPUThread&, ppu_opcode_t); + static bool CRXOR(PPUThread&, ppu_opcode_t); + static bool CRNAND(PPUThread&, ppu_opcode_t); + static bool CRAND(PPUThread&, ppu_opcode_t); + static bool CREQV(PPUThread&, ppu_opcode_t); + static bool CRORC(PPUThread&, ppu_opcode_t); + static bool CROR(PPUThread&, ppu_opcode_t); + static bool BCCTR(PPUThread&, ppu_opcode_t); + static bool RLWIMI(PPUThread&, ppu_opcode_t); + static bool RLWINM(PPUThread&, ppu_opcode_t); + static bool RLWNM(PPUThread&, ppu_opcode_t); + static bool ORI(PPUThread&, ppu_opcode_t); + static bool ORIS(PPUThread&, ppu_opcode_t); + static bool XORI(PPUThread&, ppu_opcode_t); + static bool XORIS(PPUThread&, ppu_opcode_t); + static bool ANDI(PPUThread&, ppu_opcode_t); + static bool ANDIS(PPUThread&, ppu_opcode_t); + static bool RLDICL(PPUThread&, ppu_opcode_t); + static bool RLDICR(PPUThread&, ppu_opcode_t); + static bool RLDIC(PPUThread&, ppu_opcode_t); + static bool RLDIMI(PPUThread&, ppu_opcode_t); + static bool RLDCL(PPUThread&, ppu_opcode_t); + static bool RLDCR(PPUThread&, ppu_opcode_t); + static bool CMP(PPUThread&, ppu_opcode_t); + static bool TW(PPUThread&, ppu_opcode_t); + static bool LVSL(PPUThread&, ppu_opcode_t); + static bool LVEBX(PPUThread&, ppu_opcode_t); + static bool SUBFC(PPUThread&, ppu_opcode_t); + static bool MULHDU(PPUThread&, ppu_opcode_t); + static bool ADDC(PPUThread&, ppu_opcode_t); + static bool MULHWU(PPUThread&, ppu_opcode_t); + static bool MFOCRF(PPUThread&, ppu_opcode_t); + static bool LWARX(PPUThread&, ppu_opcode_t); + static bool LDX(PPUThread&, ppu_opcode_t); + static bool LWZX(PPUThread&, ppu_opcode_t); + static bool SLW(PPUThread&, ppu_opcode_t); + static bool CNTLZW(PPUThread&, ppu_opcode_t); + static bool SLD(PPUThread&, ppu_opcode_t); + static bool AND(PPUThread&, ppu_opcode_t); + static bool CMPL(PPUThread&, ppu_opcode_t); + static bool LVSR(PPUThread&, ppu_opcode_t); + static bool LVEHX(PPUThread&, ppu_opcode_t); + static bool SUBF(PPUThread&, ppu_opcode_t); + static bool LDUX(PPUThread&, ppu_opcode_t); + static bool DCBST(PPUThread&, ppu_opcode_t); + static bool LWZUX(PPUThread&, ppu_opcode_t); + static bool CNTLZD(PPUThread&, ppu_opcode_t); + static bool ANDC(PPUThread&, ppu_opcode_t); + static bool TD(PPUThread&, ppu_opcode_t); + static bool LVEWX(PPUThread&, ppu_opcode_t); + static bool MULHD(PPUThread&, ppu_opcode_t); + static bool MULHW(PPUThread&, ppu_opcode_t); + static bool LDARX(PPUThread&, ppu_opcode_t); + static bool DCBF(PPUThread&, ppu_opcode_t); + static bool LBZX(PPUThread&, ppu_opcode_t); + static bool LVX(PPUThread&, ppu_opcode_t); + static bool NEG(PPUThread&, ppu_opcode_t); + static bool LBZUX(PPUThread&, ppu_opcode_t); + static bool NOR(PPUThread&, ppu_opcode_t); + static bool STVEBX(PPUThread&, ppu_opcode_t); + static bool SUBFE(PPUThread&, ppu_opcode_t); + static bool ADDE(PPUThread&, ppu_opcode_t); + static bool MTOCRF(PPUThread&, ppu_opcode_t); + static bool STDX(PPUThread&, ppu_opcode_t); + static bool STWCX(PPUThread&, ppu_opcode_t); + static bool STWX(PPUThread&, ppu_opcode_t); + static bool STVEHX(PPUThread&, ppu_opcode_t); + static bool STDUX(PPUThread&, ppu_opcode_t); + static bool STWUX(PPUThread&, ppu_opcode_t); + static bool STVEWX(PPUThread&, ppu_opcode_t); + static bool SUBFZE(PPUThread&, ppu_opcode_t); + static bool ADDZE(PPUThread&, ppu_opcode_t); + static bool STDCX(PPUThread&, ppu_opcode_t); + static bool STBX(PPUThread&, ppu_opcode_t); + static bool STVX(PPUThread&, ppu_opcode_t); + static bool MULLD(PPUThread&, ppu_opcode_t); + static bool SUBFME(PPUThread&, ppu_opcode_t); + static bool ADDME(PPUThread&, ppu_opcode_t); + static bool MULLW(PPUThread&, ppu_opcode_t); + static bool DCBTST(PPUThread&, ppu_opcode_t); + static bool STBUX(PPUThread&, ppu_opcode_t); + static bool ADD(PPUThread&, ppu_opcode_t); + static bool DCBT(PPUThread&, ppu_opcode_t); + static bool LHZX(PPUThread&, ppu_opcode_t); + static bool EQV(PPUThread&, ppu_opcode_t); + static bool ECIWX(PPUThread&, ppu_opcode_t); + static bool LHZUX(PPUThread&, ppu_opcode_t); + static bool XOR(PPUThread&, ppu_opcode_t); + static bool MFSPR(PPUThread&, ppu_opcode_t); + static bool LWAX(PPUThread&, ppu_opcode_t); + static bool DST(PPUThread&, ppu_opcode_t); + static bool LHAX(PPUThread&, ppu_opcode_t); + static bool LVXL(PPUThread&, ppu_opcode_t); + static bool MFTB(PPUThread&, ppu_opcode_t); + static bool LWAUX(PPUThread&, ppu_opcode_t); + static bool DSTST(PPUThread&, ppu_opcode_t); + static bool LHAUX(PPUThread&, ppu_opcode_t); + static bool STHX(PPUThread&, ppu_opcode_t); + static bool ORC(PPUThread&, ppu_opcode_t); + static bool ECOWX(PPUThread&, ppu_opcode_t); + static bool STHUX(PPUThread&, ppu_opcode_t); + static bool OR(PPUThread&, ppu_opcode_t); + static bool DIVDU(PPUThread&, ppu_opcode_t); + static bool DIVWU(PPUThread&, ppu_opcode_t); + static bool MTSPR(PPUThread&, ppu_opcode_t); + static bool DCBI(PPUThread&, ppu_opcode_t); + static bool NAND(PPUThread&, ppu_opcode_t); + static bool STVXL(PPUThread&, ppu_opcode_t); + static bool DIVD(PPUThread&, ppu_opcode_t); + static bool DIVW(PPUThread&, ppu_opcode_t); + static bool LVLX(PPUThread&, ppu_opcode_t); + static bool LDBRX(PPUThread&, ppu_opcode_t); + static bool LSWX(PPUThread&, ppu_opcode_t); + static bool LWBRX(PPUThread&, ppu_opcode_t); + static bool LFSX(PPUThread&, ppu_opcode_t); + static bool SRW(PPUThread&, ppu_opcode_t); + static bool SRD(PPUThread&, ppu_opcode_t); + static bool LVRX(PPUThread&, ppu_opcode_t); + static bool LSWI(PPUThread&, ppu_opcode_t); + static bool LFSUX(PPUThread&, ppu_opcode_t); + static bool SYNC(PPUThread&, ppu_opcode_t); + static bool LFDX(PPUThread&, ppu_opcode_t); + static bool LFDUX(PPUThread&, ppu_opcode_t); + static bool STVLX(PPUThread&, ppu_opcode_t); + static bool STDBRX(PPUThread&, ppu_opcode_t); + static bool STSWX(PPUThread&, ppu_opcode_t); + static bool STWBRX(PPUThread&, ppu_opcode_t); + static bool STFSX(PPUThread&, ppu_opcode_t); + static bool STVRX(PPUThread&, ppu_opcode_t); + static bool STFSUX(PPUThread&, ppu_opcode_t); + static bool STSWI(PPUThread&, ppu_opcode_t); + static bool STFDX(PPUThread&, ppu_opcode_t); + static bool STFDUX(PPUThread&, ppu_opcode_t); + static bool LVLXL(PPUThread&, ppu_opcode_t); + static bool LHBRX(PPUThread&, ppu_opcode_t); + static bool SRAW(PPUThread&, ppu_opcode_t); + static bool SRAD(PPUThread&, ppu_opcode_t); + static bool LVRXL(PPUThread&, ppu_opcode_t); + static bool DSS(PPUThread&, ppu_opcode_t); + static bool SRAWI(PPUThread&, ppu_opcode_t); + static bool SRADI(PPUThread&, ppu_opcode_t); + static bool EIEIO(PPUThread&, ppu_opcode_t); + static bool STVLXL(PPUThread&, ppu_opcode_t); + static bool STHBRX(PPUThread&, ppu_opcode_t); + static bool EXTSH(PPUThread&, ppu_opcode_t); + static bool STVRXL(PPUThread&, ppu_opcode_t); + static bool EXTSB(PPUThread&, ppu_opcode_t); + static bool STFIWX(PPUThread&, ppu_opcode_t); + static bool EXTSW(PPUThread&, ppu_opcode_t); + static bool ICBI(PPUThread&, ppu_opcode_t); + static bool DCBZ(PPUThread&, ppu_opcode_t); + static bool LWZ(PPUThread&, ppu_opcode_t); + static bool LWZU(PPUThread&, ppu_opcode_t); + static bool LBZ(PPUThread&, ppu_opcode_t); + static bool LBZU(PPUThread&, ppu_opcode_t); + static bool STW(PPUThread&, ppu_opcode_t); + static bool STWU(PPUThread&, ppu_opcode_t); + static bool STB(PPUThread&, ppu_opcode_t); + static bool STBU(PPUThread&, ppu_opcode_t); + static bool LHZ(PPUThread&, ppu_opcode_t); + static bool LHZU(PPUThread&, ppu_opcode_t); + static bool LHA(PPUThread&, ppu_opcode_t); + static bool LHAU(PPUThread&, ppu_opcode_t); + static bool STH(PPUThread&, ppu_opcode_t); + static bool STHU(PPUThread&, ppu_opcode_t); + static bool LMW(PPUThread&, ppu_opcode_t); + static bool STMW(PPUThread&, ppu_opcode_t); + static bool LFS(PPUThread&, ppu_opcode_t); + static bool LFSU(PPUThread&, ppu_opcode_t); + static bool LFD(PPUThread&, ppu_opcode_t); + static bool LFDU(PPUThread&, ppu_opcode_t); + static bool STFS(PPUThread&, ppu_opcode_t); + static bool STFSU(PPUThread&, ppu_opcode_t); + static bool STFD(PPUThread&, ppu_opcode_t); + static bool STFDU(PPUThread&, ppu_opcode_t); + static bool LD(PPUThread&, ppu_opcode_t); + static bool LDU(PPUThread&, ppu_opcode_t); + static bool LWA(PPUThread&, ppu_opcode_t); + static bool STD(PPUThread&, ppu_opcode_t); + static bool STDU(PPUThread&, ppu_opcode_t); + static bool FDIVS(PPUThread&, ppu_opcode_t); + static bool FSUBS(PPUThread&, ppu_opcode_t); + static bool FADDS(PPUThread&, ppu_opcode_t); + static bool FSQRTS(PPUThread&, ppu_opcode_t); + static bool FRES(PPUThread&, ppu_opcode_t); + static bool FMULS(PPUThread&, ppu_opcode_t); + static bool FMADDS(PPUThread&, ppu_opcode_t); + static bool FMSUBS(PPUThread&, ppu_opcode_t); + static bool FNMSUBS(PPUThread&, ppu_opcode_t); + static bool FNMADDS(PPUThread&, ppu_opcode_t); + static bool MTFSB1(PPUThread&, ppu_opcode_t); + static bool MCRFS(PPUThread&, ppu_opcode_t); + static bool MTFSB0(PPUThread&, ppu_opcode_t); + static bool MTFSFI(PPUThread&, ppu_opcode_t); + static bool MFFS(PPUThread&, ppu_opcode_t); + static bool MTFSF(PPUThread&, ppu_opcode_t); + static bool FCMPU(PPUThread&, ppu_opcode_t); + static bool FRSP(PPUThread&, ppu_opcode_t); + static bool FCTIW(PPUThread&, ppu_opcode_t); + static bool FCTIWZ(PPUThread&, ppu_opcode_t); + static bool FDIV(PPUThread&, ppu_opcode_t); + static bool FSUB(PPUThread&, ppu_opcode_t); + static bool FADD(PPUThread&, ppu_opcode_t); + static bool FSQRT(PPUThread&, ppu_opcode_t); + static bool FSEL(PPUThread&, ppu_opcode_t); + static bool FMUL(PPUThread&, ppu_opcode_t); + static bool FRSQRTE(PPUThread&, ppu_opcode_t); + static bool FMSUB(PPUThread&, ppu_opcode_t); + static bool FMADD(PPUThread&, ppu_opcode_t); + static bool FNMSUB(PPUThread&, ppu_opcode_t); + static bool FNMADD(PPUThread&, ppu_opcode_t); + static bool FCMPO(PPUThread&, ppu_opcode_t); + static bool FNEG(PPUThread&, ppu_opcode_t); + static bool FMR(PPUThread&, ppu_opcode_t); + static bool FNABS(PPUThread&, ppu_opcode_t); + static bool FABS(PPUThread&, ppu_opcode_t); + static bool FCTID(PPUThread&, ppu_opcode_t); + static bool FCTIDZ(PPUThread&, ppu_opcode_t); + static bool FCFID(PPUThread&, ppu_opcode_t); - static void UNK(PPUThread&, ppu_opcode_t); + static bool UNK(PPUThread&, ppu_opcode_t); }; struct ppu_interpreter_precise final : ppu_interpreter diff --git a/rpcs3/Emu/Cell/PPUModule.cpp b/rpcs3/Emu/Cell/PPUModule.cpp index 56de5d7234..8bb313482a 100644 --- a/rpcs3/Emu/Cell/PPUModule.cpp +++ b/rpcs3/Emu/Cell/PPUModule.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Utilities/AutoPause.h" #include "Crypto/sha1.h" #include "Loader/ELF.h" @@ -10,6 +11,99 @@ #include "Emu/Cell/lv2/sys_prx.h" +#include + +LOG_CHANNEL(cellAdec); +LOG_CHANNEL(cellAtrac); +LOG_CHANNEL(cellAtracMulti); +LOG_CHANNEL(cellAudio); +LOG_CHANNEL(cellAvconfExt); +LOG_CHANNEL(cellBGDL); +LOG_CHANNEL(cellCamera); +LOG_CHANNEL(cellCelp8Enc); +LOG_CHANNEL(cellCelpEnc); +LOG_CHANNEL(cellDaisy); +LOG_CHANNEL(cellDmux); +LOG_CHANNEL(cellFiber); +LOG_CHANNEL(cellFont); +LOG_CHANNEL(cellFontFT); +LOG_CHANNEL(cellFs); +LOG_CHANNEL(cellGame); +LOG_CHANNEL(cellGameExec); +LOG_CHANNEL(cellGcmSys); +LOG_CHANNEL(cellGem); +LOG_CHANNEL(cellGifDec); +LOG_CHANNEL(cellHttp); +LOG_CHANNEL(cellHttpUtil); +LOG_CHANNEL(cellImeJp); +LOG_CHANNEL(cellJpgDec); +LOG_CHANNEL(cellJpgEnc); +LOG_CHANNEL(cellKey2char); +LOG_CHANNEL(cellL10n); +LOG_CHANNEL(cellMic); +LOG_CHANNEL(cellMusic); +LOG_CHANNEL(cellMusicDecode); +LOG_CHANNEL(cellMusicExport); +LOG_CHANNEL(cellNetCtl); +LOG_CHANNEL(cellOskDialog); +LOG_CHANNEL(cellOvis); +LOG_CHANNEL(cellPamf); +LOG_CHANNEL(cellPhotoDecode); +LOG_CHANNEL(cellPhotoExport); +LOG_CHANNEL(cellPhotoImportUtil); +LOG_CHANNEL(cellPngDec); +LOG_CHANNEL(cellPngEnc); +LOG_CHANNEL(cellPrint); +LOG_CHANNEL(cellRec); +LOG_CHANNEL(cellRemotePlay); +LOG_CHANNEL(cellResc); +LOG_CHANNEL(cellRtc); +LOG_CHANNEL(cellRudp); +LOG_CHANNEL(cellSail); +LOG_CHANNEL(cellSailRec); +LOG_CHANNEL(cellSaveData); +LOG_CHANNEL(cellScreenshot); +LOG_CHANNEL(cellSearch); +LOG_CHANNEL(cellSheap); +LOG_CHANNEL(cellSpudll); +LOG_CHANNEL(cellSpurs); +LOG_CHANNEL(cellSpursJq); +LOG_CHANNEL(cellSsl); +LOG_CHANNEL(cellSubdisplay); +LOG_CHANNEL(cellSync); +LOG_CHANNEL(cellSync2); +LOG_CHANNEL(cellSysconf); +LOG_CHANNEL(cellSysmodule); +LOG_CHANNEL(cellSysutil); +LOG_CHANNEL(cellSysutilAp); +LOG_CHANNEL(cellSysutilAvc); +LOG_CHANNEL(cellSysutilAvc2); +LOG_CHANNEL(cellSysutilMisc); +LOG_CHANNEL(cellUsbd); +LOG_CHANNEL(cellUsbPspcm); +LOG_CHANNEL(cellUserInfo); +LOG_CHANNEL(cellVdec); +LOG_CHANNEL(cellVideoExport); +LOG_CHANNEL(cellVideoUpload); +LOG_CHANNEL(cellVoice); +LOG_CHANNEL(cellVpost); +LOG_CHANNEL(libmixer); +LOG_CHANNEL(libsnd3); +LOG_CHANNEL(libsynth2); +LOG_CHANNEL(sceNp); +LOG_CHANNEL(sceNp2); +LOG_CHANNEL(sceNpClans); +LOG_CHANNEL(sceNpCommerce2); +LOG_CHANNEL(sceNpSns); +LOG_CHANNEL(sceNpTrophy); +LOG_CHANNEL(sceNpTus); +LOG_CHANNEL(sceNpUtil); +LOG_CHANNEL(sys_io); +LOG_CHANNEL(sys_libc); +LOG_CHANNEL(sys_lv2dbg); +LOG_CHANNEL(libnet); +LOG_CHANNEL(sysPrxForUser); + cfg::bool_entry g_cfg_hook_ppu_funcs(cfg::root.core, "Hook static functions"); cfg::bool_entry g_cfg_load_liblv2(cfg::root.core, "Load liblv2.sprx only"); @@ -41,12 +135,18 @@ extern void ppu_execute_function(PPUThread& ppu, u32 index) { func(ppu); } - catch (...) + catch (EmulationStopped) { LOG_WARNING(PPU, "Function '%s' aborted", ppu.last_function); ppu.last_function = previous_function; throw; } + catch (...) + { + LOG_ERROR(PPU, "Function '%s' aborted", ppu.last_function); + ppu.last_function = previous_function; + throw; + } LOG_TRACE(PPU, "Function '%s' finished, r3=0x%llx", ppu.last_function, ppu.GPR[3]); ppu.last_function = previous_function; @@ -917,7 +1017,7 @@ void ppu_exec_loader::load() const } else { - throw fmt::exception("Failed to load liblv2.sprx: %s", bijective_find(loader, "???")); + throw fmt::exception("Failed to load liblv2.sprx: %s", loader.get_error()); } } else @@ -939,7 +1039,7 @@ void ppu_exec_loader::load() const } else { - LOG_FATAL(LOADER, "Failed to load %s: %s", name, bijective_find(loader, "???")); + LOG_FATAL(LOADER, "Failed to load %s: %s", name, loader.get_error()); } } } @@ -1130,7 +1230,7 @@ void ppu_exec_loader::load() const auto ppu = idm::make_ptr("main_thread"); - ppu->PC = entry.addr() & -0x1000; + ppu->pc = entry.addr() & -0x1000; ppu->stack_size = Emu.GetPrimaryStackSize(); ppu->prio = Emu.GetPrimaryPrio(); ppu->cpu_init(); @@ -1166,6 +1266,8 @@ void ppu_exec_loader::load() const ppu->GPR[9] = Emu.GetTLSFilesz(); ppu->GPR[10] = Emu.GetTLSMemsz(); + //ppu->state += cpu_state::interrupt; + // Set memory protections //for (const auto& prog : progs) //{ @@ -1175,7 +1277,7 @@ void ppu_exec_loader::load() const // if (prog.p_type == 0x1 /* LOAD */ && prog.p_memsz && (prog.p_flags & 0x2) == 0 /* W */) // { // // Set memory protection to read-only where necessary - // ASSERT(vm::page_protect(addr, ::align(size, 0x1000), 0, 0, vm::page_writable)); + // VERIFY(vm::page_protect(addr, ::align(size, 0x1000), 0, 0, vm::page_writable)); // } //} } diff --git a/rpcs3/Emu/Cell/PPUModule.h b/rpcs3/Emu/Cell/PPUModule.h index 5b1438968f..957f8b6a38 100644 --- a/rpcs3/Emu/Cell/PPUModule.h +++ b/rpcs3/Emu/Cell/PPUModule.h @@ -1,6 +1,5 @@ #pragma once -#include "Utilities/Config.h" #include "PPUFunction.h" #include "PPUCallback.h" #include "ErrorCodes.h" @@ -207,15 +206,9 @@ inline RT ppu_execute_function_or_callback(const char* name, PPUThread& ppu, Arg { return Func(std::forward(args)...); } - catch (const std::exception&) - { - LOG_ERROR(PPU, "Function '%s' aborted", ppu.last_function); - ppu.last_function = previous_function; - throw; - } catch (...) { - LOG_WARNING(PPU, "Function '%s' aborted", ppu.last_function); + LOG_ERROR(PPU, "Function call '%s' aborted", ppu.last_function); ppu.last_function = previous_function; throw; } diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index c3ddecefce..4f7b33ba06 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -93,7 +94,7 @@ void PPUThread::cpu_task() { const auto cpu = static_cast(get_current_cpu_thread()); - return fmt::format("%s [0x%08x]", cpu->get_name(), cpu->PC); + return fmt::format("%s [0x%08x]", cpu->get_name(), cpu->pc); }; const auto base = vm::_ptr(0); @@ -104,45 +105,135 @@ void PPUThread::cpu_task() g_cfg_ppu_decoder.get() == ppu_decoder_type::fast ? &s_ppu_interpreter_fast.get_table() : throw std::logic_error("Invalid PPU decoder")); - u32 _pc{}; - u32 op0, op1, op2; - ppu_inter_func_t func0, func1, func2; + v128 _op; + decltype(&ppu_interpreter::UNK) func0, func1, func2, func3; while (true) { - if (LIKELY(_pc == PC && !state.load())) + if (UNLIKELY(state.load())) { - func0(*this, { op0 }); - - if (LIKELY((_pc += 4) == (PC += 4) && !state.load())) - { - func1(*this, { op1 }); - - if (LIKELY((_pc += 4) == (PC += 4))) - { - op0 = op2; - func0 = func2; - const auto ops = reinterpret_cast*>(base + _pc); - func1 = table[ppu_decode(op1 = ops[1])]; - func2 = table[ppu_decode(op2 = ops[2])]; - continue; - } - } + if (check_status()) return; } // Reinitialize - _pc = PC; - const auto ops = reinterpret_cast*>(base + _pc); - func0 = table[ppu_decode(op0 = ops[0])]; - func1 = table[ppu_decode(op1 = ops[1])]; - func2 = table[ppu_decode(op2 = ops[2])]; + { + const auto _ops = _mm_shuffle_epi8(_mm_lddqu_si128(reinterpret_cast(base + pc)), _mm_set_epi8(12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3)); + _op.vi = _ops; + const v128 _i = v128::fromV(_mm_and_si128(_mm_or_si128(_mm_slli_epi32(_op.vi, 6), _mm_srli_epi32(_op.vi, 26)), _mm_set1_epi32(0x1ffff))); + func0 = table[_i._u32[0]]; + func1 = table[_i._u32[1]]; + func2 = table[_i._u32[2]]; + func3 = table[_i._u32[3]]; + } - if (UNLIKELY(check_status())) return; + while (LIKELY(func0(*this, { _op._u32[0] }))) + { + if (pc += 4, LIKELY(func1(*this, { _op._u32[1] }))) + { + if (pc += 4, LIKELY(func2(*this, { _op._u32[2] }))) + { + pc += 4; + func0 = func3; + + const auto _ops = _mm_shuffle_epi8(_mm_lddqu_si128(reinterpret_cast(base + pc + 4)), _mm_set_epi8(12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3)); + _op.vi = _mm_alignr_epi8(_ops, _op.vi, 12); + const v128 _i = v128::fromV(_mm_and_si128(_mm_or_si128(_mm_slli_epi32(_op.vi, 6), _mm_srli_epi32(_op.vi, 26)), _mm_set1_epi32(0x1ffff))); + func1 = table[_i._u32[1]]; + func2 = table[_i._u32[2]]; + func3 = table[_i._u32[3]]; + + if (UNLIKELY(state.load())) + { + break; + } + continue; + } + break; + } + break; + } } } +constexpr auto stop_state = make_bitset(cpu_state::stop, cpu_state::exit, cpu_state::suspend); + +atomic_t g_ppu_core[2]{}; + bool PPUThread::handle_interrupt() { + // Reschedule and wake up a new thread, possibly this one as well. + return false; + + // Check virtual core allocation + if (g_ppu_core[0] != id && g_ppu_core[1] != id) + { + auto cpu0 = idm::get(g_ppu_core[0]); + auto cpu1 = idm::get(g_ppu_core[1]); + + if (cpu0 && cpu1) + { + if (cpu1->prio > cpu0->prio) + { + cpu0 = std::move(cpu1); + } + + // Preempt thread with the lowest priority + if (prio < cpu0->prio) + { + cpu0->state += cpu_state::interrupt; + } + } + else + { + // Try to obtain a virtual core in optimistic way + if (g_ppu_core[0].compare_and_swap_test(0, id) || g_ppu_core[1].compare_and_swap_test(0, id)) + { + state -= cpu_state::interrupt; + return true; + } + } + + return false; + } + + // Select appropriate thread + u32 top_prio = -1; + u32 selected = -1; + + idm::select([&](u32 id, PPUThread& ppu) + { + // Exclude suspended and low-priority threads + if (!ppu.state.test(stop_state) && ppu.prio < top_prio /*&& (!ppu.is_sleep() || ppu.state & cpu_state::signal)*/) + { + top_prio = ppu.prio; + selected = id; + } + }); + + // If current thread selected + if (selected == id) + { + state -= cpu_state::interrupt; + VERIFY(g_ppu_core[0] == id || g_ppu_core[1] == id); + return true; + } + + // If another thread selected + const auto thread = idm::get(selected); + + // Lend virtual core to another thread + if (thread && thread->state.test_and_reset(cpu_state::interrupt)) + { + g_ppu_core[0].compare_and_swap(id, thread->id); + g_ppu_core[1].compare_and_swap(id, thread->id); + (*thread)->lock_notify(); + } + else + { + g_ppu_core[0].compare_and_swap(id, 0); + g_ppu_core[1].compare_and_swap(id, 0); + } + return false; } @@ -167,13 +258,13 @@ be_t* PPUThread::get_stack_arg(s32 i, u64 align) void PPUThread::fast_call(u32 addr, u32 rtoc) { - auto old_PC = PC; + auto old_PC = pc; auto old_stack = GPR[1]; auto old_rtoc = GPR[2]; auto old_LR = LR; auto old_task = std::move(custom_task); - PC = addr; + pc = addr; GPR[2] = rtoc; LR = Emu.GetCPUThreadStop(); custom_task = nullptr; @@ -190,7 +281,7 @@ void PPUThread::fast_call(u32 addr, u32 rtoc) state -= cpu_state::ret; - PC = old_PC; + pc = old_PC; if (GPR[1] != old_stack) // GPR[1] shouldn't change { @@ -200,4 +291,10 @@ void PPUThread::fast_call(u32 addr, u32 rtoc) GPR[2] = old_rtoc; LR = old_LR; custom_task = std::move(old_task); + + //if (custom_task) + //{ + // state += cpu_state::interrupt; + // handle_interrupt(); + //} } diff --git a/rpcs3/Emu/Cell/PPUThread.h b/rpcs3/Emu/Cell/PPUThread.h index 8507f54c44..8307245196 100644 --- a/rpcs3/Emu/Cell/PPUThread.h +++ b/rpcs3/Emu/Cell/PPUThread.h @@ -66,9 +66,9 @@ public: u64 LR{}; // Link Register u64 CTR{}; // Counter Register u32 VRSAVE{}; - u32 PC{}; - s32 prio = 0; // Thread priority + u32 pc = 0; + u32 prio = -1; // Thread priority u32 stack_addr = 0; // Stack address u32 stack_size = 0; // Stack size bool is_joinable = true; @@ -191,7 +191,7 @@ struct ppu_gpr_cast_impl, void> static inline vm::_ptr_base from(const u64 reg) { - return{ ppu_gpr_cast_impl::from(reg), vm::addr }; + return vm::cast(ppu_gpr_cast_impl::from(reg)); } }; @@ -205,7 +205,7 @@ struct ppu_gpr_cast_impl, void> static inline vm::_ref_base from(const u64 reg) { - return{ ppu_gpr_cast_impl::from(reg), vm::addr }; + return vm::cast(ppu_gpr_cast_impl::from(reg)); } }; diff --git a/rpcs3/Emu/Cell/RawSPUThread.cpp b/rpcs3/Emu/Cell/RawSPUThread.cpp index 60033cfa2f..808c0a2900 100644 --- a/rpcs3/Emu/Cell/RawSPUThread.cpp +++ b/rpcs3/Emu/Cell/RawSPUThread.cpp @@ -31,7 +31,7 @@ void RawSPUThread::on_init() // Install correct SPU index and LS address const_cast(index) = id; const_cast(offset) = vm::falloc(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * index, 0x40000); - ASSERT(offset); + VERIFY(offset); SPUThread::on_init(); } @@ -101,7 +101,7 @@ bool RawSPUThread::write_reg(const u32 addr, const u32 value) })) { state -= cpu_state::stop; - lock_notify(); + (*this)->lock_notify(); } }; diff --git a/rpcs3/Emu/Cell/SPUASMJITRecompiler.cpp b/rpcs3/Emu/Cell/SPUASMJITRecompiler.cpp index 8ac7256513..35dec7108a 100644 --- a/rpcs3/Emu/Cell/SPUASMJITRecompiler.cpp +++ b/rpcs3/Emu/Cell/SPUASMJITRecompiler.cpp @@ -7,6 +7,8 @@ #include "SPUInterpreter.h" #include "SPUASMJITRecompiler.h" +#include + #define ASMJIT_STATIC #define ASMJIT_DEBUG @@ -1962,8 +1964,8 @@ void spu_recompiler::CFLTS(spu_opcode_t op) { const XmmLink& va = XmmGet(op.ra, XmmType::Float); const XmmLink& vi = XmmAlloc(); - if (op.i8 != 173) c->mulps(va, XmmConst(_mm_set1_ps(exp2f(static_cast(173 - op.i8))))); // scale - c->movaps(vi, XmmConst(_mm_set1_ps(exp2f(31)))); + if (op.i8 != 173) c->mulps(va, XmmConst(_mm_set1_ps(std::exp2(static_cast(static_cast(173 - op.i8)))))); // scale + c->movaps(vi, XmmConst(_mm_set1_ps(std::exp2(31.f)))); c->cmpps(vi, va, 2); c->cvttps2dq(va, va); // convert to ints with truncation c->pxor(va, vi); // fix result saturation (0x80000000 -> 0x7fffffff) @@ -1976,16 +1978,16 @@ void spu_recompiler::CFLTU(spu_opcode_t op) const XmmLink& vs = XmmAlloc(); const XmmLink& vs2 = XmmAlloc(); const XmmLink& vs3 = XmmAlloc(); - if (op.i8 != 173) c->mulps(va, XmmConst(_mm_set1_ps(exp2f(static_cast(173 - op.i8))))); // scale + if (op.i8 != 173) c->mulps(va, XmmConst(_mm_set1_ps(std::exp2(static_cast(static_cast(173 - op.i8)))))); // scale c->maxps(va, XmmConst(_mm_set1_ps(0.0f))); // saturate c->movaps(vs, va); // copy scaled value c->movaps(vs2, va); - c->movaps(vs3, XmmConst(_mm_set1_ps(exp2f(31)))); + c->movaps(vs3, XmmConst(_mm_set1_ps(std::exp2(31.f)))); c->subps(vs2, vs3); c->cmpps(vs3, vs, 2); c->andps(vs2, vs3); c->cvttps2dq(va, va); - c->cmpps(vs, XmmConst(_mm_set1_ps(exp2f(32))), 5); + c->cmpps(vs, XmmConst(_mm_set1_ps(std::exp2(32.f))), 5); c->cvttps2dq(vs2, vs2); c->por(va, vs); c->por(va, vs2); @@ -1996,7 +1998,7 @@ void spu_recompiler::CSFLT(spu_opcode_t op) { const XmmLink& va = XmmGet(op.ra, XmmType::Int); c->cvtdq2ps(va, va); // convert to floats - if (op.i8 != 155) c->mulps(va, XmmConst(_mm_set1_ps(exp2f(static_cast(op.i8 - 155))))); // scale + if (op.i8 != 155) c->mulps(va, XmmConst(_mm_set1_ps(std::exp2(static_cast(static_cast(op.i8 - 155)))))); // scale c->movaps(SPU_OFF_128(gpr[op.rt]), va); } @@ -2008,9 +2010,9 @@ void spu_recompiler::CUFLT(spu_opcode_t op) c->pand(va, XmmConst(_mm_set1_epi32(0x7fffffff))); c->cvtdq2ps(va, va); // convert to floats c->psrad(v1, 31); // generate mask from sign bit - c->andps(v1, XmmConst(_mm_set1_ps(exp2f(31)))); // generate correction component + c->andps(v1, XmmConst(_mm_set1_ps(std::exp2(31.f)))); // generate correction component c->addps(va, v1); // add correction component - if (op.i8 != 155) c->mulps(va, XmmConst(_mm_set1_ps(exp2f(static_cast(op.i8 - 155))))); // scale + if (op.i8 != 155) c->mulps(va, XmmConst(_mm_set1_ps(std::exp2(static_cast(static_cast(op.i8 - 155)))))); // scale c->movaps(SPU_OFF_128(gpr[op.rt]), va); } diff --git a/rpcs3/Emu/Cell/SPUInterpreter.cpp b/rpcs3/Emu/Cell/SPUInterpreter.cpp index 217f35728c..139c91319f 100644 --- a/rpcs3/Emu/Cell/SPUInterpreter.cpp +++ b/rpcs3/Emu/Cell/SPUInterpreter.cpp @@ -5,7 +5,8 @@ #include "SPUThread.h" #include "SPUInterpreter.h" -#include +#include +#include // Compare 16 packed unsigned bytes (greater than) inline __m128i sse_cmpgt_epu8(__m128i A, __m128i B) @@ -942,8 +943,8 @@ void spu_interpreter_fast::FI(SPUThread& spu, spu_opcode_t op) const auto mask_sf = _mm_set1_epi32(0x000003ff); // step fraction mask const auto mask_yf = _mm_set1_epi32(0x0007ffff); // Y fraction mask (bits 13..31) const auto base = _mm_or_ps(_mm_and_ps(spu.gpr[op.rb].vf, mask_bf), _mm_castsi128_ps(_mm_set1_epi32(0x3f800000))); - const auto step = _mm_mul_ps(_mm_cvtepi32_ps(_mm_and_si128(spu.gpr[op.rb].vi, mask_sf)), _mm_set1_ps(exp2f(-13))); - const auto y = _mm_mul_ps(_mm_cvtepi32_ps(_mm_and_si128(spu.gpr[op.ra].vi, mask_yf)), _mm_set1_ps(exp2f(-19))); + const auto step = _mm_mul_ps(_mm_cvtepi32_ps(_mm_and_si128(spu.gpr[op.rb].vi, mask_sf)), _mm_set1_ps(std::exp2(-13.f))); + const auto y = _mm_mul_ps(_mm_cvtepi32_ps(_mm_and_si128(spu.gpr[op.ra].vi, mask_yf)), _mm_set1_ps(std::exp2(-19.f))); spu.gpr[op.rt].vf = _mm_or_ps(_mm_and_ps(mask_se, spu.gpr[op.rb].vf), _mm_andnot_ps(mask_se, _mm_sub_ps(base, _mm_mul_ps(step, y)))); } @@ -1409,9 +1410,9 @@ void spu_interpreter_precise::FRSQEST(SPUThread& spu, spu_opcode_t op) result = extended(0, 0x7FFFFF); } else if (isextended(a)) - result = 0.5f / sqrtf(fabsf(ldexpf_extended(a, -2))); + result = 0.5f / std::sqrt(std::fabs(ldexpf_extended(a, -2))); else - result = 1 / sqrtf(fabsf(a)); + result = 1 / std::sqrt(std::fabs(a)); spu.gpr[op.rt]._f[i] = result; } } @@ -1502,9 +1503,9 @@ static void FA_FS(SPUThread& spu, spu_opcode_t op, bool sub) else { result = a + b; - if (result == copysignf(FLOAT_MAX_NORMAL, result)) + if (result == std::copysign(FLOAT_MAX_NORMAL, result)) { - result = ldexpf_extended(ldexpf(a, -1) + ldexpf(b, -1), 1); + result = ldexpf_extended(std::ldexp(a, -1) + std::ldexp(b, -1), 1); if (isextended(result)) spu.fpscr.setSinglePrecisionExceptionFlags(w, FPSCR_SDIFF); } @@ -1515,7 +1516,7 @@ static void FA_FS(SPUThread& spu, spu_opcode_t op, bool sub) } else if (result == 0.0f) { - if (fabsf(a) != fabsf(b)) + if (std::fabs(a) != std::fabs(b)) spu.fpscr.setSinglePrecisionExceptionFlags(w, FPSCR_SUNF | FPSCR_SDIFF); result = +0.0f; } @@ -1560,7 +1561,7 @@ void spu_interpreter_precise::FM(SPUThread& spu, spu_opcode_t op) result = ldexpf_extended(a, -1) * b; else result = a * ldexpf_extended(b, -1); - if (result == copysignf(FLOAT_MAX_NORMAL, result)) + if (result == std::copysign(FLOAT_MAX_NORMAL, result)) { spu.fpscr.setSinglePrecisionExceptionFlags(w, FPSCR_SOVF); result = extended(sign, 0x7FFFFF); @@ -1572,13 +1573,13 @@ void spu_interpreter_precise::FM(SPUThread& spu, spu_opcode_t op) else { result = a * b; - if (result == copysignf(FLOAT_MAX_NORMAL, result)) + if (result == std::copysign(FLOAT_MAX_NORMAL, result)) { feclearexcept(FE_ALL_EXCEPT); if (fexpf(a) > fexpf(b)) - result = ldexpf(a, -1) * b; + result = std::ldexp(a, -1) * b; else - result = a * ldexpf(b, -1); + result = a * std::ldexp(b, -1); result = ldexpf_extended(result, 1); if (isextended(result)) spu.fpscr.setSinglePrecisionExceptionFlags(w, FPSCR_SDIFF); @@ -1638,12 +1639,12 @@ static void DFASM(SPUThread& spu, spu_opcode_t op, DoubleOp operation) if (isdenormal(a)) { spu.fpscr.setDoublePrecisionExceptionFlags(i, FPSCR_DDENORM); - a = copysign(0.0, a); + a = std::copysign(0.0, a); } if (isdenormal(b)) { spu.fpscr.setDoublePrecisionExceptionFlags(i, FPSCR_DDENORM); - b = copysign(0.0, b); + b = std::copysign(0.0, b); } double result; if (std::isnan(a) || std::isnan(b)) @@ -1698,17 +1699,17 @@ static void DFMA(SPUThread& spu, spu_opcode_t op, bool neg, bool sub) if (isdenormal(a)) { spu.fpscr.setDoublePrecisionExceptionFlags(i, FPSCR_DDENORM); - a = copysign(0.0, a); + a = std::copysign(0.0, a); } if (isdenormal(b)) { spu.fpscr.setDoublePrecisionExceptionFlags(i, FPSCR_DDENORM); - b = copysign(0.0, b); + b = std::copysign(0.0, b); } if (isdenormal(c)) { spu.fpscr.setDoublePrecisionExceptionFlags(i, FPSCR_DDENORM); - c = copysign(0.0, c); + c = std::copysign(0.0, c); } double result; if (std::isnan(a) || std::isnan(b) || std::isnan(c)) @@ -1857,9 +1858,9 @@ void spu_interpreter_precise::CFLTS(SPUThread& spu, spu_opcode_t op) const float a = spu.gpr[op.ra]._f[i]; float scaled; if ((fexpf(a) - 127) + scale >= 32) - scaled = copysignf(4294967296.0f, a); + scaled = std::copysign(4294967296.0f, a); else - scaled = ldexpf(a, scale); + scaled = std::ldexp(a, scale); s32 result; if (scaled >= 2147483648.0f) result = 0x7FFFFFFF; @@ -1879,9 +1880,9 @@ void spu_interpreter_precise::CFLTU(SPUThread& spu, spu_opcode_t op) const float a = spu.gpr[op.ra]._f[i]; float scaled; if ((fexpf(a) - 127) + scale >= 32) - scaled = copysignf(4294967296.0f, a); + scaled = std::copysign(4294967296.0f, a); else - scaled = ldexpf(a, scale); + scaled = std::ldexp(a, scale); u32 result; if (scaled >= 4294967296.0f) result = 0xFFFFFFFF; @@ -2002,9 +2003,9 @@ static void FMA(SPUThread& spu, spu_opcode_t op, bool neg, bool sub) } else { - result = fmaf(new_a, new_b, ldexpf_extended(c, -2)); + result = std::fma(new_a, new_b, ldexpf_extended(c, -2)); } - if (fabsf(result) >= ldexpf(1.0f, 127)) + if (std::fabs(result) >= std::ldexp(1.0f, 127)) { spu.fpscr.setSinglePrecisionExceptionFlags(w, FPSCR_SOVF); result = extended(sign, 0x7FFFFF); @@ -2033,8 +2034,8 @@ static void FMA(SPUThread& spu, spu_opcode_t op, bool neg, bool sub) } else { - result = fmaf(ldexpf(a, -1), ldexpf(b, -1), ldexpf_extended(c, -2)); - if (fabsf(result) >= ldexpf(1.0f, 127)) + result = std::fma(std::ldexp(a, -1), std::ldexp(b, -1), ldexpf_extended(c, -2)); + if (std::fabs(result) >= std::ldexp(1.0f, 127)) { spu.fpscr.setSinglePrecisionExceptionFlags(w, FPSCR_SOVF); result = extended(sign, 0x7FFFFF); @@ -2048,15 +2049,15 @@ static void FMA(SPUThread& spu, spu_opcode_t op, bool neg, bool sub) else { feclearexcept(FE_ALL_EXCEPT); - result = fmaf(a, b, c); + result = std::fma(a, b, c); if (fetestexcept(FE_OVERFLOW)) { spu.fpscr.setSinglePrecisionExceptionFlags(w, FPSCR_SDIFF); if (fexpf(a) > fexpf(b)) - result = fmaf(ldexpf(a, -2), b, ldexpf(c, -2)); + result = std::fma(std::ldexp(a, -2), b, std::ldexp(c, -2)); else - result = fmaf(a, ldexpf(b, -2), ldexpf(c, -2)); - if (fabsf(result) >= ldexpf(1.0f, 127)) + result = std::fma(a, std::ldexp(b, -2), std::ldexp(c, -2)); + if (fabsf(result) >= std::ldexp(1.0f, 127)) { spu.fpscr.setSinglePrecisionExceptionFlags(w, FPSCR_SOVF); result = extended(sign, 0x7FFFFF); diff --git a/rpcs3/Emu/Cell/SPURecompiler.h b/rpcs3/Emu/Cell/SPURecompiler.h index ed9b9aae64..355bde4bd5 100644 --- a/rpcs3/Emu/Cell/SPURecompiler.h +++ b/rpcs3/Emu/Cell/SPURecompiler.h @@ -2,6 +2,8 @@ #include "SPUAnalyser.h" +#include + // SPU Recompiler instance base (must be global or PS3 process-local) class spu_recompiler_base { diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index 9ec1cd4643..b339abedf5 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -18,10 +18,14 @@ #include "Emu/Memory/wait_engine.h" +#include #include +#include extern u64 get_timebased_time(); +extern std::mutex& get_current_thread_mutex(); + enum class spu_decoder_type { precise, @@ -54,13 +58,72 @@ void spu_int_ctrl_t::set(u64 ints) if (tag && tag->handler) { tag->handler->signal++; - tag->handler->thread->notify(); + (*tag->handler->thread)->notify(); } } } const spu_imm_table_t g_spu_imm; +spu_imm_table_t::scale_table_t::scale_table_t() +{ + for (s32 i = -155; i < 174; i++) + { + m_data[i + 155] = _mm_set1_ps(static_cast(std::exp2(i))); + } +} + +spu_imm_table_t::spu_imm_table_t() +{ + for (u32 i = 0; i < sizeof(fsm) / sizeof(fsm[0]); i++) + { + for (u32 j = 0; j < 4; j++) + { + fsm[i]._u32[j] = (i & (1 << j)) ? 0xffffffff : 0; + } + } + + for (u32 i = 0; i < sizeof(fsmh) / sizeof(fsmh[0]); i++) + { + for (u32 j = 0; j < 8; j++) + { + fsmh[i]._u16[j] = (i & (1 << j)) ? 0xffff : 0; + } + } + + for (u32 i = 0; i < sizeof(fsmb) / sizeof(fsmb[0]); i++) + { + for (u32 j = 0; j < 16; j++) + { + fsmb[i]._u8[j] = (i & (1 << j)) ? 0xff : 0; + } + } + + for (u32 i = 0; i < sizeof(sldq_pshufb) / sizeof(sldq_pshufb[0]); i++) + { + for (u32 j = 0; j < 16; j++) + { + sldq_pshufb[i]._u8[j] = static_cast(j - i); + } + } + + for (u32 i = 0; i < sizeof(srdq_pshufb) / sizeof(srdq_pshufb[0]); i++) + { + for (u32 j = 0; j < 16; j++) + { + srdq_pshufb[i]._u8[j] = (j + i > 15) ? 0xff : static_cast(j + i); + } + } + + for (u32 i = 0; i < sizeof(rldq_pshufb) / sizeof(rldq_pshufb[0]); i++) + { + for (u32 j = 0; j < 16; j++) + { + rldq_pshufb[i]._u8[j] = static_cast((j - i) & 0xf); + } + } +} + std::string SPUThread::get_name() const { return fmt::format("%sSPU[0x%x] Thread (%s)", offset > RAW_SPU_BASE_ADDR ? "Raw" : "", id, name); @@ -188,7 +251,7 @@ SPUThread::SPUThread(const std::string& name, u32 index) , index(index) , offset(vm::alloc(0x40000, vm::main)) { - Ensures(offset); + ENSURES(offset); } void SPUThread::push_snr(u32 number, u32 value) @@ -477,18 +540,13 @@ void SPUThread::set_events(u32 mask) throw EXCEPTION("Unimplemented events (0x%x)", unimpl); } - // set new events, get old event mask + // Set new events, get old event mask const u32 old_stat = ch_event_stat.fetch_or(mask); - // notify if some events were set - if (~old_stat & mask && old_stat & SPU_EVENT_WAITING) + // Notify if some events were set + if (~old_stat & mask && old_stat & SPU_EVENT_WAITING && ch_event_stat & SPU_EVENT_WAITING) { - std::lock_guard lock(get_current_thread_mutex()); - - if (ch_event_stat & SPU_EVENT_WAITING) - { - notify(); - } + (*this)->lock_notify(); } } @@ -540,30 +598,14 @@ bool SPUThread::get_ch_value(u32 ch, u32& out) auto read_channel = [&](spu_channel_t& channel) { - std::unique_lock lock(get_current_thread_mutex(), std::defer_lock); - - while (true) + if (!channel.try_pop(out)) { - if (channel.try_pop(out)) - { - return true; - } + cpu_thread_lock{*this}, thread_ctrl::wait(WRAP_EXPR(state & cpu_state::stop || channel.try_pop(out))); - CHECK_EMU_STATUS; - - if (state & cpu_state::stop) - { - return false; - } - - if (!lock) - { - lock.lock(); - continue; - } - - get_current_thread_cv().wait(lock); + return !state.test(cpu_state::stop); } + + return true; }; switch (ch) @@ -1103,7 +1145,7 @@ bool SPUThread::stop_and_signal(u32 code) { case 0x001: { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + std::this_thread::sleep_for(1ms); // hack return true; } @@ -1195,7 +1237,7 @@ bool SPUThread::stop_and_signal(u32 code) return false; } - group->cv.wait_for(lv2_lock, std::chrono::milliseconds(1)); + group->cv.wait_for(lv2_lock, 1ms); } // change group status @@ -1261,7 +1303,7 @@ bool SPUThread::stop_and_signal(u32 code) if (thread && thread.get() != this) { thread->state -= cpu_state::suspend; - thread->lock_notify(); + (*thread)->lock_notify(); } } @@ -1300,7 +1342,7 @@ bool SPUThread::stop_and_signal(u32 code) if (thread && thread.get() != this) { thread->state += cpu_state::stop; - thread->lock_notify(); + (*thread)->lock_notify(); } } @@ -1404,7 +1446,7 @@ void SPUThread::fast_call(u32 ls_addr) custom_task = std::move(old_task); } -void SPUThread::RegisterHleFunction(u32 addr, std::function function) +void SPUThread::RegisterHleFunction(u32 addr, std::function function) { m_addr_to_hle_function_map[addr] = function; _ref(addr) = 0x00000003; // STOP 3 diff --git a/rpcs3/Emu/Cell/SPUThread.h b/rpcs3/Emu/Cell/SPUThread.h index 38bb09e2b0..d75dd5e676 100644 --- a/rpcs3/Emu/Cell/SPUThread.h +++ b/rpcs3/Emu/Cell/SPUThread.h @@ -4,7 +4,6 @@ #include "Emu/CPU/CPUThread.h" #include "Emu/Cell/SPUInterpreter.h" #include "MFC.h" -#include class lv2_event_queue_t; struct lv2_spu_group_t; @@ -380,13 +379,7 @@ struct spu_imm_table_t std::array<__m128, 155 + 174> m_data; public: - scale_table_t() - { - for (s32 i = -155; i < 174; i++) - { - m_data[i + 155] = _mm_set1_ps(static_cast(std::exp2(i))); - } - } + scale_table_t(); force_inline __m128 operator [] (s32 scale) const { @@ -395,56 +388,7 @@ struct spu_imm_table_t } const scale; - spu_imm_table_t() - { - for (u32 i = 0; i < sizeof(fsm) / sizeof(fsm[0]); i++) - { - for (u32 j = 0; j < 4; j++) - { - fsm[i]._u32[j] = (i & (1 << j)) ? 0xffffffff : 0; - } - } - - for (u32 i = 0; i < sizeof(fsmh) / sizeof(fsmh[0]); i++) - { - for (u32 j = 0; j < 8; j++) - { - fsmh[i]._u16[j] = (i & (1 << j)) ? 0xffff : 0; - } - } - - for (u32 i = 0; i < sizeof(fsmb) / sizeof(fsmb[0]); i++) - { - for (u32 j = 0; j < 16; j++) - { - fsmb[i]._u8[j] = (i & (1 << j)) ? 0xff : 0; - } - } - - for (u32 i = 0; i < sizeof(sldq_pshufb) / sizeof(sldq_pshufb[0]); i++) - { - for (u32 j = 0; j < 16; j++) - { - sldq_pshufb[i]._u8[j] = static_cast(j - i); - } - } - - for (u32 i = 0; i < sizeof(srdq_pshufb) / sizeof(srdq_pshufb[0]); i++) - { - for (u32 j = 0; j < 16; j++) - { - srdq_pshufb[i]._u8[j] = (j + i > 15) ? 0xff : static_cast(j + i); - } - } - - for (u32 i = 0; i < sizeof(rldq_pshufb) / sizeof(rldq_pshufb[0]); i++) - { - for (u32 j = 0; j < 16; j++) - { - rldq_pshufb[i]._u8[j] = static_cast((j - i) & 0xf); - } - } - } + spu_imm_table_t(); }; extern const spu_imm_table_t g_spu_imm; @@ -646,7 +590,7 @@ public: return *_ptr(lsa); } - void RegisterHleFunction(u32 addr, std::function function); + void RegisterHleFunction(u32 addr, std::function function); void UnregisterHleFunction(u32 addr); void UnregisterHleFunctions(u32 start_addr, u32 end_addr); }; diff --git a/rpcs3/Emu/Cell/lv2/IPC.h b/rpcs3/Emu/Cell/lv2/IPC.h deleted file mode 100644 index 777409307a..0000000000 --- a/rpcs3/Emu/Cell/lv2/IPC.h +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -#include -#include - -#include "Utilities/SharedMutex.h" - -// IPC manager for lv2 objects of type T and 64-bit IPC keys. -// External declaration of g_ipc is required. -template -class ipc_manager final -{ - std::unordered_map> m_map; - - shared_mutex m_mutex; - - static ipc_manager g_ipc; - -public: - // Add new object if specified ipc_key is not used - template - static auto add(u64 ipc_key, F&& provider) -> decltype(static_cast>(provider())) - { - writer_lock lock(g_ipc.m_mutex); - - // Get object location - std::weak_ptr& wptr = g_ipc.m_map[ipc_key]; - - if (wptr.expired()) - { - // Call a function which must return the object - std::shared_ptr result = provider(); - wptr = result; - return result; - } - - return{}; - } - - // Get existing object with specified ipc_key - static std::shared_ptr get(u64 ipc_key) - { - reader_lock lock(g_ipc.m_mutex); - - const auto found = g_ipc.m_map.find(ipc_key); - - if (found != g_ipc.m_map.end()) - { - return found->second.lock(); - } - - return{}; - } -}; diff --git a/rpcs3/Emu/Cell/lv2/lv2.cpp b/rpcs3/Emu/Cell/lv2/lv2.cpp index 771302c551..7a1788939b 100644 --- a/rpcs3/Emu/Cell/lv2/lv2.cpp +++ b/rpcs3/Emu/Cell/lv2/lv2.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Utilities/AutoPause.h" #include "Emu/System.h" @@ -29,6 +30,30 @@ #include "sys_fs.h" #include "sys_dbg.h" +LOG_CHANNEL(sys_cond); +LOG_CHANNEL(sys_dbg); +LOG_CHANNEL(sys_event); +LOG_CHANNEL(sys_event_flag); +LOG_CHANNEL(sys_fs); +LOG_CHANNEL(sys_interrupt); +LOG_CHANNEL(sys_lwcond); +LOG_CHANNEL(sys_lwmutex); +LOG_CHANNEL(sys_memory); +LOG_CHANNEL(sys_mmapper); +LOG_CHANNEL(sys_mutex); +LOG_CHANNEL(sys_ppu_thread); +LOG_CHANNEL(sys_process); +LOG_CHANNEL(sys_prx); +LOG_CHANNEL(sys_rsx); +LOG_CHANNEL(sys_rwlock); +LOG_CHANNEL(sys_semaphore); +LOG_CHANNEL(sys_spu); +LOG_CHANNEL(sys_time); +LOG_CHANNEL(sys_timer); +LOG_CHANNEL(sys_trace); +LOG_CHANNEL(sys_tty); +LOG_CHANNEL(sys_vm); + extern std::string ppu_get_syscall_name(u64 code); static void null_func(PPUThread& ppu) @@ -903,15 +928,21 @@ extern void ppu_execute_syscall(PPUThread& ppu, u64 code) { g_ppu_syscall_table[code](ppu); } - catch (...) + catch (EmulationStopped) { LOG_WARNING(PPU, "Syscall '%s' (%llu) aborted", ppu_get_syscall_name(code), code); ppu.last_function = previous_function; throw; } + catch (...) + { + LOG_ERROR(PPU, "Syscall '%s' (%llu) aborted", ppu_get_syscall_name(code), code); + ppu.last_function = previous_function; + throw; + } LOG_TRACE(PPU, "Syscall '%s' (%llu) finished, r3=0x%llx", ppu_get_syscall_name(code), code, ppu.GPR[3]); ppu.last_function = previous_function; } -lv2_lock_t::type::mutex_type lv2_lock_t::mutex; +DECLARE(lv2_lock_t::mutex); diff --git a/rpcs3/Emu/Cell/lv2/sys_cond.cpp b/rpcs3/Emu/Cell/lv2/sys_cond.cpp index 82853dac81..db5f2478fb 100644 --- a/rpcs3/Emu/Cell/lv2/sys_cond.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_cond.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -9,7 +8,9 @@ #include "sys_mutex.h" #include "sys_cond.h" -LOG_CHANNEL(sys_cond); +#include + +logs::channel sys_cond("sys_cond", logs::level::notice); extern u64 get_system_time(); @@ -24,8 +25,8 @@ void lv2_cond_t::notify(lv2_lock_t, cpu_thread* thread) { mutex->owner = std::static_pointer_cast(thread->shared_from_this()); - ASSERT(!thread->state.test_and_set(cpu_state::signal)); - thread->notify(); + VERIFY(!thread->state.test_and_set(cpu_state::signal)); + (*thread)->notify(); } } diff --git a/rpcs3/Emu/Cell/lv2/sys_dbg.cpp b/rpcs3/Emu/Cell/lv2/sys_dbg.cpp index 3890fc906f..7c73318b80 100644 --- a/rpcs3/Emu/Cell/lv2/sys_dbg.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_dbg.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -7,4 +6,4 @@ #include "Emu/Cell/ErrorCodes.h" #include "sys_dbg.h" -LOG_CHANNEL(sys_dbg); +logs::channel sys_dbg("sys_dbg", logs::level::notice); diff --git a/rpcs3/Emu/Cell/lv2/sys_event.cpp b/rpcs3/Emu/Cell/lv2/sys_event.cpp index ac105aabb5..2c1994419b 100644 --- a/rpcs3/Emu/Cell/lv2/sys_event.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_event.cpp @@ -1,25 +1,26 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" +#include "Emu/IPC.h" #include "Emu/Cell/ErrorCodes.h" #include "Emu/Cell/PPUThread.h" #include "Emu/Cell/SPUThread.h" #include "sys_process.h" #include "sys_event.h" -#include "IPC.h" -LOG_CHANNEL(sys_event); +logs::channel sys_event("sys_event", logs::level::notice); -template<> DECLARE(ipc_manager::g_ipc) {}; +template<> DECLARE(ipc_manager::g_ipc) {}; extern u64 get_system_time(); std::shared_ptr lv2_event_queue_t::make(u32 protocol, s32 type, u64 name, u64 ipc_key, s32 size) { - auto make_expr = WRAP_EXPR(idm::import(WRAP_EXPR(std::make_shared(protocol, type, name, ipc_key, size)))); + auto queue = std::make_shared(protocol, type, name, ipc_key, size); + + auto make_expr = WRAP_EXPR(idm::import(WRAP_EXPR(queue))); if (ipc_key == SYS_EVENT_QUEUE_LOCAL) { @@ -28,7 +29,12 @@ std::shared_ptr lv2_event_queue_t::make(u32 protocol, s32 typ } // IPC queue - return ipc_manager::add(ipc_key, make_expr); + if (ipc_manager::add(ipc_key, make_expr)) + { + return queue; + } + + return nullptr; } std::shared_ptr lv2_event_queue_t::find(u64 ipc_key) @@ -39,12 +45,12 @@ std::shared_ptr lv2_event_queue_t::find(u64 ipc_key) return{}; } - return ipc_manager::get(ipc_key); + return ipc_manager::get(ipc_key); } void lv2_event_queue_t::push(lv2_lock_t, u64 source, u64 data1, u64 data2, u64 data3) { - Expects(m_sq.empty() || m_events.empty()); + EXPECTS(m_sq.empty() || m_events.empty()); // save event if no waiters if (m_sq.empty()) @@ -77,15 +83,15 @@ void lv2_event_queue_t::push(lv2_lock_t, u64 source, u64 data1, u64 data2, u64 d throw fmt::exception("Unexpected (queue.type=%d, thread.type=%d)" HERE, type, thread->type); } - ASSERT(!thread->state.test_and_set(cpu_state::signal)); - thread->notify(); + VERIFY(!thread->state.test_and_set(cpu_state::signal)); + (*thread)->notify(); return m_sq.pop_front(); } lv2_event_queue_t::event_type lv2_event_queue_t::pop(lv2_lock_t) { - Expects(m_events.size()); + EXPECTS(m_events.size()); auto result = m_events.front(); m_events.pop_front(); return result; @@ -171,7 +177,7 @@ s32 sys_event_queue_destroy(u32 equeue_id, s32 mode) } thread->state += cpu_state::signal; - thread->notify(); + (*thread)->notify(); } return CELL_OK; @@ -270,7 +276,7 @@ s32 sys_event_queue_receive(PPUThread& ppu, u32 equeue_id, vm::ptr if (ppu.GPR[3]) { - Ensures(!idm::check(equeue_id)); + ENSURES(!idm::check(equeue_id)); return CELL_ECANCELED; } diff --git a/rpcs3/Emu/Cell/lv2/sys_event_flag.cpp b/rpcs3/Emu/Cell/lv2/sys_event_flag.cpp index 87814cf8e4..d39ba434d0 100644 --- a/rpcs3/Emu/Cell/lv2/sys_event_flag.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_event_flag.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -8,7 +7,9 @@ #include "Emu/Cell/PPUThread.h" #include "sys_event_flag.h" -LOG_CHANNEL(sys_event_flag); +#include + +logs::channel sys_event_flag("sys_event_flag", logs::level::notice); extern u64 get_system_time(); @@ -28,8 +29,8 @@ void lv2_event_flag_t::notify_all(lv2_lock_t) // save pattern ppu.GPR[4] = clear_pattern(bitptn, mode); - ASSERT(!thread->state.test_and_set(cpu_state::signal)); - thread->notify(); + VERIFY(!thread->state.test_and_set(cpu_state::signal)); + (*thread)->notify(); return true; } @@ -291,8 +292,8 @@ s32 sys_event_flag_cancel(u32 id, vm::ptr num) // clear "mode" as a sign of cancellation ppu.GPR[5] = 0; - ASSERT(!thread->state.test_and_set(cpu_state::signal)); - thread->notify(); + VERIFY(!thread->state.test_and_set(cpu_state::signal)); + (*thread)->notify(); } eflag->sq.clear(); diff --git a/rpcs3/Emu/Cell/lv2/sys_fs.cpp b/rpcs3/Emu/Cell/lv2/sys_fs.cpp index a2e2899cb6..de95dfebdd 100644 --- a/rpcs3/Emu/Cell/lv2/sys_fs.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_fs.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -10,7 +9,7 @@ #include "Utilities/StrUtil.h" #include -LOG_CHANNEL(sys_fs); +logs::channel sys_fs("sys_fs", logs::level::notice); s32 sys_fs_test(u32 arg1, u32 arg2, vm::ptr arg3, u32 arg4, vm::ptr arg5, u32 arg6) { @@ -352,9 +351,9 @@ s32 sys_fs_rmdir(vm::cptr path) if (!fs::remove_dir(vfs::get(path.get_ptr()))) { - switch (auto error = fs::error) + switch (auto error = fs::g_tls_error) { - case ENOENT: return CELL_FS_ENOENT; + case fs::error::noent: return CELL_FS_ENOENT; default: sys_fs.error("sys_fs_rmdir(): unknown error %d", error); } @@ -372,9 +371,9 @@ s32 sys_fs_unlink(vm::cptr path) if (!fs::remove_file(vfs::get(path.get_ptr()))) { - switch (auto error = fs::error) + switch (auto error = fs::g_tls_error) { - case ENOENT: return CELL_FS_ENOENT; + case fs::error::noent: return CELL_FS_ENOENT; default: sys_fs.error("sys_fs_unlink(): unknown error %d", error); } @@ -451,9 +450,9 @@ s32 sys_fs_truncate(vm::cptr path, u64 size) if (!fs::truncate_file(vfs::get(path.get_ptr()), size)) { - switch (auto error = fs::error) + switch (auto error = fs::g_tls_error) { - case ENOENT: return CELL_FS_ENOENT; + case fs::error::noent: return CELL_FS_ENOENT; default: sys_fs.error("sys_fs_truncate(): unknown error %d", error); } @@ -478,9 +477,9 @@ s32 sys_fs_ftruncate(u32 fd, u64 size) if (!file->file.trunc(size)) { - switch (auto error = fs::error) + switch (auto error = fs::g_tls_error) { - case 0: + case fs::error::ok: default: sys_fs.error("sys_fs_ftruncate(): unknown error %d", error); } diff --git a/rpcs3/Emu/Cell/lv2/sys_fs.h b/rpcs3/Emu/Cell/lv2/sys_fs.h index fd63e6df52..ad044f23a3 100644 --- a/rpcs3/Emu/Cell/lv2/sys_fs.h +++ b/rpcs3/Emu/Cell/lv2/sys_fs.h @@ -2,6 +2,9 @@ #include "Utilities/Thread.h" +#include +#include + namespace vm { using namespace ps3; } #pragma pack(push, 4) diff --git a/rpcs3/Emu/Cell/lv2/sys_interrupt.cpp b/rpcs3/Emu/Cell/lv2/sys_interrupt.cpp index ca2fe1f9d9..ec831f61e4 100644 --- a/rpcs3/Emu/Cell/lv2/sys_interrupt.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_interrupt.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -8,20 +7,20 @@ #include "Emu/Cell/PPUThread.h" #include "sys_interrupt.h" -LOG_CHANNEL(sys_interrupt); +logs::channel sys_interrupt("sys_interrupt", logs::level::notice); void lv2_int_serv_t::join(PPUThread& ppu, lv2_lock_t lv2_lock) { // Use is_joining to stop interrupt thread and signal thread->is_joining = true; - thread->notify(); + (*thread)->notify(); // Start joining while (!(thread->state & cpu_state::exit)) { CHECK_EMU_STATUS; - get_current_thread_cv().wait_for(lv2_lock, std::chrono::milliseconds(1)); + get_current_thread_cv().wait_for(lv2_lock, 1ms); } // Cleanup @@ -93,7 +92,7 @@ s32 _sys_interrupt_thread_establish(vm::ptr ih, u32 intrtag, u32 intrthread it->custom_task = [handler, arg1, arg2](PPUThread& ppu) { - const u32 pc = ppu.PC; + const u32 pc = ppu.pc; const u32 rtoc = ppu.GPR[2]; LV2_LOCK; @@ -128,7 +127,7 @@ s32 _sys_interrupt_thread_establish(vm::ptr ih, u32 intrtag, u32 intrthread }; it->state -= cpu_state::stop; - it->lock_notify(); + (*it)->lock_notify(); *ih = handler->id; diff --git a/rpcs3/Emu/Cell/lv2/sys_lwcond.cpp b/rpcs3/Emu/Cell/lv2/sys_lwcond.cpp index e56a69f78d..eaea8482bc 100644 --- a/rpcs3/Emu/Cell/lv2/sys_lwcond.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_lwcond.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -9,7 +8,9 @@ #include "sys_lwmutex.h" #include "sys_lwcond.h" -LOG_CHANNEL(sys_lwcond); +#include + +logs::channel sys_lwcond("sys_lwcond", logs::level::notice); extern u64 get_system_time(); @@ -29,8 +30,8 @@ void lv2_lwcond_t::notify(lv2_lock_t, cpu_thread* thread, const std::shared_ptr< mutex->signaled--; } - ASSERT(!thread->state.test_and_set(cpu_state::signal)); - thread->notify(); + VERIFY(!thread->state.test_and_set(cpu_state::signal)); + (*thread)->notify(); } s32 _sys_lwcond_create(vm::ptr lwcond_id, u32 lwmutex_id, vm::ptr control, u64 name, u32 arg5) diff --git a/rpcs3/Emu/Cell/lv2/sys_lwmutex.cpp b/rpcs3/Emu/Cell/lv2/sys_lwmutex.cpp index 479030acf5..9178bda26d 100644 --- a/rpcs3/Emu/Cell/lv2/sys_lwmutex.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_lwmutex.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -8,7 +7,7 @@ #include "Emu/Cell/PPUThread.h" #include "sys_lwmutex.h" -LOG_CHANNEL(sys_lwmutex); +logs::channel sys_lwmutex("sys_lwmutex", logs::level::notice); extern u64 get_system_time(); @@ -22,8 +21,8 @@ void lv2_lwmutex_t::unlock(lv2_lock_t) if (sq.size()) { auto& thread = sq.front(); - ASSERT(!thread->state.test_and_set(cpu_state::signal)); - thread->notify(); + VERIFY(!thread->state.test_and_set(cpu_state::signal)); + (*thread)->notify(); sq.pop_front(); } diff --git a/rpcs3/Emu/Cell/lv2/sys_memory.cpp b/rpcs3/Emu/Cell/lv2/sys_memory.cpp index 47a7fc79cc..ac850638f4 100644 --- a/rpcs3/Emu/Cell/lv2/sys_memory.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_memory.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -7,7 +6,7 @@ #include "Emu/Cell/ErrorCodes.h" #include "sys_memory.h" -LOG_CHANNEL(sys_memory); +logs::channel sys_memory("sys_memory", logs::level::notice); s32 sys_memory_allocate(u32 size, u64 flags, vm::ptr alloc_addr) { @@ -150,28 +149,27 @@ s32 sys_memory_free(u32 addr) const auto area = vm::get(vm::user_space); // Check all memory containers - for (auto& ct : idm::get_all()) + const auto ct = idm::select([&](u32, lv2_memory_container_t& ct) { - auto found = ct->allocs.find(addr); + return ct.allocs.count(addr) != 0; + }); - if (found != ct->allocs.end()) + if (ct) + { + const u32 size = ct->allocs.at(addr); + + if (!area->dealloc(addr)) { - const u32 size = found->second; - - if (!area->dealloc(addr)) - { - throw EXCEPTION("Memory not deallocated (cid=0x%x, addr=0x%x, size=0x%x)", ct->id, addr, size); - } - - // Return memory - ct->used -= size; - ct->allocs.erase(found); - - // Fix "physical" memory - area->used += size; - - return CELL_OK; + throw EXCEPTION("Memory not deallocated (cid=0x%x, addr=0x%x, size=0x%x)", ct->id, addr, size); } + + ct->allocs.erase(addr); + + // Return "memory" + ct->used -= size; + area->used += size; + + return CELL_OK; } if (!area->dealloc(addr)) @@ -205,10 +203,10 @@ s32 sys_memory_get_user_memory_size(vm::ptr mem_info) u32 reserved = 0; // Check all memory containers - for (auto& ct : idm::get_all()) + idm::select([&](u32, lv2_memory_container_t& ct) { - reserved += ct->size; - } + reserved += ct.size; + }); const auto area = vm::get(vm::user_space); @@ -236,10 +234,10 @@ s32 sys_memory_container_create(vm::ptr cid, u32 size) u32 reserved = 0; // Check all memory containers - for (auto& ct : idm::get_all()) + idm::select([&](u32, lv2_memory_container_t& ct) { - reserved += ct->size; - } + reserved += ct.size; + }); const auto area = vm::get(vm::user_space); diff --git a/rpcs3/Emu/Cell/lv2/sys_mmapper.cpp b/rpcs3/Emu/Cell/lv2/sys_mmapper.cpp index c8e70246cd..12d9218ccd 100644 --- a/rpcs3/Emu/Cell/lv2/sys_mmapper.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_mmapper.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -7,7 +6,7 @@ #include "Emu/Cell/ErrorCodes.h" #include "sys_mmapper.h" -LOG_CHANNEL(sys_mmapper); +logs::channel sys_mmapper("sys_mmapper", logs::level::notice); s32 sys_mmapper_allocate_address(u64 size, u64 flags, u64 alignment, vm::ptr alloc_addr) { @@ -334,24 +333,26 @@ s32 sys_mmapper_unmap_memory(u32 addr, vm::ptr mem_id) return CELL_EINVAL; } - for (auto& mem : idm::get_all()) + const auto mem = idm::select([&](u32, lv2_memory_t& mem) { - if (mem->addr == addr) - { - if (!area->dealloc(addr)) - { - throw EXCEPTION("Deallocation failed (mem_id=0x%x, addr=0x%x)", mem->id, addr); - } + return mem.addr == addr; + }); - mem->addr = 0; - - *mem_id = mem->id; - - return CELL_OK; - } + if (!mem) + { + return CELL_EINVAL; } - return CELL_EINVAL; + if (!area->dealloc(addr)) + { + throw EXCEPTION("Deallocation failed (mem_id=0x%x, addr=0x%x)", mem->id, addr); + } + + mem->addr = 0; + + *mem_id = mem->id; + + return CELL_OK; } s32 sys_mmapper_enable_page_fault_notification(u32 addr, u32 eq) diff --git a/rpcs3/Emu/Cell/lv2/sys_mutex.cpp b/rpcs3/Emu/Cell/lv2/sys_mutex.cpp index 8e32dfb99e..fe0687cf67 100644 --- a/rpcs3/Emu/Cell/lv2/sys_mutex.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_mutex.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -8,7 +7,7 @@ #include "Emu/Cell/PPUThread.h" #include "sys_mutex.h" -LOG_CHANNEL(sys_mutex); +logs::channel sys_mutex("sys_mutex", logs::level::notice); extern u64 get_system_time(); @@ -21,8 +20,8 @@ void lv2_mutex_t::unlock(lv2_lock_t) // pick new owner; protocol is ignored in current implementation owner = std::static_pointer_cast(sq.front()->shared_from_this()); - ASSERT(!owner->state.test_and_set(cpu_state::signal)); - owner->notify(); + VERIFY(!owner->state.test_and_set(cpu_state::signal)); + (*owner)->notify(); } } diff --git a/rpcs3/Emu/Cell/lv2/sys_ppu_thread.cpp b/rpcs3/Emu/Cell/lv2/sys_ppu_thread.cpp index a77a242c23..d269c71245 100644 --- a/rpcs3/Emu/Cell/lv2/sys_ppu_thread.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_ppu_thread.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -8,7 +7,9 @@ #include "Emu/Cell/PPUThread.h" #include "sys_ppu_thread.h" -LOG_CHANNEL(sys_ppu_thread); +#include + +logs::channel sys_ppu_thread("sys_ppu_thread", logs::level::notice); void _sys_ppu_thread_exit(PPUThread& ppu, u64 errorcode) { @@ -29,6 +30,7 @@ void _sys_ppu_thread_exit(PPUThread& ppu, u64 errorcode) //} ppu.state += cpu_state::exit; + //ppu.handle_interrupt(); // Delete detached thread if (!ppu.is_joinable) @@ -73,6 +75,8 @@ s32 sys_ppu_thread_join(PPUThread& ppu, u32 thread_id, vm::ptr vptr) return CELL_EDEADLK; } + ppu.sleep(); + // mark joining thread->is_joining = true; @@ -81,9 +85,11 @@ s32 sys_ppu_thread_join(PPUThread& ppu, u32 thread_id, vm::ptr vptr) { CHECK_EMU_STATUS; - get_current_thread_cv().wait_for(lv2_lock, std::chrono::milliseconds(1)); + get_current_thread_cv().wait_for(lv2_lock, 1ms); } + ppu.awake(); + // get exit status from the register if (vptr) *vptr = thread->GPR[3]; @@ -219,28 +225,6 @@ s32 sys_ppu_thread_restart(u32 thread_id) return CELL_OK; } -u32 ppu_thread_create(u32 entry, u64 arg, s32 prio, u32 stacksize, const std::string& name, std::function task) -{ - const auto ppu = idm::make_ptr(name); - - ppu->prio = prio; - ppu->stack_size = stacksize; - ppu->custom_task = std::move(task); - ppu->cpu_init(); - - if (entry) - { - ppu->PC = vm::read32(entry); - ppu->GPR[2] = vm::read32(entry + 4); // rtoc - } - - ppu->GPR[3] = arg; - ppu->state -= cpu_state::stop; - ppu->lock_notify(); - - return ppu->id; -} - s32 _sys_ppu_thread_create(vm::ptr thread_id, vm::ptr param, u64 arg, u64 unk, s32 prio, u32 stacksize, u64 flags, vm::cptr threadname) { sys_ppu_thread.warning("_sys_ppu_thread_create(thread_id=*0x%x, param=*0x%x, arg=0x%llx, unk=0x%llx, prio=%d, stacksize=0x%x, flags=0x%llx, threadname=*0x%x)", @@ -267,13 +251,14 @@ s32 _sys_ppu_thread_create(vm::ptr thread_id, vm::ptr p ppu->stack_size = std::max(stacksize, 0x4000); ppu->cpu_init(); - ppu->PC = vm::read32(param->entry); + ppu->pc = vm::read32(param->entry); ppu->GPR[2] = vm::read32(param->entry + 4); // rtoc ppu->GPR[3] = arg; ppu->GPR[4] = unk; // actually unknown ppu->GPR[13] = param->tls; ppu->is_joinable = is_joinable; + //ppu->state += cpu_state::interrupt; *thread_id = ppu->id; @@ -294,7 +279,7 @@ s32 sys_ppu_thread_start(u32 thread_id) } thread->state -= cpu_state::stop; - thread->lock_notify(); + (*thread)->lock_notify(); return CELL_OK; } diff --git a/rpcs3/Emu/Cell/lv2/sys_ppu_thread.h b/rpcs3/Emu/Cell/lv2/sys_ppu_thread.h index 8a103ae7bf..eefd4d047b 100644 --- a/rpcs3/Emu/Cell/lv2/sys_ppu_thread.h +++ b/rpcs3/Emu/Cell/lv2/sys_ppu_thread.h @@ -41,9 +41,6 @@ enum : u32 PPU_THREAD_STATUS_UNKNOWN, }; -// Aux -u32 ppu_thread_create(u32 entry, u64 arg, s32 prio, u32 stacksize, const std::string& name, std::function task = nullptr); - // SysCalls void _sys_ppu_thread_exit(PPUThread& ppu, u64 errorcode); void sys_ppu_thread_yield(); diff --git a/rpcs3/Emu/Cell/lv2/sys_process.cpp b/rpcs3/Emu/Cell/lv2/sys_process.cpp index 8291849120..f1dcde9162 100644 --- a/rpcs3/Emu/Cell/lv2/sys_process.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_process.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -22,7 +21,9 @@ #include "sys_fs.h" #include "sys_process.h" -LOG_CHANNEL(sys_process); +#include + +logs::channel sys_process("sys_process", logs::level::notice); s32 process_getpid() { @@ -61,7 +62,7 @@ s32 sys_process_exit(s32 status) { CHECK_EMU_STATUS; - std::this_thread::sleep_for(std::chrono::milliseconds(1)); + std::this_thread::sleep_for(1ms); } return CELL_OK; @@ -88,7 +89,7 @@ s32 sys_process_get_number_of_object(u32 object, vm::ptr nump) case SYS_LWMUTEX_OBJECT: *nump = idm::get_count(); break; case SYS_TIMER_OBJECT: *nump = idm::get_count(); break; case SYS_SEMAPHORE_OBJECT: *nump = idm::get_count(); break; - case SYS_FS_FD_OBJECT: throw EXCEPTION("SYS_FS_FD_OBJECT"); + case SYS_FS_FD_OBJECT: *nump = idm::get_count(); break; case SYS_LWCOND_OBJECT: *nump = idm::get_count(); break; case SYS_EVENT_FLAG_OBJECT: *nump = idm::get_count(); break; @@ -101,6 +102,17 @@ s32 sys_process_get_number_of_object(u32 object, vm::ptr nump) return CELL_OK; } +#include + +template +void idm_get_set(std::set& out) +{ + idm::select([&](u32 id, T&) + { + out.emplace(id); + }); +} + s32 sys_process_get_id(u32 object, vm::ptr buffer, u32 size, vm::ptr set_size) { sys_process.error("sys_process_get_id(object=0x%x, buffer=*0x%x, size=%d, set_size=*0x%x)", object, buffer, size, set_size); @@ -109,24 +121,24 @@ s32 sys_process_get_id(u32 object, vm::ptr buffer, u32 size, vm::ptr s switch (object) { - case SYS_MEM_OBJECT: objects = idm::get_set(); break; - case SYS_MUTEX_OBJECT: objects = idm::get_set(); break; - case SYS_COND_OBJECT: objects = idm::get_set(); break; - case SYS_RWLOCK_OBJECT: objects = idm::get_set(); break; - case SYS_INTR_TAG_OBJECT: objects = idm::get_set(); break; - case SYS_INTR_SERVICE_HANDLE_OBJECT: objects = idm::get_set(); break; - case SYS_EVENT_QUEUE_OBJECT: objects = idm::get_set(); break; - case SYS_EVENT_PORT_OBJECT: objects = idm::get_set(); break; + case SYS_MEM_OBJECT: idm_get_set(objects); break; + case SYS_MUTEX_OBJECT: idm_get_set(objects); break; + case SYS_COND_OBJECT: idm_get_set(objects); break; + case SYS_RWLOCK_OBJECT: idm_get_set(objects); break; + case SYS_INTR_TAG_OBJECT: idm_get_set(objects); break; + case SYS_INTR_SERVICE_HANDLE_OBJECT: idm_get_set(objects); break; + case SYS_EVENT_QUEUE_OBJECT: idm_get_set(objects); break; + case SYS_EVENT_PORT_OBJECT: idm_get_set(objects); break; case SYS_TRACE_OBJECT: throw EXCEPTION("SYS_TRACE_OBJECT"); case SYS_SPUIMAGE_OBJECT: throw EXCEPTION("SYS_SPUIMAGE_OBJECT"); - case SYS_PRX_OBJECT: objects = idm::get_set(); break; + case SYS_PRX_OBJECT: idm_get_set(objects); break; case SYS_SPUPORT_OBJECT: throw EXCEPTION("SYS_SPUPORT_OBJECT"); - case SYS_LWMUTEX_OBJECT: objects = idm::get_set(); break; - case SYS_TIMER_OBJECT: objects = idm::get_set(); break; - case SYS_SEMAPHORE_OBJECT: objects = idm::get_set(); break; - case SYS_FS_FD_OBJECT: throw EXCEPTION("SYS_FS_FD_OBJECT"); - case SYS_LWCOND_OBJECT: objects = idm::get_set(); break; - case SYS_EVENT_FLAG_OBJECT: objects = idm::get_set(); break; + case SYS_LWMUTEX_OBJECT: idm_get_set(objects); break; + case SYS_TIMER_OBJECT: idm_get_set(objects); break; + case SYS_SEMAPHORE_OBJECT: idm_get_set(objects); break; + case SYS_FS_FD_OBJECT: idm_get_set(objects); break; + case SYS_LWCOND_OBJECT: idm_get_set(objects); break; + case SYS_EVENT_FLAG_OBJECT: idm_get_set(objects); break; default: { diff --git a/rpcs3/Emu/Cell/lv2/sys_prx.cpp b/rpcs3/Emu/Cell/lv2/sys_prx.cpp index 99ec5b9ac5..a7cf11a62c 100644 --- a/rpcs3/Emu/Cell/lv2/sys_prx.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_prx.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -9,7 +8,7 @@ #include "Emu/Cell/ErrorCodes.h" #include "sys_prx.h" -LOG_CHANNEL(sys_prx); +logs::channel sys_prx("sys_prx", logs::level::notice); s32 prx_load_module(std::string path, u64 flags, vm::ptr pOpt) { diff --git a/rpcs3/Emu/Cell/lv2/sys_rsx.cpp b/rpcs3/Emu/Cell/lv2/sys_rsx.cpp index 5d4d8ee83d..df512caf7a 100644 --- a/rpcs3/Emu/Cell/lv2/sys_rsx.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_rsx.cpp @@ -1,12 +1,11 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/Cell/ErrorCodes.h" #include "sys_rsx.h" -LOG_CHANNEL(sys_rsx); +logs::channel sys_rsx("sys_rsx", logs::level::notice); s32 sys_rsx_device_open() { diff --git a/rpcs3/Emu/Cell/lv2/sys_rwlock.cpp b/rpcs3/Emu/Cell/lv2/sys_rwlock.cpp index 351d9ca7bb..89c43c48f5 100644 --- a/rpcs3/Emu/Cell/lv2/sys_rwlock.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_rwlock.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -8,7 +7,7 @@ #include "Emu/Cell/PPUThread.h" #include "sys_rwlock.h" -LOG_CHANNEL(sys_rwlock); +logs::channel sys_rwlock("sys_rwlock", logs::level::notice); extern u64 get_system_time(); @@ -19,8 +18,8 @@ void lv2_rwlock_t::notify_all(lv2_lock_t) { writer = std::static_pointer_cast(wsq.front()->shared_from_this()); - ASSERT(!writer->state.test_and_set(cpu_state::signal)); - writer->notify(); + VERIFY(!writer->state.test_and_set(cpu_state::signal)); + (*writer)->notify(); return wsq.pop_front(); } @@ -32,8 +31,8 @@ void lv2_rwlock_t::notify_all(lv2_lock_t) for (auto& thread : rsq) { - ASSERT(!thread->state.test_and_set(cpu_state::signal)); - thread->notify(); + VERIFY(!thread->state.test_and_set(cpu_state::signal)); + (*thread)->notify(); } return rsq.clear(); diff --git a/rpcs3/Emu/Cell/lv2/sys_semaphore.cpp b/rpcs3/Emu/Cell/lv2/sys_semaphore.cpp index ec49e8c24d..c22bfa8a17 100644 --- a/rpcs3/Emu/Cell/lv2/sys_semaphore.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_semaphore.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -8,7 +7,7 @@ #include "Emu/Cell/PPUThread.h" #include "sys_semaphore.h" -LOG_CHANNEL(sys_semaphore); +logs::channel sys_semaphore("sys_semaphore", logs::level::notice); extern u64 get_system_time(); @@ -174,8 +173,8 @@ s32 sys_semaphore_post(u32 sem_id, s32 count) count--; auto& thread = sem->sq.front(); - ASSERT(!thread->state.test_and_set(cpu_state::signal)); - thread->notify(); + VERIFY(!thread->state.test_and_set(cpu_state::signal)); + (*thread)->notify(); sem->sq.pop_front(); } diff --git a/rpcs3/Emu/Cell/lv2/sys_spu.cpp b/rpcs3/Emu/Cell/lv2/sys_spu.cpp index cdccda8e14..5ffa71ca81 100644 --- a/rpcs3/Emu/Cell/lv2/sys_spu.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_spu.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -12,7 +11,7 @@ #include "sys_event.h" #include "sys_spu.h" -LOG_CHANNEL(sys_spu); +logs::channel sys_spu("sys_spu", logs::level::notice); void LoadSpuImage(const fs::file& stream, u32& spu_ep, u32 addr) { @@ -20,7 +19,7 @@ void LoadSpuImage(const fs::file& stream, u32& spu_ep, u32 addr) if (loader != elf_error::ok) { - throw fmt::exception("Failed to load SPU image: %s" HERE, bijective_find(loader, "???")); + throw fmt::exception("Failed to load SPU image: %s" HERE, loader.get_error()); } for (const auto& prog : loader.progs) @@ -323,7 +322,7 @@ s32 sys_spu_thread_group_start(u32 id) if (thread) { thread->state -= cpu_state::stop; - thread->lock_notify(); + (*thread)->lock_notify(); } } @@ -421,7 +420,7 @@ s32 sys_spu_thread_group_resume(u32 id) if (thread) { thread->state -= cpu_state::suspend; - thread->lock_notify(); + (*thread)->lock_notify(); } } @@ -504,7 +503,7 @@ s32 sys_spu_thread_group_terminate(u32 id, s32 value) if (thread) { thread->state += cpu_state::stop; - thread->lock_notify(); + (*thread)->lock_notify(); } } @@ -563,7 +562,7 @@ s32 sys_spu_thread_group_join(u32 id, vm::ptr cause, vm::ptr status) CHECK_EMU_STATUS; - group->cv.wait_for(lv2_lock, std::chrono::milliseconds(1)); + group->cv.wait_for(lv2_lock, 1ms); } switch (group->join_state & ~SPU_TGJSF_IS_JOINING) diff --git a/rpcs3/Emu/Cell/lv2/sys_sync.h b/rpcs3/Emu/Cell/lv2/sys_sync.h index e96c05f9f8..dbe76cf817 100644 --- a/rpcs3/Emu/Cell/lv2/sys_sync.h +++ b/rpcs3/Emu/Cell/lv2/sys_sync.h @@ -1,6 +1,8 @@ #pragma once #include "Utilities/SleepQueue.h" +#include +#include namespace vm { using namespace ps3; } @@ -43,7 +45,6 @@ enum SYS_SYNC_NOT_ADAPTIVE = 0x2000, }; -extern std::mutex& get_current_thread_mutex(); extern std::condition_variable& get_current_thread_cv(); // Simple class for global mutex to pass unique_lock and check it @@ -56,8 +57,8 @@ struct lv2_lock_t lv2_lock_t(type& lv2_lock) : ref(lv2_lock) { - Expects(ref.owns_lock()); - Expects(ref.mutex() == &mutex); + EXPECTS(ref.owns_lock()); + EXPECTS(ref.mutex() == &mutex); } operator type&() const diff --git a/rpcs3/Emu/Cell/lv2/sys_time.cpp b/rpcs3/Emu/Cell/lv2/sys_time.cpp index 39f4b1a156..e9a60295de 100644 --- a/rpcs3/Emu/Cell/lv2/sys_time.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_time.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" @@ -45,7 +44,7 @@ const g_time_aux_info = []() -> time_aux_info_t // initialize time-related value #endif -LOG_CHANNEL(sys_time); +logs::channel sys_time("sys_time", logs::level::notice); static const u64 g_timebase_freq = /*79800000*/ 80000000; // 80 Mhz diff --git a/rpcs3/Emu/Cell/lv2/sys_timer.cpp b/rpcs3/Emu/Cell/lv2/sys_timer.cpp index 5944157ad2..d4edeea141 100644 --- a/rpcs3/Emu/Cell/lv2/sys_timer.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_timer.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -9,10 +8,14 @@ #include "sys_process.h" #include "sys_timer.h" -LOG_CHANNEL(sys_timer); +#include + +logs::channel sys_timer("sys_timer", logs::level::notice); extern u64 get_system_time(); +extern std::mutex& get_current_thread_mutex(); + void lv2_timer_t::on_task() { std::unique_lock lock(get_current_thread_mutex()); @@ -51,7 +54,7 @@ void lv2_timer_t::on_task() continue; } - get_current_thread_cv().wait_for(lock, std::chrono::milliseconds(1)); + get_current_thread_cv().wait_for(lock, 1ms); } } @@ -64,7 +67,7 @@ void lv2_timer_t::on_stop() { // Signal thread using invalid state and join state = -1; - lock_notify(); + (*this)->lock_notify(); named_thread::on_stop(); } @@ -170,7 +173,7 @@ s32 _sys_timer_start(u32 timer_id, u64 base_time, u64 period) timer->period = period; timer->state = SYS_TIMER_STATE_RUN; - timer->lock_notify(); + (*timer)->lock_notify(); return CELL_OK; } @@ -244,6 +247,8 @@ s32 sys_timer_disconnect_event_queue(u32 timer_id) return CELL_OK; } +#include + s32 sys_timer_sleep(u32 sleep_time) { sys_timer.trace("sys_timer_sleep(sleep_time=%d)", sleep_time); @@ -258,7 +263,7 @@ s32 sys_timer_sleep(u32 sleep_time) { CHECK_EMU_STATUS; - std::this_thread::sleep_for(std::chrono::milliseconds(1)); + std::this_thread::sleep_for(1ms); } if (useconds > passed) @@ -281,7 +286,7 @@ s32 sys_timer_usleep(const u64 sleep_time) { CHECK_EMU_STATUS; - std::this_thread::sleep_for(std::chrono::milliseconds(1)); + std::this_thread::sleep_for(1ms); } if (sleep_time > passed) diff --git a/rpcs3/Emu/Cell/lv2/sys_trace.cpp b/rpcs3/Emu/Cell/lv2/sys_trace.cpp index 78a10eb063..bf5fc20c61 100644 --- a/rpcs3/Emu/Cell/lv2/sys_trace.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_trace.cpp @@ -1,12 +1,11 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/Cell/ErrorCodes.h" #include "sys_trace.h" -LOG_CHANNEL(sys_trace); +logs::channel sys_trace("sys_trace", logs::level::notice); s32 sys_trace_create() { diff --git a/rpcs3/Emu/Cell/lv2/sys_tty.cpp b/rpcs3/Emu/Cell/lv2/sys_tty.cpp index c91ded14f4..4a9b62ca72 100644 --- a/rpcs3/Emu/Cell/lv2/sys_tty.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_tty.cpp @@ -1,12 +1,11 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/Cell/ErrorCodes.h" #include "sys_tty.h" -LOG_CHANNEL(sys_tty); +logs::channel sys_tty("sys_tty", logs::level::notice); extern fs::file g_tty; diff --git a/rpcs3/Emu/Cell/lv2/sys_vm.cpp b/rpcs3/Emu/Cell/lv2/sys_vm.cpp index 22492efb6e..8c5ec0613c 100644 --- a/rpcs3/Emu/Cell/lv2/sys_vm.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_vm.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -8,7 +7,7 @@ #include "sys_memory.h" #include "sys_vm.h" -LOG_CHANNEL(sys_vm); +logs::channel sys_vm("sys_vm", logs::level::notice); s32 sys_vm_memory_map(u32 vsize, u32 psize, u32 cid, u64 flag, u64 policy, vm::ptr addr) { diff --git a/rpcs3/Emu/IPC.h b/rpcs3/Emu/IPC.h new file mode 100644 index 0000000000..f8f73d0916 --- /dev/null +++ b/rpcs3/Emu/IPC.h @@ -0,0 +1,88 @@ +#pragma once + +#include +#include + +#include "Utilities/SharedMutex.h" + +// IPC manager for objects of type T and IPC keys of type K. +// External declaration of g_ipc is required. +template +class ipc_manager final +{ + std::unordered_map> m_map; + + shared_mutex m_mutex; + + static ipc_manager g_ipc; + +public: + // Add new object if specified ipc_key is not used + template + static bool add(const K& ipc_key, F&& provider) + { + writer_lock lock(g_ipc.m_mutex); + + // Get object location + std::weak_ptr& wptr = g_ipc.m_map[ipc_key]; + + if (wptr.expired()) + { + // Call a function which must return the object + wptr = provider(); + return true; + } + + return false; + } + + // Unregister specified ipc_key, may return true even if the object doesn't exist anymore + static bool remove(const K& ipc_key) + { + writer_lock lock(g_ipc.m_mutex); + + return g_ipc.m_map.erase(ipc_key) != 0; + } + + // Unregister specified ipc_key, return the object + static std::shared_ptr withdraw(const K& ipc_key) + { + writer_lock lock(g_ipc.m_mutex); + + const auto found = g_ipc.m_map.find(ipc_key); + + if (found != g_ipc.m_map.end()) + { + auto ptr = found->second.lock(); + g_ipc.m_map.erase(found); + return ptr; + } + + return nullptr; + } + + // Get object with specified ipc_key + static std::shared_ptr get(const K& ipc_key) + { + reader_lock lock(g_ipc.m_mutex); + + const auto found = g_ipc.m_map.find(ipc_key); + + if (found != g_ipc.m_map.end()) + { + return found->second.lock(); + } + + return nullptr; + } + + // Check whether the object actually exists + static bool check(const K& ipc_key) + { + reader_lock lock(g_ipc.m_mutex); + + const auto found = g_ipc.m_map.find(ipc_key); + + return found != g_ipc.m_map.end() && !found->second.expired(); + } +}; diff --git a/rpcs3/Emu/IdManager.cpp b/rpcs3/Emu/IdManager.cpp index 32ab768c16..e2bef6e4b4 100644 --- a/rpcs3/Emu/IdManager.cpp +++ b/rpcs3/Emu/IdManager.cpp @@ -1,10 +1,17 @@ #include "stdafx.h" #include "IdManager.h" +DECLARE(idm::g_map); +DECLARE(idm::g_id); +DECLARE(idm::g_mutex); + +DECLARE(fxm::g_map); +DECLARE(fxm::g_mutex); + std::vector& id_manager::typeinfo::access() { static std::vector list; - + return list; } diff --git a/rpcs3/Emu/IdManager.h b/rpcs3/Emu/IdManager.h index 84d4f8bccf..964661661a 100644 --- a/rpcs3/Emu/IdManager.h +++ b/rpcs3/Emu/IdManager.h @@ -8,8 +8,6 @@ #include #include #include -#include -#include // Mostly helper namespace namespace id_manager @@ -37,7 +35,7 @@ namespace id_manager template struct on_init { - static void func(T*) + static inline void func(T*) { } }; @@ -45,7 +43,7 @@ namespace id_manager template struct on_init().on_init())> { - static void func(T* ptr) + static inline void func(T* ptr) { ptr->on_init(); } @@ -55,7 +53,7 @@ namespace id_manager template struct on_stop { - static void func(T*) + static inline void func(T*) { } }; @@ -63,7 +61,7 @@ namespace id_manager template struct on_stop().on_stop())> { - static void func(T* ptr) + static inline void func(T* ptr) { ptr->on_stop(); } @@ -155,15 +153,41 @@ class idm // Update optional ID storage template - static auto set_id_value(T* ptr, u32 id) -> decltype(static_cast(std::declval().id)) + static inline auto set_id_value(T* ptr, u32 id) -> decltype(static_cast(std::declval().id)) { ptr->id = id; } - static void set_id_value(...) + static inline void set_id_value(...) { } + // Helper + template + struct function_traits; + + template + struct function_traits + { + using second_type = A2; + using return_type = R; + }; + + // Helper + template + struct bool_if_void + { + friend bool operator ,(bool lhs, const bool_if_void&) + { + return lhs; + } + + operator bool() const + { + return Value; + } + }; + // Prepares new ID, returns nullptr if out of resources static map_type::pointer allocate_id(u32 tag, u32 min, u32 max); @@ -213,7 +237,7 @@ public: // Add a new ID of specified type with specified constructor arguments (returns object or nullptr) template - static std::enable_if_t::value, std::shared_ptr> make_ptr(Args&&... args) + static inline std::enable_if_t::value, std::shared_ptr> make_ptr(Args&&... args) { if (auto pair = create_id(WRAP_EXPR(std::make_shared(std::forward(args)...)))) { @@ -226,7 +250,7 @@ public: // Add a new ID of specified type with specified constructor arguments (returns id) template - static std::enable_if_t::value, u32> make(Args&&... args) + static inline std::enable_if_t::value, u32> make(Args&&... args) { if (auto pair = create_id(WRAP_EXPR(std::make_shared(std::forward(args)...)))) { @@ -239,7 +263,7 @@ public: // Add a new ID for an existing object provided (returns new id) template - static u32 import_existing(const std::shared_ptr& ptr) + static inline u32 import_existing(const std::shared_ptr& ptr) { if (auto pair = create_id(WRAP_EXPR(ptr))) { @@ -252,7 +276,7 @@ public: // Add a new ID for an object returned by provider() template> - static std::shared_ptr import(F&& provider) + static inline std::shared_ptr import(F&& provider) { if (auto pair = create_id(std::forward(provider))) { @@ -263,18 +287,18 @@ public: return nullptr; } - // Check whether ID exists + // Check whether the ID exists template - static bool check(u32 id) + static inline bool check(u32 id) { reader_lock lock(g_mutex); return find_id(get_type(), id) != nullptr; } - // Get ID + // Get the ID template - static std::shared_ptr get(u32 id) + static inline std::shared_ptr get(u32 id) { reader_lock lock(g_mutex); @@ -288,25 +312,63 @@ public: return{ found->second, static_cast(found->second.get()) }; } - // Get all IDs (unsorted) + // Conditionally get the ID, almost similar to select() but for the single object only. + template::second_type> + static inline auto get(u32 id, F&& pred) + { + using result_type = std::conditional_t::return_type>::value, void, std::shared_ptr>; + + reader_lock lock(g_mutex); + + const auto found = find_id(get_type(), id); + + if (UNLIKELY(found == nullptr)) + { + return static_cast(nullptr); + } + + if (pred(id, *static_cast(found->second.get())), bool_if_void()) + { + return static_cast(std::static_pointer_cast(found->second)); + } + + return static_cast(nullptr); + } + + // Execute for all IDs (unsorted), may return void. If the result evaluates to true, the loop stops and returns the object. + template::second_type> + static inline auto select(F&& pred) + { + using result_type = std::conditional_t::return_type>::value, void, std::shared_ptr>; + + reader_lock lock(g_mutex); + + for (u32 type : { get_type()... }) + { + for (auto& id : g_map[type]) + { + if (pred(id.first, *static_cast(id.second.get())), bool_if_void()) + { + return static_cast(std::static_pointer_cast(id.second)); + } + } + } + + return static_cast(nullptr); + } + + // Get count of objects template - static std::vector> get_all() + static inline u32 get_count() { reader_lock lock(g_mutex); - std::vector> result; - - for (auto& id : g_map[get_type()]) - { - result.emplace_back(id.second, static_cast(id.second.get())); - } - - return result; + return ::size32(g_map[get_type()]); } // Remove the ID template - static bool remove(u32 id) + static inline bool remove(u32 id) { auto&& ptr = delete_id(get_type(), get_tag(), id); @@ -320,7 +382,7 @@ public: // Remove the ID and return it template - static std::shared_ptr withdraw(u32 id) + static inline std::shared_ptr withdraw(u32 id) { auto&& ptr = delete_id(get_type(), get_tag(), id); @@ -332,44 +394,29 @@ public: return{ ptr, static_cast(ptr.get()) }; } - template - static u32 get_count() + // Conditionally remove the ID and return it. + template + static inline std::shared_ptr withdraw(u32 id, F&& pred) { - reader_lock lock(g_mutex); - - return ::size32(g_map[get_type()]); - } - - // Get sorted list of all IDs of specified type - template - static std::set get_set() - { - reader_lock lock(g_mutex); - - std::set result; - - for (auto& id : g_map[get_type()]) + std::shared_ptr ptr; { - result.emplace(id.first); + writer_lock lock(g_mutex); + + const auto found = find_id(get_type(), id); + + if (UNLIKELY(found == nullptr || !pred(id, *static_cast(found->second.get())))) + { + return nullptr; + } + + ptr = deallocate_id(get_tag(), id); + + g_map[get_type()].erase(id); } + + id_manager::on_stop::func(static_cast(ptr.get())); - return result; - } - - // Get sorted map (ID value -> ID data) of all IDs of specified type - template - static std::map> get_map() - { - reader_lock lock(g_mutex); - - std::map> result; - - for (auto& id : g_map[get_type()]) - { - result[id.first] = { id.second, static_cast(id.second.get()) }; - } - - return result; + return{ ptr, static_cast(ptr.get()) }; } }; @@ -518,7 +565,7 @@ public: // Check whether the object exists template - static bool check() + static inline bool check() { reader_lock lock(g_mutex); @@ -527,7 +574,7 @@ public: // Get the object (returns nullptr if it doesn't exist) template - static std::shared_ptr get() + static inline std::shared_ptr get() { reader_lock lock(g_mutex); @@ -538,7 +585,7 @@ public: // Delete the object template - static bool remove() + static inline bool remove() { auto&& ptr = remove(get_type()); @@ -552,7 +599,7 @@ public: // Delete the object and return it template - static std::shared_ptr withdraw() + static inline std::shared_ptr withdraw() { auto&& ptr = remove(get_type()); diff --git a/rpcs3/Emu/Memory/Memory.cpp b/rpcs3/Emu/Memory/Memory.cpp index 3f25183067..975beb34e7 100644 --- a/rpcs3/Emu/Memory/Memory.cpp +++ b/rpcs3/Emu/Memory/Memory.cpp @@ -18,7 +18,7 @@ bool VirtualMemoryBlock::IsInMyRange(const u32 addr, const u32 size) u32 VirtualMemoryBlock::Map(u32 realaddr, u32 size) { - Expects(size); + EXPECTS(size); for (u32 addr = m_range_start; addr <= m_range_start + m_range_size - 1 - GetReservedAmount() - size;) { @@ -48,7 +48,7 @@ u32 VirtualMemoryBlock::Map(u32 realaddr, u32 size) bool VirtualMemoryBlock::Map(u32 realaddr, u32 size, u32 addr) { - Expects(size); + EXPECTS(size); if (!IsInMyRange(addr, size)) { diff --git a/rpcs3/Emu/Memory/vm.cpp b/rpcs3/Emu/Memory/vm.cpp index c45a731c10..0f3f70ef5f 100644 --- a/rpcs3/Emu/Memory/vm.cpp +++ b/rpcs3/Emu/Memory/vm.cpp @@ -5,7 +5,7 @@ #include "Emu/CPU/CPUThread.h" #include "Emu/Cell/PPUThread.h" #include "Emu/Cell/SPUThread.h" -#include "Emu/ARMv7/ARMv7Thread.h" +#include "Emu/PSP2/ARMv7Thread.h" #ifdef _WIN32 #include @@ -93,66 +93,15 @@ namespace vm std::vector> g_locations; // memory locations - //using reservation_mutex_t = std::mutex; - - class reservation_mutex_t + access_violation::access_violation(u64 addr, const char* cause) + : std::runtime_error(fmt::exception("Access violation %s address 0x%llx", cause, addr)) { - atomic_t m_lock{ false }; - std::thread::id m_owner{}; + g_tls_fault_count &= ~(1ull << 63); + } - std::condition_variable m_cv; - std::mutex m_mutex; + using reservation_mutex_t = std::mutex; - public: - bool do_notify = false; - - never_inline void lock() - { - std::unique_lock lock(m_mutex, std::defer_lock); - - while (m_lock.exchange(true) == true) - { - if (m_owner == std::this_thread::get_id()) - { - throw EXCEPTION("Deadlock"); - } - - if (!lock) - { - lock.lock(); - continue; - } - - m_cv.wait_for(lock, std::chrono::milliseconds(1)); - } - - m_owner = std::this_thread::get_id(); - do_notify = true; - } - - never_inline void unlock() - { - if (m_owner != std::this_thread::get_id()) - { - throw EXCEPTION("Mutex not owned"); - } - - m_owner = {}; - - if (m_lock.exchange(false) == false) - { - throw EXCEPTION("Lost lock"); - } - - if (do_notify) - { - std::lock_guard lock(m_mutex); - m_cv.notify_one(); - } - } - }; - - const thread_ctrl* volatile g_reservation_owner = nullptr; + thread_ctrl* volatile g_reservation_owner = nullptr; u32 g_reservation_addr = 0; u32 g_reservation_size = 0; @@ -161,14 +110,6 @@ namespace vm reservation_mutex_t g_reservation_mutex; - - - access_violation::access_violation(u64 addr, const char* cause) - : std::runtime_error(fmt::exception("Access violation %s address 0x%llx", cause, addr)) - { - g_tls_fault_count &= ~(1ull << 63); - } - void _reservation_set(u32 addr, bool no_access = false) { #ifdef _WIN32 @@ -320,7 +261,7 @@ namespace vm return true; } - bool reservation_test(const thread_ctrl* current) + bool reservation_test(thread_ctrl* current) { const auto owner = g_reservation_owner; diff --git a/rpcs3/Emu/Memory/vm.h b/rpcs3/Emu/Memory/vm.h index dda271ebcc..26f1af795d 100644 --- a/rpcs3/Emu/Memory/vm.h +++ b/rpcs3/Emu/Memory/vm.h @@ -1,6 +1,7 @@ #pragma once #include +#include class thread_ctrl; @@ -32,6 +33,9 @@ namespace vm page_allocated = (1 << 7), }; + // Address type + enum addr_t : u32 {}; + struct access_violation : std::runtime_error { access_violation(u64 addr, const char* cause); @@ -60,7 +64,7 @@ namespace vm bool reservation_query(u32 addr, u32 size, bool is_writing, std::function callback); // Returns true if the current thread owns reservation - bool reservation_test(const thread_ctrl* current); + bool reservation_test(thread_ctrl* current); // Break all reservations created by the current thread void reservation_free(); @@ -133,11 +137,11 @@ namespace vm std::shared_ptr get(memory_location_t location, u32 addr = 0); // Get PS3/PSV virtual memory address from the provided pointer (nullptr always converted to 0) - inline u32 get_addr(const void* real_ptr) + inline vm::addr_t get_addr(const void* real_ptr) { if (!real_ptr) { - return 0; + return vm::addr_t{}; } const std::ptrdiff_t diff = static_cast(real_ptr) - g_base_addr; @@ -145,7 +149,7 @@ namespace vm if (res == diff) { - return res; + return static_cast(res); } throw fmt::exception("Not a virtual memory pointer (%p)", real_ptr); @@ -166,36 +170,57 @@ namespace vm template<> struct cast_impl { - static u32 cast(const u32& addr, const char* loc) + static vm::addr_t cast(u32 addr, const char* loc) { - return addr; + return static_cast(addr); + } + + static vm::addr_t cast(u32 addr) + { + return static_cast(addr); } }; template<> struct cast_impl { - static u32 cast(const u64& addr, const char* loc) + static vm::addr_t cast(u64 addr, const char* loc) { - return fmt::narrow("Memory address out of range: 0x%llx%s", addr, loc); + return static_cast(fmt::narrow("Memory address out of range: 0x%llx%s", addr, loc)); + } + + static vm::addr_t cast(u64 addr) + { + return static_cast(fmt::narrow("Memory address out of range: 0x%llx", addr)); } }; template struct cast_impl> { - static u32 cast(const se_t& addr, const char* loc) + static vm::addr_t cast(const se_t& addr, const char* loc) { return cast_impl::cast(addr, loc); } + + static vm::addr_t cast(const se_t& addr) + { + return cast_impl::cast(addr); + } }; template - u32 cast(const T& addr, const char* loc) + vm::addr_t cast(const T& addr, const char* loc) { return cast_impl::cast(addr, loc); } + template + vm::addr_t cast(const T& addr) + { + return cast_impl::cast(addr); + } + // Convert specified PS3/PSV virtual memory address to a pointer for common access inline void* base(u32 addr) { diff --git a/rpcs3/Emu/Memory/vm_ptr.h b/rpcs3/Emu/Memory/vm_ptr.h index e30a8f3b04..f5cff7fc3b 100644 --- a/rpcs3/Emu/Memory/vm_ptr.h +++ b/rpcs3/Emu/Memory/vm_ptr.h @@ -25,12 +25,12 @@ namespace vm _ptr_base() = default; - constexpr _ptr_base(addr_type addr, const addr_tag_t&) + _ptr_base(vm::addr_t addr) : m_addr(addr) { } - constexpr addr_type addr() const + addr_type addr() const { return m_addr; } @@ -40,19 +40,21 @@ namespace vm this->m_addr = addr; } - static constexpr _ptr_base make(addr_type addr) + static _ptr_base make(addr_type addr) { - return{ addr, vm::addr }; + _ptr_base result; + result.m_addr = addr; + return result; } // Enable only the conversions which are originally possible between pointer types template::value>> operator _ptr_base() const { - return{ vm::cast(m_addr, HERE), vm::addr }; + return vm::cast(m_addr, HERE); } - explicit constexpr operator bool() const + explicit operator bool() const { return m_addr != 0; } @@ -61,34 +63,34 @@ namespace vm template> _ptr_base ptr(MT T2::*const mptr) const { - return{ vm::cast(m_addr, HERE) + get_offset(mptr), vm::addr }; + return vm::cast(vm::cast(m_addr, HERE) + get_offset(mptr)); } // Get vm pointer to a struct member with array subscription template, typename = if_comparable_t> _ptr_base ptr(MT T2::*const mptr, u32 index) const { - return{ vm::cast(m_addr, HERE) + get_offset(mptr) + SIZE_32(ET) * index, vm::addr }; + return vm::cast(vm::cast(m_addr, HERE) + get_offset(mptr) + SIZE_32(ET) * index); } // Get vm reference to a struct member template> _ref_base ref(MT T2::*const mptr) const { - return{ vm::cast(m_addr, HERE) + get_offset(mptr), vm::addr }; + return vm::cast(vm::cast(m_addr, HERE) + get_offset(mptr)); } // Get vm reference to a struct member with array subscription template, typename = if_comparable_t> _ref_base ref(MT T2::*const mptr, u32 index) const { - return{ vm::cast(m_addr, HERE) + get_offset(mptr) + SIZE_32(ET) * index, vm::addr }; + return vm::cast(vm::cast(m_addr, HERE) + get_offset(mptr) + SIZE_32(ET) * index); } // Get vm reference _ref_base ref() const { - return{ vm::cast(m_addr, HERE), vm::addr }; + return vm::cast(m_addr, HERE); } T* get_ptr() const @@ -136,22 +138,22 @@ namespace vm _ptr_base operator +() const { - return{ vm::cast(m_addr, HERE), vm::addr }; + return vm::cast(m_addr, HERE); } _ptr_base operator +(u32 count) const { - return{ vm::cast(m_addr, HERE) + count * SIZE_32(T), vm::addr }; + return vm::cast(vm::cast(m_addr, HERE) + count * SIZE_32(T)); } _ptr_base operator -(u32 count) const { - return{ vm::cast(m_addr, HERE) - count * SIZE_32(T), vm::addr }; + return vm::cast(vm::cast(m_addr, HERE) - count * SIZE_32(T)); } friend _ptr_base operator +(u32 count, const _ptr_base& ptr) { - return{ vm::cast(ptr.m_addr, HERE) + count * SIZE_32(T), vm::addr }; + return vm::cast(vm::cast(ptr.m_addr, HERE) + count * SIZE_32(T)); } // Pointer difference operator @@ -163,9 +165,9 @@ namespace vm _ptr_base operator ++(int) { - const addr_type result = m_addr; + _ptr_base result = *this; m_addr = vm::cast(m_addr, HERE) + SIZE_32(T); - return{ result, vm::addr }; + return result; } _ptr_base& operator ++() @@ -176,9 +178,9 @@ namespace vm _ptr_base operator --(int) { - const addr_type result = m_addr; + _ptr_base result = m_addr; m_addr = vm::cast(m_addr, HERE) - SIZE_32(T); - return{ result, vm::addr }; + return result; } _ptr_base& operator --() @@ -210,12 +212,12 @@ namespace vm _ptr_base() = default; - constexpr _ptr_base(addr_type addr, const addr_tag_t&) + _ptr_base(vm::addr_t addr) : m_addr(addr) { } - constexpr addr_type addr() const + addr_type addr() const { return m_addr; } @@ -225,26 +227,28 @@ namespace vm m_addr = addr; } - static constexpr _ptr_base make(addr_type addr) + static _ptr_base make(addr_type addr) { - return{ addr, vm::addr }; + _ptr_base result; + result.m_addr = addr; + return result; } // Conversion to another function pointer template operator _ptr_base() const { - return{ vm::cast(m_addr, HERE), vm::addr }; + return vm::cast(m_addr, HERE); } - explicit constexpr operator bool() const + explicit operator bool() const { return m_addr != 0; } _ptr_base operator +() const { - return{ vm::cast(m_addr, HERE), vm::addr }; + return vm::cast(m_addr, HERE); } // Callback; defined in PPUCallback.h, passing context is mandatory @@ -305,14 +309,14 @@ namespace vm template*>(std::declval()))> inline _ptr_base> static_ptr_cast(const _ptr_base& other) { - return{ vm::cast(other.addr(), HERE), vm::addr }; + return vm::cast(other.addr(), HERE); } // Perform const_cast (for example, vm::cptr to vm::ptr) template*>(std::declval()))> inline _ptr_base> const_ptr_cast(const _ptr_base& other) { - return{ vm::cast(other.addr(), HERE), vm::addr }; + return vm::cast(other.addr(), HERE); } } @@ -343,93 +347,93 @@ namespace vm template*>(std::declval()))> inline _ptr_base> static_ptr_cast(const _ptr_base& other) { - return{ vm::cast(other.addr(), HERE), vm::addr }; + return vm::cast(other.addr(), HERE); } // Perform const_cast (for example, vm::cptr to vm::ptr) template*>(std::declval()))> inline _ptr_base> const_ptr_cast(const _ptr_base& other) { - return{ vm::cast(other.addr(), HERE), vm::addr }; + return vm::cast(other.addr(), HERE); } } struct null_t { template - constexpr operator _ptr_base() const + operator _ptr_base() const { - return _ptr_base{ 0, vm::addr }; + return _ptr_base{}; } template - friend constexpr bool operator ==(const null_t&, const _ptr_base& ptr) + friend bool operator ==(const null_t&, const _ptr_base& ptr) { return !ptr; } template - friend constexpr bool operator ==(const _ptr_base& ptr, const null_t&) + friend bool operator ==(const _ptr_base& ptr, const null_t&) { return !ptr; } template - friend constexpr bool operator !=(const null_t&, const _ptr_base& ptr) + friend bool operator !=(const null_t&, const _ptr_base& ptr) { return ptr.operator bool(); } template - friend constexpr bool operator !=(const _ptr_base& ptr, const null_t&) + friend bool operator !=(const _ptr_base& ptr, const null_t&) { return ptr.operator bool(); } template - friend constexpr bool operator <(const null_t&, const _ptr_base& ptr) + friend bool operator <(const null_t&, const _ptr_base& ptr) { return ptr.operator bool(); } template - friend constexpr bool operator <(const _ptr_base&, const null_t&) + friend bool operator <(const _ptr_base&, const null_t&) { return false; } template - friend constexpr bool operator <=(const null_t&, const _ptr_base&) + friend bool operator <=(const null_t&, const _ptr_base&) { return true; } template - friend constexpr bool operator <=(const _ptr_base& ptr, const null_t&) + friend bool operator <=(const _ptr_base& ptr, const null_t&) { return !ptr.operator bool(); } template - friend constexpr bool operator >(const null_t&, const _ptr_base&) + friend bool operator >(const null_t&, const _ptr_base&) { return false; } template - friend constexpr bool operator >(const _ptr_base& ptr, const null_t&) + friend bool operator >(const _ptr_base& ptr, const null_t&) { return ptr.operator bool(); } template - friend constexpr bool operator >=(const null_t&, const _ptr_base& ptr) + friend bool operator >=(const null_t&, const _ptr_base& ptr) { return !ptr; } template - friend constexpr bool operator >=(const _ptr_base&, const null_t&) + friend bool operator >=(const _ptr_base&, const null_t&) { return true; } diff --git a/rpcs3/Emu/Memory/vm_ref.h b/rpcs3/Emu/Memory/vm_ref.h index 216dff79fc..1d39be5362 100644 --- a/rpcs3/Emu/Memory/vm_ref.h +++ b/rpcs3/Emu/Memory/vm_ref.h @@ -2,9 +2,6 @@ namespace vm { - // Tag which allows to construct vm objects from the address value - static struct addr_tag_t {} constexpr addr{}; - template class _ptr_base; @@ -26,12 +23,12 @@ namespace vm _ref_base(const _ref_base&) = default; - constexpr _ref_base(addr_type addr, const addr_tag_t&) + _ref_base(vm::addr_t addr) : m_addr(addr) { } - constexpr addr_type addr() const + addr_type addr() const { return m_addr; } @@ -44,7 +41,7 @@ namespace vm // convert to vm pointer vm::_ptr_base ptr() const { - return{ vm::cast(m_addr, HERE), vm::addr }; + return vm::cast(m_addr, HERE); } operator simple_t() const diff --git a/rpcs3/Emu/Memory/vm_var.h b/rpcs3/Emu/Memory/vm_var.h index 4420d164b9..9b49aaa87e 100644 --- a/rpcs3/Emu/Memory/vm_var.h +++ b/rpcs3/Emu/Memory/vm_var.h @@ -7,9 +7,9 @@ namespace vm template struct page_allocator { - static inline u32 alloc(u32 size, u32 align) + static inline vm::addr_t alloc(u32 size, u32 align) { - return vm::alloc(size, Location, std::max(align, 4096)); + return vm::cast(vm::alloc(size, Location, std::max(align, 4096))); } static inline void dealloc(u32 addr, u32 size = 0) noexcept @@ -20,9 +20,9 @@ namespace vm struct stack_allocator { - static inline u32 alloc(u32 size, u32 align) + static inline vm::addr_t alloc(u32 size, u32 align) { - return vm::stack_push(size, align); + return vm::cast(vm::stack_push(size, align)); } static inline void dealloc(u32 addr, u32 size) noexcept @@ -39,7 +39,7 @@ namespace vm public: _var_base() - : pointer(A::alloc(SIZE_32(T), ALIGN_32(T)), vm::addr) + : pointer(A::alloc(SIZE_32(T), ALIGN_32(T))) { } @@ -71,7 +71,7 @@ namespace vm public: _var_base(u32 count) - : pointer(A::alloc(SIZE_32(T) * count, ALIGN_32(T)), vm::addr) + : pointer(A::alloc(SIZE_32(T) * count, ALIGN_32(T))) , m_size(SIZE_32(T) * count) { } diff --git a/rpcs3/Emu/Memory/wait_engine.cpp b/rpcs3/Emu/Memory/wait_engine.cpp index ffe441e39e..ed6530a12e 100644 --- a/rpcs3/Emu/Memory/wait_engine.cpp +++ b/rpcs3/Emu/Memory/wait_engine.cpp @@ -6,98 +6,70 @@ #include "Utilities/Thread.h" #include "Utilities/SharedMutex.h" -extern std::condition_variable& get_current_thread_cv(); -extern std::mutex& get_current_thread_mutex(); +#include namespace vm { static shared_mutex s_mutex; - static std::unordered_set s_waiters(256); + static std::unordered_set> s_waiters(256); - bool waiter::try_notify() + void waiter_base::initialize(u32 addr, u32 size) { - { - std::lock_guard lock(*mutex); + EXPECTS(addr && (size & (~size + 1)) == size && (addr & (size - 1)) == 0); - try - { - // Test predicate - if (!pred || !pred()) - { - return false; - } - - // Clear predicate - pred = nullptr; - } - catch (...) - { - // Capture any exception possibly thrown by predicate - pred = [exception = std::current_exception()]() -> bool - { - // New predicate will throw the captured exception from the original thread - std::rethrow_exception(exception); - }; - } - - // Set addr and mask to invalid values to prevent further polling - addr = 0; - mask = ~0; - } - - // Signal thread - cond->notify_one(); - return true; - } - - waiter::~waiter() - { - } - - waiter_lock::waiter_lock(u32 addr, u32 size) - : m_lock(get_current_thread_mutex(), std::defer_lock) - { - Expects(addr && (size & (~size + 1)) == size && (addr & (size - 1)) == 0); - - m_waiter.mutex = m_lock.mutex(); - m_waiter.cond = &get_current_thread_cv(); - m_waiter.addr = addr; - m_waiter.mask = ~(size - 1); + this->addr = addr; + this->mask = ~(size - 1); + this->thread = thread_ctrl::get_current(); { writer_lock lock(s_mutex); - - s_waiters.emplace(&m_waiter); + s_waiters.emplace(this); } - - m_lock.lock(); + + // Wait until thread == nullptr + thread_lock(), thread_ctrl::wait(WRAP_EXPR(!thread || test())); } - void waiter_lock::wait() + bool waiter_base::try_notify() { - // If another thread successfully called pred(), it must be set to null - while (m_waiter.pred) + const auto _t = atomic_storage::load(thread); + + if (UNLIKELY(!_t)) { - // If pred() called by another thread threw an exception, it'll be rethrown - if (m_waiter.pred()) - { - return; - } - - CHECK_EMU_STATUS; - - m_waiter.cond->wait(m_lock); + // Return if thread not found + return false; } + + // Lock the thread + _t->lock(); + + try + { + // Test predicate + if (UNLIKELY(!thread || !test())) + { + _t->unlock(); + return false; + } + } + catch (...) + { + // Capture any exception thrown by the predicate + _t->set_exception(std::current_exception()); + } + + // Signal the thread with nullptr + atomic_storage::store(thread, nullptr); + _t->unlock(); + _t->notify(); + return true; } - waiter_lock::~waiter_lock() + waiter_base::~waiter_base() { - if (m_lock) m_lock.unlock(); - writer_lock lock(s_mutex); - - s_waiters.erase(&m_waiter); + s_waiters.erase(this); } void notify_at(u32 addr, u32 size) @@ -114,44 +86,37 @@ namespace vm } } - static bool notify_all() + // Return amount of threads which are not notified + static std::size_t notify_all() { reader_lock lock(s_mutex); - std::size_t waiters = 0; std::size_t signaled = 0; for (const auto _w : s_waiters) { - if (_w->addr) + if (_w->try_notify()) { - waiters++; - - if (_w->try_notify()) - { - signaled++; - } + signaled++; } } - // return true if waiter list is empty or all available waiters were signaled - return waiters == signaled; + return s_waiters.size() - signaled; } void start() { - // start notification thread - thread_ctrl::spawn("vm::start thread", []() + thread_ctrl::spawn("vm::wait", []() { while (!Emu.IsStopped()) { - // poll waiters periodically (TODO) - while (!notify_all() && !Emu.IsPaused()) + // Poll waiters periodically (TODO) + while (notify_all() && !Emu.IsPaused()) { - std::this_thread::yield(); + thread_ctrl::sleep(50); } - std::this_thread::sleep_for(std::chrono::milliseconds(1)); + thread_ctrl::sleep(1000); } }); } diff --git a/rpcs3/Emu/Memory/wait_engine.h b/rpcs3/Emu/Memory/wait_engine.h index 433884aee7..e674ca7250 100644 --- a/rpcs3/Emu/Memory/wait_engine.h +++ b/rpcs3/Emu/Memory/wait_engine.h @@ -1,61 +1,50 @@ #pragma once -#include -#include -#include +#include "Utilities/types.h" +#include "Utilities/Macro.h" -class named_thread; +class thread_ctrl; namespace vm { - using mutex_t = std::mutex; - using cond_t = std::condition_variable; - - struct waiter + struct waiter_base { u32 addr; u32 mask; - mutex_t* mutex; - cond_t* cond; - - std::function pred; - - ~waiter(); + thread_ctrl* thread{}; + void initialize(u32 addr, u32 size); bool try_notify(); + + protected: + ~waiter_base(); + + virtual bool test() = 0; }; - class waiter_lock + // Wait until pred() returns true, addr must be aligned to size which must be a power of 2. + // It's possible for pred() to be called from any thread once the waiter is registered. + template + auto wait_op(u32 addr, u32 size, F&& pred) -> decltype(static_cast(pred())) { - waiter m_waiter; - std::unique_lock m_lock; + if (LIKELY(pred())) return; - public: - waiter_lock(u32 addr, u32 size); - - waiter* operator ->() + struct waiter : waiter_base { - return &m_waiter; - } + std::conditional_t, F&&> func; - void wait(); + waiter(F&& func) + : func(std::forward(func)) + { + } - ~waiter_lock(); - }; + bool test() override + { + return func(); + } + }; - // Wait until pred() returns true, addr must be aligned to size which must be a power of 2, pred() may be called by any thread - template - auto wait_op(u32 addr, u32 size, F&& pred, Args&&... args) -> decltype(static_cast(pred(args...))) - { - // Return immediately if condition passed (optimistic case) - if (pred(args...)) return; - - waiter_lock lock(addr, size); - - // Initialize predicate - lock->pred = WRAP_EXPR(pred(args...)); - - lock.wait(); + waiter(std::forward(pred)).initialize(addr, size); } // Notify waiters on specific addr, addr must be aligned to size which must be a power of 2 diff --git a/rpcs3/Emu/ARMv7/ARMv7Callback.h b/rpcs3/Emu/PSP2/ARMv7Callback.h similarity index 100% rename from rpcs3/Emu/ARMv7/ARMv7Callback.h rename to rpcs3/Emu/PSP2/ARMv7Callback.h diff --git a/rpcs3/Emu/ARMv7/ARMv7DisAsm.cpp b/rpcs3/Emu/PSP2/ARMv7DisAsm.cpp similarity index 99% rename from rpcs3/Emu/ARMv7/ARMv7DisAsm.cpp rename to rpcs3/Emu/PSP2/ARMv7DisAsm.cpp index 5334757d1c..178fcb3ca2 100644 --- a/rpcs3/Emu/ARMv7/ARMv7DisAsm.cpp +++ b/rpcs3/Emu/PSP2/ARMv7DisAsm.cpp @@ -99,8 +99,8 @@ static const char* fmt_reg(u32 reg) static std::string fmt_shift(u32 type, u32 amount) { - Expects(type != arm_code::SRType_RRX || amount == 1); - Expects(amount <= 32); + EXPECTS(type != arm_code::SRType_RRX || amount == 1); + EXPECTS(amount <= 32); if (amount) { diff --git a/rpcs3/Emu/ARMv7/ARMv7DisAsm.h b/rpcs3/Emu/PSP2/ARMv7DisAsm.h similarity index 100% rename from rpcs3/Emu/ARMv7/ARMv7DisAsm.h rename to rpcs3/Emu/PSP2/ARMv7DisAsm.h diff --git a/rpcs3/Emu/ARMv7/ARMv7Function.cpp b/rpcs3/Emu/PSP2/ARMv7Function.cpp similarity index 100% rename from rpcs3/Emu/ARMv7/ARMv7Function.cpp rename to rpcs3/Emu/PSP2/ARMv7Function.cpp diff --git a/rpcs3/Emu/ARMv7/ARMv7Function.h b/rpcs3/Emu/PSP2/ARMv7Function.h similarity index 100% rename from rpcs3/Emu/ARMv7/ARMv7Function.h rename to rpcs3/Emu/PSP2/ARMv7Function.h diff --git a/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp b/rpcs3/Emu/PSP2/ARMv7Interpreter.cpp similarity index 99% rename from rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp rename to rpcs3/Emu/PSP2/ARMv7Interpreter.cpp index 30330a477a..4e8082fc83 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp +++ b/rpcs3/Emu/PSP2/ARMv7Interpreter.cpp @@ -669,7 +669,7 @@ void arm_interpreter::LDM(ARMv7Thread& cpu, const u32 op, const u32 cond) if (ConditionPassed(cpu, cond)) { - vm::ptr memory(cpu.read_gpr(n), vm::addr); + vm::ptr memory(vm::cast(cpu.read_gpr(n))); for (u32 i = 0; i < 16; i++) { @@ -1384,7 +1384,7 @@ void arm_interpreter::PUSH(ARMv7Thread& cpu, const u32 op, const u32 cond) if (ConditionPassed(cpu, cond)) { - vm::ptr memory(cpu.SP, vm::addr); + vm::ptr memory(vm::cast(cpu.SP)); for (u32 i = 15; ~i; i--) { diff --git a/rpcs3/Emu/ARMv7/ARMv7Interpreter.h b/rpcs3/Emu/PSP2/ARMv7Interpreter.h similarity index 99% rename from rpcs3/Emu/ARMv7/ARMv7Interpreter.h rename to rpcs3/Emu/PSP2/ARMv7Interpreter.h index 33f3b3d622..fd77ae1374 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Interpreter.h +++ b/rpcs3/Emu/PSP2/ARMv7Interpreter.h @@ -48,46 +48,46 @@ struct arm_interpreter static u32 LSL_C(u32 x, s32 shift, bool& carry_out) { - Expects(shift > 0); + EXPECTS(shift > 0); carry_out = shift <= 32 ? (x & (1 << (32 - shift))) != 0 : false; return shift < 32 ? x << shift : 0; } static u32 LSL_(u32 x, s32 shift) { - Expects(shift >= 0); + EXPECTS(shift >= 0); return shift < 32 ? x << shift : 0; } static u32 LSR_C(u32 x, s32 shift, bool& carry_out) { - Expects(shift > 0); + EXPECTS(shift > 0); carry_out = shift <= 32 ? (x & (1 << (shift - 1))) != 0 : false; return shift < 32 ? x >> shift : 0; } static u32 LSR_(u32 x, s32 shift) { - Expects(shift >= 0); + EXPECTS(shift >= 0); return shift < 32 ? x >> shift : 0; } static s32 ASR_C(s32 x, s32 shift, bool& carry_out) { - Expects(shift > 0); + EXPECTS(shift > 0); carry_out = shift <= 32 ? (x & (1 << (shift - 1))) != 0 : x < 0; return shift < 32 ? x >> shift : x >> 31; } static s32 ASR_(s32 x, s32 shift) { - Expects(shift >= 0); + EXPECTS(shift >= 0); return shift < 32 ? x >> shift : x >> 31; } static u32 ROR_C(u32 x, s32 shift, bool& carry_out) { - Expects(shift); + EXPECTS(shift); const u32 result = x >> shift | x << (32 - shift); carry_out = (result >> 31) != 0; return result; @@ -111,7 +111,7 @@ struct arm_interpreter static u32 Shift_C(u32 value, u32 type, s32 amount, bool carry_in, bool& carry_out) { - Expects(type != arm_code::SRType_RRX || amount == 1); + EXPECTS(type != arm_code::SRType_RRX || amount == 1); if (amount) { diff --git a/rpcs3/Emu/ARMv7/ARMv7Module.cpp b/rpcs3/Emu/PSP2/ARMv7Module.cpp similarity index 91% rename from rpcs3/Emu/ARMv7/ARMv7Module.cpp rename to rpcs3/Emu/PSP2/ARMv7Module.cpp index c4a104ce0d..69d4802e77 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Module.cpp +++ b/rpcs3/Emu/PSP2/ARMv7Module.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Loader/ELF.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" @@ -9,6 +10,67 @@ #include "ARMv7Function.h" #include "ARMv7Module.h" +LOG_CHANNEL(sceAppMgr); +LOG_CHANNEL(sceAppUtil); +LOG_CHANNEL(sceAudio); +LOG_CHANNEL(sceAudiodec); +LOG_CHANNEL(sceAudioenc); +LOG_CHANNEL(sceAudioIn); +LOG_CHANNEL(sceCamera); +LOG_CHANNEL(sceCodecEngine); +LOG_CHANNEL(sceCommonDialog); +LOG_CHANNEL(sceCtrl); +LOG_CHANNEL(sceDbg); +LOG_CHANNEL(sceDeci4p); +LOG_CHANNEL(sceDeflt); +LOG_CHANNEL(sceDisplay); +LOG_CHANNEL(sceFiber); +LOG_CHANNEL(sceFios); +LOG_CHANNEL(sceFpu); +LOG_CHANNEL(sceGxm); +LOG_CHANNEL(sceHttp); +LOG_CHANNEL(sceIme); +LOG_CHANNEL(sceJpeg); +LOG_CHANNEL(sceJpegEnc); +LOG_CHANNEL(sceLibc); +LOG_CHANNEL(sceLibKernel); +LOG_CHANNEL(sceLibm); +LOG_CHANNEL(sceLibstdcxx); +LOG_CHANNEL(sceLibXml); +LOG_CHANNEL(sceLiveArea); +LOG_CHANNEL(sceLocation); +LOG_CHANNEL(sceMd5); +LOG_CHANNEL(sceMotion); +LOG_CHANNEL(sceMt19937); +LOG_CHANNEL(sceNet); +LOG_CHANNEL(sceNetCtl); +LOG_CHANNEL(sceNgs); +LOG_CHANNEL(sceNpBasic); +LOG_CHANNEL(sceNpCommon); +LOG_CHANNEL(sceNpManager); +LOG_CHANNEL(sceNpMatching); +LOG_CHANNEL(sceNpScore); +LOG_CHANNEL(sceNpUtility); +LOG_CHANNEL(scePerf); +LOG_CHANNEL(scePgf); +LOG_CHANNEL(scePhotoExport); +LOG_CHANNEL(sceRazorCapture); +LOG_CHANNEL(sceRtc); +LOG_CHANNEL(sceSas); +LOG_CHANNEL(sceScreenShot); +LOG_CHANNEL(sceSfmt); +LOG_CHANNEL(sceSha); +LOG_CHANNEL(sceSqlite); +LOG_CHANNEL(sceSsl); +LOG_CHANNEL(sceSulpha); +LOG_CHANNEL(sceSysmodule); +LOG_CHANNEL(sceSystemGesture); +LOG_CHANNEL(sceTouch); +LOG_CHANNEL(sceUlt); +LOG_CHANNEL(sceVideodec); +LOG_CHANNEL(sceVoice); +LOG_CHANNEL(sceVoiceQoS); + extern void armv7_init_tls(); extern std::string arm_get_function_name(const std::string& module, u32 fnid); @@ -29,18 +91,18 @@ extern void arm_execute_function(ARMv7Thread& cpu, u32 index) { func(cpu); } - catch (const std::exception&) - { - LOG_ERROR(ARMv7, "Function '%s' aborted", cpu.last_function); - cpu.last_function = previous_function; - throw; - } catch (EmulationStopped) { LOG_WARNING(ARMv7, "Function '%s' aborted", cpu.last_function); cpu.last_function = previous_function; throw; } + catch (...) + { + LOG_ERROR(ARMv7, "Function '%s' aborted", cpu.last_function); + cpu.last_function = previous_function; + throw; + } LOG_TRACE(ARMv7, "Function '%s' finished, r0=0x%x", cpu.last_function, cpu.GPR[0]); cpu.last_function = previous_function; @@ -411,7 +473,7 @@ void arm_exec_loader::load() const case 0x6c2224ba: // __sce_moduleinfo { - ASSERT(addr == module_info.addr()); + VERIFY(addr == module_info.addr()); break; } @@ -546,8 +608,8 @@ void arm_exec_loader::load() const LOG_NOTICE(LOADER, "__sce_process_param(*0x%x) analysis...", proc_param); - ASSERT(proc_param->size >= sizeof(psv_process_param_t)); - ASSERT(proc_param->ver == "PSP2"_u32); + VERIFY(proc_param->size >= sizeof(psv_process_param_t)); + VERIFY(proc_param->ver == "PSP2"_u32); LOG_NOTICE(LOADER, "*** size=0x%x; 0x%x, 0x%x, 0x%x", proc_param->size, proc_param->ver, proc_param->unk0, proc_param->unk1); @@ -563,7 +625,7 @@ void arm_exec_loader::load() const LOG_NOTICE(LOADER, "__sce_libcparam(*0x%x) analysis...", libc_param); - ASSERT(libc_param->size >= 0x1c); + VERIFY(libc_param->size >= 0x1c); LOG_NOTICE(LOADER, "*** size=0x%x; 0x%x, 0x%x, 0x%x", libc_param->size, libc_param->unk0, libc_param->unk1, libc_param->unk2); diff --git a/rpcs3/Emu/ARMv7/ARMv7Module.h b/rpcs3/Emu/PSP2/ARMv7Module.h similarity index 93% rename from rpcs3/Emu/ARMv7/ARMv7Module.h rename to rpcs3/Emu/PSP2/ARMv7Module.h index 8083f9b581..3a40c3b0ef 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Module.h +++ b/rpcs3/Emu/PSP2/ARMv7Module.h @@ -1,6 +1,5 @@ #pragma once -#include "Utilities/Config.h" #include "ARMv7Function.h" #include "ARMv7Callback.h" #include "ErrorCodes.h" @@ -167,37 +166,3 @@ public: #define REG_FNID(module, nid, func, ...) arm_module_manager::register_static_function(#module, #func, BIND_FUNC(func), nid, {__VA_ARGS__}) #define REG_VNID(module, nid, var, ...) arm_module_manager::register_static_variable(#module, #var, nid, {__VA_ARGS__}) - -struct SceDateTime -{ - le_t year; - le_t month; - le_t day; - le_t hour; - le_t minute; - le_t second; - le_t microsecond; -}; - -struct SceFVector3 -{ - le_t x, y, z; -}; - -struct SceFQuaternion -{ - le_t x, y, z, w; -}; - -union SceUMatrix4 -{ - struct - { - le_t f[4][4]; - }; - - struct - { - le_t i[4][4]; - }; -}; diff --git a/rpcs3/Emu/ARMv7/ARMv7Opcodes.h b/rpcs3/Emu/PSP2/ARMv7Opcodes.h similarity index 100% rename from rpcs3/Emu/ARMv7/ARMv7Opcodes.h rename to rpcs3/Emu/PSP2/ARMv7Opcodes.h diff --git a/rpcs3/Emu/ARMv7/ARMv7Thread.cpp b/rpcs3/Emu/PSP2/ARMv7Thread.cpp similarity index 100% rename from rpcs3/Emu/ARMv7/ARMv7Thread.cpp rename to rpcs3/Emu/PSP2/ARMv7Thread.cpp diff --git a/rpcs3/Emu/ARMv7/ARMv7Thread.h b/rpcs3/Emu/PSP2/ARMv7Thread.h similarity index 96% rename from rpcs3/Emu/ARMv7/ARMv7Thread.h rename to rpcs3/Emu/PSP2/ARMv7Thread.h index 7b9e619a08..59b9c393a9 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Thread.h +++ b/rpcs3/Emu/PSP2/ARMv7Thread.h @@ -129,7 +129,7 @@ public: std::array counters{}; u32 PC = 0; - s32 prio = 0; + u32 prio = -1; u32 stack_addr = 0; u32 stack_size = 0; @@ -155,7 +155,7 @@ public: void write_gpr(u32 n, u32 value, u32 size) { - Expects(n < 16); + EXPECTS(n < 16); if (n < 15) { @@ -169,7 +169,7 @@ public: u32 read_gpr(u32 n) { - Expects(n < 16); + EXPECTS(n < 16); if (n < 15) { @@ -242,7 +242,7 @@ struct arm_gpr_cast_impl, void> static inline vm::_ptr_base from(const u32 reg) { - return{ arm_gpr_cast_impl::from(reg), vm::addr }; + return vm::cast(arm_gpr_cast_impl::from(reg)); } }; @@ -256,7 +256,7 @@ struct arm_gpr_cast_impl, void> static inline vm::_ref_base from(const u32 reg) { - return{ arm_gpr_cast_impl::from(reg), vm::addr }; + return vm::cast(arm_gpr_cast_impl::from(reg)); } }; diff --git a/rpcs3/Emu/ARMv7/ErrorCodes.h b/rpcs3/Emu/PSP2/ErrorCodes.h similarity index 98% rename from rpcs3/Emu/ARMv7/ErrorCodes.h rename to rpcs3/Emu/PSP2/ErrorCodes.h index 7cba3359e8..924c337b5d 100644 --- a/rpcs3/Emu/ARMv7/ErrorCodes.h +++ b/rpcs3/Emu/PSP2/ErrorCodes.h @@ -179,9 +179,12 @@ struct arm_error_code { } + // Helper + enum class not_an_error : s32 {}; + // Silence any error - constexpr arm_error_code(s32 value, const std::nothrow_t&) - : value(value) + constexpr arm_error_code(not_an_error value) + : value(static_cast(value)) { } @@ -193,7 +196,7 @@ struct arm_error_code }; // Helper macro for silencing possible error checks on returning arm_error_code values -#define NOT_AN_ERROR(value) { static_cast(value), std::nothrow } +#define NOT_AN_ERROR(...) static_cast(static_cast(__VA_ARGS__)) template struct arm_gpr_cast_impl; diff --git a/rpcs3/Emu/PSP2/Modules/Common.h b/rpcs3/Emu/PSP2/Modules/Common.h new file mode 100644 index 0000000000..c86c93de3e --- /dev/null +++ b/rpcs3/Emu/PSP2/Modules/Common.h @@ -0,0 +1,38 @@ +#pragma once + +#include "Utilities/types.h" +#include "Utilities/BEType.h" + +struct SceDateTime +{ + le_t year; + le_t month; + le_t day; + le_t hour; + le_t minute; + le_t second; + le_t microsecond; +}; + +struct SceFVector3 +{ + le_t x, y, z; +}; + +struct SceFQuaternion +{ + le_t x, y, z, w; +}; + +union SceUMatrix4 +{ + struct + { + le_t f[4][4]; + }; + + struct + { + le_t i[4][4]; + }; +}; diff --git a/rpcs3/Emu/ARMv7/Modules/sceAppMgr.cpp b/rpcs3/Emu/PSP2/Modules/sceAppMgr.cpp similarity index 88% rename from rpcs3/Emu/ARMv7/Modules/sceAppMgr.cpp rename to rpcs3/Emu/PSP2/Modules/sceAppMgr.cpp index 1dee409ee3..9d3661a650 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceAppMgr.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceAppMgr.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceAppMgr.h" -LOG_CHANNEL(sceAppMgr); +logs::channel sceAppMgr("sceAppMgr", logs::level::notice); s32 sceAppMgrReceiveEventNum(vm::ptr eventNum) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceAppMgr.h b/rpcs3/Emu/PSP2/Modules/sceAppMgr.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceAppMgr.h rename to rpcs3/Emu/PSP2/Modules/sceAppMgr.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceAppUtil.cpp b/rpcs3/Emu/PSP2/Modules/sceAppUtil.cpp similarity index 96% rename from rpcs3/Emu/ARMv7/Modules/sceAppUtil.cpp rename to rpcs3/Emu/PSP2/Modules/sceAppUtil.cpp index 6d63c2bf94..267bbbfba8 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceAppUtil.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceAppUtil.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceAppUtil.h" -LOG_CHANNEL(sceAppUtil); +logs::channel sceAppUtil("sceAppUtil", logs::level::notice); s32 sceAppUtilInit(vm::cptr initParam, vm::ptr bootParam) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceAppUtil.h b/rpcs3/Emu/PSP2/Modules/sceAppUtil.h similarity index 98% rename from rpcs3/Emu/ARMv7/Modules/sceAppUtil.h rename to rpcs3/Emu/PSP2/Modules/sceAppUtil.h index 3e3ef55694..3e35140209 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceAppUtil.h +++ b/rpcs3/Emu/PSP2/Modules/sceAppUtil.h @@ -1,5 +1,7 @@ #pragma once +#include "Common.h" + struct SceAppUtilInitParam { le_t workBufSize; diff --git a/rpcs3/Emu/ARMv7/Modules/sceAudio.cpp b/rpcs3/Emu/PSP2/Modules/sceAudio.cpp similarity index 93% rename from rpcs3/Emu/ARMv7/Modules/sceAudio.cpp rename to rpcs3/Emu/PSP2/Modules/sceAudio.cpp index 0261c2e89b..447c19a83b 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceAudio.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceAudio.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceAudio.h" -LOG_CHANNEL(sceAudio); +logs::channel sceAudio("sceAudio", logs::level::notice); s32 sceAudioOutOpenPort(s32 portType, s32 len, s32 freq, s32 param) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceAudio.h b/rpcs3/Emu/PSP2/Modules/sceAudio.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceAudio.h rename to rpcs3/Emu/PSP2/Modules/sceAudio.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceAudioIn.cpp b/rpcs3/Emu/PSP2/Modules/sceAudioIn.cpp similarity index 86% rename from rpcs3/Emu/ARMv7/Modules/sceAudioIn.cpp rename to rpcs3/Emu/PSP2/Modules/sceAudioIn.cpp index b97a8c6988..870adbdbc7 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceAudioIn.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceAudioIn.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceAudioIn.h" -LOG_CHANNEL(sceAudioIn); +logs::channel sceAudioIn("sceAudioIn", logs::level::notice); s32 sceAudioInOpenPort(s32 portType, s32 grain, s32 freq, s32 param) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceAudioIn.h b/rpcs3/Emu/PSP2/Modules/sceAudioIn.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceAudioIn.h rename to rpcs3/Emu/PSP2/Modules/sceAudioIn.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceAudiodec.cpp b/rpcs3/Emu/PSP2/Modules/sceAudiodec.cpp similarity index 92% rename from rpcs3/Emu/ARMv7/Modules/sceAudiodec.cpp rename to rpcs3/Emu/PSP2/Modules/sceAudiodec.cpp index bce2640203..00fd6ac245 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceAudiodec.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceAudiodec.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceAudiodec.h" -LOG_CHANNEL(sceAudiodec); +logs::channel sceAudiodec("sceAudiodec", logs::level::notice); s32 sceAudiodecInitLibrary(u32 codecType, vm::ptr pInitParam) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceAudiodec.h b/rpcs3/Emu/PSP2/Modules/sceAudiodec.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceAudiodec.h rename to rpcs3/Emu/PSP2/Modules/sceAudiodec.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceAudioenc.cpp b/rpcs3/Emu/PSP2/Modules/sceAudioenc.cpp similarity index 93% rename from rpcs3/Emu/ARMv7/Modules/sceAudioenc.cpp rename to rpcs3/Emu/PSP2/Modules/sceAudioenc.cpp index ca7bc17aec..0b26d376dd 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceAudioenc.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceAudioenc.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceAudioenc.h" -LOG_CHANNEL(sceAudioenc); +logs::channel sceAudioenc("sceAudioenc", logs::level::notice); s32 sceAudioencInitLibrary(u32 codecType, vm::ptr pInitParam) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceAudioenc.h b/rpcs3/Emu/PSP2/Modules/sceAudioenc.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceAudioenc.h rename to rpcs3/Emu/PSP2/Modules/sceAudioenc.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceCamera.cpp b/rpcs3/Emu/PSP2/Modules/sceCamera.cpp similarity index 98% rename from rpcs3/Emu/ARMv7/Modules/sceCamera.cpp rename to rpcs3/Emu/PSP2/Modules/sceCamera.cpp index 766b450b4f..4bfe8de61d 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceCamera.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceCamera.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceCamera.h" -LOG_CHANNEL(sceCamera); +logs::channel sceCamera("sceCamera", logs::level::notice); s32 sceCameraOpen(s32 devnum, vm::ptr pInfo) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceCamera.h b/rpcs3/Emu/PSP2/Modules/sceCamera.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceCamera.h rename to rpcs3/Emu/PSP2/Modules/sceCamera.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceCodecEngine.cpp b/rpcs3/Emu/PSP2/Modules/sceCodecEngine.cpp similarity index 87% rename from rpcs3/Emu/ARMv7/Modules/sceCodecEngine.cpp rename to rpcs3/Emu/PSP2/Modules/sceCodecEngine.cpp index 0fb17012d2..ecb2dc7021 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceCodecEngine.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceCodecEngine.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceCodecEngine.h" -LOG_CHANNEL(sceCodecEngine); +logs::channel sceCodecEngine("sceCodecEngine", logs::level::notice); s32 sceCodecEnginePmonStart() { diff --git a/rpcs3/Emu/ARMv7/Modules/sceCodecEngine.h b/rpcs3/Emu/PSP2/Modules/sceCodecEngine.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceCodecEngine.h rename to rpcs3/Emu/PSP2/Modules/sceCodecEngine.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceCommonDialog.cpp b/rpcs3/Emu/PSP2/Modules/sceCommonDialog.cpp similarity index 98% rename from rpcs3/Emu/ARMv7/Modules/sceCommonDialog.cpp rename to rpcs3/Emu/PSP2/Modules/sceCommonDialog.cpp index c3c290dc53..254972d198 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceCommonDialog.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceCommonDialog.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceCommonDialog.h" -LOG_CHANNEL(sceCommonDialog); +logs::channel sceCommonDialog("sceCommonDialog", logs::level::notice); s32 sceCommonDialogUpdate(vm::cptr updateParam) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceCommonDialog.h b/rpcs3/Emu/PSP2/Modules/sceCommonDialog.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceCommonDialog.h rename to rpcs3/Emu/PSP2/Modules/sceCommonDialog.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceCtrl.cpp b/rpcs3/Emu/PSP2/Modules/sceCtrl.cpp similarity index 93% rename from rpcs3/Emu/ARMv7/Modules/sceCtrl.cpp rename to rpcs3/Emu/PSP2/Modules/sceCtrl.cpp index 1351e97738..ca5f36e827 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceCtrl.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceCtrl.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceCtrl.h" -LOG_CHANNEL(sceCtrl); +logs::channel sceCtrl("sceCtrl", logs::level::notice); s32 sceCtrlSetSamplingMode(u32 uiMode) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceCtrl.h b/rpcs3/Emu/PSP2/Modules/sceCtrl.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceCtrl.h rename to rpcs3/Emu/PSP2/Modules/sceCtrl.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceDbg.cpp b/rpcs3/Emu/PSP2/Modules/sceDbg.cpp similarity index 91% rename from rpcs3/Emu/ARMv7/Modules/sceDbg.cpp rename to rpcs3/Emu/PSP2/Modules/sceDbg.cpp index 3617d18e07..dacfd1066c 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceDbg.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceDbg.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceDbg.h" -LOG_CHANNEL(sceDbg); +logs::channel sceDbg("sceDbg", logs::level::notice); s32 sceDbgSetMinimumLogLevel(s32 minimumLogLevel) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceDbg.h b/rpcs3/Emu/PSP2/Modules/sceDbg.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceDbg.h rename to rpcs3/Emu/PSP2/Modules/sceDbg.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceDeci4p.cpp b/rpcs3/Emu/PSP2/Modules/sceDeci4p.cpp similarity index 90% rename from rpcs3/Emu/ARMv7/Modules/sceDeci4p.cpp rename to rpcs3/Emu/PSP2/Modules/sceDeci4p.cpp index abacc1199e..3b79bb78ee 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceDeci4p.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceDeci4p.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceDeci4p.h" -LOG_CHANNEL(sceDeci4p); +logs::channel sceDeci4p("sceDeci4p", logs::level::notice); s32 sceKernelDeci4pOpen(vm::cptr protoname, u32 protonum, u32 bufsize) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceDeci4p.h b/rpcs3/Emu/PSP2/Modules/sceDeci4p.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceDeci4p.h rename to rpcs3/Emu/PSP2/Modules/sceDeci4p.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceDeflt.cpp b/rpcs3/Emu/PSP2/Modules/sceDeflt.cpp similarity index 95% rename from rpcs3/Emu/ARMv7/Modules/sceDeflt.cpp rename to rpcs3/Emu/PSP2/Modules/sceDeflt.cpp index dc70310c59..32e34b9060 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceDeflt.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceDeflt.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceDeflt.h" -LOG_CHANNEL(sceDeflt); +logs::channel sceDeflt("sceDeflt", logs::level::notice); s32 sceGzipIsValid(vm::cptr pSrcGzip) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceDeflt.h b/rpcs3/Emu/PSP2/Modules/sceDeflt.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceDeflt.h rename to rpcs3/Emu/PSP2/Modules/sceDeflt.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceDisplay.cpp b/rpcs3/Emu/PSP2/Modules/sceDisplay.cpp similarity index 95% rename from rpcs3/Emu/ARMv7/Modules/sceDisplay.cpp rename to rpcs3/Emu/PSP2/Modules/sceDisplay.cpp index b9f978e3b0..a069620b79 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceDisplay.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceDisplay.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceDisplay.h" -LOG_CHANNEL(sceDisplay); +logs::channel sceDisplay("sceDisplay", logs::level::notice); s32 sceDisplayGetRefreshRate(vm::ptr pFps) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceDisplay.h b/rpcs3/Emu/PSP2/Modules/sceDisplay.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceDisplay.h rename to rpcs3/Emu/PSP2/Modules/sceDisplay.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceFiber.cpp b/rpcs3/Emu/PSP2/Modules/sceFiber.cpp similarity index 94% rename from rpcs3/Emu/ARMv7/Modules/sceFiber.cpp rename to rpcs3/Emu/PSP2/Modules/sceFiber.cpp index bc769383df..14cb3ea270 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceFiber.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceFiber.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceFiber.h" -LOG_CHANNEL(sceFiber); +logs::channel sceFiber("sceFiber", logs::level::notice); s32 _sceFiberInitializeImpl(vm::ptr fiber, vm::cptr name, vm::ptr entry, u32 argOnInitialize, vm::ptr addrContext, u32 sizeContext, vm::cptr optParam, u32 buildVersion) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceFiber.h b/rpcs3/Emu/PSP2/Modules/sceFiber.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceFiber.h rename to rpcs3/Emu/PSP2/Modules/sceFiber.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceFios.cpp b/rpcs3/Emu/PSP2/Modules/sceFios.cpp similarity index 99% rename from rpcs3/Emu/ARMv7/Modules/sceFios.cpp rename to rpcs3/Emu/PSP2/Modules/sceFios.cpp index 67420d112f..08f24eb6dd 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceFios.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceFios.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceFios.h" -LOG_CHANNEL(sceFios); +logs::channel sceFios("sceFios", logs::level::notice); s32 sceFiosInitialize(vm::cptr pParameters) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceFios.h b/rpcs3/Emu/PSP2/Modules/sceFios.h similarity index 99% rename from rpcs3/Emu/ARMv7/Modules/sceFios.h rename to rpcs3/Emu/PSP2/Modules/sceFios.h index 569c663893..838e31b5ce 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceFios.h +++ b/rpcs3/Emu/PSP2/Modules/sceFios.h @@ -1,5 +1,7 @@ #pragma once +#include "Common.h" + using SceFiosOpCallback = s32(vm::ptr pContext, s32 op, u8 event, s32 err); using SceFiosVprintfCallback = s32(vm::cptr fmt, arm_va_args_t ap /* va_list */); using SceFiosMemcpyCallback = vm::ptr(vm::ptr dst, vm::cptr src, u32 len); diff --git a/rpcs3/Emu/ARMv7/Modules/sceFpu.cpp b/rpcs3/Emu/PSP2/Modules/sceFpu.cpp similarity index 94% rename from rpcs3/Emu/ARMv7/Modules/sceFpu.cpp rename to rpcs3/Emu/PSP2/Modules/sceFpu.cpp index 9dda61cf8e..e6480e5528 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceFpu.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceFpu.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceFpu.h" -LOG_CHANNEL(sceFpu); +logs::channel sceFpu("sceFpu", logs::level::notice); float sceFpuSinf(float x) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceFpu.h b/rpcs3/Emu/PSP2/Modules/sceFpu.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceFpu.h rename to rpcs3/Emu/PSP2/Modules/sceFpu.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceGxm.cpp b/rpcs3/Emu/PSP2/Modules/sceGxm.cpp similarity index 99% rename from rpcs3/Emu/ARMv7/Modules/sceGxm.cpp rename to rpcs3/Emu/PSP2/Modules/sceGxm.cpp index 22fb6d3a92..3f433da956 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceGxm.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceGxm.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceGxm.h" -LOG_CHANNEL(sceGxm); +logs::channel sceGxm("sceGxm", logs::level::notice); s32 sceGxmInitialize(vm::cptr params) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceGxm.h b/rpcs3/Emu/PSP2/Modules/sceGxm.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceGxm.h rename to rpcs3/Emu/PSP2/Modules/sceGxm.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceHttp.cpp b/rpcs3/Emu/PSP2/Modules/sceHttp.cpp similarity index 99% rename from rpcs3/Emu/ARMv7/Modules/sceHttp.cpp rename to rpcs3/Emu/PSP2/Modules/sceHttp.cpp index 1889742d60..c52183762e 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceHttp.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceHttp.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceHttp.h" -LOG_CHANNEL(sceHttp); +logs::channel sceHttp("sceHttp", logs::level::notice); s32 sceHttpInit(u32 poolSize) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceHttp.h b/rpcs3/Emu/PSP2/Modules/sceHttp.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceHttp.h rename to rpcs3/Emu/PSP2/Modules/sceHttp.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceIme.cpp b/rpcs3/Emu/PSP2/Modules/sceIme.cpp similarity index 89% rename from rpcs3/Emu/ARMv7/Modules/sceIme.cpp rename to rpcs3/Emu/PSP2/Modules/sceIme.cpp index 7404b7d5d5..c8499c0b5c 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceIme.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceIme.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceIme.h" -LOG_CHANNEL(sceIme); +logs::channel sceIme("sceIme", logs::level::notice); s32 sceImeOpen(vm::ptr param) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceIme.h b/rpcs3/Emu/PSP2/Modules/sceIme.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceIme.h rename to rpcs3/Emu/PSP2/Modules/sceIme.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceJpeg.cpp b/rpcs3/Emu/PSP2/Modules/sceJpeg.cpp similarity index 95% rename from rpcs3/Emu/ARMv7/Modules/sceJpeg.cpp rename to rpcs3/Emu/PSP2/Modules/sceJpeg.cpp index cc003a075a..1bc2fcf01b 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceJpeg.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceJpeg.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceJpeg.h" -LOG_CHANNEL(sceJpeg); +logs::channel sceJpeg("sceJpeg", logs::level::notice); s32 sceJpegInitMJpeg(s32 maxSplitDecoder) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceJpeg.h b/rpcs3/Emu/PSP2/Modules/sceJpeg.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceJpeg.h rename to rpcs3/Emu/PSP2/Modules/sceJpeg.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceJpegEnc.cpp b/rpcs3/Emu/PSP2/Modules/sceJpegEnc.cpp similarity index 94% rename from rpcs3/Emu/ARMv7/Modules/sceJpegEnc.cpp rename to rpcs3/Emu/PSP2/Modules/sceJpegEnc.cpp index 6146d926ba..afec5b64b1 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceJpegEnc.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceJpegEnc.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceJpegEnc.h" -LOG_CHANNEL(sceJpegEnc); +logs::channel sceJpegEnc("sceJpegEnc", logs::level::notice); s32 sceJpegEncoderGetContextSize() { diff --git a/rpcs3/Emu/ARMv7/Modules/sceJpegEnc.h b/rpcs3/Emu/PSP2/Modules/sceJpegEnc.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceJpegEnc.h rename to rpcs3/Emu/PSP2/Modules/sceJpegEnc.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceLibKernel.cpp b/rpcs3/Emu/PSP2/Modules/sceLibKernel.cpp similarity index 77% rename from rpcs3/Emu/ARMv7/Modules/sceLibKernel.cpp rename to rpcs3/Emu/PSP2/Modules/sceLibKernel.cpp index f2ce259f97..114e7341bf 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceLibKernel.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceLibKernel.cpp @@ -1,18 +1,20 @@ #include "stdafx.h" #include "Emu/System.h" #include "Emu/IdManager.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/IPC.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceLibKernel.h" #include "Utilities/StrUtil.h" +#include "Utilities/lockless.h" -LOG_CHANNEL(sceLibKernel); +#include + +logs::channel sceLibKernel("sceLibKernel", logs::level::notice); extern u64 get_system_time(); -extern std::condition_variable& get_current_thread_cv(); - s32 sceKernelAllocMemBlock(vm::cptr name, s32 type, u32 vsize, vm::ptr pOpt) { throw EXCEPTION(""); @@ -75,7 +77,7 @@ arm_error_code sceKernelStartThread(s32 threadId, u32 argSize, vm::cptr pA thread->GPR[1] = pos; thread->state -= cpu_state::stop; - thread->lock_notify(); + (*thread)->lock_notify(); return SCE_OK; } @@ -207,19 +209,6 @@ s32 sceKernelGetSystemInfo(vm::ptr pInfo) throw EXCEPTION(""); } -arm_error_code sceKernelGetThreadmgrUIDClass(s32 uid) -{ - sceLibKernel.error("sceKernelGetThreadmgrUIDClass(uid=0x%x)", uid); - - if (idm::check(uid)) return SCE_KERNEL_THREADMGR_UID_CLASS_THREAD; - if (idm::check(uid)) return SCE_KERNEL_THREADMGR_UID_CLASS_SEMA; - if (idm::check(uid)) return SCE_KERNEL_THREADMGR_UID_CLASS_EVENT_FLAG; - if (idm::check(uid)) return SCE_KERNEL_THREADMGR_UID_CLASS_MUTEX; - if (idm::check(uid)) return SCE_KERNEL_THREADMGR_UID_CLASS_COND; - - return SCE_KERNEL_ERROR_INVALID_UID; -} - s32 sceKernelChangeThreadVfpException(s32 clearMask, s32 setMask) { sceLibKernel.todo("sceKernelChangeThreadVfpException(clearMask=0x%x, setMask=0x%x)", clearMask, setMask); @@ -263,12 +252,7 @@ arm_error_code sceKernelWaitThreadEnd(s32 threadId, vm::ptr pExitStatus, vm { } - while (!(thread->state & cpu_state::exit)) - { - CHECK_EMU_STATUS; - - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack - } + (*thread)->join(); if (pExitStatus) { @@ -374,20 +358,352 @@ s32 sceKernelWaitMultipleEventsCB(vm::ptr pWaitEventList, s3 throw EXCEPTION(""); } -// Event flag functions +struct psp2_event_flag final +{ + struct alignas(8) ctrl_t + { + u32 waiters; + u32 pattern; + }; + + atomic_t ctrl; // Sync variable + atomic_t wait_ctr{}; // FIFO ordering helper + + using ipc = ipc_manager; + + const std::string name; // IPC/Debug Name + atomic_t ipc_ref{1}; // IPC Ref Count + + const u32 attr; + const u32 init; + + psp2_event_flag(std::string&& name, u32 attr, u32 pattern) + : ctrl({0, pattern}) + , name(std::move(name)) + , attr(attr) + , init(pattern) + { + } + + static inline bool pat_test(u32 current, u32 pattern, u32 mode) + { + const u32 or_mask = mode & SCE_KERNEL_EVF_WAITMODE_OR ? pattern : 0; + const u32 and_mask = mode & SCE_KERNEL_EVF_WAITMODE_OR ? 0 : pattern; + + return (current & or_mask) != 0 && (current & and_mask) == and_mask; + } + + // Get mask for bitwise AND for bit clear operation + static inline u32 pat_clear(u32 pattern, u32 mode) + { + return + mode & SCE_KERNEL_EVF_WAITMODE_CLEAR_ALL ? 0 : + mode & SCE_KERNEL_EVF_WAITMODE_CLEAR_PAT ? ~pattern : ~0; + } + + // Commands + enum class task : u32 + { + null = 0, + wait, + poll, + set, + clear, + cancel, + destroy, + signal, + }; + + struct alignas(8) cmd_t + { + task type; + u32 arg; + }; + + // Enqueue a command and try to execute all pending commands. Commands are executed sequentially. + // Returns true if the command has been completed immediately. Its status is unknown otherwise. + bool exec(task type, u32 arg) + { + // Acquire position in the queue + const u32 push_pos = m_workload.push_begin(); + + // Make the command + cmd_t cmd{type, arg}; + + u32 pos = m_workload.peek(); + + // Check optimistic case + if (UNLIKELY(pos != push_pos)) + { + // Write the command + m_workload[push_pos] = cmd; + pos = m_workload.peek(); // ??? + + // Try to acquire a command + cmd = m_workload[pos].exchange({task::null}); + } + + while (true) + { + switch (cmd.type) + { + case task::null: + { + // Return immediately if can't process a command. Possible reasons: + // 1) The command has not yet been written + // 2) The command has already been acquired + return push_pos < pos; + } + + case task::wait: op_wait(cmd.arg); break; + case task::poll: op_poll(cmd.arg); break; + case task::set: op_set(cmd.arg); break; + case task::clear: op_clear(cmd.arg); break; + case task::cancel: op_stop(vm::cast(cmd.arg), SCE_KERNEL_ERROR_WAIT_CANCEL); break; + case task::destroy: op_stop(vm::cast(cmd.arg), SCE_KERNEL_ERROR_WAIT_DELETE); break; + + case task::signal: + { + idm::get(cmd.arg, [&](u32, ARMv7Thread& cpu) + { + cpu.state += cpu_state::signal; + cpu->lock_notify(); + }); + + break; + } + + default: ASSUME(0); + } + + // Get next position + pos = m_workload.pop_end(); + + // Exit after the cleanup + if (LIKELY(!pos)) return true; + + // Get next command + cmd = m_workload[pos].exchange({task::null}); + } + } + + // Enqueue a command and ensure its completion. + void sync(ARMv7Thread& cpu, task type, u32 arg) + { + if (UNLIKELY(!exec(type, arg))) + { + if (!exec(task::signal, cpu.id)) + { + thread_lock{cpu}, thread_ctrl::wait(WRAP_EXPR(cpu.state.test_and_reset(cpu_state::signal))); + } + else + { + cpu.state -= cpu_state::signal; + } + } + } + +private: + lf_fifo, 16> m_workload; + + // Check condition + void op_wait(u32 thread_id) + { + idm::get(thread_id, [&](u32, ARMv7Thread& cpu) + { + const u32 pattern = ctrl.atomic_op([&](psp2_event_flag::ctrl_t& state) -> u32 + { + const u32 pat = state.pattern; + if (pat_test(pat, cpu.GPR[1], cpu.GPR[0])) + { + state.pattern &= pat_clear(cpu.GPR[1], cpu.GPR[0]); + state.waiters -= attr & SCE_KERNEL_ATTR_MULTI ? 1 : cpu.id; + return pat; + } + + return 0; + }); + + if (pattern) + { + cpu.GPR[0] = SCE_OK; + cpu.GPR[1] = pattern; + cpu.state += cpu_state::signal; + cpu->lock_notify(); + } + else + { + cpu.owner = this; + cpu.GPR_D[1] = ++wait_ctr; + } + }); + } + + // Check condition + void op_poll(u32 thread_id) + { + idm::get(thread_id, [&](u32, ARMv7Thread& cpu) + { + cpu.GPR[1] = ctrl.atomic_op([&](psp2_event_flag::ctrl_t& state) -> u32 + { + const u32 pat = state.pattern; + if (pat_test(pat, cpu.GPR[1], cpu.GPR[0])) + { + state.pattern &= pat_clear(cpu.GPR[1], cpu.GPR[0]); + return pat; + } + + return 0; + }); + }); + } + + // Set pattern bits and wake up threads + void op_set(u32 pattern) + { + const auto new_state = ctrl.op_fetch([&](psp2_event_flag::ctrl_t& state) + { + state.pattern |= pattern; + }); + + if (new_state.waiters) + { + std::vector> threads; + + // Check and lock appropriate threads + if (attr & SCE_KERNEL_ATTR_MULTI) + { + threads.reserve(new_state.waiters); + + idm::select([&](u32 id, ARMv7Thread& cpu) + { + if (cpu->lock_if(WRAP_EXPR(cpu.owner == this && pat_test(new_state.pattern, cpu.GPR[1], cpu.GPR[0])))) + { + threads.emplace_back(cpu); + } + }); + + // Sort the thread list using appropriate scheduling policy + std::sort(threads.begin(), threads.end(), [&](const ARMv7Thread& cpu1, const ARMv7Thread& cpu2) + { + if (attr & SCE_KERNEL_ATTR_TH_PRIO && cpu1.prio != cpu2.prio) + { + return cpu1.prio < cpu2.prio; + } + else + { + return cpu1.GPR_D[1] < cpu2.GPR_D[1]; + } + }); + } + else + { + idm::get(new_state.waiters, [&](u32 id, ARMv7Thread& cpu) + { + if (cpu->lock_if(WRAP_EXPR(cpu.owner == this && pat_test(new_state.pattern, cpu.GPR[1], cpu.GPR[0])))) + { + threads.emplace_back(cpu); + } + }); + } + + // Wake up threads + for (ARMv7Thread& cpu : threads) + { + const u32 old_pattern = ctrl.atomic_op([&](psp2_event_flag::ctrl_t& state) -> u32 + { + const u32 pat = state.pattern; + + if (pat_test(pat, cpu.GPR[1], cpu.GPR[0])) + { + state.pattern &= pat_clear(cpu.GPR[1], cpu.GPR[0]); + state.waiters -= attr & SCE_KERNEL_ATTR_MULTI ? 1 : cpu.id; + return pat; + } + + return 0; + }); + + if (old_pattern) + { + cpu.GPR[0] = SCE_OK; + cpu.GPR[1] = old_pattern; + cpu.state += cpu_state::signal; + cpu.owner = nullptr; + cpu->unlock(); + cpu->notify(); + } + else + { + cpu->unlock(); + } + } + } + } + + // Clear pattern bits (bitwise AND) + void op_clear(u32 pattern) + { + ctrl.atomic_op([&](psp2_event_flag::ctrl_t& state) + { + state.pattern &= pattern; + }); + } + + // Wake up all threads + void op_stop(vm::ptr ptr, s32 error) + { + s32 result = 0; + const u32 pattern = ptr ? ptr->value() : ctrl.load().pattern; + + idm::select([&](u32, ARMv7Thread& cpu) + { + if (cpu->lock_if(WRAP_EXPR(cpu.owner == this))) + { + cpu.GPR[0] = error; + cpu.GPR[1] = pattern; + cpu.state += cpu_state::signal; + cpu.owner = nullptr; + cpu->unlock(); + cpu->notify(); + result++; + } + }); + + if (ptr) + { + *ptr = result; + } + + ctrl.atomic_op([&](psp2_event_flag::ctrl_t& state) + { + state.pattern = pattern; + state.waiters = attr & SCE_KERNEL_ATTR_MULTI ? state.waiters - result : 0; + }); + } +}; + +template<> DECLARE(psp2_event_flag::ipc::g_ipc) {}; arm_error_code sceKernelCreateEventFlag(vm::cptr pName, u32 attr, u32 initPattern, vm::cptr pOptParam) { sceLibKernel.error("sceKernelCreateEventFlag(pName=*0x%x, attr=0x%x, initPattern=0x%x, pOptParam=*0x%x)", pName, attr, initPattern, pOptParam); - return NOT_AN_ERROR(idm::make(pName.get_ptr(), attr, initPattern)); + // Create EVF + auto evf = std::make_shared(pName.get_ptr(), attr, initPattern); + + // Try to register IPC name, only if not empty string (TODO) + if (evf->name.empty() || !psp2_event_flag::ipc::add(evf->name, WRAP_EXPR(evf))) evf->ipc_ref = 0; + + // Register ID + return NOT_AN_ERROR(idm::import_existing(evf)); } arm_error_code sceKernelDeleteEventFlag(s32 evfId) { sceLibKernel.error("sceKernelDeleteEventFlag(evfId=0x%x)", evfId); - const auto evf = idm::withdraw(evfId); + const auto evf = idm::withdraw(evfId); if (!evf) { @@ -395,9 +711,15 @@ arm_error_code sceKernelDeleteEventFlag(s32 evfId) } // Unregister IPC name - if (evf->ref.atomic_op(ipc_ref_try_unregister)) + if (evf->ipc_ref.fetch_op([](u32& ref) { if (ref) ref--; })) { - evf->destroy(); + psp2_event_flag::ipc::remove(evf->name); + } + + // Finalize the last reference + if (!evf->ipc_ref) + { + evf->exec(psp2_event_flag::task::destroy, 0); } return SCE_OK; @@ -407,35 +729,32 @@ arm_error_code sceKernelOpenEventFlag(vm::cptr pName) { sceLibKernel.error("sceKernelOpenEventFlag(pName=*0x%x)", pName); - // For now, go through all objects to find the name - for (const auto& data : idm::get_map()) - { - const auto& evf = data.second; + const auto evf = psp2_event_flag::ipc::get(pName.get_ptr()); - if (evf->name == pName.get_ptr() && evf->ref.atomic_op(ipc_ref_try_inc)) - { - return NOT_AN_ERROR(idm::import_existing(evf)); - } + // Try to add IPC reference + if (!evf || !evf->ipc_ref.fetch_op([](u32& ref) { if (ref) ref++; })) + { + return SCE_KERNEL_ERROR_UID_CANNOT_FIND_BY_NAME; } - return SCE_KERNEL_ERROR_UID_CANNOT_FIND_BY_NAME; + return NOT_AN_ERROR(idm::import_existing(evf)); } arm_error_code sceKernelCloseEventFlag(s32 evfId) { sceLibKernel.error("sceKernelCloseEventFlag(evfId=0x%x)", evfId); - const auto evf = idm::withdraw(evfId); + const auto evf = idm::withdraw(evfId); - if (!evf) + if (!evf || !evf->ipc_ref) { return SCE_KERNEL_ERROR_INVALID_UID; } - // Decrement IPC ref - if (evf->ref.atomic_op(ipc_ref_try_dec)) + // Remove one IPC reference + if (!evf->ipc_ref.op_fetch([](u32& ref) { if (ref) ref--; })) { - evf->destroy(); + evf->exec(psp2_event_flag::task::destroy, 0); } return SCE_OK; @@ -448,52 +767,64 @@ arm_error_code sceKernelWaitEventFlag(ARMv7Thread& cpu, s32 evfId, u32 bitPatter const u64 start_time = pTimeout ? get_system_time() : 0; const u32 timeout = pTimeout ? pTimeout->value() : 0; - const auto evf = idm::get(evfId); + const auto evf = idm::get(evfId); if (!evf) { return SCE_KERNEL_ERROR_INVALID_UID; } - std::unique_lock lock(evf->mutex); - - const u32 result = evf->pattern.fetch_op(event_flag_try_poll, bitPattern, waitMode); - - if (event_flag_test(result, bitPattern, waitMode)) + // First chance + const auto state = evf->ctrl.fetch_op([&](psp2_event_flag::ctrl_t& state) { - if (pResultPat) *pResultPat = result; + if (!state.waiters && psp2_event_flag::pat_test(state.pattern, bitPattern, waitMode)) + { + state.pattern &= psp2_event_flag::pat_clear(bitPattern, waitMode); + } + else if (evf->attr & SCE_KERNEL_ATTR_MULTI) + { + state.waiters++; + } + else if (!state.waiters) + { + state.waiters = cpu.id; + } + }); + if (state.waiters && !(evf->attr & SCE_KERNEL_ATTR_MULTI)) + { + return SCE_KERNEL_ERROR_EVF_MULTI; + } + + if (!state.waiters && psp2_event_flag::pat_test(state.pattern, bitPattern, waitMode)) + { + if (pResultPat) *pResultPat = state.pattern; return SCE_OK; } - // fixup register values for external use + // Set register values for external use + cpu.GPR[0] = waitMode; cpu.GPR[1] = bitPattern; - cpu.GPR[2] = waitMode; - // add waiter; attributes are ignored in current implementation - sleep_entry waiter(evf->sq, cpu); - - while (!cpu.state.test_and_reset(cpu_state::signal)) + // Second chance + if (evf->exec(psp2_event_flag::task::wait, cpu.id) && cpu.state.test_and_reset(cpu_state::signal)) { - CHECK_EMU_STATUS; + if (pResultPat) *pResultPat = cpu.GPR[1]; + return SCE_OK; + } - if (pTimeout) + cpu_thread_lock entry(cpu); + + if (!thread_ctrl::wait(timeout, WRAP_EXPR(cpu.state.test_and_reset(cpu_state::signal)))) + { + // Timeout cleanup + cpu.owner = nullptr; + cpu.GPR[0] = SCE_KERNEL_ERROR_WAIT_TIMEOUT; + cpu.GPR[1] = evf->ctrl.atomic_op([&](psp2_event_flag::ctrl_t& state) { - const u64 passed = get_system_time() - start_time; - - if (passed >= timeout) - { - cpu.GPR[0] = SCE_KERNEL_ERROR_WAIT_TIMEOUT; - cpu.GPR[1] = evf->pattern; - break; - } - - get_current_thread_cv().wait_for(lock, std::chrono::microseconds(timeout - passed)); - } - else - { - get_current_thread_cv().wait(lock); - } + state.waiters -= evf->attr & SCE_KERNEL_ATTR_MULTI ? 1 : cpu.id; + return state.pattern; + }); } if (pResultPat) *pResultPat = cpu.GPR[1]; @@ -509,73 +840,63 @@ arm_error_code sceKernelWaitEventFlagCB(ARMv7Thread& cpu, s32 evfId, u32 bitPatt return sceKernelWaitEventFlag(cpu, evfId, bitPattern, waitMode, pResultPat, pTimeout); } -arm_error_code sceKernelPollEventFlag(s32 evfId, u32 bitPattern, u32 waitMode, vm::ptr pResultPat) +arm_error_code sceKernelPollEventFlag(ARMv7Thread& cpu, s32 evfId, u32 bitPattern, u32 waitMode, vm::ptr pResultPat) { sceLibKernel.error("sceKernelPollEventFlag(evfId=0x%x, bitPattern=0x%x, waitMode=0x%x, pResultPat=*0x%x)", evfId, bitPattern, waitMode, pResultPat); - const auto evf = idm::get(evfId); + const auto evf = idm::get(evfId); if (!evf) { return SCE_KERNEL_ERROR_INVALID_UID; } - std::lock_guard lock(evf->mutex); - - const u32 result = evf->pattern.fetch_op(event_flag_try_poll, bitPattern, waitMode); - - if (!event_flag_test(result, bitPattern, waitMode)) + // First chance + const auto state = evf->ctrl.fetch_op([&](psp2_event_flag::ctrl_t& state) { - return SCE_KERNEL_ERROR_EVENT_COND; + if (!state.waiters && psp2_event_flag::pat_test(state.pattern, bitPattern, waitMode)) + { + state.pattern &= psp2_event_flag::pat_clear(bitPattern, waitMode); + } + }); + + if (psp2_event_flag::pat_test(state.pattern, bitPattern, waitMode)) + { + if (!state.waiters) + { + *pResultPat = state.pattern; + return SCE_OK; + } + + cpu.GPR[0] = waitMode; + cpu.GPR[1] = bitPattern; + + evf->sync(cpu, psp2_event_flag::task::poll, cpu.id); + + if (cpu.GPR[1]) + { + *pResultPat = cpu.GPR[1]; + return SCE_OK; + } } - *pResultPat = result; - - return SCE_OK; + return NOT_AN_ERROR(SCE_KERNEL_ERROR_EVENT_COND); } arm_error_code sceKernelSetEventFlag(s32 evfId, u32 bitPattern) { sceLibKernel.error("sceKernelSetEventFlag(evfId=0x%x, bitPattern=0x%x)", evfId, bitPattern); - const auto evf = idm::get(evfId); + const auto evf = idm::get(evfId); if (!evf) { return SCE_KERNEL_ERROR_INVALID_UID; } - std::lock_guard lock(evf->mutex); - - evf->pattern |= bitPattern; - - auto pred = [&](cpu_thread* thread) -> bool + if (!evf->exec(psp2_event_flag::task::set, bitPattern)) { - auto& cpu = static_cast(*thread); - - // load pattern and mode from registers - const u32 pattern = cpu.GPR[1]; - const u32 mode = cpu.GPR[2]; - - // check specific pattern - const u32 result = evf->pattern.fetch_op(event_flag_try_poll, pattern, mode); - - if (event_flag_test(result, pattern, mode)) - { - // save pattern - cpu.GPR[0] = SCE_OK; - cpu.GPR[1] = result; - - thread->state += cpu_state::signal; - thread->notify(); - return true; - } - - return false; - }; - - // check all waiters; protocol is ignored in current implementation - evf->sq.erase(std::remove_if(evf->sq.begin(), evf->sq.end(), pred), evf->sq.end()); + } return SCE_OK; } @@ -584,45 +905,34 @@ arm_error_code sceKernelClearEventFlag(s32 evfId, u32 bitPattern) { sceLibKernel.error("sceKernelClearEventFlag(evfId=0x%x, bitPattern=0x%x)", evfId, bitPattern); - const auto evf = idm::get(evfId); + const auto evf = idm::get(evfId); if (!evf) { return SCE_KERNEL_ERROR_INVALID_UID; } - std::lock_guard lock(evf->mutex); - - evf->pattern &= ~bitPattern; + if (!evf->exec(psp2_event_flag::task::clear, bitPattern)) + { + } return SCE_OK; } -arm_error_code sceKernelCancelEventFlag(s32 evfId, u32 setPattern, vm::ptr pNumWaitThreads) +arm_error_code sceKernelCancelEventFlag(ARMv7Thread& cpu, s32 evfId, u32 setPattern, vm::ptr pNumWaitThreads) { sceLibKernel.error("sceKernelCancelEventFlag(evfId=0x%x, setPattern=0x%x, pNumWaitThreads=*0x%x)", evfId, setPattern, pNumWaitThreads); - const auto evf = idm::get(evfId); + const auto evf = idm::get(evfId); if (!evf) { return SCE_KERNEL_ERROR_INVALID_UID; } - std::lock_guard lock(evf->mutex); + *pNumWaitThreads = setPattern; - for (auto& thread : evf->sq) - { - static_cast(*thread).GPR[0] = SCE_KERNEL_ERROR_WAIT_CANCEL; - static_cast(*thread).GPR[1] = setPattern; - thread->state += cpu_state::signal; - thread->notify(); - } - - *pNumWaitThreads = static_cast(evf->sq.size()); - - evf->pattern = setPattern; - evf->sq.clear(); + evf->sync(cpu, psp2_event_flag::task::cancel, pNumWaitThreads.addr()); return SCE_OK; } @@ -631,15 +941,13 @@ arm_error_code sceKernelGetEventFlagInfo(s32 evfId, vm::ptr(evfId); + const auto evf = idm::get(evfId); if (!evf) { return SCE_KERNEL_ERROR_INVALID_UID; } - std::lock_guard lock(evf->mutex); - pInfo->size = SIZE_32(SceKernelEventFlagInfo); pInfo->evfId = evfId; @@ -647,8 +955,11 @@ arm_error_code sceKernelGetEventFlagInfo(s32 evfId, vm::ptrattr = evf->attr; pInfo->initPattern = evf->init; - pInfo->currentPattern = evf->pattern; - pInfo->numWaitThreads = static_cast(evf->sq.size()); + + const auto state = evf->ctrl.load(); + + pInfo->currentPattern = state.pattern; + pInfo->numWaitThreads = evf->attr & SCE_KERNEL_ATTR_MULTI ? state.waiters : state.waiters != 0; return SCE_OK; } @@ -659,14 +970,14 @@ arm_error_code sceKernelCreateSema(vm::cptr pName, u32 attr, s32 initCount { sceLibKernel.error("sceKernelCreateSema(pName=*0x%x, attr=0x%x, initCount=%d, maxCount=%d, pOptParam=*0x%x)", pName, attr, initCount, maxCount, pOptParam); - return NOT_AN_ERROR(idm::make(pName.get_ptr(), attr, initCount, maxCount)); + return NOT_AN_ERROR(idm::make(pName.get_ptr(), attr, initCount, maxCount)); } arm_error_code sceKernelDeleteSema(s32 semaId) { sceLibKernel.error("sceKernelDeleteSema(semaId=0x%x)", semaId); - const auto sema = idm::withdraw(semaId); + const auto sema = idm::withdraw(semaId); if (!sema) { @@ -692,7 +1003,7 @@ arm_error_code sceKernelWaitSema(s32 semaId, s32 needCount, vm::ptr pTimeou { sceLibKernel.error("sceKernelWaitSema(semaId=0x%x, needCount=%d, pTimeout=*0x%x)", semaId, needCount, pTimeout); - const auto sema = idm::get(semaId); + const auto sema = idm::get(semaId); if (!sema) { @@ -735,14 +1046,14 @@ arm_error_code sceKernelCreateMutex(vm::cptr pName, u32 attr, s32 initCoun { sceLibKernel.error("sceKernelCreateMutex(pName=*0x%x, attr=0x%x, initCount=%d, pOptParam=*0x%x)", pName, attr, initCount, pOptParam); - return NOT_AN_ERROR(idm::make(pName.get_ptr(), attr, initCount)); + return NOT_AN_ERROR(idm::make(pName.get_ptr(), attr, initCount)); } arm_error_code sceKernelDeleteMutex(s32 mutexId) { sceLibKernel.error("sceKernelDeleteMutex(mutexId=0x%x)", mutexId); - const auto mutex = idm::withdraw(mutexId); + const auto mutex = idm::withdraw(mutexId); if (!mutex) { @@ -842,21 +1153,21 @@ arm_error_code sceKernelCreateCond(vm::cptr pName, u32 attr, s32 mutexId, { sceLibKernel.error("sceKernelCreateCond(pName=*0x%x, attr=0x%x, mutexId=0x%x, pOptParam=*0x%x)", pName, attr, mutexId, pOptParam); - const auto mutex = idm::get(mutexId); + const auto mutex = idm::get(mutexId); if (!mutex) { return SCE_KERNEL_ERROR_INVALID_UID; } - return NOT_AN_ERROR(idm::make(pName.get_ptr(), attr, mutex)); + return NOT_AN_ERROR(idm::make(pName.get_ptr(), attr, mutex)); } arm_error_code sceKernelDeleteCond(s32 condId) { sceLibKernel.error("sceKernelDeleteCond(condId=0x%x)", condId); - const auto cond = idm::withdraw(condId); + const auto cond = idm::withdraw(condId); if (!cond) { @@ -1121,6 +1432,19 @@ s32 sceKernelGetRWLockInfo(s32 rwLockId, vm::ptr pInfo) throw EXCEPTION(""); } +arm_error_code sceKernelGetThreadmgrUIDClass(s32 uid) +{ + sceLibKernel.error("sceKernelGetThreadmgrUIDClass(uid=0x%x)", uid); + + if (idm::check(uid)) return SCE_KERNEL_THREADMGR_UID_CLASS_THREAD; + if (idm::check(uid)) return SCE_KERNEL_THREADMGR_UID_CLASS_SEMA; + if (idm::check(uid)) return SCE_KERNEL_THREADMGR_UID_CLASS_EVENT_FLAG; + if (idm::check(uid)) return SCE_KERNEL_THREADMGR_UID_CLASS_MUTEX; + if (idm::check(uid)) return SCE_KERNEL_THREADMGR_UID_CLASS_COND; + + return SCE_KERNEL_ERROR_INVALID_UID; +} + // IO/File functions s32 sceIoRemove(vm::cptr filename) diff --git a/rpcs3/Emu/ARMv7/Modules/sceLibKernel.h b/rpcs3/Emu/PSP2/Modules/sceLibKernel.h similarity index 94% rename from rpcs3/Emu/ARMv7/Modules/sceLibKernel.h rename to rpcs3/Emu/PSP2/Modules/sceLibKernel.h index 443b2f5df1..7bab50ac68 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceLibKernel.h +++ b/rpcs3/Emu/PSP2/Modules/sceLibKernel.h @@ -1,10 +1,9 @@ #pragma once -#include "Utilities/SleepQueue.h" -#include "Emu/ARMv7/ErrorCodes.h" +#include "Emu/PSP2/ErrorCodes.h" +#include "Emu/PSP2/Modules/Common.h" // Error Codes - enum SceLibKernelError : s32 { SCE_KERNEL_ERROR_ERROR = ERROR_CODE(0x80020001), @@ -99,6 +98,7 @@ enum SceLibKernelError : s32 SCE_KERNEL_ERROR_ILLEGAL_SELF_HEADER = ERROR_CODE(0x80025002), }; +// Error Codes enum SceLibKernelError0 : s32 { SCE_KERNEL_ERROR_EXCPMGR_ERROR = ERROR_CODE(0x80027000), @@ -204,6 +204,7 @@ enum SceLibKernelError0 : s32 SCE_KERNEL_ERROR_RW_LOCK_FAILED_TO_UNLOCK = ERROR_CODE(0x80028046), }; +// Error Codes enum SceLibKernelError1 : s32 { SCE_KERNEL_ERROR_PROCESSMGR_ERROR = ERROR_CODE(0x80029000), @@ -535,7 +536,8 @@ inline const char* arm_error_code::print(SceLibKernelError1 error) return nullptr; } -enum psv_object_class_t : u32 +// PSP2 UID Class +enum : u32 { SCE_KERNEL_UID_CLASS_PROCESS = 0, SCE_KERNEL_THREADMGR_UID_CLASS_THREAD = 1, @@ -589,6 +591,15 @@ struct SceKernelAllocMemBlockOpt // Thread Manager definitions (threads) +enum +{ + SCE_KERNEL_ATTR_TH_FIFO = 0, + SCE_KERNEL_ATTR_TH_PRIO = 0x2000, + + SCE_KERNEL_ATTR_SINGLE = 0, // Event Flag only + SCE_KERNEL_ATTR_MULTI = 0x1000, // Event Flag only +}; + using SceKernelThreadEntry = s32(u32 argSize, vm::ptr pArgBlock); struct SceKernelThreadOptParam @@ -727,78 +738,6 @@ struct SceKernelEventFlagInfo le_t numWaitThreads; }; -struct psv_event_flag_t -{ - const std::string name; // IPC Name - - atomic_t ref{ 0x80000000 }; // IPC Ref Counter - - const u32 attr; // Event Flag Attributes - const u32 init; // Event Flag Init Pattern - - atomic_t pattern; // Event Flag Pattern - - std::mutex mutex; - - sleep_queue sq; - - psv_event_flag_t(const char* name, u32 attr, u32 pattern) - : name(name) - , attr(attr) - , init(pattern) - , pattern(pattern) - { - } - - // Wakeup all waiters to return SCE_KERNEL_ERROR_WAIT_DELETE - void destroy() - { - std::lock_guard lock(mutex); - - const u32 pattern = this->pattern; - - for (auto& thread : sq) - { - static_cast(*thread).GPR[0] = SCE_KERNEL_ERROR_WAIT_DELETE; - static_cast(*thread).GPR[1] = pattern; - thread->state += cpu_state::signal; - thread->notify(); - } - } -}; - -inline bool event_flag_test(u32 value, u32 pattern, u32 mode) -{ - if (mode & SCE_KERNEL_EVF_WAITMODE_OR) - { - return (value & pattern) != 0; - } - else - { - return (value & pattern) == pattern; - } -} - -inline void event_flag_try_poll(u32& value, u32 pattern, u32 mode) -{ - if (mode & ~7 || (mode & 6) == 6) - { - throw EXCEPTION("Unknown mode (0x%x)", mode); - } - - if (event_flag_test(value, pattern, mode)) - { - if (mode & SCE_KERNEL_EVF_WAITMODE_CLEAR_ALL) - { - value = 0; - } - else if (mode & SCE_KERNEL_EVF_WAITMODE_CLEAR_PAT) - { - value &= ~pattern; - } - } -} - // Thread Manager definitions (semaphores) struct SceKernelSemaOptParam @@ -818,18 +757,18 @@ struct SceKernelSemaInfo le_t numWaitThreads; }; -struct psv_semaphore_t +struct psp2_semaphore { const std::string name; // IPC Name - atomic_t ref{ 0x80000000 }; // IPC Ref Counter + atomic_t ref{}; // IPC Ref Counter const u32 attr; const s32 max; atomic_t count; - psv_semaphore_t(const char* name, u32 attr, s32 count, s32 max) + psp2_semaphore(const char* name, u32 attr, s32 count, s32 max) : name(name) , attr(attr) , max(max) @@ -858,17 +797,17 @@ struct SceKernelMutexInfo le_t numWaitThreads; }; -struct psv_mutex_t +struct psp2_mutex { const std::string name; // IPC Name - atomic_t ref{ 0x80000000 }; // IPC Ref Counter + atomic_t ref{}; // IPC Ref Counter const u32 attr; atomic_t count; - psv_mutex_t(const char* name, u32 attr, s32 count) + psp2_mutex(const char* name, u32 attr, s32 count) : name(name) , attr(attr) , count(count) @@ -918,17 +857,17 @@ struct SceKernelCondInfo le_t numWaitThreads; }; -struct psv_cond_t +struct psp2_cond { const std::string name; // IPC Name - atomic_t ref{ 0x80000000 }; // IPC Ref Counter + atomic_t ref{}; // IPC Ref Counter const u32 attr; - const std::shared_ptr mutex; + const std::shared_ptr mutex; - psv_cond_t(const char* name, u32 attr, const std::shared_ptr& mutex) + psp2_cond(const char* name, u32 attr, const std::shared_ptr& mutex) : name(name) , attr(attr) , mutex(mutex) @@ -1022,47 +961,3 @@ struct SceIoDirent vm::lptr d_private; le_t dummy; }; - -// Module -// Aux - -inline bool ipc_ref_try_dec(u32& ref) -{ - if (ref & 0x7fffffff) - { - // return true if the last reference is removed and object must be deleted - return !--ref; - } - else - { - throw EXCEPTION("Unexpected IPC Ref value (0x%x)", ref); - } -} - -inline bool ipc_ref_try_inc(u32& ref) -{ - if (ref & 0x80000000) - { - if (!++ref) - { - throw EXCEPTION("IPC Ref overflow"); - } - - return true; - } - - return false; -} - -inline bool ipc_ref_try_unregister(u32& ref) -{ - if (ref & 0x80000000) - { - ref &= ~0x80000000; - - // return true if object must be deleted - return !ref; - } - - throw EXCEPTION("Unexpected IPC Ref value (0x%x)", ref); -} diff --git a/rpcs3/Emu/ARMv7/Modules/sceLibXml.cpp b/rpcs3/Emu/PSP2/Modules/sceLibXml.cpp similarity index 99% rename from rpcs3/Emu/ARMv7/Modules/sceLibXml.cpp rename to rpcs3/Emu/PSP2/Modules/sceLibXml.cpp index 789a45e8d7..18d1686c47 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceLibXml.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceLibXml.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceLibXml.h" -LOG_CHANNEL(sceLibXml); +logs::channel sceLibXml("sceLibXml", logs::level::notice); #define REG_FUNC(nid, name) REG_FNID(SceLibXml, nid, name) diff --git a/rpcs3/Emu/ARMv7/Modules/sceLibXml.h b/rpcs3/Emu/PSP2/Modules/sceLibXml.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceLibXml.h rename to rpcs3/Emu/PSP2/Modules/sceLibXml.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceLibc.cpp b/rpcs3/Emu/PSP2/Modules/sceLibc.cpp similarity index 97% rename from rpcs3/Emu/ARMv7/Modules/sceLibc.cpp rename to rpcs3/Emu/PSP2/Modules/sceLibc.cpp index 4532f085c7..e00b4ca46c 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceLibc.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceLibc.cpp @@ -1,12 +1,14 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" -#include "Emu/ARMv7/ARMv7Thread.h" -#include "Emu/ARMv7/ARMv7Callback.h" +#include "Emu/PSP2/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Thread.h" +#include "Emu/PSP2/ARMv7Callback.h" #include "sceLibc.h" -LOG_CHANNEL(sceLibc); +#include + +logs::channel sceLibc("sceLibc", logs::level::notice); extern fs::file g_tty; @@ -15,8 +17,6 @@ vm::ptr g_dso; std::vector> g_atexit; -std::mutex g_atexit_mutex; - std::string arm_fmt(ARMv7Thread& cpu, vm::cptr fmt, u32 g_count) { std::string result; @@ -132,7 +132,7 @@ std::string arm_fmt(ARMv7Thread& cpu, vm::cptr fmt, u32 g_count) case 's': { // string - const vm::cptr string{ cpu.get_next_gpr_arg(g_count), vm::addr }; + const vm::cptr string = vm::cast(cpu.get_next_gpr_arg(g_count)); if (plus_sign || minus_sign || space_sign || number_sign || zero_padding || width || prec) break; @@ -157,8 +157,6 @@ namespace sce_libc_func { sceLibc.warning("__cxa_atexit(func=*0x%x, arg=*0x%x, dso=*0x%x)", func, arg, dso); - std::lock_guard lock(g_atexit_mutex); - g_atexit.insert(g_atexit.begin(), [func, arg, dso](ARMv7Thread& cpu) { func(cpu, arg); @@ -169,8 +167,6 @@ namespace sce_libc_func { sceLibc.warning("__aeabi_atexit(arg=*0x%x, func=*0x%x, dso=*0x%x)", arg, func, dso); - std::lock_guard lock(g_atexit_mutex); - g_atexit.insert(g_atexit.begin(), [func, arg, dso](ARMv7Thread& cpu) { func(cpu, arg); @@ -181,8 +177,6 @@ namespace sce_libc_func { sceLibc.warning("exit()"); - std::lock_guard lock(g_atexit_mutex); - CHECK_EMU_STATUS; for (auto& func : decltype(g_atexit)(std::move(g_atexit))) diff --git a/rpcs3/Emu/ARMv7/Modules/sceLibc.h b/rpcs3/Emu/PSP2/Modules/sceLibc.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceLibc.h rename to rpcs3/Emu/PSP2/Modules/sceLibc.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceLibm.cpp b/rpcs3/Emu/PSP2/Modules/sceLibm.cpp similarity index 98% rename from rpcs3/Emu/ARMv7/Modules/sceLibm.cpp rename to rpcs3/Emu/PSP2/Modules/sceLibm.cpp index cdadc4e103..c56118c908 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceLibm.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceLibm.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceLibm.h" -LOG_CHANNEL(sceLibm); +logs::channel sceLibm("sceLibm", logs::level::notice); namespace sce_libm_func { diff --git a/rpcs3/Emu/ARMv7/Modules/sceLibm.h b/rpcs3/Emu/PSP2/Modules/sceLibm.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceLibm.h rename to rpcs3/Emu/PSP2/Modules/sceLibm.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceLibstdcxx.cpp b/rpcs3/Emu/PSP2/Modules/sceLibstdcxx.cpp similarity index 99% rename from rpcs3/Emu/ARMv7/Modules/sceLibstdcxx.cpp rename to rpcs3/Emu/PSP2/Modules/sceLibstdcxx.cpp index 53fd57dcec..986ba30972 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceLibstdcxx.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceLibstdcxx.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceLibstdcxx.h" -LOG_CHANNEL(sceLibstdcxx); +logs::channel sceLibstdcxx("sceLibstdcxx", logs::level::notice); namespace sce_libstdcxx_func { diff --git a/rpcs3/Emu/ARMv7/Modules/sceLibstdcxx.h b/rpcs3/Emu/PSP2/Modules/sceLibstdcxx.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceLibstdcxx.h rename to rpcs3/Emu/PSP2/Modules/sceLibstdcxx.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceLiveArea.cpp b/rpcs3/Emu/PSP2/Modules/sceLiveArea.cpp similarity index 82% rename from rpcs3/Emu/ARMv7/Modules/sceLiveArea.cpp rename to rpcs3/Emu/PSP2/Modules/sceLiveArea.cpp index f93fe7479e..9165edaf95 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceLiveArea.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceLiveArea.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceLiveArea.h" -LOG_CHANNEL(sceLiveArea); +logs::channel sceLiveArea("sceLiveArea", logs::level::notice); s32 sceLiveAreaResourceReplaceAll(vm::cptr dirpath) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceLiveArea.h b/rpcs3/Emu/PSP2/Modules/sceLiveArea.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceLiveArea.h rename to rpcs3/Emu/PSP2/Modules/sceLiveArea.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceLocation.cpp b/rpcs3/Emu/PSP2/Modules/sceLocation.cpp similarity index 96% rename from rpcs3/Emu/ARMv7/Modules/sceLocation.cpp rename to rpcs3/Emu/PSP2/Modules/sceLocation.cpp index c180e99c52..5d8988cdc2 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceLocation.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceLocation.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceLocation.h" -LOG_CHANNEL(sceLocation); +logs::channel sceLocation("sceLocation", logs::level::notice); s32 sceLocationOpen(vm::ptr handle, SceLocationLocationMethod lmethod, SceLocationHeadingMethod hmethod) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceLocation.h b/rpcs3/Emu/PSP2/Modules/sceLocation.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceLocation.h rename to rpcs3/Emu/PSP2/Modules/sceLocation.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceMd5.cpp b/rpcs3/Emu/PSP2/Modules/sceMd5.cpp similarity index 89% rename from rpcs3/Emu/ARMv7/Modules/sceMd5.cpp rename to rpcs3/Emu/PSP2/Modules/sceMd5.cpp index e7f1412a5e..21906de842 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceMd5.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceMd5.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceMd5.h" -LOG_CHANNEL(sceMd5); +logs::channel sceMd5("sceMd5", logs::level::notice); s32 sceMd5Digest(vm::cptr plain, u32 len, vm::ptr digest) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceMd5.h b/rpcs3/Emu/PSP2/Modules/sceMd5.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceMd5.h rename to rpcs3/Emu/PSP2/Modules/sceMd5.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceMotion.cpp b/rpcs3/Emu/PSP2/Modules/sceMotion.cpp similarity index 95% rename from rpcs3/Emu/ARMv7/Modules/sceMotion.cpp rename to rpcs3/Emu/PSP2/Modules/sceMotion.cpp index 10d1729ecd..fc5f858d33 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceMotion.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceMotion.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceMotion.h" -LOG_CHANNEL(sceMotion); +logs::channel sceMotion("sceMotion", logs::level::notice); s32 sceMotionGetState(vm::ptr motionState) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceMotion.h b/rpcs3/Emu/PSP2/Modules/sceMotion.h similarity index 96% rename from rpcs3/Emu/ARMv7/Modules/sceMotion.h rename to rpcs3/Emu/PSP2/Modules/sceMotion.h index 102108b336..307c50bf5d 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceMotion.h +++ b/rpcs3/Emu/PSP2/Modules/sceMotion.h @@ -1,5 +1,7 @@ #pragma once +#include "Common.h" + struct SceMotionState { le_t timestamp; diff --git a/rpcs3/Emu/ARMv7/Modules/sceMt19937.cpp b/rpcs3/Emu/PSP2/Modules/sceMt19937.cpp similarity index 82% rename from rpcs3/Emu/ARMv7/Modules/sceMt19937.cpp rename to rpcs3/Emu/PSP2/Modules/sceMt19937.cpp index 5acabc9c25..42c4e1d20d 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceMt19937.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceMt19937.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceMt19937.h" -LOG_CHANNEL(sceMt19937); +logs::channel sceMt19937("sceMt19937", logs::level::notice); s32 sceMt19937Init(vm::ptr pCtx, u32 seed) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceMt19937.h b/rpcs3/Emu/PSP2/Modules/sceMt19937.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceMt19937.h rename to rpcs3/Emu/PSP2/Modules/sceMt19937.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceNet.cpp b/rpcs3/Emu/PSP2/Modules/sceNet.cpp similarity index 98% rename from rpcs3/Emu/ARMv7/Modules/sceNet.cpp rename to rpcs3/Emu/PSP2/Modules/sceNet.cpp index 1775cb22a4..4945c9ab86 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceNet.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceNet.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceNet.h" -LOG_CHANNEL(sceNet); +logs::channel sceNet("sceNet", logs::level::notice); s32 sceNetSetDnsInfo(vm::ptr info, s32 flags) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceNet.h b/rpcs3/Emu/PSP2/Modules/sceNet.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceNet.h rename to rpcs3/Emu/PSP2/Modules/sceNet.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceNetCtl.cpp b/rpcs3/Emu/PSP2/Modules/sceNetCtl.cpp similarity index 96% rename from rpcs3/Emu/ARMv7/Modules/sceNetCtl.cpp rename to rpcs3/Emu/PSP2/Modules/sceNetCtl.cpp index 6a19caba05..9390c957ab 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceNetCtl.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceNetCtl.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceNetCtl.h" -LOG_CHANNEL(sceNetCtl); +logs::channel sceNetCtl("sceNetCtl", logs::level::notice); s32 sceNetCtlInit() { diff --git a/rpcs3/Emu/ARMv7/Modules/sceNetCtl.h b/rpcs3/Emu/PSP2/Modules/sceNetCtl.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceNetCtl.h rename to rpcs3/Emu/PSP2/Modules/sceNetCtl.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceNgs.cpp b/rpcs3/Emu/PSP2/Modules/sceNgs.cpp similarity index 99% rename from rpcs3/Emu/ARMv7/Modules/sceNgs.cpp rename to rpcs3/Emu/PSP2/Modules/sceNgs.cpp index 7b8005c8f0..c987b844d4 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceNgs.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceNgs.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceNgs.h" -LOG_CHANNEL(sceNgs); +logs::channel sceNgs("sceNgs", logs::level::notice); s32 sceNgsSystemGetRequiredMemorySize(vm::cptr pSynthParams, vm::ptr pnSize) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceNgs.h b/rpcs3/Emu/PSP2/Modules/sceNgs.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceNgs.h rename to rpcs3/Emu/PSP2/Modules/sceNgs.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceNpBasic.cpp b/rpcs3/Emu/PSP2/Modules/sceNpBasic.cpp similarity index 97% rename from rpcs3/Emu/ARMv7/Modules/sceNpBasic.cpp rename to rpcs3/Emu/PSP2/Modules/sceNpBasic.cpp index c09a8002c4..7800496720 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceNpBasic.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceNpBasic.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceNpBasic.h" -LOG_CHANNEL(sceNpBasic); +logs::channel sceNpBasic("sceNpBasic", logs::level::notice); s32 sceNpBasicInit(vm::ptr opt) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceNpBasic.h b/rpcs3/Emu/PSP2/Modules/sceNpBasic.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceNpBasic.h rename to rpcs3/Emu/PSP2/Modules/sceNpBasic.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceNpCommon.cpp b/rpcs3/Emu/PSP2/Modules/sceNpCommon.cpp similarity index 94% rename from rpcs3/Emu/ARMv7/Modules/sceNpCommon.cpp rename to rpcs3/Emu/PSP2/Modules/sceNpCommon.cpp index f052347148..bfe145d62a 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceNpCommon.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceNpCommon.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceNpCommon.h" -LOG_CHANNEL(sceNpCommon); +logs::channel sceNpCommon("sceNpCommon", logs::level::notice); s32 sceNpAuthInit() { diff --git a/rpcs3/Emu/ARMv7/Modules/sceNpCommon.h b/rpcs3/Emu/PSP2/Modules/sceNpCommon.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceNpCommon.h rename to rpcs3/Emu/PSP2/Modules/sceNpCommon.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceNpManager.cpp b/rpcs3/Emu/PSP2/Modules/sceNpManager.cpp similarity index 94% rename from rpcs3/Emu/ARMv7/Modules/sceNpManager.cpp rename to rpcs3/Emu/PSP2/Modules/sceNpManager.cpp index e964eaccd2..d0eab10b94 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceNpManager.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceNpManager.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceNpManager.h" -LOG_CHANNEL(sceNpManager); +logs::channel sceNpManager("sceNpManager", logs::level::notice); s32 sceNpInit(vm::cptr commConf, vm::ptr opt) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceNpManager.h b/rpcs3/Emu/PSP2/Modules/sceNpManager.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceNpManager.h rename to rpcs3/Emu/PSP2/Modules/sceNpManager.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceNpMatching.cpp b/rpcs3/Emu/PSP2/Modules/sceNpMatching.cpp similarity index 98% rename from rpcs3/Emu/ARMv7/Modules/sceNpMatching.cpp rename to rpcs3/Emu/PSP2/Modules/sceNpMatching.cpp index 0d19c7d717..83c4b03750 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceNpMatching.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceNpMatching.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceNpMatching.h" -LOG_CHANNEL(sceNpMatching); +logs::channel sceNpMatching("sceNpMatching", logs::level::notice); // Functions diff --git a/rpcs3/Emu/ARMv7/Modules/sceNpMatching.h b/rpcs3/Emu/PSP2/Modules/sceNpMatching.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceNpMatching.h rename to rpcs3/Emu/PSP2/Modules/sceNpMatching.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceNpScore.cpp b/rpcs3/Emu/PSP2/Modules/sceNpScore.cpp similarity index 98% rename from rpcs3/Emu/ARMv7/Modules/sceNpScore.cpp rename to rpcs3/Emu/PSP2/Modules/sceNpScore.cpp index c9557fdc41..88c47ea935 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceNpScore.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceNpScore.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceNpScore.h" -LOG_CHANNEL(sceNpScore); +logs::channel sceNpScore("sceNpScore", logs::level::notice); s32 sceNpScoreInit(s32 threadPriority, s32 cpuAffinityMask, vm::ptr option) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceNpScore.h b/rpcs3/Emu/PSP2/Modules/sceNpScore.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceNpScore.h rename to rpcs3/Emu/PSP2/Modules/sceNpScore.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceNpUtility.cpp b/rpcs3/Emu/PSP2/Modules/sceNpUtility.cpp similarity index 97% rename from rpcs3/Emu/ARMv7/Modules/sceNpUtility.cpp rename to rpcs3/Emu/PSP2/Modules/sceNpUtility.cpp index 561bd9d7a2..a5a46791e0 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceNpUtility.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceNpUtility.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceNpUtility.h" -LOG_CHANNEL(sceNpUtility); +logs::channel sceNpUtility("sceNpUtility", logs::level::notice); s32 sceNpLookupInit(s32 usesAsync, s32 threadPriority, s32 cpuAffinityMask, vm::ptr option) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceNpUtility.h b/rpcs3/Emu/PSP2/Modules/sceNpUtility.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceNpUtility.h rename to rpcs3/Emu/PSP2/Modules/sceNpUtility.h diff --git a/rpcs3/Emu/ARMv7/Modules/scePerf.cpp b/rpcs3/Emu/PSP2/Modules/scePerf.cpp similarity index 91% rename from rpcs3/Emu/ARMv7/Modules/scePerf.cpp rename to rpcs3/Emu/PSP2/Modules/scePerf.cpp index bb04f5b6ad..c771da3d2f 100644 --- a/rpcs3/Emu/ARMv7/Modules/scePerf.cpp +++ b/rpcs3/Emu/PSP2/Modules/scePerf.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "scePerf.h" -LOG_CHANNEL(scePerf); +logs::channel scePerf("scePerf", logs::level::notice); extern u64 get_system_time(); @@ -12,7 +12,7 @@ arm_error_code scePerfArmPmonReset(ARMv7Thread& cpu, s32 threadId) { scePerf.warning("scePerfArmPmonReset(threadId=0x%x)", threadId); - ASSERT(threadId == SCE_PERF_ARM_PMON_THREAD_ID_SELF); + VERIFY(threadId == SCE_PERF_ARM_PMON_THREAD_ID_SELF); cpu.counters = {}; @@ -23,7 +23,7 @@ arm_error_code scePerfArmPmonSelectEvent(ARMv7Thread& cpu, s32 threadId, u32 cou { scePerf.warning("scePerfArmPmonSelectEvent(threadId=0x%x, counter=0x%x, eventCode=0x%x)", threadId, counter, eventCode); - ASSERT(threadId == SCE_PERF_ARM_PMON_THREAD_ID_SELF); + VERIFY(threadId == SCE_PERF_ARM_PMON_THREAD_ID_SELF); if (counter >= 6) { @@ -72,7 +72,7 @@ arm_error_code scePerfArmPmonStart(ARMv7Thread& cpu, s32 threadId) { scePerf.warning("scePerfArmPmonStart(threadId=0x%x)", threadId); - ASSERT(threadId == SCE_PERF_ARM_PMON_THREAD_ID_SELF); + VERIFY(threadId == SCE_PERF_ARM_PMON_THREAD_ID_SELF); return SCE_OK; } @@ -81,7 +81,7 @@ arm_error_code scePerfArmPmonStop(ARMv7Thread& cpu, s32 threadId) { scePerf.warning("scePerfArmPmonStop(threadId=0x%x)"); - ASSERT(threadId == SCE_PERF_ARM_PMON_THREAD_ID_SELF); + VERIFY(threadId == SCE_PERF_ARM_PMON_THREAD_ID_SELF); return SCE_OK; } @@ -90,7 +90,7 @@ arm_error_code scePerfArmPmonGetCounterValue(ARMv7Thread& cpu, s32 threadId, u32 { scePerf.warning("scePerfArmPmonGetCounterValue(threadId=0x%x, counter=%d, pValue=*0x%x)", threadId, counter, pValue); - ASSERT(threadId == SCE_PERF_ARM_PMON_THREAD_ID_SELF); + VERIFY(threadId == SCE_PERF_ARM_PMON_THREAD_ID_SELF); if (counter >= 6 && counter != SCE_PERF_ARM_PMON_CYCLE_COUNTER) { diff --git a/rpcs3/Emu/ARMv7/Modules/scePerf.h b/rpcs3/Emu/PSP2/Modules/scePerf.h similarity index 98% rename from rpcs3/Emu/ARMv7/Modules/scePerf.h rename to rpcs3/Emu/PSP2/Modules/scePerf.h index 81d4833320..acd7c5a383 100644 --- a/rpcs3/Emu/ARMv7/Modules/scePerf.h +++ b/rpcs3/Emu/PSP2/Modules/scePerf.h @@ -1,6 +1,6 @@ #pragma once -#include "Emu/ARMv7/ErrorCodes.h" +#include "Emu/PSP2/ErrorCodes.h" enum ScePerfError : s32 { diff --git a/rpcs3/Emu/ARMv7/Modules/scePgf.cpp b/rpcs3/Emu/PSP2/Modules/scePgf.cpp similarity index 93% rename from rpcs3/Emu/ARMv7/Modules/scePgf.cpp rename to rpcs3/Emu/PSP2/Modules/scePgf.cpp index 550c08def8..87418324a9 100644 --- a/rpcs3/Emu/ARMv7/Modules/scePgf.cpp +++ b/rpcs3/Emu/PSP2/Modules/scePgf.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "scePgf.h" -LOG_CHANNEL(scePgf); +logs::channel scePgf("scePgf", logs::level::notice); #define REG_FUNC(nid, name) REG_FNID(ScePgf, nid, name) diff --git a/rpcs3/Emu/ARMv7/Modules/scePgf.h b/rpcs3/Emu/PSP2/Modules/scePgf.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/scePgf.h rename to rpcs3/Emu/PSP2/Modules/scePgf.h diff --git a/rpcs3/Emu/ARMv7/Modules/scePhotoExport.cpp b/rpcs3/Emu/PSP2/Modules/scePhotoExport.cpp similarity index 89% rename from rpcs3/Emu/ARMv7/Modules/scePhotoExport.cpp rename to rpcs3/Emu/PSP2/Modules/scePhotoExport.cpp index d2caa21947..ad120525ec 100644 --- a/rpcs3/Emu/ARMv7/Modules/scePhotoExport.cpp +++ b/rpcs3/Emu/PSP2/Modules/scePhotoExport.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "scePhotoExport.h" -LOG_CHANNEL(scePhotoExport); +logs::channel scePhotoExport("scePhotoExport", logs::level::notice); s32 scePhotoExportFromData( vm::cptr photodata, diff --git a/rpcs3/Emu/ARMv7/Modules/scePhotoExport.h b/rpcs3/Emu/PSP2/Modules/scePhotoExport.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/scePhotoExport.h rename to rpcs3/Emu/PSP2/Modules/scePhotoExport.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceRazorCapture.cpp b/rpcs3/Emu/PSP2/Modules/sceRazorCapture.cpp similarity index 85% rename from rpcs3/Emu/ARMv7/Modules/sceRazorCapture.cpp rename to rpcs3/Emu/PSP2/Modules/sceRazorCapture.cpp index 5fa33f4102..8e5f828e32 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceRazorCapture.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceRazorCapture.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceRazorCapture.h" -LOG_CHANNEL(sceRazorCapture); +logs::channel sceRazorCapture("sceRazorCapture", logs::level::notice); void sceRazorCaptureSetTrigger(u32 frameIndex, vm::cptr captureFilename) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceRazorCapture.h b/rpcs3/Emu/PSP2/Modules/sceRazorCapture.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceRazorCapture.h rename to rpcs3/Emu/PSP2/Modules/sceRazorCapture.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceRtc.cpp b/rpcs3/Emu/PSP2/Modules/sceRtc.cpp similarity index 98% rename from rpcs3/Emu/ARMv7/Modules/sceRtc.cpp rename to rpcs3/Emu/PSP2/Modules/sceRtc.cpp index b0c8836dc6..ea44db8ee7 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceRtc.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceRtc.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceRtc.h" -LOG_CHANNEL(sceRtc); +logs::channel sceRtc("sceRtc", logs::level::notice); u32 sceRtcGetTickResolution() { diff --git a/rpcs3/Emu/PSP2/Modules/sceRtc.h b/rpcs3/Emu/PSP2/Modules/sceRtc.h new file mode 100644 index 0000000000..4fd403207b --- /dev/null +++ b/rpcs3/Emu/PSP2/Modules/sceRtc.h @@ -0,0 +1,3 @@ +#pragma once + +#include "Common.h" diff --git a/rpcs3/Emu/ARMv7/Modules/sceSas.cpp b/rpcs3/Emu/PSP2/Modules/sceSas.cpp similarity index 98% rename from rpcs3/Emu/ARMv7/Modules/sceSas.cpp rename to rpcs3/Emu/PSP2/Modules/sceSas.cpp index 52088d1e00..921fadfb9a 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceSas.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceSas.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceSas.h" -LOG_CHANNEL(sceSas); +logs::channel sceSas("sceSas", logs::level::notice); s32 sceSasGetNeededMemorySize(vm::cptr config, vm::ptr outSize) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceSas.h b/rpcs3/Emu/PSP2/Modules/sceSas.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceSas.h rename to rpcs3/Emu/PSP2/Modules/sceSas.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceScreenShot.cpp b/rpcs3/Emu/PSP2/Modules/sceScreenShot.cpp similarity index 87% rename from rpcs3/Emu/ARMv7/Modules/sceScreenShot.cpp rename to rpcs3/Emu/PSP2/Modules/sceScreenShot.cpp index a1d4385b02..b9acb49793 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceScreenShot.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceScreenShot.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceScreenShot.h" -LOG_CHANNEL(sceScreenShot); +logs::channel sceScreenShot("sceScreenShot", logs::level::notice); s32 sceScreenShotSetParam(vm::cptr param) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceScreenShot.h b/rpcs3/Emu/PSP2/Modules/sceScreenShot.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceScreenShot.h rename to rpcs3/Emu/PSP2/Modules/sceScreenShot.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceSfmt.cpp b/rpcs3/Emu/PSP2/Modules/sceSfmt.cpp similarity index 97% rename from rpcs3/Emu/ARMv7/Modules/sceSfmt.cpp rename to rpcs3/Emu/PSP2/Modules/sceSfmt.cpp index 601c7d02de..ca0912b311 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceSfmt.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceSfmt.cpp @@ -1,8 +1,8 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" -LOG_CHANNEL(sceSfmt); +logs::channel sceSfmt("sceSfmt", logs::level::notice); #define REG_FUNC(nid, name) REG_FNID(SceSfmt, nid, name) diff --git a/rpcs3/Emu/ARMv7/Modules/sceSha.cpp b/rpcs3/Emu/PSP2/Modules/sceSha.cpp similarity index 93% rename from rpcs3/Emu/ARMv7/Modules/sceSha.cpp rename to rpcs3/Emu/PSP2/Modules/sceSha.cpp index a5322de9f6..0cf3a6c1e0 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceSha.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceSha.cpp @@ -1,8 +1,8 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" -LOG_CHANNEL(sceSha); +logs::channel sceSha("sceSha", logs::level::notice); #define REG_FUNC(nid, name) REG_FNID(SceSha, nid, name) diff --git a/rpcs3/Emu/ARMv7/Modules/sceSqlite.cpp b/rpcs3/Emu/PSP2/Modules/sceSqlite.cpp similarity index 98% rename from rpcs3/Emu/ARMv7/Modules/sceSqlite.cpp rename to rpcs3/Emu/PSP2/Modules/sceSqlite.cpp index 8d50081196..d73740a75f 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceSqlite.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceSqlite.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceSqlite.h" -LOG_CHANNEL(sceSqlite); +logs::channel sceSqlite("sceSqlite", logs::level::notice); #define REG_FUNC(nid, name) REG_FNID(SceSqlite, nid, name) diff --git a/rpcs3/Emu/ARMv7/Modules/sceSqlite.h b/rpcs3/Emu/PSP2/Modules/sceSqlite.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceSqlite.h rename to rpcs3/Emu/PSP2/Modules/sceSqlite.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceSsl.cpp b/rpcs3/Emu/PSP2/Modules/sceSsl.cpp similarity index 95% rename from rpcs3/Emu/ARMv7/Modules/sceSsl.cpp rename to rpcs3/Emu/PSP2/Modules/sceSsl.cpp index 1a9979517f..e1d117dba6 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceSsl.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceSsl.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceSsl.h" -LOG_CHANNEL(sceSsl); +logs::channel sceSsl("sceSsl", logs::level::notice); s32 sceSslInit(u32 poolSize) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceSsl.h b/rpcs3/Emu/PSP2/Modules/sceSsl.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceSsl.h rename to rpcs3/Emu/PSP2/Modules/sceSsl.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceSulpha.cpp b/rpcs3/Emu/PSP2/Modules/sceSulpha.cpp similarity index 96% rename from rpcs3/Emu/ARMv7/Modules/sceSulpha.cpp rename to rpcs3/Emu/PSP2/Modules/sceSulpha.cpp index 3210e04906..a602794ade 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceSulpha.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceSulpha.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceSulpha.h" -LOG_CHANNEL(sceSulpha); +logs::channel sceSulpha("sceSulpha", logs::level::notice); s32 sceSulphaNetworkInit() { diff --git a/rpcs3/Emu/ARMv7/Modules/sceSulpha.h b/rpcs3/Emu/PSP2/Modules/sceSulpha.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceSulpha.h rename to rpcs3/Emu/PSP2/Modules/sceSulpha.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceSysmodule.cpp b/rpcs3/Emu/PSP2/Modules/sceSysmodule.cpp similarity index 89% rename from rpcs3/Emu/ARMv7/Modules/sceSysmodule.cpp rename to rpcs3/Emu/PSP2/Modules/sceSysmodule.cpp index 6906f2cf3a..71dbe9870f 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceSysmodule.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceSysmodule.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceSysmodule.h" -LOG_CHANNEL(sceSysmodule); +logs::channel sceSysmodule("sceSysmodule", logs::level::notice); s32 sceSysmoduleLoadModule(u16 id) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceSysmodule.h b/rpcs3/Emu/PSP2/Modules/sceSysmodule.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceSysmodule.h rename to rpcs3/Emu/PSP2/Modules/sceSysmodule.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceSystemGesture.cpp b/rpcs3/Emu/PSP2/Modules/sceSystemGesture.cpp similarity index 97% rename from rpcs3/Emu/ARMv7/Modules/sceSystemGesture.cpp rename to rpcs3/Emu/PSP2/Modules/sceSystemGesture.cpp index 6d6dedf763..c410a0c62f 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceSystemGesture.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceSystemGesture.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceSystemGesture.h" -LOG_CHANNEL(sceSystemGesture); +logs::channel sceSystemGesture("sceSystemGesture", logs::level::notice); s32 sceSystemGestureInitializePrimitiveTouchRecognizer(vm::ptr parameter) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceSystemGesture.h b/rpcs3/Emu/PSP2/Modules/sceSystemGesture.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceSystemGesture.h rename to rpcs3/Emu/PSP2/Modules/sceSystemGesture.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceTouch.cpp b/rpcs3/Emu/PSP2/Modules/sceTouch.cpp similarity index 90% rename from rpcs3/Emu/ARMv7/Modules/sceTouch.cpp rename to rpcs3/Emu/PSP2/Modules/sceTouch.cpp index 5f07db80e6..e59a7ef936 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceTouch.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceTouch.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceTouch.h" -LOG_CHANNEL(sceTouch); +logs::channel sceTouch("sceTouch", logs::level::notice); s32 sceTouchGetPanelInfo(u32 port, vm::ptr pPanelInfo) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceTouch.h b/rpcs3/Emu/PSP2/Modules/sceTouch.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceTouch.h rename to rpcs3/Emu/PSP2/Modules/sceTouch.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceUlt.cpp b/rpcs3/Emu/PSP2/Modules/sceUlt.cpp similarity index 99% rename from rpcs3/Emu/ARMv7/Modules/sceUlt.cpp rename to rpcs3/Emu/PSP2/Modules/sceUlt.cpp index 445cf18212..af1ecd53dc 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceUlt.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceUlt.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceUlt.h" -LOG_CHANNEL(sceUlt); +logs::channel sceUlt("sceUlt", logs::level::notice); // Functions diff --git a/rpcs3/Emu/ARMv7/Modules/sceUlt.h b/rpcs3/Emu/PSP2/Modules/sceUlt.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceUlt.h rename to rpcs3/Emu/PSP2/Modules/sceUlt.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceVideodec.cpp b/rpcs3/Emu/PSP2/Modules/sceVideodec.cpp similarity index 95% rename from rpcs3/Emu/ARMv7/Modules/sceVideodec.cpp rename to rpcs3/Emu/PSP2/Modules/sceVideodec.cpp index 9c57870236..0ebef4aa25 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceVideodec.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceVideodec.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceVideodec.h" -LOG_CHANNEL(sceVideodec); +logs::channel sceVideodec("sceVideodec", logs::level::notice); s32 sceVideodecInitLibrary(u32 codecType, vm::cptr pInitInfo) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceVideodec.h b/rpcs3/Emu/PSP2/Modules/sceVideodec.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceVideodec.h rename to rpcs3/Emu/PSP2/Modules/sceVideodec.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceVoice.cpp b/rpcs3/Emu/PSP2/Modules/sceVoice.cpp similarity index 97% rename from rpcs3/Emu/ARMv7/Modules/sceVoice.cpp rename to rpcs3/Emu/PSP2/Modules/sceVoice.cpp index b0c1d53bca..88967abaac 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceVoice.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceVoice.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceVoice.h" -LOG_CHANNEL(sceVoice); +logs::channel sceVoice("sceVoice", logs::level::notice); s32 sceVoiceInit(vm::ptr pArg, SceVoiceVersion version) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceVoice.h b/rpcs3/Emu/PSP2/Modules/sceVoice.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceVoice.h rename to rpcs3/Emu/PSP2/Modules/sceVoice.h diff --git a/rpcs3/Emu/ARMv7/Modules/sceVoiceQoS.cpp b/rpcs3/Emu/PSP2/Modules/sceVoiceQoS.cpp similarity index 96% rename from rpcs3/Emu/ARMv7/Modules/sceVoiceQoS.cpp rename to rpcs3/Emu/PSP2/Modules/sceVoiceQoS.cpp index b584945713..f5ae9af81e 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceVoiceQoS.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceVoiceQoS.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" -#include "Emu/ARMv7/ARMv7Module.h" +#include "Emu/PSP2/ARMv7Module.h" #include "sceVoiceQoS.h" -LOG_CHANNEL(sceVoiceQoS); +logs::channel sceVoiceQoS("sceVoiceQoS", logs::level::notice); s32 sceVoiceQoSInit() { diff --git a/rpcs3/Emu/ARMv7/Modules/sceVoiceQoS.h b/rpcs3/Emu/PSP2/Modules/sceVoiceQoS.h similarity index 100% rename from rpcs3/Emu/ARMv7/Modules/sceVoiceQoS.h rename to rpcs3/Emu/PSP2/Modules/sceVoiceQoS.h diff --git a/rpcs3/Emu/RSX/CgBinaryFragmentProgram.cpp b/rpcs3/Emu/RSX/CgBinaryFragmentProgram.cpp index 743be6817a..14c969b960 100644 --- a/rpcs3/Emu/RSX/CgBinaryFragmentProgram.cpp +++ b/rpcs3/Emu/RSX/CgBinaryFragmentProgram.cpp @@ -4,9 +4,11 @@ #include "CgBinaryProgram.h" #include "Emu/RSX/RSXFragmentProgram.h" +#include + void CgBinaryDisasm::AddCodeAsm(const std::string& code) { - Expects(m_opcode < 70); + EXPECTS(m_opcode < 70); std::string op_name = ""; if (dst.dest_reg == 63) @@ -223,7 +225,7 @@ void CgBinaryDisasm::TaskFP() { m_size = 0; u32* data = (u32*)&m_buffer[m_offset]; - Expects((m_buffer_size - m_offset) % sizeof(u32) == 0); + EXPECTS((m_buffer_size - m_offset) % sizeof(u32) == 0); for (u32 i = 0; i < (m_buffer_size - m_offset) / sizeof(u32); i++) { data[i] = se_storage::swap(data[i]); // WTF, cannot use be_t<> there? @@ -471,7 +473,7 @@ void CgBinaryDisasm::TaskFP() break; } - Ensures(m_step % sizeof(u32) == 0); + ENSURES(m_step % sizeof(u32) == 0); data += m_step / sizeof(u32); } -} \ No newline at end of file +} diff --git a/rpcs3/Emu/RSX/CgBinaryProgram.h b/rpcs3/Emu/RSX/CgBinaryProgram.h index 566468ecea..0b1752347c 100644 --- a/rpcs3/Emu/RSX/CgBinaryProgram.h +++ b/rpcs3/Emu/RSX/CgBinaryProgram.h @@ -373,7 +373,7 @@ public: m_offset = prog.ucode; u32* vdata = (u32*)&m_buffer[m_offset]; - Ensures((m_buffer_size - m_offset) % sizeof(u32) == 0); + ENSURES((m_buffer_size - m_offset) % sizeof(u32) == 0); for (u32 i = 0; i < (m_buffer_size - m_offset) / sizeof(u32); i++) { vdata[i] = se_storage::swap(vdata[i]); // WTF, cannot use be_t<> there? diff --git a/rpcs3/Emu/RSX/CgBinaryVertexProgram.cpp b/rpcs3/Emu/RSX/CgBinaryVertexProgram.cpp index a318201274..a6f03ffffa 100644 --- a/rpcs3/Emu/RSX/CgBinaryVertexProgram.cpp +++ b/rpcs3/Emu/RSX/CgBinaryVertexProgram.cpp @@ -6,13 +6,13 @@ void CgBinaryDisasm::AddScaCodeDisasm(const std::string& code) { - Expects(m_sca_opcode < 21); + EXPECTS(m_sca_opcode < 21); m_arb_shader += rsx_vp_sca_op_names[m_sca_opcode] + code + " "; } void CgBinaryDisasm::AddVecCodeDisasm(const std::string& code) { - Expects(m_vec_opcode < 26); + EXPECTS(m_vec_opcode < 26); m_arb_shader += rsx_vp_vec_op_names[m_vec_opcode] + code + " "; } @@ -448,4 +448,4 @@ void CgBinaryDisasm::TaskVP() } m_arb_shader += "END\n"; -} \ No newline at end of file +} diff --git a/rpcs3/Emu/RSX/Common/BufferUtils.cpp b/rpcs3/Emu/RSX/Common/BufferUtils.cpp index 05c4a8acdc..9e8f338f48 100644 --- a/rpcs3/Emu/RSX/Common/BufferUtils.cpp +++ b/rpcs3/Emu/RSX/Common/BufferUtils.cpp @@ -48,7 +48,7 @@ namespace void write_vertex_array_data_to_buffer(gsl::span raw_dst_span, const gsl::byte *src_ptr, u32 first, u32 count, rsx::vertex_base_type type, u32 vector_element_count, u32 attribute_src_stride, u8 dst_stride) { - Expects(vector_element_count > 0); + EXPECTS(vector_element_count > 0); switch (type) { @@ -98,7 +98,7 @@ std::tuple upload_untouched(gsl::span> src, gsl::span T min_index = -1; T max_index = 0; - Expects(dst.size_bytes() >= src.size_bytes()); + EXPECTS(dst.size_bytes() >= src.size_bytes()); size_t dst_idx = 0; for (T index : src) @@ -124,7 +124,7 @@ std::tuple expand_indexed_triangle_fan(gsl::span> src, gs T min_index = -1; T max_index = 0; - Expects(dst.size() >= 3 * (src.size() - 2)); + EXPECTS(dst.size() >= 3 * (src.size() - 2)); const T index0 = src[0]; if (!is_primitive_restart_enabled || index0 != -1) // Cut @@ -174,7 +174,7 @@ std::tuple expand_indexed_quads(gsl::span> src, gsl::span T min_index = -1; T max_index = 0; - Expects(4 * dst.size_bytes() >= 6 * src.size_bytes()); + EXPECTS(4 * dst.size_bytes() >= 6 * src.size_bytes()); size_t dst_idx = 0; while (!src.empty()) @@ -353,7 +353,7 @@ std::tuple write_index_array_data_to_buffer_impl(gsl::span(get_index_type_size(type)); - Expects(rsx::method_registers[NV4097_SET_VERTEX_DATA_BASE_INDEX] == 0); + EXPECTS(rsx::method_registers[NV4097_SET_VERTEX_DATA_BASE_INDEX] == 0); bool is_primitive_restart_enabled = !!rsx::method_registers[NV4097_SET_RESTART_INDEX_ENABLE]; u32 primitive_restart_index = rsx::method_registers[NV4097_SET_RESTART_INDEX]; @@ -363,7 +363,7 @@ std::tuple write_index_array_data_to_buffer_impl(gsl::span &range = first_count_arguments[i]; const std::tuple &next_range = first_count_arguments[i + 1]; - Expects(std::get<0>(range) + std::get<1>(range) == std::get<0>(next_range)); + EXPECTS(std::get<0>(range) + std::get<1>(range) == std::get<0>(next_range)); } u32 first = std::get<0>(first_count_arguments.front()); u32 count = std::get<0>(first_count_arguments.back()) + std::get<1>(first_count_arguments.back()) - first; @@ -415,7 +415,7 @@ std::tuple write_index_array_data_to_buffer_untouched(gsl::span &range = first_count_arguments[i]; const std::tuple &next_range = first_count_arguments[i + 1]; - Expects(std::get<0>(range) + std::get<1>(range) == std::get<0>(next_range)); + EXPECTS(std::get<0>(range) + std::get<1>(range) == std::get<0>(next_range)); } u32 first = std::get<0>(first_count_arguments.front()); u32 count = std::get<0>(first_count_arguments.back()) + std::get<1>(first_count_arguments.back()) - first; @@ -438,7 +438,7 @@ std::tuple write_index_array_data_to_buffer_untouched(gsl::span &range = first_count_arguments[i]; const std::tuple &next_range = first_count_arguments[i + 1]; - Expects(std::get<0>(range) + std::get<1>(range) == std::get<0>(next_range)); + EXPECTS(std::get<0>(range) + std::get<1>(range) == std::get<0>(next_range)); } u32 first = std::get<0>(first_count_arguments.front()); u32 count = std::get<0>(first_count_arguments.back()) + std::get<1>(first_count_arguments.back()) - first; diff --git a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp index b0b9e76057..1c905301e6 100644 --- a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp @@ -4,6 +4,8 @@ #include "FragmentProgramDecompiler.h" +#include + FragmentProgramDecompiler::FragmentProgramDecompiler(const RSXFragmentProgram &prog, u32& size) : m_prog(prog), m_size(size), @@ -522,21 +524,21 @@ std::string FragmentProgramDecompiler::Decompile() while (true) { - for (auto finded = std::find(m_end_offsets.begin(), m_end_offsets.end(), m_size); - finded != m_end_offsets.end(); - finded = std::find(m_end_offsets.begin(), m_end_offsets.end(), m_size)) + for (auto found = std::find(m_end_offsets.begin(), m_end_offsets.end(), m_size); + found != m_end_offsets.end(); + found = std::find(m_end_offsets.begin(), m_end_offsets.end(), m_size)) { - m_end_offsets.erase(finded); + m_end_offsets.erase(found); m_code_level--; AddCode("}"); m_loop_count--; } - for (auto finded = std::find(m_else_offsets.begin(), m_else_offsets.end(), m_size); - finded != m_else_offsets.end(); - finded = std::find(m_else_offsets.begin(), m_else_offsets.end(), m_size)) + for (auto found = std::find(m_else_offsets.begin(), m_else_offsets.end(), m_size); + found != m_else_offsets.end(); + found = std::find(m_else_offsets.begin(), m_else_offsets.end(), m_size)) { - m_else_offsets.erase(finded); + m_else_offsets.erase(found); m_code_level--; AddCode("}"); AddCode("else"); @@ -644,7 +646,7 @@ std::string FragmentProgramDecompiler::Decompile() if (dst.end) break; - Ensures(m_offset % sizeof(u32) == 0); + ENSURES(m_offset % sizeof(u32) == 0); data += m_offset / sizeof(u32); } diff --git a/rpcs3/Emu/RSX/Common/ProgramStateCache.h b/rpcs3/Emu/RSX/Common/ProgramStateCache.h index 604a4ecf54..e76983b481 100644 --- a/rpcs3/Emu/RSX/Common/ProgramStateCache.h +++ b/rpcs3/Emu/RSX/Common/ProgramStateCache.h @@ -227,7 +227,7 @@ public: 0x6, 0x7, 0x4, 0x5, 0x2, 0x3, 0x0, 0x1); - Expects(dst_buffer.size_bytes() >= gsl::narrow(I->second.FragmentConstantOffsetCache.size()) * 16); + EXPECTS(dst_buffer.size_bytes() >= gsl::narrow(I->second.FragmentConstantOffsetCache.size()) * 16); size_t offset = 0; for (size_t offset_in_fragment_program : I->second.FragmentConstantOffsetCache) diff --git a/rpcs3/Emu/RSX/Common/ShaderParam.h b/rpcs3/Emu/RSX/Common/ShaderParam.h index 747f45bdcf..d667369565 100644 --- a/rpcs3/Emu/RSX/Common/ShaderParam.h +++ b/rpcs3/Emu/RSX/Common/ShaderParam.h @@ -152,7 +152,7 @@ public: { auto var_blocks = fmt::split(var, { "." }); - Expects(var_blocks.size() != 0); + EXPECTS(var_blocks.size() != 0); name = var_blocks[0]; diff --git a/rpcs3/Emu/RSX/Common/TextureUtils.cpp b/rpcs3/Emu/RSX/Common/TextureUtils.cpp index f39c06601b..960512b5af 100644 --- a/rpcs3/Emu/RSX/Common/TextureUtils.cpp +++ b/rpcs3/Emu/RSX/Common/TextureUtils.cpp @@ -21,7 +21,7 @@ namespace constexpr void copy(gsl::span dst, gsl::span src) { static_assert(std::is_convertible::value, "Cannot convert source and destination span type."); - Expects(dst.size() == src.size()); + EXPECTS(dst.size() == src.size()); std::copy(src.begin(), src.end(), dst.begin()); } diff --git a/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.cpp b/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.cpp index 39f72c2674..fed540d080 100644 --- a/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.cpp @@ -3,6 +3,8 @@ #include "VertexProgramDecompiler.h" +#include + std::string VertexProgramDecompiler::GetMask(bool is_sca) { std::string ret; diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp index c987400078..fdaf42161f 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp @@ -1,6 +1,6 @@ +#ifdef _MSC_VER #include "stdafx.h" #include "stdafx_d3d12.h" -#ifdef _MSC_VER #include "D3D12GSRender.h" #include "d3dx12.h" @@ -78,7 +78,7 @@ std::vector D3D12GSRender::upload_vertex_attrib u32 vertex_count = get_vertex_count(vertex_ranges); size_t offset_in_vertex_buffers_buffer = 0; u32 input_mask = rsx::method_registers[NV4097_SET_VERTEX_ATTRIB_INPUT_MASK]; - Expects(rsx::method_registers[NV4097_SET_VERTEX_DATA_BASE_INDEX] == 0); + EXPECTS(rsx::method_registers[NV4097_SET_VERTEX_DATA_BASE_INDEX] == 0); for (int index = 0; index < rsx::limits::vertex_count; ++index) { @@ -350,7 +350,7 @@ std::tuple> D3D12GSRe return std::make_tuple(true, index_count, upload_vertex_attributes(first_count_commands, command_list)); } - Expects(draw_command == rsx::draw_command::indexed); + EXPECTS(draw_command == rsx::draw_command::indexed); // Index count size_t index_count = get_index_count(draw_mode, gsl::narrow(get_vertex_count(first_count_commands))); diff --git a/rpcs3/Emu/RSX/D3D12/D3D12CommonDecompiler.cpp b/rpcs3/Emu/RSX/D3D12/D3D12CommonDecompiler.cpp index d5721cb1ed..29a7ddfc79 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12CommonDecompiler.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12CommonDecompiler.cpp @@ -1,6 +1,6 @@ +#ifdef _MSC_VER #include "stdafx.h" #include "stdafx_d3d12.h" -#ifdef _MSC_VER #include "D3D12CommonDecompiler.h" std::string getFloatTypeNameImp(size_t elementCount) diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp index 03478f5640..fe42ff7be9 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp @@ -1,6 +1,6 @@ +#ifdef _MSC_VER #include "stdafx.h" #include "stdafx_d3d12.h" -#ifdef _MSC_VER #include "D3D12Formats.h" #include "D3D12Utils.h" #include "Emu/RSX/GCM.h" diff --git a/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp b/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp index 1eba50945c..1d6d2f26fc 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp @@ -1,6 +1,6 @@ +#ifdef _MSC_VER #include "stdafx.h" #include "stdafx_d3d12.h" -#ifdef _MSC_VER #include "D3D12FragmentProgramDecompiler.h" #include "D3D12CommonDecompiler.h" #include "Emu/Memory/Memory.h" diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp index c4f2e66e17..8f71e92e44 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp @@ -1,6 +1,6 @@ +#ifdef _MSC_VER #include "stdafx.h" #include "stdafx_d3d12.h" -#ifdef _MSC_VER #include "Utilities/Config.h" #include "D3D12GSRender.h" #include @@ -43,13 +43,13 @@ HMODULE D3DCompiler; void loadD3D12FunctionPointers() { - ASSERT(D3D12Module = LoadLibrary(L"d3d12.dll")); + VERIFY(D3D12Module = LoadLibrary(L"d3d12.dll")); wrapD3D12CreateDevice = (PFN_D3D12_CREATE_DEVICE)GetProcAddress(D3D12Module, "D3D12CreateDevice"); wrapD3D12GetDebugInterface = (PFN_D3D12_GET_DEBUG_INTERFACE)GetProcAddress(D3D12Module, "D3D12GetDebugInterface"); wrapD3D12SerializeRootSignature = (PFN_D3D12_SERIALIZE_ROOT_SIGNATURE)GetProcAddress(D3D12Module, "D3D12SerializeRootSignature"); - ASSERT(D3D11Module = LoadLibrary(L"d3d11.dll")); + VERIFY(D3D11Module = LoadLibrary(L"d3d11.dll")); wrapD3D11On12CreateDevice = (PFN_D3D11ON12_CREATE_DEVICE)GetProcAddress(D3D11Module, "D3D11On12CreateDevice"); - ASSERT(D3DCompiler = LoadLibrary(L"d3dcompiler_47.dll")); + VERIFY(D3DCompiler = LoadLibrary(L"d3dcompiler_47.dll")); wrapD3DCompile = (pD3DCompile)GetProcAddress(D3DCompiler, "D3DCompile"); } @@ -486,7 +486,7 @@ void D3D12GSRender::flip(int buffer) if (!is_flip_surface_in_global_memory(rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]))) { resource_storage &storage = get_current_resource_storage(); - ASSERT(storage.ram_framebuffer == nullptr); + VERIFY(storage.ram_framebuffer == nullptr); size_t w = 0, h = 0, row_pitch = 0; diff --git a/rpcs3/Emu/RSX/D3D12/D3D12MemoryHelpers.cpp b/rpcs3/Emu/RSX/D3D12/D3D12MemoryHelpers.cpp index c97e8e47f8..38de09d3c6 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12MemoryHelpers.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12MemoryHelpers.cpp @@ -1,6 +1,6 @@ +#ifdef _MSC_VER #include "stdafx.h" #include "stdafx_d3d12.h" -#ifdef _MSC_VER #include "D3D12MemoryHelpers.h" diff --git a/rpcs3/Emu/RSX/D3D12/D3D12MemoryHelpers.h b/rpcs3/Emu/RSX/D3D12/D3D12MemoryHelpers.h index 2de6ee913b..d9d58adc38 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12MemoryHelpers.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12MemoryHelpers.h @@ -3,6 +3,7 @@ #include "d3dx12.h" #include "../Common/ring_buffer_helper.h" #include +#include struct d3d12_data_heap : public data_heap { diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Overlay.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Overlay.cpp index d82978e04d..1df51b57e6 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Overlay.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Overlay.cpp @@ -1,6 +1,6 @@ +#ifdef _MSC_VER #include "stdafx.h" #include "stdafx_d3d12.h" -#ifdef _MSC_VER #include "D3D12GSRender.h" #include #include diff --git a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp index 2ba3d0e5ec..2957cf514f 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp @@ -1,6 +1,6 @@ +#ifdef _MSC_VER #include "stdafx.h" #include "stdafx_d3d12.h" -#ifdef _MSC_VER #include "Utilities/Config.h" #include "D3D12PipelineState.h" #include "D3D12GSRender.h" diff --git a/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp b/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp index 1370d91f30..0644e2dff6 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp @@ -1,6 +1,6 @@ +#ifdef _MSC_VER #include "stdafx.h" #include "stdafx_d3d12.h" -#ifdef _MSC_VER #include "Utilities/Config.h" #include "D3D12RenderTargetSets.h" #include "Emu/Memory/Memory.h" diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp index 26ca992e45..17013b3c97 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp @@ -1,6 +1,6 @@ +#ifdef _MSC_VER #include "stdafx.h" #include "stdafx_d3d12.h" -#ifdef _MSC_VER #include "D3D12GSRender.h" #include "d3dx12.h" #include "../Common/TextureUtils.h" diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Utils.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Utils.cpp index e6cd73157a..9e7645df06 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Utils.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Utils.cpp @@ -1,6 +1,6 @@ +#ifdef _MSC_VER #include "stdafx.h" #include "stdafx_d3d12.h" -#ifdef _MSC_VER #include "D3D12GSRender.h" #include "d3dx12.h" #define STRINGIFY(x) #x diff --git a/rpcs3/Emu/RSX/D3D12/D3D12VertexProgramDecompiler.cpp b/rpcs3/Emu/RSX/D3D12/D3D12VertexProgramDecompiler.cpp index 2688e08930..f49a409e40 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12VertexProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12VertexProgramDecompiler.cpp @@ -1,6 +1,6 @@ +#ifdef _MSC_VER #include "stdafx.h" #include "stdafx_d3d12.h" -#ifdef _MSC_VER #include "D3D12VertexProgramDecompiler.h" #include "D3D12CommonDecompiler.h" #include "Emu/System.h" diff --git a/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp b/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp index 36d7b638b9..ccf1c35880 100644 --- a/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp +++ b/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp @@ -4,6 +4,8 @@ #include "GLVertexProgram.h" #include "GLCommonDecompiler.h" +#include + std::string GLVertexDecompilerThread::getFloatTypeName(size_t elementCount) { return getFloatTypeNameImpl(elementCount); diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 370befbbc2..886179031e 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -12,6 +12,8 @@ #include "Utilities/GSL.h" #include "Utilities/StrUtil.h" +#include + #define CMD_DEBUG 0 cfg::bool_entry g_cfg_rsx_write_color_buffers(cfg::root.video, "Write Color Buffers"); @@ -40,7 +42,7 @@ namespace rsx void shaders_cache::load(const std::string &path, shader_language lang) { - const std::string lang_name = bijective_find(lang, ""); + const std::string lang_name(::unveil::get(lang)); auto extract_hash = [](const std::string &string) { @@ -174,7 +176,7 @@ namespace rsx } throw EXCEPTION("Wrong vector size"); case vertex_base_type::cmp: return sizeof(u16) * 4; - case vertex_base_type::ub256: Expects(size == 4); return sizeof(u8) * 4; + case vertex_base_type::ub256: EXPECTS(size == 4); return sizeof(u8) * 4; } throw EXCEPTION("RSXVertexData::GetTypeSize: Bad vertex data type (%d)!", type); } @@ -561,7 +563,7 @@ namespace rsx } else { - Expects(0); + EXPECTS(0); //std::lock_guard lock{ m_mtx_task }; //internal_task_entry &front = m_internal_tasks.front(); diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index 4f84b5a716..9b2afa5bb9 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -3,6 +3,7 @@ #include #include #include +#include #include "GCM.h" #include "RSXTexture.h" #include "RSXVertexProgram.h" @@ -52,13 +53,18 @@ namespace rsx } template<> -struct bijective +struct unveil { - static constexpr bijective_pair map[] + static inline const char* get(rsx::shader_language in) { - { rsx::shader_language::glsl, "glsl" }, - { rsx::shader_language::hlsl, "hlsl" }, - }; + switch (in) + { + case rsx::shader_language::glsl: return "glsl"; + case rsx::shader_language::hlsl: return "hlsl"; + } + + return ""; + } }; namespace rsx diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index 0ea6ddb38f..73919ceb96 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -99,7 +99,7 @@ namespace vk size_t color_format_idx = 0; size_t depth_format_idx = 0; - Expects(color_count < 5); + EXPECTS(color_count < 5); switch (color_format) { diff --git a/rpcs3/Emu/RSX/rsx_methods.cpp b/rpcs3/Emu/RSX/rsx_methods.cpp index 968589bc75..96e8c224a0 100644 --- a/rpcs3/Emu/RSX/rsx_methods.cpp +++ b/rpcs3/Emu/RSX/rsx_methods.cpp @@ -7,6 +7,8 @@ #include "rsx_utils.h" #include "Emu/Cell/PPUCallback.h" +#include + cfg::map_entry g_cfg_rsx_frame_limit(cfg::root.video, "Frame limit", { { "Off", 0. }, @@ -43,7 +45,7 @@ namespace rsx if (Emu.IsStopped()) break; - std::this_thread::sleep_for(std::chrono::milliseconds(1)); + std::this_thread::sleep_for(1ms); } } @@ -253,7 +255,7 @@ namespace rsx return; } - vm::ps3::ptr result = { get_address(offset, location), vm::addr }; + vm::ps3::ptr result = vm::cast(get_address(offset, location)); result->timer = rsx->timestamp(); diff --git a/rpcs3/Emu/RSX/rsx_utils.h b/rpcs3/Emu/RSX/rsx_utils.h index 989c4470a5..d02b63218c 100644 --- a/rpcs3/Emu/RSX/rsx_utils.h +++ b/rpcs3/Emu/RSX/rsx_utils.h @@ -5,8 +5,6 @@ extern "C" #include } -#include - namespace rsx { template @@ -26,6 +24,12 @@ namespace rsx } } + // + static inline u32 ceil_log2(u32 value) + { + return value <= 1 ? 0 : ::cntlz32((value - 1) << 1) ^ 31; + } + /* Note: What the ps3 calls swizzling in this case is actually z-ordering / morton ordering of pixels * - Input can be swizzled or linear, bool flag handles conversion to and from * - It will handle any width and height that are a power of 2, square or non square @@ -34,8 +38,8 @@ namespace rsx template void convert_linear_swizzle(void* input_pixels, void* output_pixels, u16 width, u16 height, bool input_is_swizzled) { - u16 log2width = ::narrow(ceil(std::log2(width))); - u16 log2height = ::narrow(ceil(std::log2(height))); + u32 log2width = ceil_log2(width); + u32 log2height = ceil_log2(height); // Max mask possible for square texture u32 x_mask = 0x55555555; diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index e49240a652..253824b2de 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -9,7 +9,9 @@ #include "Emu/Cell/PPUCallback.h" #include "Emu/Cell/PPUOpcodes.h" #include "Emu/Cell/SPUThread.h" +#include "Emu/Cell/RawSPUThread.h" #include "Emu/Cell/lv2/sys_sync.h" +#include "Emu/PSP2/ARMv7Thread.h" #include "Emu/IdManager.h" #include "Emu/RSX/GSRender.h" @@ -21,6 +23,8 @@ #include "../Crypto/unself.h" +#include + cfg::bool_entry g_cfg_autostart(cfg::root.misc, "Always start after boot"); cfg::bool_entry g_cfg_autoexit(cfg::root.misc, "Exit RPCS3 when process finishes"); @@ -31,6 +35,8 @@ extern cfg::string_entry g_cfg_vfs_app_home; extern atomic_t g_thread_count; +extern atomic_t g_ppu_core[2]; + extern u64 get_system_time(); fs::file g_tty; @@ -60,6 +66,9 @@ void Emulator::Init() idm::init(); fxm::init(); + g_ppu_core[0] = 0; + g_ppu_core[1] = 0; + // Reset defaults, cache them cfg::root.from_default(); g_cfg_defaults = cfg::root.to_string(); @@ -252,10 +261,10 @@ void Emulator::Load() { LOG_ERROR(LOADER, "Invalid or unsupported file format: %s", m_path); - LOG_WARNING(LOADER, "** ppu_exec_loader -> %s", bijective_find(ppu_exec, "???")); - LOG_WARNING(LOADER, "** ppu_prx_loader -> %s", bijective_find(ppu_prx, "???")); - LOG_WARNING(LOADER, "** spu_exec_loader -> %s", bijective_find(spu_exec, "???")); - LOG_WARNING(LOADER, "** arm_exec_loader -> %s", bijective_find(arm_exec, "???")); + LOG_WARNING(LOADER, "** ppu_exec_loader -> %s", ppu_exec.get_error()); + LOG_WARNING(LOADER, "** ppu_prx_loader -> %s", ppu_prx.get_error()); + LOG_WARNING(LOADER, "** spu_exec_loader -> %s", spu_exec.get_error()); + LOG_WARNING(LOADER, "** arm_exec_loader -> %s", arm_exec.get_error()); return; } @@ -294,11 +303,11 @@ void Emulator::Run() m_pause_amend_time = 0; m_status = Running; - for (auto& thread : get_all_cpu_threads()) + idm::select([](u32, cpu_thread& cpu) { - thread->state -= cpu_state::stop; - thread->lock_notify(); - } + cpu.state -= cpu_state::stop; + cpu->lock_notify(); + }); SendDbgCommand(DID_STARTED_EMU); } @@ -323,10 +332,10 @@ bool Emulator::Pause() SendDbgCommand(DID_PAUSE_EMU); - for (auto& thread : get_all_cpu_threads()) + idm::select([](u32, cpu_thread& cpu) { - thread->state += cpu_state::dbg_global_pause; - } + cpu.state += cpu_state::dbg_global_pause; + }); SendDbgCommand(DID_PAUSED_EMU); @@ -357,11 +366,11 @@ void Emulator::Resume() SendDbgCommand(DID_RESUME_EMU); - for (auto& thread : get_all_cpu_threads()) + idm::select([](u32, cpu_thread& cpu) { - thread->state -= cpu_state::dbg_global_pause; - thread->lock_notify(); - } + cpu.state -= cpu_state::dbg_global_pause; + cpu->lock_notify(); + }); rpcs3::on_resume()(); @@ -383,11 +392,11 @@ void Emulator::Stop() { LV2_LOCK; - for (auto& thread : get_all_cpu_threads()) + idm::select([](u32, cpu_thread& cpu) { - thread->state += cpu_state::dbg_global_stop; - thread->lock_notify(); - } + cpu.state += cpu_state::dbg_global_stop; + cpu->lock_notify(); + }); } LOG_NOTICE(GENERAL, "All threads signaled..."); @@ -424,16 +433,3 @@ void Emulator::Stop() } Emulator Emu; - -DECLARE(idm::g_map); -DECLARE(idm::g_id); -DECLARE(idm::g_mutex); - -DECLARE(fxm::g_map); -DECLARE(fxm::g_mutex); - -#ifndef _MSC_VER -constexpr DECLARE(bijective::map); -constexpr DECLARE(bijective<_log::level, const char*>::map); -constexpr DECLARE(bijective::map); -#endif diff --git a/rpcs3/Gui/ConLogFrame.cpp b/rpcs3/Gui/ConLogFrame.cpp index c8296bf0b1..f363c0e2e9 100644 --- a/rpcs3/Gui/ConLogFrame.cpp +++ b/rpcs3/Gui/ConLogFrame.cpp @@ -2,6 +2,8 @@ #include "stdafx_gui.h" #include "Gui/ConLogFrame.h" +#include + enum { id_log_copy, // Copy log to ClipBoard @@ -210,19 +212,19 @@ void LogFrame::OnTimer(wxTimerEvent& event) if (text[pos + 2] == ' ') { - _log::level level; + logs::level level; wxColour color; switch (text[pos + 1].GetValue()) { - case 'A': level = _log::level::always; color.Set(0x00, 0xFF, 0xFF); break; // Cyan - case 'F': level = _log::level::fatal; color.Set(0xFF, 0x00, 0xFF); break; // Fuchsia - case 'E': level = _log::level::error; color.Set(0xFF, 0x00, 0x00); break; // Red - case 'U': level = _log::level::todo; color.Set(0xFF, 0x60, 0x00); break; // Orange - case 'S': level = _log::level::success; color.Set(0x00, 0xFF, 0x00); break; // Green - case 'W': level = _log::level::warning; color.Set(0xFF, 0xFF, 0x00); break; // Yellow - case '!': level = _log::level::notice; color.Set(0xFF, 0xFF, 0xFF); break; // White - case 'T': level = _log::level::trace; color.Set(0x80, 0x80, 0x80); break; // Gray + case 'A': level = logs::level::always; color.Set(0x00, 0xFF, 0xFF); break; // Cyan + case 'F': level = logs::level::fatal; color.Set(0xFF, 0x00, 0xFF); break; // Fuchsia + case 'E': level = logs::level::error; color.Set(0xFF, 0x00, 0x00); break; // Red + case 'U': level = logs::level::todo; color.Set(0xFF, 0x60, 0x00); break; // Orange + case 'S': level = logs::level::success; color.Set(0x00, 0xFF, 0x00); break; // Green + case 'W': level = logs::level::warning; color.Set(0xFF, 0xFF, 0x00); break; // Yellow + case '!': level = logs::level::notice; color.Set(0xFF, 0xFF, 0xFF); break; // White + case 'T': level = logs::level::trace; color.Set(0x80, 0x80, 0x80); break; // Gray default: continue; } diff --git a/rpcs3/Gui/ConLogFrame.h b/rpcs3/Gui/ConLogFrame.h index 316cd37a39..10ae45834a 100644 --- a/rpcs3/Gui/ConLogFrame.h +++ b/rpcs3/Gui/ConLogFrame.h @@ -5,7 +5,7 @@ class LogFrame : public wxPanel fs::file m_log_file; fs::file m_tty_file; - _log::level m_level{ _log::level::always }; // current log level + logs::level m_level{ logs::level::always }; // current log level wxColour m_color{ 0, 255, 255 }; // current log color wxAuiNotebook m_tabs; @@ -20,7 +20,7 @@ class LogFrame : public wxPanel YAML::Node m_cfg_level; YAML::Node m_cfg_tty; - _log::level get_cfg_level() const { return static_cast<_log::level>(m_cfg_level.as(4)); } + logs::level get_cfg_level() const { return static_cast(m_cfg_level.as(4)); } bool get_cfg_tty() const { return m_cfg_tty.as(true); } public: diff --git a/rpcs3/Gui/GameViewer.cpp b/rpcs3/Gui/GameViewer.cpp index 283725b2f7..46d2e6a2fa 100644 --- a/rpcs3/Gui/GameViewer.cpp +++ b/rpcs3/Gui/GameViewer.cpp @@ -6,6 +6,8 @@ #include "Loader/PSF.h" #include "SettingsDialog.h" +#include + static const std::string m_class_name = "GameViewer"; // Auxiliary classes diff --git a/rpcs3/Gui/InterpreterDisAsm.cpp b/rpcs3/Gui/InterpreterDisAsm.cpp index e28e1c60d9..c593d9e376 100644 --- a/rpcs3/Gui/InterpreterDisAsm.cpp +++ b/rpcs3/Gui/InterpreterDisAsm.cpp @@ -2,15 +2,17 @@ #include "stdafx_gui.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" +#include "Emu/IdManager.h" #include "rpcs3.h" #include "InterpreterDisAsm.h" #include "Emu/CPU/CPUThread.h" #include "Emu/Cell/PPUThread.h" #include "Emu/Cell/SPUThread.h" -#include "Emu/ARMv7/ARMv7Thread.h" +#include "Emu/Cell/RawSPUThread.h" +#include "Emu/PSP2/ARMv7Thread.h" #include "Emu/Cell/PPUDisAsm.h" #include "Emu/Cell/SPUDisAsm.h" -#include "Emu/ARMv7/ARMv7DisAsm.h" +#include "Emu/PSP2/ARMv7DisAsm.h" #include "InstructionEditor.h" #include "RegisterEditor.h" @@ -23,7 +25,7 @@ u32 InterpreterDisAsmFrame::GetPc() const { switch (cpu->type) { - case cpu_type::ppu: return static_cast(cpu)->PC; + case cpu_type::ppu: return static_cast(cpu)->pc; case cpu_type::spu: return static_cast(cpu)->pc; case cpu_type::arm: return static_cast(cpu)->PC; } @@ -121,10 +123,10 @@ void InterpreterDisAsmFrame::UpdateUnitList() m_choice_units->Freeze(); m_choice_units->Clear(); - for (auto& t : get_all_cpu_threads()) + idm::select([&](u32, cpu_thread& cpu) { - m_choice_units->Append(t->get_name(), t.get()); - } + m_choice_units->Append(cpu.get_name(), &cpu); + }); m_choice_units->Thaw(); } @@ -437,7 +439,7 @@ void InterpreterDisAsmFrame::DoRun(wxCommandEvent& WXUNUSED(event)) if (cpu && cpu->state.test(cpu_state_pause)) { cpu->state -= cpu_state::dbg_pause; - cpu->lock_notify(); + (*cpu)->lock_notify(); } } @@ -459,7 +461,7 @@ void InterpreterDisAsmFrame::DoStep(wxCommandEvent& WXUNUSED(event)) return state.test_and_reset(cpu_state::dbg_pause); })) { - cpu->lock_notify(); + (*cpu)->lock_notify(); } } } diff --git a/rpcs3/Gui/KernelExplorer.cpp b/rpcs3/Gui/KernelExplorer.cpp index 7e139cb9b2..df743ed1f4 100644 --- a/rpcs3/Gui/KernelExplorer.cpp +++ b/rpcs3/Gui/KernelExplorer.cpp @@ -80,221 +80,166 @@ void KernelExplorer::Update() // TODO: FileSystem // Semaphores - const auto sema_map = idm::get_map(); - - if (sema_map.size()) + if (const u32 count = idm::get_count()) { - const auto& node = m_tree->AppendItem(root, fmt::format("Semaphores (%zu)", sema_map.size())); + const auto& node = m_tree->AppendItem(root, fmt::format("Semaphores (%zu)", count)); - for (const auto& data : sema_map) + idm::select([&](u32 id, lv2_sema_t& sema) { - const auto& sema = *data.second; - - m_tree->AppendItem(node, fmt::format("Semaphore: ID = 0x%08x '%s', Count = %d, Max Count = %d, Waiters = %#zu", data.first, + m_tree->AppendItem(node, fmt::format("Semaphore: ID = 0x%08x '%s', Count = %d, Max Count = %d, Waiters = %#zu", id, &name64(sema.name), sema.value.load(), sema.max, sema.sq.size())); - } + }); } // Mutexes - const auto mutex_map = idm::get_map(); - - if (mutex_map.size()) + if (const u32 count = idm::get_count()) { - const auto& node = m_tree->AppendItem(root, fmt::format("Mutexes (%zu)", mutex_map.size())); + const auto& node = m_tree->AppendItem(root, fmt::format("Mutexes (%zu)", count)); - for (const auto& data : mutex_map) + idm::select([&](u32 id, lv2_mutex_t& mutex) { - const auto& mutex = *data.second; - - m_tree->AppendItem(node, fmt::format("Mutex: ID = 0x%08x '%s'", data.first, + m_tree->AppendItem(node, fmt::format("Mutex: ID = 0x%08x '%s'", id, &name64(mutex.name))); - } + }); } // Lightweight Mutexes - const auto lwm_map = idm::get_map(); - - if (lwm_map.size()) + if (const u32 count = idm::get_count()) { - const auto& node = m_tree->AppendItem(root, fmt::format("Lightweight Mutexes (%zu)", lwm_map.size())); + const auto& node = m_tree->AppendItem(root, fmt::format("Lightweight Mutexes (%zu)", count)); - for (const auto& data : lwm_map) + idm::select([&](u32 id, lv2_lwmutex_t& lwm) { - const auto& lwm = *data.second; - - m_tree->AppendItem(node, fmt::format("LWMutex: ID = 0x%08x '%s'", data.first, + m_tree->AppendItem(node, fmt::format("LWMutex: ID = 0x%08x '%s'", id, &name64(lwm.name))); - } + }); } // Condition Variables - const auto cond_map = idm::get_map(); - - if (cond_map.size()) + if (const u32 count = idm::get_count()) { - const auto& node = m_tree->AppendItem(root, fmt::format("Condition Variables (%zu)", cond_map.size())); + const auto& node = m_tree->AppendItem(root, fmt::format("Condition Variables (%zu)", count)); - for (const auto& data : cond_map) + idm::select([&](u32 id, lv2_cond_t& cond) { - const auto& cond = *data.second; - - m_tree->AppendItem(node, fmt::format("Cond: ID = 0x%08x '%s'", data.first, + m_tree->AppendItem(node, fmt::format("Cond: ID = 0x%08x '%s'", id, &name64(cond.name))); - } + }); } // Lightweight Condition Variables - const auto lwc_map = idm::get_map(); - - if (lwc_map.size()) + if (const u32 count = idm::get_count()) { - const auto& node = m_tree->AppendItem(root, fmt::format("Lightweight Condition Variables (%zu)", lwc_map.size())); + const auto& node = m_tree->AppendItem(root, fmt::format("Lightweight Condition Variables (%zu)", count)); - for (const auto& data : lwc_map) + idm::select([&](u32 id, lv2_lwcond_t& lwc) { - const auto& lwc = *data.second; - - m_tree->AppendItem(node, fmt::format("LWCond: ID = 0x%08x '%s'", data.first, + m_tree->AppendItem(node, fmt::format("LWCond: ID = 0x%08x '%s'", id, &name64(lwc.name))); - } + }); } // Event Queues - const auto eq_map = idm::get_map(); - - if (eq_map.size()) + if (const u32 count = idm::get_count()) { - const auto& node = m_tree->AppendItem(root, fmt::format("Event Queues (%zu)", eq_map.size())); + const auto& node = m_tree->AppendItem(root, fmt::format("Event Queues (%zu)", count)); - for (const auto& data : eq_map) + idm::select([&](u32 id, lv2_event_queue_t& eq) { - const auto& eq = *data.second; - - m_tree->AppendItem(node, fmt::format("Event Queue: ID = 0x%08x '%s', %s, Key = %#llx, Events = %zu/%d, Waiters = %zu", data.first, + m_tree->AppendItem(node, fmt::format("Event Queue: ID = 0x%08x '%s', %s, Key = %#llx, Events = %zu/%d, Waiters = %zu", id, &name64(eq.name), eq.type == SYS_SPU_QUEUE ? "SPU" : "PPU", eq.ipc_key, eq.events(), eq.size, eq.waiters())); - } + }); } // Event Ports - const auto ep_map = idm::get_map(); - - if (ep_map.size()) + if (const u32 count = idm::get_count()) { - const auto& node = m_tree->AppendItem(root, fmt::format("Event Ports (%zu)", ep_map.size())); + const auto& node = m_tree->AppendItem(root, fmt::format("Event Ports (%zu)", count)); - for (const auto& data : ep_map) + idm::select([&](u32 id, lv2_event_port_t& ep) { - const auto& ep = *data.second; - - m_tree->AppendItem(node, fmt::format("Event Port: ID = 0x%08x, Name = %#llx", data.first, + m_tree->AppendItem(node, fmt::format("Event Port: ID = 0x%08x, Name = %#llx", id, ep.name)); - } + }); } // Event Flags - const auto ef_map = idm::get_map(); - - if (ef_map.size()) + if (const u32 count = idm::get_count()) { - const auto& node = m_tree->AppendItem(root, fmt::format("Event Flags (%zu)", ef_map.size())); + const auto& node = m_tree->AppendItem(root, fmt::format("Event Flags (%zu)", count)); - for (const auto& data : ef_map) + idm::select([&](u32 id, lv2_event_flag_t& ef) { - const auto& ef = *data.second; - - m_tree->AppendItem(node, fmt::format("Event Flag: ID = 0x%08x '%s', Type = 0x%x, Pattern = 0x%llx", data.first, &name64(ef.name), ef.type, ef.pattern.load())); - } + m_tree->AppendItem(node, fmt::format("Event Flag: ID = 0x%08x '%s', Type = 0x%x, Pattern = 0x%llx", id, + &name64(ef.name), ef.type, ef.pattern.load())); + }); } // Reader/writer Locks - const auto rwlock_map = idm::get_map(); - - if (rwlock_map.size()) + if (const u32 count = idm::get_count()) { - const auto& node = m_tree->AppendItem(root, fmt::format("Reader/writer Locks (%zu)", rwlock_map.size())); + const auto& node = m_tree->AppendItem(root, fmt::format("Reader/writer Locks (%zu)", count)); - for (const auto& data : rwlock_map) + idm::select([&](u32 id, lv2_rwlock_t&) { - const auto& rwlock = *data.second; - - m_tree->AppendItem(node, fmt::format("RWLock: ID = 0x%08x", data.first)); - } + m_tree->AppendItem(node, fmt::format("RWLock: ID = 0x%08x", id)); + }); } // PRX Libraries - const auto prx_map = idm::get_map(); - - if (prx_map.size()) + if (const u32 count = idm::get_count()) { - const auto& node = m_tree->AppendItem(root, fmt::format("PRX Libraries (%zu)", prx_map.size())); + const auto& node = m_tree->AppendItem(root, fmt::format("PRX Libraries (%zu)", count)); - for (const auto& data : prx_map) + idm::select([&](u32 id, lv2_prx_t&) { - const auto& prx = *data.second; - - m_tree->AppendItem(node, fmt::format("PRX: ID = 0x%08x", data.first)); - } + m_tree->AppendItem(node, fmt::format("PRX: ID = 0x%08x", id)); + }); } // Memory Containers - const auto ct_map = idm::get_map(); - - if (ct_map.size()) + if (const u32 count = idm::get_count()) { - const auto& node = m_tree->AppendItem(root, fmt::format("Memory Containers (%zu)", ct_map.size())); + const auto& node = m_tree->AppendItem(root, fmt::format("Memory Containers (%zu)", count)); - for (const auto& data : ct_map) + idm::select([&](u32 id, lv2_memory_container_t&) { - const auto& ct = *data.second; - - m_tree->AppendItem(node, fmt::format("Memory Container: ID = 0x%08x", data.first)); - } + m_tree->AppendItem(node, fmt::format("Memory Container: ID = 0x%08x", id)); + }); } // Memory Objects - const auto mem_map = idm::get_map(); - - if (mem_map.size()) + if (const u32 count = idm::get_count()) { - const auto& node = m_tree->AppendItem(root, fmt::format("Memory Objects (%zu)", mem_map.size())); + const auto& node = m_tree->AppendItem(root, fmt::format("Memory Objects (%zu)", count)); - for (const auto& data : mem_map) + idm::select([&](u32 id, lv2_memory_t&) { - const auto& mem = *data.second; - - m_tree->AppendItem(node, fmt::format("Memory Object: ID = 0x%08x", data.first)); - } + m_tree->AppendItem(node, fmt::format("Memory Object: ID = 0x%08x", id)); + }); } // PPU Threads - const auto ppu_map = idm::get_map(); - - if (ppu_map.size()) + if (const u32 count = idm::get_count()) { - const auto& node = m_tree->AppendItem(root, fmt::format("PPU Threads (%zu)", ppu_map.size())); + const auto& node = m_tree->AppendItem(root, fmt::format("PPU Threads (%zu)", count)); - for (const auto& data : ppu_map) + idm::select([&](u32 id, PPUThread& ppu) { - const auto& ppu = *data.second; - - m_tree->AppendItem(node, fmt::format("PPU Thread: ID = 0x%08x '%s'", data.first, ppu.get_name())); - } + m_tree->AppendItem(node, fmt::format("PPU Thread: ID = 0x%08x '%s'", id, ppu.get_name())); + }); } // SPU Thread Groups - const auto spu_map = idm::get_map(); - - if (spu_map.size()) + if (const u32 count = idm::get_count()) { - const auto& node = m_tree->AppendItem(root, fmt::format("SPU Thread Groups (%d)", spu_map.size())); + const auto& node = m_tree->AppendItem(root, fmt::format("SPU Thread Groups (%d)", count)); - for (const auto& data : spu_map) + idm::select([&](u32 id, lv2_spu_group_t& tg) { - const auto& tg = *data.second; - - m_tree->AppendItem(node, fmt::format("SPU Thread Group: ID = 0x%08x '%s'", data.first, + m_tree->AppendItem(node, fmt::format("SPU Thread Group: ID = 0x%08x '%s'", id, tg.name.c_str())); - } + }); } // RawSPU Threads (TODO) diff --git a/rpcs3/Gui/MainFrame.cpp b/rpcs3/Gui/MainFrame.cpp index d9cdf5709e..8233aaf435 100644 --- a/rpcs3/Gui/MainFrame.cpp +++ b/rpcs3/Gui/MainFrame.cpp @@ -21,6 +21,8 @@ #include "Utilities/Thread.h" +#include + #ifndef _WIN32 #include "frame_icon.xpm" #endif diff --git a/rpcs3/Gui/SettingsDialog.cpp b/rpcs3/Gui/SettingsDialog.cpp index 6c3139874e..95226fcf50 100644 --- a/rpcs3/Gui/SettingsDialog.cpp +++ b/rpcs3/Gui/SettingsDialog.cpp @@ -15,6 +15,7 @@ #include "SettingsDialog.h" #include +#include // Node location using cfg_location = std::vector; diff --git a/rpcs3/Loader/ELF.h b/rpcs3/Loader/ELF.h index 71e2cfde76..f66084ad19 100644 --- a/rpcs3/Loader/ELF.h +++ b/rpcs3/Loader/ELF.h @@ -1,5 +1,6 @@ #pragma once +#include "../../Utilities/types.h" #include "../../Utilities/File.h" enum class elf_os : u8 @@ -155,26 +156,31 @@ enum class elf_error // ELF loader error information template<> -struct bijective +struct unveil { - static constexpr bijective_pair map[] + static inline const char* get(elf_error error) { - { elf_error::ok, "" }, + switch (error) + { + case elf_error::ok: return "OK"; - { elf_error::stream, "Invalid stream" }, - { elf_error::stream_header, "Failed to read ELF header" }, - { elf_error::stream_phdrs, "Failed to read ELF program headers" }, - { elf_error::stream_shdrs, "Failed to read ELF section headers" }, - { elf_error::stream_data, "Failed to read ELF program data" }, + case elf_error::stream: return "Invalid stream"; + case elf_error::stream_header: return "Failed to read ELF header"; + case elf_error::stream_phdrs: return "Failed to read ELF program headers"; + case elf_error::stream_shdrs: return "Failed to read ELF section headers"; + case elf_error::stream_data: return "Failed to read ELF program data"; - { elf_error::header_magic, "Not an ELF" }, - { elf_error::header_version, "Invalid or unsupported ELF format" }, - { elf_error::header_class, "Invalid ELF class" }, - { elf_error::header_machine, "Invalid ELF machine" }, - { elf_error::header_endianness, "Invalid ELF data (endianness)" }, - { elf_error::header_type, "Invalid ELF type" }, - { elf_error::header_os, "Invalid ELF OS ABI" }, - }; + case elf_error::header_magic: return "Not an ELF"; + case elf_error::header_version: return "Invalid or unsupported ELF format"; + case elf_error::header_class: return "Invalid ELF class"; + case elf_error::header_machine: return "Invalid ELF machine"; + case elf_error::header_endianness: return "Invalid ELF data (endianness)"; + case elf_error::header_type: return "Invalid ELF type"; + case elf_error::header_os: return "Invalid ELF OS ABI"; + + default: throw error; + } + } }; // ELF loader with specified parameters. @@ -185,7 +191,7 @@ class elf_loader { elf_error m_error{}; - elf_error error(elf_error e) + elf_error set_error(elf_error e) { return m_error = e; } @@ -213,57 +219,57 @@ public: { // Check stream if (!stream) - return error(elf_error::stream); + return set_error(elf_error::stream); // Read ELF header stream.seek(offset); if (!stream.read(header)) - return error(elf_error::stream_header); + return set_error(elf_error::stream_header); // Check magic if (header.e_magic != "\177ELF"_u32) - return error(elf_error::header_magic); + return set_error(elf_error::header_magic); // Check class if (header.e_class != (std::is_same::value ? 1 : 2)) - return error(elf_error::header_class); + return set_error(elf_error::header_class); // Check endianness if (header.e_data != (std::is_same, le_t>::value ? 1 : 2)) - return error(elf_error::header_endianness); + return set_error(elf_error::header_endianness); // Check machine if (header.e_machine != Machine) - return error(elf_error::header_machine); + return set_error(elf_error::header_machine); // Check OS only if specified (hack) if (OS != elf_os::none && header.e_os_abi != OS) - return error(elf_error::header_os); + return set_error(elf_error::header_os); // Check type only if specified (hack) if (Type != elf_type::none && header.e_type != Type) - return error(elf_error::header_type); + return set_error(elf_error::header_type); // Check version and other params if (header.e_curver != 1 || header.e_version != 1 || header.e_ehsize != sizeof(ehdr_t)) - return error(elf_error::header_version); + return set_error(elf_error::header_version); if (header.e_phnum && header.e_phentsize != sizeof(phdr_t)) - return error(elf_error::header_version); + return set_error(elf_error::header_version); if (header.e_shnum && header.e_shentsize != sizeof(shdr_t)) - return error(elf_error::header_version); + return set_error(elf_error::header_version); // Load program headers std::vector _phdrs(header.e_phnum); stream.seek(offset + header.e_phoff); if (!stream.read(_phdrs)) - return error(elf_error::stream_phdrs); + return set_error(elf_error::stream_phdrs); shdrs.resize(header.e_shnum); stream.seek(offset + header.e_shoff); if (!stream.read(shdrs)) - return error(elf_error::stream_shdrs); + return set_error(elf_error::stream_shdrs); progs.clear(); progs.reserve(_phdrs.size()); @@ -275,7 +281,7 @@ public: progs.back().bin.resize(hdr.p_filesz); stream.seek(offset + hdr.p_offset); if (!stream.read(progs.back().bin)) - return error(elf_error::stream_data); + return set_error(elf_error::stream_data); } shdrs.shrink_to_fit(); @@ -336,6 +342,11 @@ public: return m_error; } + elf_error get_error() const + { + return m_error; + } + // Format-specific loader function (must be specialized) typename elf_load_result::type load() const; }; diff --git a/rpcs3/Loader/PSF.cpp b/rpcs3/Loader/PSF.cpp index 8f23aef7f7..f5caf5182f 100644 --- a/rpcs3/Loader/PSF.cpp +++ b/rpcs3/Loader/PSF.cpp @@ -3,7 +3,7 @@ namespace psf { - _log::channel log("PSF", _log::level::notice); + logs::channel log("PSF", logs::level::notice); struct header_t { @@ -23,28 +23,49 @@ namespace psf le_t data_off; }; + + entry::entry(format type, u32 max_size, const std::string& value) + : m_type(type) + , m_max_size(max_size) + , m_value_string(value) + { + EXPECTS(type == format::string || type == format::array); + EXPECTS(max_size); + } + + entry::entry(u32 value) + : m_type(format::integer) + , m_max_size(sizeof(u32)) + , m_value_integer(value) + { + } + + entry::~entry() + { + } + const std::string& entry::as_string() const { - Expects(m_type == format::string || m_type == format::array); + EXPECTS(m_type == format::string || m_type == format::array); return m_value_string; } u32 entry::as_integer() const { - Expects(m_type == format::integer); + EXPECTS(m_type == format::integer); return m_value_integer; } entry& entry::operator =(const std::string& value) { - Expects(m_type == format::string || m_type == format::array); + EXPECTS(m_type == format::string || m_type == format::array); m_value_string = value; return *this; } entry& entry::operator =(u32 value) { - Expects(m_type == format::integer); + EXPECTS(m_type == format::integer); m_value_integer = value; return *this; } @@ -64,73 +85,75 @@ namespace psf throw fmt::exception("Invalid format (0x%x)" HERE, m_type); } - registry load_object(const std::vector& data) + registry load_object(const fs::file& stream) { registry result; // Hack for empty input (TODO) - if (data.empty()) + if (!stream) { return result; } // Check size - Expects(data.size() >= sizeof(header_t)); - Expects((std::uintptr_t)data.data() % 8 == 0); + EXPECTS(stream.size() >= sizeof(header_t)); // Get header - const header_t& header = reinterpret_cast(data[0]); + header_t header; + EXPECTS(stream.read(header)); // Check magic and version - Expects(header.magic == "\0PSF"_u32); - Expects(header.version == 0x101); - Expects(sizeof(header_t) + header.entries_num * sizeof(def_table_t) <= header.off_key_table); - Expects(header.off_key_table <= header.off_data_table); - Expects(header.off_data_table <= data.size()); + EXPECTS(header.magic == "\0PSF"_u32); + EXPECTS(header.version == 0x101); + EXPECTS(sizeof(header_t) + header.entries_num * sizeof(def_table_t) <= header.off_key_table); + EXPECTS(header.off_key_table <= header.off_data_table); + EXPECTS(header.off_data_table <= stream.size()); - // Get indices (alignment should be fine) - const def_table_t* indices = reinterpret_cast(data.data() + sizeof(header_t)); + // Get indices + std::vector indices; + EXPECTS(stream.read(indices, header.entries_num)); + + // Get keys + std::string keys; + EXPECTS(stream.seek(header.off_key_table) == header.off_key_table); + EXPECTS(stream.read(keys, header.off_data_table - header.off_key_table)); // Load entries for (u32 i = 0; i < header.entries_num; ++i) { - Expects(indices[i].key_off < header.off_data_table - header.off_key_table); + EXPECTS(indices[i].key_off < header.off_data_table - header.off_key_table); - // Get key name range - const auto name_ptr = data.begin() + header.off_key_table + indices[i].key_off; - const auto name_end = std::find(name_ptr , data.begin() + header.off_data_table, '\0'); + // Get key name (null-terminated string) + std::string key(keys.data() + indices[i].key_off); - // Get name (must be unique) - std::string key(name_ptr, name_end); + EXPECTS(result.count(key) == 0); + EXPECTS(indices[i].param_len <= indices[i].param_max); + EXPECTS(indices[i].data_off < stream.size() - header.off_data_table); + EXPECTS(indices[i].param_max < stream.size() - indices[i].data_off); - Expects(result.count(key) == 0); - Expects(indices[i].param_len <= indices[i].param_max); - Expects(indices[i].data_off < data.size() - header.off_data_table); - Expects(indices[i].param_max < data.size() - indices[i].data_off); - - // Get data pointer - const auto value_ptr = data.begin() + header.off_data_table + indices[i].data_off; + // Seek data pointer + stream.seek(header.off_data_table + indices[i].data_off); if (indices[i].param_fmt == format::integer && indices[i].param_max == sizeof(u32) && indices[i].param_len == sizeof(u32)) { // Integer data + le_t value; + EXPECTS(stream.read(value)); + result.emplace(std::piecewise_construct, std::forward_as_tuple(std::move(key)), - std::forward_as_tuple(reinterpret_cast&>(*value_ptr))); + std::forward_as_tuple(value)); } else if (indices[i].param_fmt == format::string || indices[i].param_fmt == format::array) { // String/array data std::string value; + EXPECTS(stream.read(value, indices[i].param_len)); if (indices[i].param_fmt == format::string) { // Find null terminator - value.assign(value_ptr, std::find(value_ptr, value_ptr + indices[i].param_len, '\0')); - } - else - { - value.assign(value_ptr, value_ptr + indices[i].param_len); + value.resize(std::strlen(value.c_str())); } result.emplace(std::piecewise_construct, @@ -147,7 +170,7 @@ namespace psf return result; } - std::vector save_object(const registry& psf) + void save_object(const fs::file& stream, const psf::registry& psf) { std::vector indices; indices.reserve(psf.size()); @@ -182,20 +205,18 @@ namespace psf header.entries_num = ::narrow(psf.size()); // Save header and indices - std::vector result; result.reserve(header.off_data_table + data_offset); - - result.insert(result.end(), (char*)&header, (char*)&header + sizeof(header_t)); - result.insert(result.end(), (char*)indices.data(), (char*)indices.data() + sizeof(def_table_t) * psf.size()); + stream.write(header); + stream.write(indices); // Save key table for (const auto& entry : psf) { - result.insert(result.end(), entry.first.begin(), entry.first.end()); - result.push_back('\0'); + stream.write(entry.first); + stream.write('\0'); } - // Insert zero padding - result.insert(result.end(), header.off_data_table - result.size(), '\0'); + // Skip padding + stream.seek(header.off_data_table); // Save data for (const auto& entry : psf) @@ -206,7 +227,7 @@ namespace psf if (fmt == format::integer && max == sizeof(u32)) { const le_t value = entry.second.as_integer(); - result.insert(result.end(), (char*)&value, (char*)&value + sizeof(u32)); + stream.write(value); } else if (fmt == format::string || fmt == format::array) { @@ -219,16 +240,14 @@ namespace psf log.error("Entry value shrinkage (key='%s', value='%s', size=0x%zx, max=0x%x)", entry.first, value, size, max); } - result.insert(result.end(), value.begin(), value.begin() + size); - result.insert(result.end(), max - size, '\0'); // Write zeros up to max_size + stream.write(value); + stream.seek(max - size, fs::seek_cur); // Skip up to max_size } else { throw EXCEPTION("Invalid entry format (key='%s', fmt=0x%x)", entry.first, fmt); } } - - return result; } std::string get_string(const registry& psf, const std::string& key, const std::string& def) diff --git a/rpcs3/Loader/PSF.h b/rpcs3/Loader/PSF.h index ed360ed2b8..08fa4c5ec2 100644 --- a/rpcs3/Loader/PSF.h +++ b/rpcs3/Loader/PSF.h @@ -20,22 +20,12 @@ namespace psf public: // Construct string entry, assign the value - entry(format type, u32 max_size, const std::string& value = {}) - : m_type(type) - , m_max_size(max_size) - , m_value_string(value) - { - Expects(type == format::string || type == format::array); - Expects(max_size); - } + entry(format type, u32 max_size, const std::string& value = {}); // Construct integer entry, assign the value - entry(u32 value) - : m_type(format::integer) - , m_max_size(sizeof(u32)) - , m_value_integer(value) - { - } + entry(u32 value); + + ~entry(); const std::string& as_string() const; u32 as_integer() const; @@ -51,24 +41,11 @@ namespace psf // Define PSF registry as a sorted map of entries: using registry = std::map; - // Load PSF registry from SFO binary data - registry load_object(const std::vector&); - - // Load PSF registry from SFO file, if opened - inline registry load_object(const fs::file& f) - { - if (f) - { - return load_object(f.to_vector()); - } - else - { - return registry{}; - } - } + // Load PSF registry from SFO binary format + registry load_object(const fs::file&); // Convert PSF registry to SFO binary format - std::vector save_object(const registry&); + void save_object(const fs::file&, const registry&); // Get string value or default value std::string get_string(const registry& psf, const std::string& key, const std::string& def = {}); diff --git a/rpcs3/Loader/TROPUSR.cpp b/rpcs3/Loader/TROPUSR.cpp index bd3e859a41..b58b71e122 100644 --- a/rpcs3/Loader/TROPUSR.cpp +++ b/rpcs3/Loader/TROPUSR.cpp @@ -138,7 +138,7 @@ bool TROPUSRLoader::Generate(const std::string& filepath, const std::string& con const std::string& path = vfs::get(configpath); // TODO: rXmlDocument can open only real file - ASSERT(!fs::get_virtual_device(path)); + VERIFY(!fs::get_virtual_device(path)); rXmlDocument doc; doc.Load(path); diff --git a/rpcs3/Loader/TRP.cpp b/rpcs3/Loader/TRP.cpp index 2f59b9b2b1..be78fb7c63 100644 --- a/rpcs3/Loader/TRP.cpp +++ b/rpcs3/Loader/TRP.cpp @@ -16,7 +16,7 @@ bool TRPLoader::Install(const std::string& dest, bool show) const std::string& local_path = vfs::get(dest); - if (!fs::create_dir(local_path) && fs::error != EEXIST) + if (!fs::create_dir(local_path) && fs::g_tls_error != fs::error::exist) { return false; } diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index f63cba175f..f2ee70cae5 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -85,7 +85,7 @@ - + @@ -265,70 +265,70 @@ NotUsing - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -364,6 +364,8 @@ + + @@ -372,7 +374,6 @@ - @@ -389,78 +390,79 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index d7baae4115..ca8e48a36b 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -54,12 +54,6 @@ {2a8841dc-bce0-41bb-9fcb-5bf1f8dda213} - - {93b1cff1-0158-4327-a437-e9abcac8d724} - - - {1d9e6fc4-9a79-4329-a8b5-081e24822aaa} - {13d20086-2188-425a-9856-0440fe6f79f2} @@ -69,6 +63,12 @@ {4317ac27-38e4-4f8d-9bac-496f9b00f615} + + {93b1cff1-0158-4327-a437-e9abcac8d724} + + + {1d9e6fc4-9a79-4329-a8b5-081e24822aaa} + @@ -113,9 +113,6 @@ Emu\CPU - - Emu\ARMv7 - Emu\Audio @@ -161,192 +158,9 @@ Crypto - - Emu\ARMv7 - - - Emu\ARMv7 - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - Utilities - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - Emu\GPU\RSX @@ -419,9 +233,6 @@ Emu\Cell - - Emu\ARMv7 - Emu\Cell\lv2 @@ -833,12 +644,6 @@ Emu\Cell\Modules - - Emu\ARMv7 - - - Emu\ARMv7\Modules - Utilities @@ -854,6 +659,201 @@ Emu + + Emu\PSP2 + + + Emu\PSP2 + + + Emu\PSP2 + + + Emu\PSP2 + + + Emu\PSP2 + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + @@ -937,18 +937,6 @@ Emu\CPU - - Emu\ARMv7 - - - Emu\ARMv7 - - - Emu\ARMv7 - - - Emu\ARMv7 - Emu\Audio @@ -1057,33 +1045,6 @@ Emu\Audio - - Emu\ARMv7 - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - Utilities @@ -1099,159 +1060,9 @@ Emu\GPU\RSX\Common - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - - - Emu\ARMv7\Modules - Utilities - - Utilities - Emu\Cell @@ -1306,9 +1117,6 @@ Loader - - Emu\ARMv7 - Emu\Cell\lv2 @@ -1579,15 +1387,6 @@ Emu\Cell - - Emu\ARMv7 - - - Emu\ARMv7 - - - Emu\ARMv7\Modules - Header Files @@ -1606,9 +1405,6 @@ Emu\Memory - - Emu\Cell\lv2 - Utilities @@ -1618,5 +1414,215 @@ Utilities + + Emu\PSP2 + + + Emu\PSP2 + + + Emu\PSP2 + + + Emu\PSP2 + + + Emu\PSP2 + + + Emu\PSP2 + + + Emu\PSP2 + + + Emu\PSP2 + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu\PSP2\Modules + + + Emu + + + Utilities + + + Utilities + \ No newline at end of file diff --git a/rpcs3/stdafx.h b/rpcs3/stdafx.h index 7148a0c127..d29af71143 100644 --- a/rpcs3/stdafx.h +++ b/rpcs3/stdafx.h @@ -23,20 +23,20 @@ #include #include #include +#include #include -#include -#include #include #include #include #include -#include -#include #include -#include -using namespace std::string_literals; -using namespace std::chrono_literals; +// MSVC bug workaround +#ifdef _MSC_VER +namespace std { inline namespace literals { inline namespace chrono_literals {}}} +#endif + +using namespace std::literals; // Obsolete, throw fmt::exception directly. Use 'HERE' macro, if necessary. #define EXCEPTION(format_str, ...) fmt::exception("%s(): " format_str HERE, __FUNCTION__, ##__VA_ARGS__)