Formatting system improved

`unveil<>` renamed to `fmt_unveil<>`, now packs args to u64 imitating va_args
`bijective...` removed, `cfg::enum_entry` now uses formatting system
`fmt_class_string<>` added, providing type-specific "%s" handler function
Added `fmt::append`, removed `fmt::narrow` (too obscure)
Utilities/cfmt.h: C-style format template function (WIP)
Minor formatting fixes and cleanup
This commit is contained in:
Nekotekina 2016-08-03 23:51:05 +03:00
parent 662fce38bd
commit 5a36c57c57
63 changed files with 1305 additions and 469 deletions

View file

@ -298,10 +298,6 @@ union alignas(16) v128
_u64[0] = 0;
_u64[1] = 0;
}
std::string to_hex() const;
std::string to_xyzw() const;
};
inline v128 operator |(const v128& left, const v128& right)
@ -950,11 +946,13 @@ template<typename T> using atomic_le_t = atomic_t<le_t<T>>;
// Formatting for BE/LE data
template<typename T, bool Se, std::size_t Align>
struct unveil<se_t<T, Se, Align>, void>
struct fmt_unveil<se_t<T, Se, Align>, void>
{
static inline auto get(const se_t<T, Se, Align>& arg)
using type = typename fmt_unveil<T>::type;
static inline u64 get(const se_t<T, Se, Align>& arg)
{
return unveil<T>::get(arg);
return fmt_unveil<T>::get(arg);
}
};

View file

@ -242,3 +242,36 @@ struct ff_t : bf_base<T, N>
return V;
}
};
template<typename T, uint I, uint N>
struct fmt_unveil<bf_t<T, I, N>, void>
{
using type = typename fmt_unveil<simple_t<T>>::type;
static inline u64 get(const bf_t<T, I, N>& bf)
{
return fmt_unveil<type>::get(bf);
}
};
template<typename F, typename... Fields>
struct fmt_unveil<cf_t<F, Fields...>, void>
{
using type = typename fmt_unveil<simple_t<typename F::type>>::type;
static inline u64 get(const cf_t<F, Fields...>& cf)
{
return fmt_unveil<type>::get(cf);
}
};
template<typename T, T V, uint N>
struct fmt_unveil<ff_t<T, V, N>, void>
{
using type = typename fmt_unveil<simple_t<T>>::type;
static inline u64 get(const ff_t<T, V, N>& ff)
{
return fmt_unveil<type>::get(ff);
}
};

View file

@ -256,3 +256,14 @@ struct atomic_test_and_complement<bitset_t<T>, T, std::enable_if_t<std::is_enum<
static constexpr auto atomic_op = &_op;
};
template<typename T, std::size_t BitSize>
struct fmt_unveil<bitset_t<T, BitSize>, void>
{
using type = typename bitset_t<T, BitSize>::raw_type;
static inline u64 get(const bitset_t<T, BitSize>& value)
{
return fmt_unveil<type>::get(static_cast<type>(value._value()));
}
};

View file

@ -85,6 +85,62 @@ bool cfg::try_to_int64(s64* out, const std::string& value, s64 min, s64 max)
return true;
}
bool cfg::try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) func, const std::string& value)
{
for (u64 i = 0;; i++)
{
std::string var;
func(var, i);
if (var == value)
{
if (out) *out = i;
return true;
}
std::string hex;
fmt_class_string<u64>::format(hex, i);
if (var == hex)
{
break;
}
}
try
{
const auto val = std::stoull(value, nullptr, 0);
if (out) *out = val;
return true;
}
catch (...)
{
return false;
}
}
std::vector<std::string> cfg::try_to_enum_list(decltype(&fmt_class_string<int>::format) func)
{
std::vector<std::string> result;
for (u64 i = 0;; i++)
{
std::string var;
func(var, i);
std::string hex;
fmt_class_string<u64>::format(hex, i);
if (var == hex)
{
break;
}
result.emplace_back(std::move(var));
}
return result;
}
void cfg::encode(YAML::Emitter& out, const cfg::entry_base& rhs)
{
switch (rhs.get_type())

View file

@ -2,6 +2,7 @@
#include "Utilities/types.h"
#include "Utilities/Atomic.h"
#include "Utilities/StrFmt.h"
#include <initializer_list>
#include <exception>
@ -18,6 +19,12 @@ namespace cfg
// Convert string to signed integer
bool try_to_int64(s64* out, const std::string& value, s64 min, s64 max);
// Internal hack
bool try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) func, const std::string&);
// Internal hack
std::vector<std::string> try_to_enum_list(decltype(&fmt_class_string<int>::format) func);
// Config tree entry type.
enum class type : uint
{
@ -296,26 +303,26 @@ namespace cfg
std::string to_string() const override
{
for (std::size_t i = 0; i < sizeof(bijective<T, const char*>::map) / sizeof(bijective_pair<T, const char*>); i++)
{
if (bijective<T, const char*>::map[i].v1 == m_value)
{
return bijective<T, const char*>::map[i].v2;
}
}
return{}; // TODO: ???
std::string result;
fmt_class_string<T>::format(result, fmt_unveil<T>::get(m_value));
return result; // TODO: ???
}
bool from_string(const std::string& value) override
{
for (std::size_t i = 0; i < sizeof(bijective<T, const char*>::map) / sizeof(bijective_pair<T, const char*>); i++)
u64 result;
if (try_to_enum_value(&result, &fmt_class_string<T>::format, value))
{
if (bijective<T, const char*>::map[i].v2 == value)
const auto val = static_cast<std::underlying_type_t<T>>(result);
if (static_cast<u64>(val) != result)
{
m_value = bijective<T, const char*>::map[i].v1;
return true;
return false;
}
m_value = static_cast<T>(val);
return true;
}
return false;
@ -323,14 +330,7 @@ namespace cfg
std::vector<std::string> to_list() const override
{
std::vector<std::string> result;
for (std::size_t i = 0; i < sizeof(bijective<T, const char*>::map) / sizeof(bijective_pair<T, const char*>); i++)
{
result.emplace_back(bijective<T, const char*>::map[i].v2);
}
return result;
return try_to_enum_list(&fmt_class_string<T>::format);
}
};

View file

@ -1333,3 +1333,37 @@ u64 fs::get_dir_size(const std::string& path)
return result;
}
template<>
void fmt_class_string<fs::seek_mode>::format(std::string& out, u64 arg)
{
format_enum(out, arg, [](auto arg)
{
switch (arg)
{
STR_CASE(fs::seek_mode::seek_set);
STR_CASE(fs::seek_mode::seek_cur);
STR_CASE(fs::seek_mode::seek_end);
}
return unknown;
});
}
template<>
void fmt_class_string<fs::error>::format(std::string& out, u64 arg)
{
format_enum(out, arg, [](auto arg)
{
switch (arg)
{
case fs::error::ok: return "OK";
case fs::error::inval: return "Invalid arguments";
case fs::error::noent: return "Not found";
case fs::error::exist: return "Already exists";
}
return unknown;
});
}

View file

@ -463,21 +463,3 @@ namespace fs
// Error code returned
extern thread_local error g_tls_error;
}
template<>
struct unveil<fs::error>
{
static inline const char* get(fs::error error)
{
switch (error)
{
case fs::error::ok: return "OK";
case fs::error::inval: return "Invalid arguments";
case fs::error::noent: return "Not found";
case fs::error::exist: return "Already exists";
default: throw error;
}
}
};

View file

@ -3,15 +3,31 @@
#include "StrFmt.h"
#include "rpcs3_version.h"
#include <cstdarg>
#include <string>
// Thread-specific log prefix provider
thread_local std::string(*g_tls_log_prefix)() = nullptr;
#ifndef _MSC_VER
constexpr DECLARE(bijective<logs::level, const char*>::map);
#endif
template<>
void fmt_class_string<logs::level>::format(std::string& out, u64 arg)
{
format_enum(out, arg, [](auto lev)
{
switch (lev)
{
case logs::level::always: return "Nothing";
case logs::level::fatal: return "Fatal";
case logs::level::error: return "Error";
case logs::level::todo: return "TODO";
case logs::level::success: return "Success";
case logs::level::warning: return "Warning";
case logs::level::notice: return "Notice";
case logs::level::trace: return "Trace";
}
return unknown;
});
}
namespace logs
{
@ -72,13 +88,10 @@ void logs::listener::add(logs::listener* _new)
}
}
void logs::channel::broadcast(const logs::channel& ch, logs::level sev, const char* fmt...)
void logs::channel::broadcast(const logs::channel& ch, logs::level sev, const char* fmt, const fmt::supplementary_info* sup, const u64* args)
{
va_list args;
va_start(args, fmt);
std::string&& text = fmt::unsafe_vformat(fmt, args);
std::string&& prefix = g_tls_log_prefix ? g_tls_log_prefix() : "";
va_end(args);
std::string text; fmt::raw_append(text, fmt, sup, args);
std::string prefix(g_tls_log_prefix ? g_tls_log_prefix() : "");
// Prepare message information
message msg;

View file

@ -1,7 +1,9 @@
#pragma once
#include "types.h"
#include "Platform.h"
#include "Atomic.h"
#include "StrFmt.h"
namespace logs
{
@ -67,19 +69,17 @@ namespace logs
// Formatting function
template<typename... Args>
void format(level sev, const char* fmt, const Args&... args) const
SAFE_BUFFERS void format(level sev, const char* fmt, const Args&... args) const
{
#ifdef _MSC_VER
if (sev <= enabled)
#else
if (__builtin_expect(sev <= enabled, 0))
#endif
broadcast(*this, sev, fmt, ::unveil<Args>::get(args)...);
if (UNLIKELY(sev <= enabled))
{
broadcast(*this, sev, fmt, fmt::arg_type_info::get<typename fmt_unveil<Args>::type...>(), fmt::args_t<Args...>{::fmt_unveil<Args>::get(args)...});
}
}
#define GEN_LOG_METHOD(_sev)\
template<typename... Args>\
void _sev(const char* fmt, const Args&... args) const\
SAFE_BUFFERS void _sev(const char* fmt, const Args&... args) const\
{\
return format<Args...>(level::_sev, fmt, args...);\
}
@ -95,7 +95,7 @@ namespace logs
#undef GEN_LOG_METHOD
private:
// Send log message to global logger instance
static void broadcast(const channel& ch, level sev, const char* fmt...);
static void broadcast(const channel& ch, level sev, const char*, const fmt::supplementary_info*, const u64*);
};
/* Small set of predefined channels */
@ -110,22 +110,6 @@ namespace logs
extern channel ARMv7;
}
template<>
struct bijective<logs::level, const char*>
{
static constexpr bijective_pair<logs::level, const char*> map[]
{
{ 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, ...) logs::ch.success(fmt, ##__VA_ARGS__)

View file

@ -61,7 +61,7 @@ public:
Show();
}
force_inline void Update(const u8 thread_id, const u64 value, const wxString& msg)
void Update(const u8 thread_id, const u64 value, const wxString& msg)
{
if(thread_id > m_cores) return;

View file

@ -29,15 +29,21 @@
#endif
#ifdef _MSC_VER
#define never_inline __declspec(noinline)
#define SAFE_BUFFERS __declspec(safebuffers)
#else
#define never_inline __attribute__((noinline))
#define SAFE_BUFFERS
#endif
#ifdef _MSC_VER
#define force_inline __forceinline
#define NEVER_INLINE __declspec(noinline)
#else
#define force_inline __attribute__((always_inline)) inline
#define NEVER_INLINE __attribute__((noinline))
#endif
#ifdef _MSC_VER
#define FORCE_INLINE __forceinline
#else
#define FORCE_INLINE __attribute__((always_inline)) inline
#endif
#if defined(__GNUG__)

View file

@ -1,73 +1,178 @@
#include "StrFmt.h"
#include "BEType.h"
#include "StrUtil.h"
#include "cfmt.h"
#include <cassert>
#include <array>
#include <memory>
#include <algorithm>
std::string v128::to_hex() const
void fmt_class_string<const void*>::format(std::string& out, u64 arg)
{
return fmt::format("%016llx%016llx", _u64[1], _u64[0]);
fmt::append(out, "%p", reinterpret_cast<const void*>(static_cast<std::uintptr_t>(arg)));
}
std::string v128::to_xyzw() const
void fmt_class_string<const char*>::format(std::string& out, u64 arg)
{
return fmt::format("x: %g y: %g z: %g w: %g", _f[3], _f[2], _f[1], _f[0]);
out += reinterpret_cast<const char*>(static_cast<std::uintptr_t>(arg));
}
std::string fmt::unsafe_vformat(const char* fmt, va_list _args) noexcept
template<>
void fmt_class_string<std::string>::format(std::string& out, u64 arg)
{
// Fixed stack buffer for the first attempt
std::array<char, 4096> fixed_buf;
out += get_object(arg).c_str(); // TODO?
}
// Possibly dynamically allocated buffer for the second attempt
std::unique_ptr<char[]> buf;
template<>
void fmt_class_string<std::vector<char>>::format(std::string& out, u64 arg)
{
const std::vector<char>& obj = get_object(arg);
out.append(obj.cbegin(), obj.cend());
}
// Pointer to the current buffer
char* buf_addr = fixed_buf.data();
template<>
void fmt_class_string<char>::format(std::string& out, u64 arg)
{
fmt::append(out, "0x%hhx", static_cast<char>(arg));
}
for (std::size_t buf_size = fixed_buf.size();;)
template<>
void fmt_class_string<uchar>::format(std::string& out, u64 arg)
{
fmt::append(out, "0x%hhx", static_cast<uchar>(arg));
}
template<>
void fmt_class_string<schar>::format(std::string& out, u64 arg)
{
fmt::append(out, "0x%hhx", static_cast<schar>(arg));
}
template<>
void fmt_class_string<short>::format(std::string& out, u64 arg)
{
fmt::append(out, "0x%hx", static_cast<short>(arg));
}
template<>
void fmt_class_string<ushort>::format(std::string& out, u64 arg)
{
fmt::append(out, "0x%hx", static_cast<ushort>(arg));
}
template<>
void fmt_class_string<int>::format(std::string& out, u64 arg)
{
fmt::append(out, "0x%x", static_cast<int>(arg));
}
template<>
void fmt_class_string<uint>::format(std::string& out, u64 arg)
{
fmt::append(out, "0x%x", static_cast<uint>(arg));
}
template<>
void fmt_class_string<long>::format(std::string& out, u64 arg)
{
fmt::append(out, "0x%lx", static_cast<long>(arg));
}
template<>
void fmt_class_string<ulong>::format(std::string& out, u64 arg)
{
fmt::append(out, "0x%lx", static_cast<ulong>(arg));
}
template<>
void fmt_class_string<llong>::format(std::string& out, u64 arg)
{
fmt::append(out, "0x%llx", static_cast<llong>(arg));
}
template<>
void fmt_class_string<ullong>::format(std::string& out, u64 arg)
{
fmt::append(out, "0x%llx", static_cast<ullong>(arg));
}
template<>
void fmt_class_string<float>::format(std::string& out, u64 arg)
{
fmt::append(out, "%f", static_cast<float>(reinterpret_cast<f64&>(arg)));
}
template<>
void fmt_class_string<double>::format(std::string& out, u64 arg)
{
fmt::append(out, "%f", reinterpret_cast<f64&>(arg));
}
template<>
void fmt_class_string<bool>::format(std::string& out, u64 arg)
{
out += arg ? "true" : "false"; // TODO?
}
template<>
void fmt_class_string<v128>::format(std::string& out, u64 arg)
{
const v128& vec = get_object(arg);
fmt::append(out, "0x%016llx%016llx", vec._u64[1], vec._u64[0]);
}
namespace fmt
{
struct cfmt_src;
}
// Temporary implementation
struct fmt::cfmt_src
{
const fmt::supplementary_info* sup;
const u64* args;
bool test(std::size_t index = 0)
{
va_list args;
va_copy(args, _args);
#ifndef _MSC_VER
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-security"
#endif
const std::size_t len = std::vsnprintf(buf_addr, buf_size, fmt, args);
#ifndef _MSC_VER
#pragma GCC diagnostic pop
#endif
va_end(args);
assert(len <= INT_MAX);
if (len < buf_size)
for (std::size_t i = 0; i <= index; i++)
{
return{ buf_addr, len };
if (!sup[i].fmt_string)
{
return false;
}
}
buf.reset(buf_addr = new char[buf_size = len + 1]);
return true;
}
template<typename T>
T get(std::size_t index = 0)
{
return reinterpret_cast<const T&>(args[index]);
}
void skip(std::size_t extra)
{
++sup += extra;
++args += extra;
}
std::size_t fmt_string(std::string& out)
{
const std::size_t start = out.size();
sup->fmt_string(out, args[0]);
return out.size() - start;
}
};
void fmt::raw_append(std::string& out, const char* fmt, const fmt::supplementary_info* sup, const u64* args) noexcept
{
cfmt_append(out, fmt, cfmt_src{sup, args});
}
std::string fmt::unsafe_format(const char* fmt...) noexcept
char* fmt::alloc_format(const char* fmt, const fmt::supplementary_info* sup, const u64* args) noexcept
{
va_list args;
va_start(args, fmt);
auto result = unsafe_vformat(fmt, args);
va_end(args);
return result;
}
fmt::exception_base::exception_base(const char* fmt...)
: std::runtime_error((va_start(m_args, fmt), unsafe_vformat(fmt, m_args)))
{
va_end(m_args);
std::string str;
raw_append(str, fmt, sup, args);
return static_cast<char*>(std::memcpy(std::malloc(str.size() + 1), str.data(), str.size() + 1));
}
std::string fmt::replace_first(const std::string& src, const std::string& from, const std::string& to)

View file

@ -1,6 +1,5 @@
#pragma once
#include <cstdarg>
#include <exception>
#include <string>
@ -9,44 +8,224 @@
namespace fmt
{
std::string unsafe_format(const char* fmt...) noexcept;
std::string unsafe_vformat(const char*, va_list) noexcept;
// Formatting function
template<typename... Args>
inline std::string format(const char* fmt, const Args&... args)
static std::string format(const char*, const Args&...);
}
template<typename T, typename>
struct fmt_unveil
{
static_assert(sizeof(T) > 0, "fmt_unveil<>: cannot pass forward-declared object");
using type = T;
static inline u64 get(const T& arg)
{
return unsafe_format(fmt, ::unveil<Args>::get(args)...);
return reinterpret_cast<std::uintptr_t>(&arg);
}
};
template<typename T>
struct fmt_unveil<T, std::enable_if_t<std::is_integral<T>::value && sizeof(T) <= 8 && alignof(T) <= 8>>
{
using type = T;
static inline u64 get(T arg)
{
return static_cast<T>(arg);
}
};
template<typename T>
struct fmt_unveil<T, std::enable_if_t<std::is_floating_point<T>::value && sizeof(T) <= 8 && alignof(T) <= 8>>
{
using type = T;
// Convert FP to f64 and reinterpret (TODO?)
static inline u64 get(f64 arg)
{
return reinterpret_cast<u64&>(arg);
}
};
template<typename T>
struct fmt_unveil<T, std::enable_if_t<std::is_enum<T>::value>>
{
using type = T;
static inline u64 get(T arg)
{
return static_cast<std::underlying_type_t<T>>(arg);
}
};
template<typename T>
struct fmt_unveil<T*, void>
{
using type = const T*;
static inline u64 get(const T* arg)
{
return reinterpret_cast<std::uintptr_t>(arg);
}
};
template<typename T, std::size_t N>
struct fmt_unveil<T[N], void>
{
using type = const T*;
static inline u64 get(const T* arg)
{
return reinterpret_cast<std::uintptr_t>(arg);
}
};
template<>
struct fmt_unveil<b8, void>
{
using type = bool;
static inline u64 get(const b8& value)
{
return fmt_unveil<bool>::get(value);
}
};
// String type format provider, also type classifier (format() called if an argument is formatted as "%s")
template<typename T, typename = void>
struct fmt_class_string
{
// Formatting function (must be explicitly specialized)
static void format(std::string& out, u64 arg);
// Helper typedef (visible in format())
using type = T;
// Helper function (converts arg to object reference)
static SAFE_BUFFERS FORCE_INLINE const T& get_object(u64 arg)
{
return *reinterpret_cast<const T*>(static_cast<std::uintptr_t>(arg));
}
// Helper class
class exception_base : public std::runtime_error
// Helper function (safely converts arg to enum value)
static SAFE_BUFFERS FORCE_INLINE void format_enum(std::string& out, u64 arg, const char*(*get)(T value))
{
// Helper (there is no other room)
va_list m_args;
const auto value = static_cast<std::underlying_type_t<T>>(arg);
protected:
// Internal formatting constructor
exception_base(const char* fmt...);
};
// Exception type derived from std::runtime_error with formatting constructor
class exception : public exception_base
{
public:
template<typename... Args>
exception(const char* fmt, const Args&... args)
: exception_base(fmt, ::unveil<Args>::get(args)...)
// Check narrowing
if (static_cast<u64>(value) == arg)
{
if (const char* str = get(static_cast<T>(value)))
{
out += str;
return;
}
}
// Fallback to underlying type formatting
fmt_class_string<std::underlying_type_t<T>>::format(out, static_cast<u64>(value));
}
// Helper constant (may be used in format_enum as lambda return value)
static constexpr const char* unknown = nullptr;
};
template<>
struct fmt_class_string<const void*, void>
{
static void format(std::string& out, u64 arg);
};
template<typename T>
struct fmt_class_string<T*, void> : fmt_class_string<const void*, void>
{
// Classify all pointers as const void*
};
template<>
struct fmt_class_string<const char*, void>
{
static void format(std::string& out, u64 arg);
};
template<>
struct fmt_class_string<char*, void> : fmt_class_string<const char*>
{
// Classify char* as const char*
};
namespace fmt
{
// Argument array type (each element generated via fmt_unveil<>)
template<typename... Args>
using args_t = const u64(&&)[sizeof...(Args) + 1];
using supplementary_info = const struct arg_type_info;
struct arg_type_info
{
decltype(&fmt_class_string<int>::format) fmt_string;
template<typename T>
static constexpr arg_type_info make()
{
return arg_type_info
{
&fmt_class_string<T>::format,
};
}
template<typename... Args>
static inline const supplementary_info* get()
{
// Constantly initialized null-terminated list of type-specific information
static constexpr arg_type_info result[sizeof...(Args) + 1]
{
make<Args>()...
};
return result;
}
};
// Narrow cast (similar to gsl::narrow) with exception message formatting
template<typename To, typename From, typename... Args>
inline auto narrow(const char* format_str, const From& value, const Args&... args) -> decltype(static_cast<To>(static_cast<From>(std::declval<To>())))
// Internal formatting function
void raw_append(std::string& out, const char*, const supplementary_info*, const u64*) noexcept;
// Formatting function
template<typename... Args>
static SAFE_BUFFERS void append(std::string& out, const char* fmt, const Args&... args)
{
const auto result = static_cast<To>(value);
if (static_cast<From>(result) != value) throw fmt::exception(format_str, value, args...);
raw_append(out, fmt, arg_type_info::get<typename fmt_unveil<Args>::type...>(), args_t<Args...>{::fmt_unveil<Args>::get(args)...});
}
// Formatting function
template<typename... Args>
static SAFE_BUFFERS std::string format(const char* fmt, const Args&... args)
{
std::string result;
append<Args...>(result, fmt, args...);
return result;
}
// Internal helper function
char* alloc_format(const char*, const supplementary_info*, const u64*) noexcept;
// Exception type with formatting constructor
template<typename Base>
class exception_t : public Base
{
using base = Base;
public:
template<typename... Args>
SAFE_BUFFERS exception_t(const char* fmt, const Args&... args)
: base((fmt = alloc_format(fmt, arg_type_info::get<typename fmt_unveil<Args>::type...>(), args_t<Args...>{::fmt_unveil<Args>::get(args)...})))
{
std::free(const_cast<char*>(fmt));
}
};
// Exception type derived from std::runtime_error with formatting constructor
using exception = exception_t<std::runtime_error>;
}

View file

@ -863,7 +863,7 @@ bool get_x64_reg_value(x64_context* context, x64_reg_t reg, size_t d_size, size_
return true;
}
LOG_ERROR(MEMORY, "get_x64_reg_value(): invalid arguments (reg=%d, d_size=%lld, i_size=%lld)", reg, d_size, i_size);
LOG_ERROR(MEMORY, "get_x64_reg_value(): invalid arguments (reg=%d, d_size=%lld, i_size=%lld)", (u32)reg, d_size, i_size);
return false;
}
@ -882,7 +882,7 @@ bool put_x64_reg_value(x64_context* context, x64_reg_t reg, size_t d_size, u64 v
}
}
LOG_ERROR(MEMORY, "put_x64_reg_value(): invalid destination (reg=%d, d_size=%lld, value=0x%llx)", reg, d_size, value);
LOG_ERROR(MEMORY, "put_x64_reg_value(): invalid destination (reg=%d, d_size=%lld, value=0x%llx)", (u32)reg, d_size, value);
return false;
}
@ -1062,7 +1062,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
if (a_size != 4 || !d_size || !i_size)
{
LOG_ERROR(MEMORY, "Invalid or unsupported instruction (op=%d, reg=%d, d_size=%lld, a_size=0x%llx, i_size=%lld)", op, reg, d_size, a_size, i_size);
LOG_ERROR(MEMORY, "Invalid or unsupported instruction (op=%d, reg=%d, d_size=%lld, a_size=0x%llx, i_size=%lld)", (u32)op, (u32)reg, d_size, a_size, i_size);
report_opcode();
return false;
}
@ -1134,7 +1134,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
case X64OP_STOS:
default:
{
LOG_ERROR(MEMORY, "Invalid or unsupported operation (op=%d, reg=%d, d_size=%lld, i_size=%lld)", op, reg, d_size, i_size);
LOG_ERROR(MEMORY, "Invalid or unsupported operation (op=%d, reg=%d, d_size=%lld, i_size=%lld)", (u32)op, (u32)reg, d_size, i_size);
report_opcode();
return false;
}
@ -1151,7 +1151,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
// write memory using "privileged" access to avoid breaking reservation
if (!d_size || !i_size)
{
LOG_ERROR(MEMORY, "Invalid or unsupported instruction (op=%d, reg=%d, d_size=%lld, a_size=0x%llx, i_size=%lld)", op, reg, d_size, a_size, i_size);
LOG_ERROR(MEMORY, "Invalid or unsupported instruction (op=%d, reg=%d, d_size=%lld, a_size=0x%llx, i_size=%lld)", (u32)op, (u32)reg, d_size, a_size, i_size);
report_opcode();
return false;
}
@ -1165,7 +1165,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
{
if (reg - X64R_XMM0 >= 16)
{
LOG_ERROR(MEMORY, "X64OP_STORE: d_size=16, reg=%d", reg);
LOG_ERROR(MEMORY, "X64OP_STORE: d_size=16, reg=%d", (u32)reg);
return false;
}
@ -1577,7 +1577,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
}
default:
{
LOG_ERROR(MEMORY, "Invalid or unsupported operation (op=%d, reg=%d, d_size=%lld, a_size=0x%llx, i_size=%lld)", op, reg, d_size, a_size, i_size);
LOG_ERROR(MEMORY, "Invalid or unsupported operation (op=%d, reg=%d, d_size=%lld, a_size=0x%llx, i_size=%lld)", (u32)op, (u32)reg, d_size, a_size, i_size);
report_opcode();
return false;
}

431
Utilities/cfmt.h Normal file
View file

@ -0,0 +1,431 @@
#pragma once
#include "types.h"
#include <string>
#include <vector>
/*
C-style format parser. Appends formatted string to `out`, returns number of characters written.
Arguments are provided via `src`. TODO
*/
template<typename Src, typename Size = std::size_t>
Size cfmt_append(std::string& out, const char* fmt, Src&& src)
{
const std::size_t old_size = out.size();
out.reserve(old_size + 992);
struct cfmt_context
{
std::size_t size; // Size of current format sequence
u8 args; // Number of extra args used
u8 type; // Integral type bytesize
bool dot; // Precision enabled
bool left;
bool sign;
bool space;
bool alter;
bool zeros;
uint width;
uint prec;
};
cfmt_context ctx{0};
// Error handling: print untouched sequence, stop further formatting
const auto drop_sequence = [&]
{
out.append(fmt - ctx.size, ctx.size);
ctx.size = -1;
};
// TODO: check overflow
const auto read_decimal = [&](uint result) -> uint
{
while (fmt[0] >= '0' && fmt[0] <= '9')
{
result = result * 10 + (fmt[0] - '0');
fmt++, ctx.size++;
}
return result;
};
// TODO: remove this
const auto fallback = [&]()
{
const std::string _fmt(fmt - ctx.size, fmt);
const u64 arg0 = src.template get<u64>();
const int arg1 = ctx.args >= 1 ? src.template get<int>(1) : 0;
const int arg2 = ctx.args >= 2 ? src.template get<int>(2) : 0;
if (const std::size_t _size = std::snprintf(0, 0, _fmt.c_str(), arg0, arg1, arg2))
{
out.resize(out.size() + _size);
std::snprintf(&out.front() + out.size() - _size, _size + 1, _fmt.c_str(), arg0, arg1, arg2);
}
};
// Single pass over fmt string (null-terminated), TODO: check correct order
while (const char ch = *fmt++) if (ctx.size == 0)
{
if (ch == '%')
{
ctx.size = 1;
}
else
{
out += ch;
}
}
else if (ctx.size == 1 && ch == '%')
{
ctx = {0};
out += ch;
}
else if (ctx.size == -1)
{
out += ch;
}
else switch (ctx.size++, ch)
{
case '-': ctx.left = true; break;
case '+': ctx.sign = true; break;
case ' ': ctx.space = true; break;
case '#': ctx.alter = true; break;
case '0': ctx.zeros = true; break;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
{
ctx.width = read_decimal(ch - '0');
break;
}
case '*':
{
if (!src.test(++ctx.args))
{
drop_sequence();
break;
}
const int warg = src.template get<int>(ctx.args);
ctx.width = std::abs(warg);
ctx.left |= warg < 0;
break;
}
case '.':
{
if (*fmt >= '0' && *fmt <= '9') // TODO: does it allow '0'?
{
ctx.prec = read_decimal(0);
ctx.dot = true;
}
else if (*fmt == '*')
{
if (!src.test(++ctx.args))
{
drop_sequence();
break;
}
fmt++, ctx.size++;
const int parg = src.template get<int>(ctx.args);
ctx.prec = parg;
ctx.dot = parg >= 0;
}
else
{
ctx.prec = 0;
ctx.dot = true;
}
break;
}
case 'h':
{
if (ctx.type)
{
drop_sequence();
}
else if (fmt[0] == 'h')
{
fmt++, ctx.size++;
ctx.type = sizeof(char);
}
else
{
ctx.type = sizeof(short);
}
break;
}
case 'l':
{
if (ctx.type)
{
drop_sequence();
}
else if (fmt[0] == 'l')
{
fmt++, ctx.size++;
ctx.type = sizeof(llong);
}
else
{
ctx.type = sizeof(long);
}
break;
}
case 'z':
{
if (ctx.type)
{
drop_sequence();
}
else
{
ctx.type = sizeof(std::size_t);
}
break;
}
case 'j':
{
if (ctx.type)
{
drop_sequence();
}
else
{
ctx.type = sizeof(std::intmax_t);
}
break;
}
case 't':
{
if (ctx.type)
{
drop_sequence();
}
else
{
ctx.type = sizeof(std::ptrdiff_t);
}
break;
}
case 'c':
{
if (ctx.type || !src.test())
{
drop_sequence();
break;
}
const std::size_t start = out.size();
out += src.template get<char>(0);
if (1 < ctx.width)
{
// Add spaces if necessary
out.insert(start + ctx.left, ctx.width - 1, ' ');
}
src.skip(ctx.args);
ctx = {0};
break;
}
case 's':
{
if (ctx.type || !src.test())
{
drop_sequence();
break;
}
const std::size_t start = out.size();
const std::size_t size1 = src.fmt_string(out);
if (ctx.dot && size1 > ctx.prec)
{
// Shrink if necessary
out.resize(start + ctx.prec);
}
// TODO: how it works if precision and width specified simultaneously?
const std::size_t size2 = out.size() - start;
if (size2 < ctx.width)
{
// Add spaces if necessary
out.insert(ctx.left ? out.size() : start, ctx.width - size2, ' ');
}
src.skip(ctx.args);
ctx = {0};
break;
}
case 'd':
case 'i':
{
if (!src.test())
{
drop_sequence();
break;
}
if (!ctx.type)
{
ctx.type = sizeof(int);
}
fallback(); // TODO
src.skip(ctx.args);
ctx = {0};
break;
}
case 'o':
{
if (!src.test())
{
drop_sequence();
break;
}
if (!ctx.type)
{
ctx.type = sizeof(int);
}
fallback(); // TODO
src.skip(ctx.args);
ctx = {0};
break;
}
case 'x':
case 'X':
{
if (!src.test())
{
drop_sequence();
break;
}
if (!ctx.type)
{
ctx.type = sizeof(int);
}
fallback(); // TODO
src.skip(ctx.args);
ctx = {0};
break;
}
case 'u':
{
if (!src.test())
{
drop_sequence();
break;
}
if (!ctx.type)
{
ctx.type = sizeof(int);
}
fallback(); // TODO
src.skip(ctx.args);
ctx = {0};
break;
}
case 'p':
{
if (!src.test())
{
drop_sequence();
break;
}
if (ctx.type)
{
drop_sequence();
break;
}
fallback(); // TODO
src.skip(ctx.args);
ctx = {0};
break;
}
case 'f':
case 'F':
case 'e':
case 'E':
case 'a':
case 'A':
case 'g':
case 'G':
{
if (!src.test())
{
drop_sequence();
break;
}
if (ctx.type)
{
drop_sequence();
break;
}
fallback(); // TODO
src.skip(ctx.args);
ctx = {0};
break;
}
case 'L': // long double, not supported
case 'n': // writeback, not supported
default:
{
drop_sequence();
}
}
// Handle unfinished sequence
if (ctx.size && ctx.size != -1)
{
fmt--, drop_sequence();
}
return static_cast<Size>(out.size() - old_size);
}

View file

@ -27,12 +27,13 @@ namespace gsl
enum class byte : u8;
}
template<typename T1, typename T2>
struct bijective_pair
namespace fmt
{
T1 v1;
T2 v2;
};
}
// Formatting helper, type-specific preprocessing for improving safety and functionality
template<typename T, typename = void>
struct fmt_unveil;
template<typename T, std::size_t Align = alignof(T), std::size_t Size = sizeof(T)>
struct se_storage;
@ -40,10 +41,6 @@ struct se_storage;
template<typename T, bool Se = true, std::size_t Align = alignof(T)>
class se_t;
// Specialization with static constexpr bijective_pair<T1, T2> map[] member expected
template<typename T1, typename T2>
struct bijective;
template<typename T, std::size_t Size = sizeof(T)>
struct atomic_storage;
@ -501,40 +498,6 @@ struct multicast<void>
}
};
template<typename T1, typename T2 = const char*, typename T = T1, typename DT = T2>
T2 bijective_find(const T& left, const DT& def = {})
{
for (std::size_t i = 0; i < sizeof(bijective<T1, T2>::map) / sizeof(bijective_pair<T1, T2>); i++)
{
if (bijective<T1, T2>::map[i].v1 == left)
{
return bijective<T1, T2>::map[i].v2;
}
}
return def;
}
// Formatting helper, type-specific preprocessing for improving safety and functionality
template<typename T, typename = void>
struct unveil
{
// TODO
static inline const T& get(const T& arg)
{
return arg;
}
};
template<typename T>
struct unveil<T, void_t<decltype(std::declval<T>().c_str())>>
{
static inline const char* get(const T& arg)
{
return arg.c_str();
}
};
// Tagged ID type
template<typename T = void, typename ID = u32>
class id_value
@ -560,3 +523,14 @@ public:
return m_value;
}
};
template<typename T, typename ID>
struct fmt_unveil<id_value<T, ID>>
{
using type = typename fmt_unveil<ID>::type;
static inline u64 get(const id_value<T, ID>& value)
{
return fmt_unveil<ID>::get(value);
}
};

View file

@ -7,86 +7,86 @@
// TODO: Still reliant on wxWidgets for zlib functions. Alternative solutions?
#include <zlib.h>
force_inline u8 Read8(const fs::file& f)
inline u8 Read8(const fs::file& f)
{
u8 ret;
f.read(&ret, sizeof(ret));
return ret;
}
force_inline u16 Read16(const fs::file& f)
inline u16 Read16(const fs::file& f)
{
be_t<u16> ret;
f.read(&ret, sizeof(ret));
return ret;
}
force_inline u32 Read32(const fs::file& f)
inline u32 Read32(const fs::file& f)
{
be_t<u32> ret;
f.read(&ret, sizeof(ret));
return ret;
}
force_inline u64 Read64(const fs::file& f)
inline u64 Read64(const fs::file& f)
{
be_t<u64> ret;
f.read(&ret, sizeof(ret));
return ret;
}
force_inline u16 Read16LE(const fs::file& f)
inline u16 Read16LE(const fs::file& f)
{
u16 ret;
f.read(&ret, sizeof(ret));
return ret;
}
force_inline u32 Read32LE(const fs::file& f)
inline u32 Read32LE(const fs::file& f)
{
u32 ret;
f.read(&ret, sizeof(ret));
return ret;
}
force_inline u64 Read64LE(const fs::file& f)
inline u64 Read64LE(const fs::file& f)
{
u64 ret;
f.read(&ret, sizeof(ret));
return ret;
}
force_inline void Write8(const fs::file& f, const u8 data)
inline void Write8(const fs::file& f, const u8 data)
{
f.write(&data, sizeof(data));
}
force_inline void Write16LE(const fs::file& f, const u16 data)
inline void Write16LE(const fs::file& f, const u16 data)
{
f.write(&data, sizeof(data));
}
force_inline void Write32LE(const fs::file& f, const u32 data)
inline void Write32LE(const fs::file& f, const u32 data)
{
f.write(&data, sizeof(data));
}
force_inline void Write64LE(const fs::file& f, const u64 data)
inline void Write64LE(const fs::file& f, const u64 data)
{
f.write(&data, sizeof(data));
}
force_inline void Write16(const fs::file& f, const be_t<u16> data)
inline void Write16(const fs::file& f, const be_t<u16> data)
{
f.write(&data, sizeof(data));
}
force_inline void Write32(const fs::file& f, const be_t<u32> data)
inline void Write32(const fs::file& f, const be_t<u32> data)
{
f.write(&data, sizeof(data));
}
force_inline void Write64(const fs::file& f, const be_t<u64> data)
inline void Write64(const fs::file& f, const be_t<u64> data)
{
f.write(&data, sizeof(data));
}

View file

@ -4,6 +4,28 @@
#include <mutex>
template<>
void fmt_class_string<cpu_type>::format(std::string& out, u64 arg)
{
format_enum(out, arg, [](auto arg)
{
switch (arg)
{
STR_CASE(cpu_type::ppu);
STR_CASE(cpu_type::spu);
STR_CASE(cpu_type::arm);
}
return unknown;
});
}
template<>
void fmt_class_string<bitset_t<cpu_state>::raw_type>::format(std::string& out, u64 arg)
{
out += "[UNIMPLEMENTED]";
}
thread_local cpu_thread* g_tls_current_cpu_thread = nullptr;
void cpu_thread::on_task()

View file

@ -390,7 +390,7 @@ public:
default:
{
throw EXCEPTION("Unknown task(%d)", task.type);
throw EXCEPTION("Unknown task(%d)", (u32)task.type);
}
}
}
@ -476,7 +476,7 @@ next:
default:
{
cellAdec.error("adecRawRead(): unknown task (%d)", task.type);
cellAdec.error("adecRawRead(): unknown task (%d)", (u32)task.type);
Emu.Pause();
return -1;
}

View file

@ -461,7 +461,7 @@ s32 cellAudioGetPortConfig(u32 portNum, vm::ptr<CellAudioPortConfig> portConfig)
case audio_port_state::closed: portConfig->status = CELL_AUDIO_STATUS_CLOSE; break;
case audio_port_state::opened: portConfig->status = CELL_AUDIO_STATUS_READY; break;
case audio_port_state::started: portConfig->status = CELL_AUDIO_STATUS_RUN; break;
default: throw fmt::exception("Invalid port state (%d: %d)", portNum, state);
default: throw fmt::exception("Invalid port state (%d: %d)", portNum, (u32)state);
}
portConfig->nChannel = port.channel;
@ -492,7 +492,7 @@ s32 cellAudioPortStart(u32 portNum)
case audio_port_state::closed: return CELL_AUDIO_ERROR_PORT_NOT_OPEN;
case audio_port_state::started: return CELL_AUDIO_ERROR_PORT_ALREADY_RUN;
case audio_port_state::opened: return CELL_OK;
default: throw fmt::exception("Invalid port state (%d: %d)", portNum, state);
default: throw fmt::exception("Invalid port state (%d: %d)", portNum, (u32)state);
}
}
@ -517,7 +517,7 @@ s32 cellAudioPortClose(u32 portNum)
case audio_port_state::closed: return CELL_AUDIO_ERROR_PORT_NOT_OPEN;
case audio_port_state::started: return CELL_OK;
case audio_port_state::opened: return CELL_OK;
default: throw fmt::exception("Invalid port state (%d: %d)", portNum, state);
default: throw fmt::exception("Invalid port state (%d: %d)", portNum, (u32)state);
}
}
@ -542,7 +542,7 @@ s32 cellAudioPortStop(u32 portNum)
case audio_port_state::closed: return CELL_AUDIO_ERROR_PORT_NOT_RUN;
case audio_port_state::started: return CELL_OK;
case audio_port_state::opened: return CELL_AUDIO_ERROR_PORT_NOT_RUN;
default: throw fmt::exception("Invalid port state (%d: %d)", portNum, state);
default: throw fmt::exception("Invalid port state (%d: %d)", portNum, (u32)state);
}
}

View file

@ -648,7 +648,7 @@ public:
default:
{
throw EXCEPTION("Demuxer thread error: unknown task (0x%x)", task.type);
throw EXCEPTION("Demuxer thread error: unknown task (0x%x)", (u32)task.type);
}
}
}

View file

@ -509,12 +509,12 @@ public:
return push(data, [do_exit]() { return do_exit && *do_exit; });
}
force_inline bool push(const T& data)
bool push(const T& data)
{
return push(data, SQUEUE_NEVER_EXIT);
}
force_inline bool try_push(const T& data)
bool try_push(const T& data)
{
return push(data, SQUEUE_ALWAYS_EXIT);
}
@ -577,12 +577,12 @@ public:
return pop(data, [do_exit]() { return do_exit && *do_exit; });
}
force_inline bool pop(T& data)
bool pop(T& data)
{
return pop(data, SQUEUE_NEVER_EXIT);
}
force_inline bool try_pop(T& data)
bool try_pop(T& data)
{
return pop(data, SQUEUE_ALWAYS_EXIT);
}
@ -639,12 +639,12 @@ public:
return peek(data, start_pos, [do_exit]() { return do_exit && *do_exit; });
}
force_inline bool peek(T& data, u32 start_pos = 0)
bool peek(T& data, u32 start_pos = 0)
{
return peek(data, start_pos, SQUEUE_NEVER_EXIT);
}
force_inline bool try_peek(T& data, u32 start_pos = 0)
bool try_peek(T& data, u32 start_pos = 0)
{
return peek(data, start_pos, SQUEUE_ALWAYS_EXIT);
}

View file

@ -147,7 +147,7 @@ void cellRescSetVBlankHandler(vm::ptr<void(u32)> handler)
s32 cellRescCreateInterlaceTable(u32 ea_addr, f32 srcH, CellRescTableElement depth, s32 length)
{
cellResc.todo("cellRescCreateInterlaceTable(ea_addr=0x%x, srcH=%f, depth=%d, length=%d)", ea_addr, srcH, depth, length);
cellResc.todo("cellRescCreateInterlaceTable(ea_addr=0x%x, srcH=%f, depth=%d, length=%d)", ea_addr, srcH, (s32)depth, length);
return CELL_OK;
}

View file

@ -37,7 +37,7 @@ enum : u32
std::mutex g_savedata_mutex;
static never_inline s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version, vm::cptr<char> dirName,
static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version, vm::cptr<char> dirName,
u32 errDialog, PSetList setList, PSetBuf setBuf, PFuncList funcList, PFuncFixed funcFixed, PFuncStat funcStat,
PFuncFile funcFile, u32 container, u32 unknown, vm::ptr<void> userdata, u32 userId, PFuncDone funcDone)
{

View file

@ -562,7 +562,7 @@ struct alignas(128) CellSpurs
_sub_str4 wklH2[0x10]; // 0x1A00
u8 unknown_[0x2000 - 0x1B00];
force_inline atomic_t<u8>& wklState(const u32 wid)
atomic_t<u8>& wklState(const u32 wid)
{
if (wid & 0x10)
{

View file

@ -74,25 +74,15 @@ cfg::map_entry<s32> g_cfg_sys_language(cfg::root.sys, "Language",
{ "English (UK)", CELL_SYSUTIL_LANG_ENGLISH_GB },
});
enum class systemparam_id_name : s32 {};
// For test
enum systemparam_id_name : s32 {};
template<>
struct unveil<systemparam_id_name, void>
void fmt_class_string<systemparam_id_name>::format(std::string& out, u64 arg)
{
struct temp
format_enum(out, arg, [](auto value)
{
s32 value;
char buf[12];
temp(systemparam_id_name value)
: value(s32(value))
{
}
};
static inline const char* get(temp&& in)
{
switch (in.value)
switch (value)
{
case CELL_SYSUTIL_SYSTEMPARAM_ID_LANG: return "ID_LANG";
case CELL_SYSUTIL_SYSTEMPARAM_ID_ENTER_BUTTON_ASSIGN: return "ID_ENTER_BUTTON_ASSIGN";
@ -113,14 +103,13 @@ struct unveil<systemparam_id_name, void>
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;
}
};
return unknown;
});
}
s32 cellSysutilGetSystemParamInt(s32 id, vm::ptr<s32> value)
s32 cellSysutilGetSystemParamInt(systemparam_id_name id, vm::ptr<s32> value)
{
cellSysutil.warning("cellSysutilGetSystemParamInt(id=%s, value=*0x%x)", systemparam_id_name(id), value);
cellSysutil.warning("cellSysutilGetSystemParamInt(id=0x%x(%s), value=*0x%x)", id, id, value);
// TODO: load this information from config (preferably "sys/" group)
@ -193,9 +182,9 @@ s32 cellSysutilGetSystemParamInt(s32 id, vm::ptr<s32> value)
return CELL_OK;
}
s32 cellSysutilGetSystemParamString(s32 id, vm::ptr<char> buf, u32 bufsize)
s32 cellSysutilGetSystemParamString(systemparam_id_name id, vm::ptr<char> buf, u32 bufsize)
{
cellSysutil.trace("cellSysutilGetSystemParamString(id=0x%x(%s), buf=*0x%x, bufsize=%d)", id, systemparam_id_name(id), buf, bufsize);
cellSysutil.trace("cellSysutilGetSystemParamString(id=0x%x(%s), buf=*0x%x, bufsize=%d)", id, id, buf, bufsize);
memset(buf.get_ptr(), 0, bufsize);

View file

@ -223,7 +223,7 @@ struct vdec_thread : ppu_thread
if (decode < 0)
{
throw fmt::exception("vdecDecodeAu: AU decoding error(0x%x)" HERE, decode);
throw fmt::exception("AU decoding error(0x%x)" HERE, decode);
}
if (got_picture == 0)
@ -233,7 +233,7 @@ struct vdec_thread : ppu_thread
if (decode != packet.size)
{
cellVdec.error("vdecDecodeAu: incorrect AU size (0x%x, decoded 0x%x)", packet.size, decode);
cellVdec.error("Incorrect AU size (0x%x, decoded 0x%x)", packet.size, decode);
}
if (got_picture)
@ -322,7 +322,7 @@ struct vdec_thread : ppu_thread
frame.dts = last_dts = frame->pkt_dts != AV_NOPTS_VALUE ? frame->pkt_dts : last_dts;
frame.userdata = au_usrd;
cellVdec.trace("got picture (pts=0x%llx, dts=0x%llx)", frame.pts, frame.dts);
cellVdec.trace("Got picture (pts=0x%llx, dts=0x%llx)", frame.pts, frame.dts);
thread_lock{*this}, out.push(std::move(frame));
@ -355,7 +355,7 @@ struct vdec_thread : ppu_thread
default:
{
throw fmt::exception("Unknown command (0x%x)" HERE, vcmd);
throw fmt::exception("Unknown command (0x%x)" HERE, (u32)vcmd);
}
}
}
@ -476,7 +476,7 @@ s32 cellVdecEndSeq(u32 handle)
s32 cellVdecDecodeAu(u32 handle, CellVdecDecodeMode mode, vm::cptr<CellVdecAuInfo> auInfo)
{
cellVdec.trace("cellVdecDecodeAu(handle=0x%x, mode=%d, auInfo=*0x%x)", handle, mode, auInfo);
cellVdec.trace("cellVdecDecodeAu(handle=0x%x, mode=%d, auInfo=*0x%x)", handle, (s32)mode, auInfo);
const auto vdec = idm::get<ppu_thread, vdec_thread>(handle);
@ -487,7 +487,7 @@ s32 cellVdecDecodeAu(u32 handle, CellVdecDecodeMode mode, vm::cptr<CellVdecAuInf
if (mode != CELL_VDEC_DEC_MODE_NORMAL)
{
throw EXCEPTION("Unsupported decoding mode (%d)", mode);
throw EXCEPTION("Unsupported decoding mode (%d)", (s32)mode);
}
// TODO: check info
@ -689,12 +689,12 @@ s32 cellVdecGetPicItem(u32 handle, vm::pptr<CellVdecPicItem> picItem)
avc->horizontalSize = frame->width;
avc->verticalSize = frame->height;
switch (frame->pict_type)
switch (s32 pct = frame->pict_type)
{
case AV_PICTURE_TYPE_I: avc->pictureType[0] = CELL_VDEC_AVC_PCT_I; break;
case AV_PICTURE_TYPE_P: avc->pictureType[0] = CELL_VDEC_AVC_PCT_P; break;
case AV_PICTURE_TYPE_B: avc->pictureType[0] = CELL_VDEC_AVC_PCT_B; break;
default: cellVdec.error("cellVdecGetPicItem(AVC): unknown pict_type value (0x%x)", frame->pict_type);
default: cellVdec.error("cellVdecGetPicItem(AVC): unknown pict_type value (0x%x)", pct);
}
avc->pictureType[1] = CELL_VDEC_AVC_PCT_UNKNOWN; // ???
@ -742,12 +742,12 @@ s32 cellVdecGetPicItem(u32 handle, vm::pptr<CellVdecPicItem> picItem)
{
const vm::ptr<CellVdecDivxInfo> dvx = vm::cast(info.addr() + SIZE_32(CellVdecPicItem));
switch (frame->pict_type)
switch (s32 pct = frame->pict_type)
{
case AV_PICTURE_TYPE_I: dvx->pictureType = CELL_VDEC_DIVX_VCT_I; break;
case AV_PICTURE_TYPE_P: dvx->pictureType = CELL_VDEC_DIVX_VCT_P; break;
case AV_PICTURE_TYPE_B: dvx->pictureType = CELL_VDEC_DIVX_VCT_B; break;
default: cellVdec.error("cellVdecGetPicItem(DivX): unknown pict_type value (0x%x)", frame->pict_type);
default: cellVdec.error("cellVdecGetPicItem(DivX): unknown pict_type value (0x%x)", pct);
}
dvx->horizontalSize = frame->width;
@ -801,12 +801,12 @@ s32 cellVdecGetPicItem(u32 handle, vm::pptr<CellVdecPicItem> picItem)
mp2->video_format = CELL_VDEC_MPEG2_VF_UNSPECIFIED; // ???
mp2->colour_description = false; // ???
switch (frame->pict_type)
switch (s32 pct = frame->pict_type)
{
case AV_PICTURE_TYPE_I: mp2->picture_coding_type[0] = CELL_VDEC_MPEG2_PCT_I; break;
case AV_PICTURE_TYPE_P: mp2->picture_coding_type[0] = CELL_VDEC_MPEG2_PCT_P; break;
case AV_PICTURE_TYPE_B: mp2->picture_coding_type[0] = CELL_VDEC_MPEG2_PCT_B; break;
default: cellVdec.error("cellVdecGetPicItem(MPEG2): unknown pict_type value (0x%x)", frame->pict_type);
default: cellVdec.error("cellVdecGetPicItem(MPEG2): unknown pict_type value (0x%x)", pct);
}
mp2->picture_coding_type[1] = CELL_VDEC_MPEG2_PCT_FORBIDDEN; // ???
@ -822,7 +822,7 @@ s32 cellVdecGetPicItem(u32 handle, vm::pptr<CellVdecPicItem> picItem)
s32 cellVdecSetFrameRate(u32 handle, CellVdecFrameRate frc)
{
cellVdec.trace("cellVdecSetFrameRate(handle=0x%x, frc=0x%x)", handle, frc);
cellVdec.trace("cellVdecSetFrameRate(handle=0x%x, frc=0x%x)", handle, (s32)frc);
const auto vdec = idm::get<ppu_thread, vdec_thread>(handle);

View file

@ -147,7 +147,7 @@ namespace sys_net
// TODO
thread_local vm::ptr<_tls_data_t> g_tls_net_data{};
static never_inline void initialize_tls()
static NEVER_INLINE void initialize_tls()
{
// allocate if not initialized
if (!g_tls_net_data)

View file

@ -10,6 +10,12 @@
const ppu_decoder<ppu_itype> s_ppu_itype;
const ppu_decoder<ppu_iname> s_ppu_iname;
template<>
void fmt_class_string<bitset_t<ppu_attr>::raw_type>::format(std::string& out, u64 arg)
{
out += "[UNIMPLEMENTED]";
}
void ppu_validate(const std::string& fname, const std::vector<ppu_function>& funcs, u32 reloc)
{
// Load custom PRX configuration if available

View file

@ -73,20 +73,20 @@ namespace ppu_cb_detail
{
static_assert(std::is_same<T, ppu_thread&>::value, "Invalid callback argument type for ARG_CONTEXT");
force_inline static void set_value(ppu_thread& CPU, const T& arg)
FORCE_INLINE static void set_value(ppu_thread& CPU, const T& arg)
{
}
};
template<u32 g_count, u32 f_count, u32 v_count>
force_inline static bool _bind_func_args(ppu_thread& CPU)
FORCE_INLINE static bool _bind_func_args(ppu_thread& CPU)
{
// terminator
return false;
}
template<u32 g_count, u32 f_count, u32 v_count, typename T1, typename... T>
force_inline static bool _bind_func_args(ppu_thread& CPU, T1 arg1, T... args)
FORCE_INLINE static bool _bind_func_args(ppu_thread& CPU, T1 arg1, T... args)
{
const bool is_float = std::is_floating_point<T1>::value;
const bool is_vector = std::is_same<CV T1, CV v128>::value;
@ -116,7 +116,7 @@ namespace ppu_cb_detail
static_assert(type == ARG_GENERAL, "Unknown callback result type");
static_assert(sizeof(T) <= 8, "Invalid callback result type for ARG_GENERAL");
force_inline static T get_value(const ppu_thread& CPU)
FORCE_INLINE static T get_value(const ppu_thread& CPU)
{
return ppu_gpr_cast<T>(CPU.gpr[3]);
}
@ -127,7 +127,7 @@ namespace ppu_cb_detail
{
static_assert(sizeof(T) <= 8, "Invalid callback result type for ARG_FLOAT");
force_inline static T get_value(const ppu_thread& CPU)
FORCE_INLINE static T get_value(const ppu_thread& CPU)
{
return static_cast<T>(CPU.fpr[1]);
}
@ -138,7 +138,7 @@ namespace ppu_cb_detail
{
static_assert(std::is_same<CV T, CV v128>::value, "Invalid callback result type for ARG_VECTOR");
force_inline static T get_value(const ppu_thread& CPU)
FORCE_INLINE static T get_value(const ppu_thread& CPU)
{
return CPU.vr[2];
}
@ -147,7 +147,7 @@ namespace ppu_cb_detail
template<typename RT, typename... T>
struct _func_caller
{
force_inline static RT call(ppu_thread& CPU, u32 pc, u32 rtoc, T... args)
FORCE_INLINE static RT call(ppu_thread& CPU, u32 pc, u32 rtoc, T... args)
{
_func_caller<void, T...>::call(CPU, pc, rtoc, args...);
@ -164,7 +164,7 @@ namespace ppu_cb_detail
template<typename... T>
struct _func_caller<void, T...>
{
force_inline static void call(ppu_thread& CPU, u32 pc, u32 rtoc, T... args)
FORCE_INLINE static void call(ppu_thread& CPU, u32 pc, u32 rtoc, T... args)
{
const bool stack = _bind_func_args<0, 0, 0, T...>(CPU, args...);
CPU.gpr[1] -= stack ? FIXED_STACK_FRAME_SIZE : 0x30; // create reserved area
@ -177,7 +177,7 @@ namespace ppu_cb_detail
namespace vm
{
template<typename AT, typename RT, typename... T>
force_inline RT _ptr_base<RT(T...), AT>::operator()(ppu_thread& CPU, T... args) const
FORCE_INLINE RT _ptr_base<RT(T...), AT>::operator()(ppu_thread& CPU, T... args) const
{
const auto data = vm::ps3::_ptr<u32>(vm::cast(m_addr, HERE));
const u32 pc = data[0];

View file

@ -66,7 +66,7 @@ namespace ppu_func_detail
{
static_assert(std::is_same<CV T, CV v128>::value, "Invalid function argument type for ARG_VECTOR");
static force_inline T get_arg(ppu_thread& ppu)
static FORCE_INLINE T get_arg(ppu_thread& ppu)
{
return ppu.vr[v_count + 1];
}
@ -77,7 +77,7 @@ namespace ppu_func_detail
{
static_assert(alignof(T) <= 16, "Unsupported type alignment for ARG_STACK");
static force_inline T get_arg(ppu_thread& ppu)
static FORCE_INLINE T get_arg(ppu_thread& ppu)
{
return ppu_gpr_cast<T, u64>(*ppu.get_stack_arg(g_count, alignof(T))); // TODO
}
@ -88,7 +88,7 @@ namespace ppu_func_detail
{
static_assert(std::is_same<T, ppu_thread&>::value, "Invalid function argument type for ARG_CONTEXT");
static force_inline ppu_thread& get_arg(ppu_thread& ppu)
static FORCE_INLINE ppu_thread& get_arg(ppu_thread& ppu)
{
return ppu;
}
@ -99,7 +99,7 @@ namespace ppu_func_detail
{
static_assert(std::is_same<T, ppu_va_args_t>::value, "Invalid function argument type for ARG_VARIADIC");
static force_inline ppu_va_args_t get_arg(ppu_thread& ppu)
static FORCE_INLINE ppu_va_args_t get_arg(ppu_thread& ppu)
{
return{ g_count };
}
@ -111,7 +111,7 @@ namespace ppu_func_detail
static_assert(type == ARG_GENERAL, "Unknown function result type");
static_assert(sizeof(T) <= 8, "Invalid function result type for ARG_GENERAL");
static force_inline void put_result(ppu_thread& ppu, const T& result)
static FORCE_INLINE void put_result(ppu_thread& ppu, const T& result)
{
ppu.gpr[3] = ppu_gpr_cast(result);
}
@ -122,7 +122,7 @@ namespace ppu_func_detail
{
static_assert(sizeof(T) <= 8, "Invalid function result type for ARG_FLOAT");
static force_inline void put_result(ppu_thread& ppu, const T& result)
static FORCE_INLINE void put_result(ppu_thread& ppu, const T& result)
{
ppu.fpr[1] = static_cast<T>(result);
}
@ -133,7 +133,7 @@ namespace ppu_func_detail
{
static_assert(std::is_same<CV T, CV v128>::value, "Invalid function result type for ARG_VECTOR");
static force_inline void put_result(ppu_thread& ppu, const T& result)
static FORCE_INLINE void put_result(ppu_thread& ppu, const T& result)
{
ppu.vr[2] = result;
}
@ -160,21 +160,21 @@ namespace ppu_func_detail
// argument type + g/f/v_count unpacker
template<typename T, u32 type_pack> struct bind_arg_packed
{
static force_inline T get_arg(ppu_thread& ppu)
static FORCE_INLINE T get_arg(ppu_thread& ppu)
{
return bind_arg<T, static_cast<arg_class>(type_pack & 0xff), (type_pack >> 8) & 0xff, (type_pack >> 16) & 0xff, (type_pack >> 24)>::get_arg(ppu);
}
};
template<u32... Info, typename RT, typename... Args>
force_inline RT call(ppu_thread& ppu, RT(*func)(Args...), arg_info_pack_t<Info...>)
FORCE_INLINE RT call(ppu_thread& ppu, RT(*func)(Args...), arg_info_pack_t<Info...>)
{
// do the actual function call when all arguments are prepared (simultaneous unpacking of Args... and Info...)
return func(bind_arg_packed<Args, Info>::get_arg(ppu)...);
}
template<typename T, typename... Types, u32... Info, typename RT, typename... Args>
force_inline RT call(ppu_thread& ppu, RT(*func)(Args...), arg_info_pack_t<Info...> info)
FORCE_INLINE RT call(ppu_thread& ppu, RT(*func)(Args...), arg_info_pack_t<Info...> info)
{
// unpack previous type counts (0/0/0 for the first time)
const u32 g_count = (info.last_value >> 8) & 0xff;
@ -220,7 +220,7 @@ namespace ppu_func_detail
{
using func_t = void(*)(T...);
static force_inline void do_call(ppu_thread& ppu, func_t func)
static FORCE_INLINE void do_call(ppu_thread& ppu, func_t func)
{
call<T...>(ppu, func, arg_info_pack_t<>{});
}
@ -231,14 +231,14 @@ namespace ppu_func_detail
{
using func_t = RT(*)(T...);
static force_inline void do_call(ppu_thread& ppu, func_t func)
static FORCE_INLINE void do_call(ppu_thread& ppu, func_t func)
{
bind_result<RT, result_type<RT>::value>::put_result(ppu, call<T...>(ppu, func, arg_info_pack_t<>{}));
}
};
template<typename RT, typename... T>
force_inline void do_call(ppu_thread& ppu, RT(*func)(T...))
FORCE_INLINE void do_call(ppu_thread& ppu, RT(*func)(T...))
{
func_binder<RT, T...>::do_call(ppu, func);
}

View file

@ -283,7 +283,7 @@ public:
}
}
force_inline __m128 operator [] (s32 scale) const
FORCE_INLINE __m128 operator [] (s32 scale) const
{
return m_data[scale + 31];
}

View file

@ -748,9 +748,9 @@ std::shared_ptr<lv2_prx_t> ppu_load_prx(const ppu_prx_object& elf)
{
if (prog.p_memsz)
{
const u32 mem_size = fmt::narrow<u32>("Invalid p_memsz (0x%llx)" HERE, prog.p_memsz);
const u32 file_size = fmt::narrow<u32>("Invalid p_filesz (0x%llx)" HERE, prog.p_filesz);
const u32 init_addr = fmt::narrow<u32>("Invalid p_vaddr (0x%llx)" HERE, prog.p_vaddr);
const u32 mem_size = ::narrow<u32>(prog.p_memsz, "p_memsz" HERE);
const u32 file_size = ::narrow<u32>(prog.p_filesz, "p_filesz" HERE);
const u32 init_addr = ::narrow<u32>(prog.p_vaddr, "p_vaddr" HERE);
// Alloc segment memory
const u32 addr = vm::alloc(mem_size, vm::main);
@ -965,7 +965,7 @@ void ppu_load_exec(const ppu_exec_object& elf)
LOG_NOTICE(LOADER, "** Segment: p_type=0x%x, p_vaddr=0x%llx, p_filesz=0x%llx, p_memsz=0x%llx, flags=0x%x", prog.p_type, prog.p_vaddr, prog.p_filesz, prog.p_memsz, prog.p_flags);
const u32 addr = vm::cast(prog.p_vaddr, HERE);
const u32 size = fmt::narrow<u32>("Invalid p_memsz: 0x%llx" HERE, prog.p_memsz);
const u32 size = ::narrow<u32>(prog.p_memsz, "p_memsz" HERE);
if (prog.p_type == 0x1 /* LOAD */ && prog.p_memsz)
{
@ -1004,8 +1004,8 @@ void ppu_load_exec(const ppu_exec_object& elf)
case 0x00000007: // TLS
{
tls_vaddr = vm::cast(prog.p_vaddr, HERE);
tls_fsize = fmt::narrow<u32>("Invalid p_filesz (0x%llx)" HERE, prog.p_filesz);
tls_vsize = fmt::narrow<u32>("Invalid p_memsz (0x%llx)" HERE, prog.p_memsz);
tls_fsize = ::narrow<u32>(prog.p_filesz, "p_filesz" HERE);
tls_vsize = ::narrow<u32>(prog.p_memsz, "p_memsz" HERE);
break;
}

View file

@ -87,7 +87,7 @@ std::string ppu_thread::dump() const
ret += "\nRegisters:\n=========\n";
for (uint i = 0; i < 32; ++i) ret += fmt::format("GPR[%d] = 0x%llx\n", i, gpr[i]);
for (uint i = 0; i < 32; ++i) ret += fmt::format("FPR[%d] = %.6G\n", i, fpr[i]);
for (uint i = 0; i < 32; ++i) ret += fmt::format("VR[%d] = 0x%s [%s]\n", i, vr[i].to_hex().c_str(), vr[i].to_xyzw().c_str());
for (uint i = 0; i < 32; ++i) ret += fmt::format("VR[%d] = %s [x: %g y: %g z: %g w: %g]\n", i, vr[i], vr[i]._f[3], vr[i]._f[2], vr[i]._f[1], vr[i]._f[0]);
if (g_cfg_ppu_decoder.get() != ppu_decoder_type::llvm)
{

View file

@ -130,7 +130,7 @@ std::string SPUThread::dump() const
{
std::string ret = "Registers:\n=========\n";
for (uint i = 0; i<128; ++i) ret += fmt::format("GPR[%d] = 0x%s\n", i, gpr[i].to_hex().c_str());
for (uint i = 0; i<128; ++i) ret += fmt::format("GPR[%d] = %s\n", i, gpr[i]);
return ret;
}
@ -1254,7 +1254,7 @@ bool SPUThread::stop_and_signal(u32 code)
}
else
{
throw EXCEPTION("Unexpected SPU Thread Group state (%d)", group->state);
throw EXCEPTION("Unexpected SPU Thread Group state (%d)", (u32)group->state);
}
if (queue->events())
@ -1294,7 +1294,7 @@ bool SPUThread::stop_and_signal(u32 code)
}
else
{
throw EXCEPTION("Unexpected SPU Thread Group state (%d)", group->state);
throw EXCEPTION("Unexpected SPU Thread Group state (%d)", (u32)group->state);
}
for (auto& thread : group->threads)

View file

@ -377,7 +377,7 @@ struct spu_imm_table_t
public:
scale_table_t();
force_inline __m128 operator [] (s32 scale) const
FORCE_INLINE __m128 operator [] (s32 scale) const
{
return m_data[scale + 155];
}

View file

@ -80,7 +80,7 @@ void lv2_event_queue_t::push(lv2_lock_t, u64 source, u64 data1, u64 data2, u64 d
}
else
{
throw fmt::exception("Unexpected (queue.type=%d, thread.type=%d)" HERE, type, thread->type);
throw fmt::exception("Unexpected (queue type=%d, thread type=%d)" HERE, type, (s32)thread->type);
}
VERIFY(!thread->state.test_and_set(cpu_state::signal));

View file

@ -490,7 +490,7 @@ namespace vm
if (!block)
{
throw EXCEPTION("Invalid memory location (%d)", location);
throw fmt::exception("Invalid memory location (%u)" HERE, (uint)location);
}
return block->alloc(size, align, sup);
@ -502,7 +502,7 @@ namespace vm
if (!block)
{
throw EXCEPTION("Invalid memory location (%d, addr=0x%x)", location, addr);
throw fmt::exception("Invalid memory location (%u, addr=0x%x)" HERE, (uint)location, addr);
}
return block->falloc(addr, size, sup);
@ -514,7 +514,7 @@ namespace vm
if (!block)
{
throw EXCEPTION("Invalid memory location (%d, addr=0x%x)", location, addr);
throw fmt::exception("Invalid memory location (%u, addr=0x%x)" HERE, (uint)location, addr);
}
return block->dealloc(addr, sup_out);
@ -526,7 +526,7 @@ namespace vm
if (!block)
{
LOG_ERROR(MEMORY, "vm::dealloc(): invalid memory location (%d, addr=0x%x)\n", location, addr);
LOG_ERROR(MEMORY, "vm::dealloc(): invalid memory location (%u, addr=0x%x)\n", (uint)location, addr);
return;
}

View file

@ -182,12 +182,12 @@ namespace vm
{
static vm::addr_t cast(u64 addr, const char* loc)
{
return static_cast<vm::addr_t>(fmt::narrow<u32>("Memory address out of range: 0x%llx%s", addr, loc));
return static_cast<vm::addr_t>(static_cast<u32>(addr));
}
static vm::addr_t cast(u64 addr)
{
return static_cast<vm::addr_t>(fmt::narrow<u32>("Memory address out of range: 0x%llx", addr));
return static_cast<vm::addr_t>(static_cast<u32>(addr));
}
};

View file

@ -492,10 +492,12 @@ struct to_se<vm::_ptr_base<T, AT>, Se>
// Format pointer
template<typename T, typename AT>
struct unveil<vm::_ptr_base<T, AT>, void>
struct fmt_unveil<vm::_ptr_base<T, AT>, void>
{
static inline auto get(const vm::_ptr_base<T, AT>& arg)
using type = typename fmt_unveil<AT>::type;
static inline u64 get(const vm::_ptr_base<T, AT>& arg)
{
return unveil<AT>::get(arg.addr());
return fmt_unveil<AT>::get(arg.addr());
}
};

View file

@ -191,7 +191,7 @@ struct to_se<vm::_ref_base<T, AT>, Se>
// Forbid formatting
template<typename T, typename AT>
struct unveil<vm::_ref_base<T, AT>, void>
struct fmt_unveil<vm::_ref_base<T, AT>, void>
{
static_assert(!sizeof(T), "vm::_ref_base<>: ambiguous format argument");
};

View file

@ -5,7 +5,7 @@
namespace vm
{
template<typename AT, typename RT, typename... T>
force_inline RT _ptr_base<RT(T...), AT>::operator()(ARMv7Thread& cpu, T... args) const
FORCE_INLINE RT _ptr_base<RT(T...), AT>::operator()(ARMv7Thread& cpu, T... args) const
{
return arm_func_detail::func_caller<RT, T...>::call(cpu, vm::cast(this->addr(), HERE), args...);
}

View file

@ -39,12 +39,12 @@ namespace arm_func_detail
static_assert(!std::is_reference<T>::value, "Invalid function argument type (reference)");
static_assert(sizeof(T) <= 4, "Invalid function argument type for ARG_GENERAL");
force_inline static T get_arg(ARMv7Thread& cpu)
FORCE_INLINE static T get_arg(ARMv7Thread& cpu)
{
return arm_gpr_cast<T>(cpu.GPR[g_count - 1]);
}
force_inline static void put_arg(ARMv7Thread& cpu, const T& arg)
FORCE_INLINE static void put_arg(ARMv7Thread& cpu, const T& arg)
{
cpu.GPR[g_count - 1] = arm_gpr_cast(arg);
}
@ -56,12 +56,12 @@ namespace arm_func_detail
// first u64 argument is passed in r0-r1, second one is passed in r2-r3 (if g_count = 3)
static_assert(g_count == 2 || g_count == 4, "Wrong u64 argument position");
force_inline static u64 get_arg(ARMv7Thread& cpu)
FORCE_INLINE static u64 get_arg(ARMv7Thread& cpu)
{
return cpu.GPR_D[(g_count - 1) >> 1];
}
force_inline static void put_arg(ARMv7Thread& cpu, u64 arg)
FORCE_INLINE static void put_arg(ARMv7Thread& cpu, u64 arg)
{
cpu.GPR_D[(g_count - 1) >> 1] = arg;
}
@ -72,12 +72,12 @@ namespace arm_func_detail
{
static_assert(g_count == 2 || g_count == 4, "Wrong s64 argument position");
force_inline static s64 get_arg(ARMv7Thread& cpu)
FORCE_INLINE static s64 get_arg(ARMv7Thread& cpu)
{
return cpu.GPR_D[(g_count - 1) >> 1];
}
force_inline static void put_arg(ARMv7Thread& cpu, s64 arg)
FORCE_INLINE static void put_arg(ARMv7Thread& cpu, s64 arg)
{
cpu.GPR_D[(g_count - 1) >> 1] = arg;
}
@ -89,11 +89,11 @@ namespace arm_func_detail
static_assert(f_count <= 0, "TODO: Unsupported argument type (float)");
static_assert(sizeof(T) <= 8, "Invalid function argument type for ARG_FLOAT");
force_inline static T get_arg(ARMv7Thread& cpu)
FORCE_INLINE static T get_arg(ARMv7Thread& cpu)
{
}
force_inline static void put_arg(ARMv7Thread& cpu, const T& arg)
FORCE_INLINE static void put_arg(ARMv7Thread& cpu, const T& arg)
{
}
};
@ -104,11 +104,11 @@ namespace arm_func_detail
static_assert(v_count <= 0, "TODO: Unsupported argument type (vector)");
static_assert(std::is_same<CV T, CV v128>::value, "Invalid function argument type for ARG_VECTOR");
force_inline static T get_arg(ARMv7Thread& cpu)
FORCE_INLINE static T get_arg(ARMv7Thread& cpu)
{
}
force_inline static void put_arg(ARMv7Thread& cpu, const T& arg)
FORCE_INLINE static void put_arg(ARMv7Thread& cpu, const T& arg)
{
}
};
@ -120,13 +120,13 @@ namespace arm_func_detail
static_assert(v_count <= 0, "TODO: Unsupported stack argument type (vector)");
static_assert(sizeof(T) <= 4, "Invalid function argument type for ARG_STACK");
force_inline static T get_arg(ARMv7Thread& cpu)
FORCE_INLINE static T get_arg(ARMv7Thread& cpu)
{
// TODO: check
return arm_gpr_cast<T, u32>(vm::psv::read32(cpu.SP + sizeof(u32) * (g_count - 5)));
}
force_inline static void put_arg(ARMv7Thread& cpu, const T& arg)
FORCE_INLINE static void put_arg(ARMv7Thread& cpu, const T& arg)
{
// TODO: check
const int stack_pos = (g_count - 5) * 4 - FIXED_STACK_FRAME_SIZE;
@ -139,13 +139,13 @@ namespace arm_func_detail
template<u32 g_count, u32 f_count, u32 v_count>
struct bind_arg<u64, ARG_STACK, g_count, f_count, v_count>
{
force_inline static u64 get_arg(ARMv7Thread& cpu)
FORCE_INLINE static u64 get_arg(ARMv7Thread& cpu)
{
// TODO: check
return vm::psv::read64(cpu.SP + sizeof(u32) * (g_count - 6));
}
force_inline static void put_arg(ARMv7Thread& cpu, u64 arg)
FORCE_INLINE static void put_arg(ARMv7Thread& cpu, u64 arg)
{
// TODO: check
const int stack_pos = (g_count - 6) * 4 - FIXED_STACK_FRAME_SIZE;
@ -158,13 +158,13 @@ namespace arm_func_detail
template<u32 g_count, u32 f_count, u32 v_count>
struct bind_arg<s64, ARG_STACK, g_count, f_count, v_count>
{
force_inline static s64 get_arg(ARMv7Thread& cpu)
FORCE_INLINE static s64 get_arg(ARMv7Thread& cpu)
{
// TODO: check
return vm::psv::read64(cpu.SP + sizeof(u32) * (g_count - 6));
}
force_inline static void put_arg(ARMv7Thread& cpu, s64 arg)
FORCE_INLINE static void put_arg(ARMv7Thread& cpu, s64 arg)
{
// TODO: check
const int stack_pos = (g_count - 6) * 4 - FIXED_STACK_FRAME_SIZE;
@ -179,12 +179,12 @@ namespace arm_func_detail
{
static_assert(std::is_same<T, ARMv7Thread&>::value, "Invalid function argument type for ARG_CONTEXT");
force_inline static ARMv7Thread& get_arg(ARMv7Thread& cpu)
FORCE_INLINE static ARMv7Thread& get_arg(ARMv7Thread& cpu)
{
return cpu;
}
force_inline static void put_arg(ARMv7Thread& cpu, ARMv7Thread& arg)
FORCE_INLINE static void put_arg(ARMv7Thread& cpu, ARMv7Thread& arg)
{
}
};
@ -194,7 +194,7 @@ namespace arm_func_detail
{
static_assert(std::is_same<CV T, CV arm_va_args_t>::value, "Invalid function argument type for ARG_VARIADIC");
force_inline static arm_va_args_t get_arg(ARMv7Thread& cpu)
FORCE_INLINE static arm_va_args_t get_arg(ARMv7Thread& cpu)
{
return{ g_count };
}
@ -208,12 +208,12 @@ namespace arm_func_detail
static_assert(type == ARG_GENERAL, "Wrong use of bind_result template");
static_assert(sizeof(T) <= 4, "Invalid function result type for ARG_GENERAL");
force_inline static T get_result(ARMv7Thread& cpu)
FORCE_INLINE static T get_result(ARMv7Thread& cpu)
{
return arm_gpr_cast<T>(cpu.GPR[0]);
}
force_inline static void put_result(ARMv7Thread& cpu, const T& result)
FORCE_INLINE static void put_result(ARMv7Thread& cpu, const T& result)
{
cpu.GPR[0] = arm_gpr_cast(result);
}
@ -222,12 +222,12 @@ namespace arm_func_detail
template<>
struct bind_result<u64, ARG_GENERAL>
{
force_inline static u64 get_result(ARMv7Thread& cpu)
FORCE_INLINE static u64 get_result(ARMv7Thread& cpu)
{
return cpu.GPR_D[0];
}
force_inline static void put_result(ARMv7Thread& cpu, u64 result)
FORCE_INLINE static void put_result(ARMv7Thread& cpu, u64 result)
{
cpu.GPR_D[0] = result;
}
@ -236,12 +236,12 @@ namespace arm_func_detail
template<>
struct bind_result<s64, ARG_GENERAL>
{
force_inline static s64 get_result(ARMv7Thread& cpu)
FORCE_INLINE static s64 get_result(ARMv7Thread& cpu)
{
return cpu.GPR_D[0];
}
force_inline static void put_result(ARMv7Thread& cpu, s64 result)
FORCE_INLINE static void put_result(ARMv7Thread& cpu, s64 result)
{
cpu.GPR_D[0] = result;
}
@ -252,7 +252,7 @@ namespace arm_func_detail
//{
// static_assert(sizeof(T) <= 8, "Invalid function result type for ARG_FLOAT");
// static force_inline void put_result(ARMv7Thread& cpu, const T& result)
// static FORCE_INLINE void put_result(ARMv7Thread& cpu, const T& result)
// {
// }
//};
@ -262,7 +262,7 @@ namespace arm_func_detail
//{
// static_assert(std::is_same<std::remove_cv_t<T>, v128>::value, "Invalid function result type for ARG_VECTOR");
// static force_inline void put_result(ARMv7Thread& cpu, const T& result)
// static FORCE_INLINE void put_result(ARMv7Thread& cpu, const T& result)
// {
// }
//};
@ -322,21 +322,21 @@ namespace arm_func_detail
// argument type + g/f/v_count unpacker
template<typename T, u32 type_pack> struct bind_arg_packed
{
force_inline static T get_arg(ARMv7Thread& cpu)
FORCE_INLINE static T get_arg(ARMv7Thread& cpu)
{
return bind_arg<T, static_cast<arg_class>(type_pack & 0xff), (type_pack >> 8) & 0xff, (type_pack >> 16) & 0xff, (type_pack >> 24)>::get_arg(cpu);
}
};
template<u32... Info, typename RT, typename... Args>
force_inline RT call(ARMv7Thread& cpu, RT(*func)(Args...), arg_info_pack_t<Info...> info)
FORCE_INLINE RT call(ARMv7Thread& cpu, RT(*func)(Args...), arg_info_pack_t<Info...> info)
{
// do the actual function call when all arguments are prepared (simultaneous unpacking of Args... and Info...)
return func(bind_arg_packed<Args, Info>::get_arg(cpu)...);
}
template<typename T, typename... Types, u32... Info, typename RT, typename... Args>
force_inline RT call(ARMv7Thread& cpu, RT(*func)(Args...), arg_info_pack_t<Info...> info)
FORCE_INLINE RT call(ARMv7Thread& cpu, RT(*func)(Args...), arg_info_pack_t<Info...> info)
{
// unpack previous type counts (0/0/0 for the first time)
const u32 g_count = (info.last_value >> 8) & 0xff;
@ -353,14 +353,14 @@ namespace arm_func_detail
}
template<u32 g_count, u32 f_count, u32 v_count>
force_inline static bool put_func_args(ARMv7Thread& cpu)
FORCE_INLINE static bool put_func_args(ARMv7Thread& cpu)
{
// terminator
return false;
}
template<u32 g_count, u32 f_count, u32 v_count, typename T1, typename... T>
force_inline static bool put_func_args(ARMv7Thread& cpu, T1 arg, T... args)
FORCE_INLINE static bool put_func_args(ARMv7Thread& cpu, T1 arg, T... args)
{
using type = arg_type<T1, g_count, f_count, v_count>;
const arg_class t = type::value;
@ -402,7 +402,7 @@ namespace arm_func_detail
template<typename RT, typename... T>
struct func_caller
{
force_inline static RT call(ARMv7Thread& cpu, u32 addr, T... args)
FORCE_INLINE static RT call(ARMv7Thread& cpu, u32 addr, T... args)
{
func_caller<void, T...>::call(cpu, addr, args...);
@ -413,7 +413,7 @@ namespace arm_func_detail
template<typename... T>
struct func_caller<void, T...>
{
force_inline static void call(ARMv7Thread& cpu, u32 addr, T... args)
FORCE_INLINE static void call(ARMv7Thread& cpu, u32 addr, T... args)
{
if (put_func_args<0, 0, 0, T...>(cpu, args...))
{
@ -428,7 +428,7 @@ namespace arm_func_detail
}
};
template<typename RT, typename... T> force_inline void do_call(ARMv7Thread& cpu, RT(*func)(T...))
template<typename RT, typename... T> FORCE_INLINE void do_call(ARMv7Thread& cpu, RT(*func)(T...))
{
func_binder<RT, T...>::do_call(cpu, func);
}

View file

@ -20,7 +20,7 @@ D3D12_BLEND_OP get_blend_op(rsx::blend_equation op)
case rsx::blend_equation::reverse_substract_signed:
break;
}
throw EXCEPTION("Invalid or unsupported blend op (0x%x)", op);
throw EXCEPTION("Invalid or unsupported blend op (0x%x)", (u32)op);
}
D3D12_BLEND get_blend_factor(rsx::blend_factor factor)
@ -45,7 +45,7 @@ D3D12_BLEND get_blend_factor(rsx::blend_factor factor)
case rsx::blend_factor::one_minus_constant_alpha:
return D3D12_BLEND_INV_BLEND_FACTOR;
}
throw EXCEPTION("Invalid blend factor (0x%x)", factor);
throw EXCEPTION("Invalid blend factor (0x%x)", (u32)factor);
}
D3D12_BLEND get_blend_factor_alpha(rsx::blend_factor factor)
@ -70,7 +70,7 @@ D3D12_BLEND get_blend_factor_alpha(rsx::blend_factor factor)
case rsx::blend_factor::one_minus_constant_alpha:
return D3D12_BLEND_INV_BLEND_FACTOR;
}
throw EXCEPTION("Invalid blend alpha factor (0x%x)", factor);
throw EXCEPTION("Invalid blend alpha factor (0x%x)", (u32)factor);
}
/**
@ -96,7 +96,7 @@ D3D12_LOGIC_OP get_logic_op(rsx::logic_op op)
case rsx::logic_op::logic_or_inverted: return D3D12_LOGIC_OP_OR_INVERTED;
case rsx::logic_op::logic_nand: return D3D12_LOGIC_OP_NAND;
}
throw EXCEPTION("Invalid logic op (0x%x)", op);
throw EXCEPTION("Invalid logic op (0x%x)", (u32)op);
}
/**
@ -115,7 +115,7 @@ D3D12_STENCIL_OP get_stencil_op(rsx::stencil_op op)
case rsx::stencil_op::incr_wrap: return D3D12_STENCIL_OP_INCR;
case rsx::stencil_op::decr_wrap: return D3D12_STENCIL_OP_DECR;
}
throw EXCEPTION("Invalid stencil op (0x%x)", op);
throw EXCEPTION("Invalid stencil op (0x%x)", (u32)op);
}
D3D12_COMPARISON_FUNC get_compare_func(rsx::comparison_function op)
@ -131,7 +131,7 @@ D3D12_COMPARISON_FUNC get_compare_func(rsx::comparison_function op)
case rsx::comparison_function::greater_or_equal: return D3D12_COMPARISON_FUNC_GREATER_EQUAL;
case rsx::comparison_function::always: return D3D12_COMPARISON_FUNC_ALWAYS;
}
throw EXCEPTION("Invalid or unsupported compare func (0x%x)", op);
throw EXCEPTION("Invalid or unsupported compare func (0x%x)", (u32)op);
}
DXGI_FORMAT get_texture_format(u8 format)
@ -169,7 +169,7 @@ DXGI_FORMAT get_texture_format(u8 format)
case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: return DXGI_FORMAT_R8G8_B8G8_UNORM;
break;
}
throw EXCEPTION("Invalid or unsupported texture format (0x%x)", format);
throw EXCEPTION("Invalid or unsupported texture format (0x%x)", (u32)format);
}
UINT get_texture_max_aniso(rsx::texture_max_anisotropy aniso)
@ -185,7 +185,7 @@ UINT get_texture_max_aniso(rsx::texture_max_anisotropy aniso)
case rsx::texture_max_anisotropy::x12: return 12;
case rsx::texture_max_anisotropy::x16: return 16;
}
throw EXCEPTION("Invalid texture max aniso (0x%x)", aniso);
throw EXCEPTION("Invalid texture max aniso (0x%x)", (u32)aniso);
}
D3D12_TEXTURE_ADDRESS_MODE get_texture_wrap_mode(rsx::texture_wrap_mode wrap)
@ -201,7 +201,7 @@ D3D12_TEXTURE_ADDRESS_MODE get_texture_wrap_mode(rsx::texture_wrap_mode wrap)
case rsx::texture_wrap_mode::mirror_once_border: return D3D12_TEXTURE_ADDRESS_MODE_MIRROR_ONCE;
case rsx::texture_wrap_mode::mirror_once_clamp: return D3D12_TEXTURE_ADDRESS_MODE_MIRROR_ONCE;
}
throw EXCEPTION("Invalid texture wrap mode (0x%x)", wrap);
throw EXCEPTION("Invalid texture wrap mode (0x%x)", (u32)wrap);
}
namespace
@ -277,7 +277,7 @@ D3D12_PRIMITIVE_TOPOLOGY get_primitive_topology(rsx::primitive_type draw_mode)
case rsx::primitive_type::quad_strip: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
case rsx::primitive_type::polygon: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
}
throw EXCEPTION("Invalid draw mode (0x%x)", draw_mode);
throw EXCEPTION("Invalid draw mode (0x%x)", (u32)draw_mode);
}
D3D12_PRIMITIVE_TOPOLOGY_TYPE get_primitive_topology_type(rsx::primitive_type draw_mode)
@ -295,7 +295,7 @@ D3D12_PRIMITIVE_TOPOLOGY_TYPE get_primitive_topology_type(rsx::primitive_type dr
case rsx::primitive_type::polygon: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
case rsx::primitive_type::line_loop: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE;
}
throw EXCEPTION("Invalid or unsupported draw mode (0x%x)", draw_mode);
throw EXCEPTION("Invalid or unsupported draw mode (0x%x)", (u32)draw_mode);
}
DXGI_FORMAT get_color_surface_format(rsx::surface_color_format format)
@ -316,7 +316,7 @@ DXGI_FORMAT get_color_surface_format(rsx::surface_color_format format)
case rsx::surface_color_format::w32z32y32x32: return DXGI_FORMAT_R32G32B32A32_FLOAT;
case rsx::surface_color_format::x32: return DXGI_FORMAT_R32_FLOAT;
}
throw EXCEPTION("Invalid format (0x%x)", format);
throw EXCEPTION("Invalid format (0x%x)", (u32)format);
}
DXGI_FORMAT get_depth_stencil_surface_format(rsx::surface_depth_format format)
@ -326,7 +326,7 @@ DXGI_FORMAT get_depth_stencil_surface_format(rsx::surface_depth_format format)
case rsx::surface_depth_format::z16: return DXGI_FORMAT_D16_UNORM;
case rsx::surface_depth_format::z24s8: return DXGI_FORMAT_D24_UNORM_S8_UINT;
}
throw EXCEPTION("Invalid format (0x%x)", format);
throw EXCEPTION("Invalid format (0x%x)", (u32)format);
}
DXGI_FORMAT get_depth_stencil_surface_clear_format(rsx::surface_depth_format format)
@ -336,7 +336,7 @@ DXGI_FORMAT get_depth_stencil_surface_clear_format(rsx::surface_depth_format for
case rsx::surface_depth_format::z16: return DXGI_FORMAT_D16_UNORM;
case rsx::surface_depth_format::z24s8: return DXGI_FORMAT_D24_UNORM_S8_UINT;
}
throw EXCEPTION("Invalid format (0x%x)", format);
throw EXCEPTION("Invalid format (0x%x)", (u32)format);
}
DXGI_FORMAT get_depth_stencil_typeless_surface_format(rsx::surface_depth_format format)
@ -346,7 +346,7 @@ DXGI_FORMAT get_depth_stencil_typeless_surface_format(rsx::surface_depth_format
case rsx::surface_depth_format::z16: return DXGI_FORMAT_R16_TYPELESS;
case rsx::surface_depth_format::z24s8: return DXGI_FORMAT_R24G8_TYPELESS;
}
throw EXCEPTION("Invalid format (0x%x)", format);
throw EXCEPTION("Invalid format (0x%x)", (u32)format);
}
DXGI_FORMAT get_depth_samplable_surface_format(rsx::surface_depth_format format)
@ -356,7 +356,7 @@ DXGI_FORMAT get_depth_samplable_surface_format(rsx::surface_depth_format format)
case rsx::surface_depth_format::z16: return DXGI_FORMAT_R16_UNORM;
case rsx::surface_depth_format::z24s8: return DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
}
throw EXCEPTION("Invalid format (0x%x)", format);
throw EXCEPTION("Invalid format (0x%x)", (u32)format);
}
BOOL get_front_face_ccw(rsx::front_face ffv)
@ -366,7 +366,7 @@ BOOL get_front_face_ccw(rsx::front_face ffv)
case rsx::front_face::cw: return FALSE;
case rsx::front_face::ccw: return TRUE;
}
throw EXCEPTION("Invalid front face value (0x%x)", ffv);
throw EXCEPTION("Invalid front face value (0x%x)", (u32)ffv);
}
D3D12_CULL_MODE get_cull_face(rsx::cull_face cfv)
@ -377,7 +377,7 @@ D3D12_CULL_MODE get_cull_face(rsx::cull_face cfv)
case rsx::cull_face::back: return D3D12_CULL_MODE_BACK;
case rsx::cull_face::front_and_back: return D3D12_CULL_MODE_NONE;
}
throw EXCEPTION("Invalid cull face value (0x%x)", cfv);
throw EXCEPTION("Invalid cull face value (0x%x)", (u32)cfv);
}
DXGI_FORMAT get_index_type(rsx::index_array_type index_type)
@ -387,7 +387,7 @@ DXGI_FORMAT get_index_type(rsx::index_array_type index_type)
case rsx::index_array_type::u16: return DXGI_FORMAT_R16_UINT;
case rsx::index_array_type::u32: return DXGI_FORMAT_R32_UINT;
}
throw EXCEPTION("Invalid index_type (0x%x)", index_type);
throw EXCEPTION("Invalid index_type (0x%x)", (u32)index_type);
}
DXGI_FORMAT get_vertex_attribute_format(rsx::vertex_base_type type, u8 size)
@ -473,7 +473,7 @@ DXGI_FORMAT get_vertex_attribute_format(rsx::vertex_base_type type, u8 size)
}
}
throw EXCEPTION("Invalid or unsupported type or size (type=0x%x, size=0x%x)", type, size);
throw EXCEPTION("Invalid or unsupported type or size (type=0x%x, size=0x%x)", (u32)type, size);
}
D3D12_RECT get_scissor(u16 clip_origin_x, u16 clip_origin_y, u16 clip_w, u16 clip_h)

View file

@ -363,7 +363,7 @@ void GLGSRender::end()
switch (control)
{
default:
LOG_ERROR(RSX, "bad clip plane control (0x%x)", control);
LOG_ERROR(RSX, "bad clip plane control (0x%x)", (u32)control);
case rsx::user_clip_plane_op::disable:
value = 0;
@ -1019,7 +1019,7 @@ void GLGSRender::flip(int buffer)
std::string message =
"draw_calls: " + std::to_string(m_draw_calls) + ", " + "draw_call_setup: " + std::to_string(m_begin_time) + "us, " + "vertex_upload_time: " + std::to_string(m_vertex_upload_time) + "us, " + "draw_call_execution: " + std::to_string(m_draw_time) + "us";
LOG_ERROR(RSX, message.c_str());
LOG_ERROR(RSX, "%s", message);
}
}

View file

@ -46,7 +46,7 @@ color_format rsx::internals::surface_color_format_to_gl(rsx::surface_color_forma
case rsx::surface_color_format::a8b8g8r8:
default:
LOG_ERROR(RSX, "Surface color buffer: Unsupported surface color format (0x%x)", color_format);
LOG_ERROR(RSX, "Surface color buffer: Unsupported surface color format (0x%x)", (u32)color_format);
return{ ::gl::texture::type::uint_8_8_8_8, ::gl::texture::format::bgra, false, 4, 1 };
}
}
@ -59,7 +59,7 @@ depth_format rsx::internals::surface_depth_format_to_gl(rsx::surface_depth_forma
return{ ::gl::texture::type::ushort, ::gl::texture::format::depth, ::gl::texture::internal_format::depth16 };
default:
LOG_ERROR(RSX, "Surface depth buffer: Unsupported surface depth format (0x%x)", depth_format);
LOG_ERROR(RSX, "Surface depth buffer: Unsupported surface depth format (0x%x)", (u32)depth_format);
case rsx::surface_depth_format::z24s8:
return{ ::gl::texture::type::uint_24_8, ::gl::texture::format::depth_stencil, ::gl::texture::internal_format::depth24_stencil8 };
}

View file

@ -37,7 +37,7 @@ namespace
case CELL_GCM_TEXTURE_COMPRESSED_DXT23: return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
case CELL_GCM_TEXTURE_COMPRESSED_DXT45: return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
}
throw EXCEPTION("Compressed or unknown texture format %x", texture_format);
throw EXCEPTION("Compressed or unknown texture format 0x%x", texture_format);
}
@ -66,7 +66,7 @@ namespace
case CELL_GCM_TEXTURE_D8R8G8B8: return std::make_tuple(GL_BGRA, GL_UNSIGNED_INT_8_8_8_8);
case CELL_GCM_TEXTURE_Y16_X16_FLOAT: return std::make_tuple(GL_RG, GL_HALF_FLOAT);
}
throw EXCEPTION("Compressed or unknown texture format %x", texture_format);
throw EXCEPTION("Compressed or unknown texture format 0x%x", texture_format);
}
bool is_compressed_format(u32 texture_format)
@ -99,7 +99,7 @@ namespace
case CELL_GCM_TEXTURE_COMPRESSED_DXT45:
return true;
}
throw EXCEPTION("Unknown format %x", texture_format);
throw EXCEPTION("Unknown format 0x%x", texture_format);
}
bool requires_unpack_byte(u32 texture_format)
@ -178,7 +178,7 @@ namespace
return { GL_ZERO, GL_GREEN, GL_BLUE, GL_RED };
}
throw EXCEPTION("Unknown format %x", texture_format);
throw EXCEPTION("Unknown format 0x%x", texture_format);
}
}
@ -248,7 +248,7 @@ namespace rsx
case rsx::texture_wrap_mode::mirror_once_clamp: return GL_MIRROR_CLAMP_EXT;
}
LOG_ERROR(RSX, "Texture wrap error: bad wrap (%d).", wrap);
LOG_ERROR(RSX, "Texture wrap error: bad wrap (%d)", (u32)wrap);
return GL_REPEAT;
}
@ -266,7 +266,7 @@ namespace rsx
case rsx::texture_max_anisotropy::x16: return 16.0f;
}
LOG_ERROR(RSX, "Texture anisotropy error: bad max aniso (%d).", aniso);
LOG_ERROR(RSX, "Texture anisotropy error: bad max aniso (%d)", (u32)aniso);
return 1.0f;
}
@ -526,7 +526,7 @@ namespace rsx
{
if (tex.get_exact_mipmap_count() <= 1 || m_target == GL_TEXTURE_RECTANGLE)
{
LOG_WARNING(RSX, "Texture %d, target 0x%X, requesting mipmap filtering without any mipmaps set!", m_id, m_target);
LOG_WARNING(RSX, "Texture %d, target 0x%x, requesting mipmap filtering without any mipmaps set!", m_id, m_target);
min_filter = GL_LINEAR;
}
}
@ -631,7 +631,7 @@ namespace rsx
{
if (tex.get_exact_mipmap_count() <= 1 || m_target == GL_TEXTURE_RECTANGLE)
{
LOG_WARNING(RSX, "Texture %d, target 0x%X, requesting mipmap filtering without any mipmaps set!", m_id, m_target);
LOG_WARNING(RSX, "Texture %d, target 0x%x, requesting mipmap filtering without any mipmaps set!", m_id, m_target);
min_filter = GL_LINEAR;
}
}

View file

@ -20,7 +20,7 @@ namespace
const u32* vec_selectors[] = { 0, vec1_types, vec2_types, vec3_types, vec4_types };
if (type > rsx::vertex_base_type::ub256)
throw EXCEPTION("OpenGL error: unknown vertex base type 0x%X.", (u32)type);
throw EXCEPTION("OpenGL error: unknown vertex base type 0x%x", (u32)type);
return vec_selectors[size][(int)type];
}
@ -131,7 +131,7 @@ namespace
std::tuple<u32, u32> get_index_array_for_emulated_non_indexed_draw(const std::vector<std::pair<u32, u32>> &first_count_commands, rsx::primitive_type primitive_mode, gl::ring_buffer &dst)
{
u32 vertex_draw_count = 0;
assert(!gl::is_primitive_native(primitive_mode));
EXPECTS(gl::is_primitive_native(primitive_mode));
for (const auto &pair : first_count_commands)
{
@ -411,7 +411,7 @@ u32 GLGSRender::set_vertex_buffer()
break;
}
default:
LOG_ERROR(RSX, "bad non array vertex data format (type = %d, size = %d)", vertex_info.type, vertex_info.size);
LOG_ERROR(RSX, "bad non array vertex data format (type=%d, size=%d)", (u32)vertex_info.type, vertex_info.size);
break;
}
}

View file

@ -44,7 +44,7 @@ namespace rsx
void old_shaders_cache::shaders_cache::load(const std::string &path, shader_language lang)
{
const std::string lang_name(::unveil<shader_language>::get(lang));
const std::string lang_name(lang == shader_language::glsl ? "glsl" : "hlsl");
auto extract_hash = [](const std::string &string)
{
@ -180,7 +180,7 @@ namespace rsx
case vertex_base_type::cmp: return sizeof(u16) * 4;
case vertex_base_type::ub256: EXPECTS(size == 4); return sizeof(u8) * 4;
}
throw EXCEPTION("RSXVertexData::GetTypeSize: Bad vertex data type (%d)!", type);
throw EXCEPTION("RSXVertexData::GetTypeSize: Bad vertex data type (%d)!", (u8)type);
}
void tiled_region::write(const void *src, u32 width, u32 height, u32 pitch)

View file

@ -34,21 +34,6 @@ namespace rsx
}
}
template<>
struct unveil<rsx::old_shaders_cache::shader_language>
{
static inline const char* get(rsx::old_shaders_cache::shader_language in)
{
switch (in)
{
case rsx::old_shaders_cache::shader_language::glsl: return "glsl";
case rsx::old_shaders_cache::shader_language::hlsl: return "hlsl";
}
return "";
}
};
namespace rsx
{
namespace limits

View file

@ -36,7 +36,7 @@ VkFormat get_compatible_depth_surface_format(const gpu_formats_support &support,
throw EXCEPTION("No hardware support for z24s8");
}
}
throw EXCEPTION("Invalid format (0x%x)", format);
throw EXCEPTION("Invalid format (0x%x)", (u32)format);
}
std::tuple<VkFilter, VkSamplerMipmapMode> get_min_filter_and_mip(rsx::texture_minify_filter min_filter)
@ -62,7 +62,7 @@ VkFilter get_mag_filter(rsx::texture_magnify_filter mag_filter)
case rsx::texture_magnify_filter::linear: return VK_FILTER_LINEAR;
case rsx::texture_magnify_filter::convolution_mag: return VK_FILTER_LINEAR;
}
throw EXCEPTION("Invalid mag filter (0x%x)", mag_filter);
throw EXCEPTION("Invalid mag filter (0x%x)", (u32)mag_filter);
}
VkBorderColor get_border_color(u8 color)
@ -105,7 +105,7 @@ float max_aniso(rsx::texture_max_anisotropy gcm_aniso)
case rsx::texture_max_anisotropy::x16: return 16.0f;
}
throw EXCEPTION("Texture anisotropy error: bad max aniso (%d).", gcm_aniso);
throw EXCEPTION("Texture anisotropy error: bad max aniso (%d)", (u32)gcm_aniso);
}

View file

@ -44,7 +44,7 @@ namespace vk
case rsx::comparison_function::not_equal: return VK_COMPARE_OP_NOT_EQUAL;
case rsx::comparison_function::always: return VK_COMPARE_OP_ALWAYS;
default:
throw EXCEPTION("Unknown compare op: 0x%X", op);
throw EXCEPTION("Unknown compare op: 0x%x", (u32)op);
}
}
@ -91,7 +91,7 @@ namespace vk
return std::make_pair(VK_FORMAT_R32_SFLOAT, vk::default_component_map());
default:
LOG_ERROR(RSX, "Surface color buffer: Unsupported surface color format (0x%x)", color_format);
LOG_ERROR(RSX, "Surface color buffer: Unsupported surface color format (0x%x)", (u32)color_format);
return std::make_pair(VK_FORMAT_B8G8R8A8_UNORM, vk::default_component_map());
}
}
@ -170,7 +170,7 @@ namespace vk
case rsx::surface_target::surfaces_a_b_c_d:
return{ 0, 1, 2, 3 };
default:
LOG_ERROR(RSX, "Bad surface color target: %d", fmt);
LOG_ERROR(RSX, "Bad surface color target: %d", (u32)fmt);
return{};
}
}
@ -195,7 +195,7 @@ namespace vk
case rsx::logic_op::logic_or_inverted: return VK_LOGIC_OP_OR_INVERTED;
case rsx::logic_op::logic_nand: return VK_LOGIC_OP_NAND;
default:
throw EXCEPTION("Unknown logic op 0x%X", op);
throw EXCEPTION("Unknown logic op 0x%x", (u32)op);
}
}
@ -218,7 +218,7 @@ namespace vk
case rsx::blend_factor::one_minus_constant_alpha: return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA;
case rsx::blend_factor::one_minus_constant_color: return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR;
default:
throw EXCEPTION("Unknown blend factor 0x%X", factor);
throw EXCEPTION("Unknown blend factor 0x%x", (u32)factor);
}
};
@ -232,7 +232,7 @@ namespace vk
case rsx::blend_equation::min: return VK_BLEND_OP_MIN;
case rsx::blend_equation::max: return VK_BLEND_OP_MAX;
default:
throw EXCEPTION("Unknown blend op: 0x%X", op);
throw EXCEPTION("Unknown blend op: 0x%x", (u32)op);
}
}
@ -250,7 +250,7 @@ namespace vk
case rsx::stencil_op::incr_wrap: return VK_STENCIL_OP_INCREMENT_AND_WRAP;
case rsx::stencil_op::decr_wrap: return VK_STENCIL_OP_DECREMENT_AND_WRAP;
default:
throw EXCEPTION("Unknown stencil op: 0x%X", op);
throw EXCEPTION("Unknown stencil op: 0x%x", (u32)op);
}
}
@ -261,7 +261,7 @@ namespace vk
case rsx::front_face::cw: return VK_FRONT_FACE_CLOCKWISE;
case rsx::front_face::ccw: return VK_FRONT_FACE_COUNTER_CLOCKWISE;
default:
throw EXCEPTION("Unknown front face value: 0x%X", ffv);
throw EXCEPTION("Unknown front face value: 0x%x", (u32)ffv);
}
}
@ -274,7 +274,7 @@ namespace vk
case CELL_GCM_FRONT_AND_BACK: return VK_CULL_MODE_FRONT_AND_BACK;
default: return VK_CULL_MODE_NONE;
}
throw EXCEPTION("Unknown cull face value: 0x%X", cfv);
throw EXCEPTION("Unknown cull face value: 0x%x", (u32)cfv);
}
}
@ -861,7 +861,7 @@ bool VKGSRender::load_program()
if (rsx::method_registers.restart_index() != 0xFFFF &&
rsx::method_registers.restart_index() != 0xFFFFFFFF)
{
LOG_ERROR(RSX, "Custom primitive restart index 0x%X. Should rewrite index buffer with proper value!", rsx::method_registers.restart_index());
LOG_ERROR(RSX, "Custom primitive restart index 0x%x should rewrite index buffer with proper value!", rsx::method_registers.restart_index());
}
properties.ia.primitiveRestartEnable = VK_TRUE;
}

View file

@ -24,7 +24,7 @@ namespace rsx
namespace vk
{
#define CHECK_RESULT(expr) { VkResult __res = expr; if(__res != VK_SUCCESS) throw EXCEPTION("Assertion failed! Result is %Xh", __res); }
#define CHECK_RESULT(expr) do { VkResult _res = (expr); if (_res != VK_SUCCESS) throw fmt::exception("Assertion failed! Result is %Xh", (s32)_res); } while (0)
VKAPI_ATTR void *VKAPI_CALL mem_realloc(void *pUserData, void *pOriginal, size_t size, size_t alignment, VkSystemAllocationScope allocationScope);
VKAPI_ATTR void *VKAPI_CALL mem_alloc(void *pUserData, size_t size, size_t alignment, VkSystemAllocationScope allocationScope);

View file

@ -49,7 +49,7 @@ namespace vk
const VkFormat* vec_selectors[] = { 0, vec1_types, vec2_types, vec3_types, vec4_types };
if (type > rsx::vertex_base_type::ub256)
throw EXCEPTION("VKGS error: unknown vertex base type 0x%X.", (u32)type);
throw EXCEPTION("VKGS error: unknown vertex base type 0x%x", (u32)type);
return vec_selectors[size][(int)type];
}
@ -425,7 +425,7 @@ VKGSRender::upload_vertex_data()
vk::copy_inlined_data_to_buffer<u16, 1>(src, dst, vertex_draw_count, vertex_info.type, vertex_info.size, opt_size, element_size, stride);
break;
default:
throw EXCEPTION("Unknown base type %d", vertex_info.type);
throw EXCEPTION("Unknown base type %d", (u32)vertex_info.type);
}
m_attrib_ring_info.unmap();
@ -545,7 +545,7 @@ VKGSRender::upload_vertex_data()
break;
}
default:
LOG_ERROR(RSX, "bad non array vertex data format (type = %d, size = %d)", vertex_info.type, vertex_info.size);
LOG_ERROR(RSX, "bad non array vertex data format (type=%d, size=%d)", (u32)vertex_info.type, vertex_info.size);
break;
}
}

View file

@ -298,7 +298,7 @@ namespace rsx
case blit_engine::context_dma::to_memory_get_report: location = CELL_GCM_LOCATION_LOCAL; break;
case blit_engine::context_dma::report_location_main: location = CELL_GCM_LOCATION_MAIN; break;
default:
LOG_WARNING(RSX, "nv4097::get_report: bad report dma: 0x%x", report_dma);
LOG_WARNING(RSX, "nv4097::get_report: bad report dma: 0x%x", (u8)report_dma);
return;
}
@ -406,12 +406,12 @@ namespace rsx
if (in_origin != blit_engine::transfer_origin::corner)
{
LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown origin (%d)", in_origin);
LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown origin (%d)", (u8)in_origin);
}
if (operation != rsx::blit_engine::transfer_operation::srccopy)
{
LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown operation (%d)", operation);
LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown operation (%d)", (u8)operation);
}
const u32 src_offset = method_registers.blit_engine_input_offset();
@ -440,7 +440,7 @@ namespace rsx
break;
default:
LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown m_context_surface (0x%x)", method_registers.blit_engine_context_surface());
LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown m_context_surface (0x%x)", (u8)method_registers.blit_engine_context_surface());
return;
}
@ -512,13 +512,13 @@ namespace rsx
if (dst_color_format != rsx::blit_engine::transfer_destination_format::r5g6b5 &&
dst_color_format != rsx::blit_engine::transfer_destination_format::a8r8g8b8)
{
LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown dst_color_format (%d)", dst_color_format);
LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown dst_color_format (%d)", (u8)dst_color_format);
}
if (src_color_format != rsx::blit_engine::transfer_source_format::r5g6b5 &&
src_color_format != rsx::blit_engine::transfer_source_format::a8r8g8b8)
{
LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown src_color_format (%d)", src_color_format);
LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown src_color_format (%d)", (u8)src_color_format);
}
//LOG_WARNING(RSX, "NV3089_IMAGE_IN_SIZE: SIZE=0x%08x, pitch=0x%x, offset=0x%x, scaleX=%f, scaleY=%f, CLIP_SIZE=0x%08x, OUT_SIZE=0x%08x",

View file

@ -121,10 +121,10 @@ public:
void Resume();
void Stop();
force_inline bool IsRunning() const { return m_status == Running; }
force_inline bool IsPaused() const { return m_status == Paused; }
force_inline bool IsStopped() const { return m_status == Stopped; }
force_inline bool IsReady() const { return m_status == Ready; }
bool IsRunning() const { return m_status == Running; }
bool IsPaused() const { return m_status == Paused; }
bool IsStopped() const { return m_status == Stopped; }
bool IsReady() const { return m_status == Ready; }
};
extern Emulator Emu;

View file

@ -27,14 +27,14 @@ static YAML::Node loaded;
static YAML::Node saved;
// Emit sorted YAML
static never_inline void emit(YAML::Emitter& out, const YAML::Node& node)
static NEVER_INLINE void emit(YAML::Emitter& out, const YAML::Node& node)
{
// TODO
out << node;
}
// Incrementally load YAML
static never_inline void operator +=(YAML::Node& left, const YAML::Node& node)
static NEVER_INLINE void operator +=(YAML::Node& left, const YAML::Node& node)
{
if (node && !node.IsNull())
{

31
rpcs3/Loader/ELF.cpp Normal file
View file

@ -0,0 +1,31 @@
#include "stdafx.h"
#include "ELF.h"
// ELF loading error information
template<>
void fmt_class_string<elf_error>::format(std::string& out, u64 arg)
{
format_enum(out, arg, [](elf_error error)
{
switch (error)
{
case elf_error::ok: return "OK";
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";
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";
}
return unknown;
});
}

View file

@ -153,35 +153,6 @@ enum class elf_error
header_os,
};
// ELF loading error information
template<>
struct unveil<elf_error>
{
static inline const char* get(elf_error error)
{
switch (error)
{
case elf_error::ok: return "OK";
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";
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 object with specified parameters.
// en_t: endianness (specify le_t or be_t)
// sz_t: size (specify u32 for ELF32, u64 for ELF64)

View file

@ -1,6 +1,22 @@
#include "stdafx.h"
#include "PSF.h"
template<>
void fmt_class_string<psf::format>::format(std::string& out, u64 arg)
{
format_enum(out, arg, [](auto fmt)
{
switch (fmt)
{
STR_CASE(psf::format::array);
STR_CASE(psf::format::string);
STR_CASE(psf::format::integer);
}
return unknown;
});
}
namespace psf
{
logs::channel log("PSF", logs::level::notice);

View file

@ -367,6 +367,7 @@
<ClCompile Include="Emu\RSX\RSXThread.cpp" />
<ClCompile Include="Emu\Memory\vm.cpp" />
<ClCompile Include="Emu\System.cpp" />
<ClCompile Include="Loader\ELF.cpp" />
<ClCompile Include="Loader\PSF.cpp" />
<ClCompile Include="Loader\TROPUSR.cpp" />
<ClCompile Include="Loader\TRP.cpp" />
@ -386,6 +387,7 @@
<ClInclude Include="..\Utilities\BEType.h" />
<ClInclude Include="..\Utilities\BitField.h" />
<ClInclude Include="..\Utilities\BitSet.h" />
<ClInclude Include="..\Utilities\cfmt.h" />
<ClInclude Include="..\Utilities\dynamic_library.h" />
<ClInclude Include="..\Utilities\event.h" />
<ClInclude Include="..\Utilities\geometry.h" />

View file

@ -884,6 +884,9 @@
<ClCompile Include="Emu\RSX\gcm_enums.cpp">
<Filter>Emu\GPU\RSX</Filter>
</ClCompile>
<ClCompile Include="Loader\ELF.cpp">
<Filter>Loader</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Crypto\aes.h">
@ -1702,5 +1705,8 @@
<ClInclude Include="Emu\RSX\gcm_enums.h">
<Filter>Emu\GPU\RSX</Filter>
</ClInclude>
<ClInclude Include="..\Utilities\cfmt.h">
<Filter>Utilities</Filter>
</ClInclude>
</ItemGroup>
</Project>

View file

@ -175,7 +175,7 @@ bool Rpcs3App::OnInit()
case frame_type::Vulkan: return std::make_unique<GSFrame>("Vulkan", w, h);
}
throw EXCEPTION("Invalid Frame Type (0x%x)", type);
throw fmt::exception("Invalid frame type (0x%x)" HERE, (int)type);
};
callbacks.get_gs_render = PURE_EXPR(g_cfg_gs_render.get()());