clang-format: left-align escaped newlines

alternative to #3638. this is theoretically better for side-by-side diffs. in
practice it may make other diffs worse since all the \'s change when part of the
macro change.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
This commit is contained in:
Alyssa Rosenzweig 2024-05-20 09:46:52 -04:00
parent 048c8ded88
commit a10f984b1c
31 changed files with 262 additions and 262 deletions

View File

@ -7,7 +7,7 @@ AlignConsecutiveAssignments: None
AlignConsecutiveBitFields: Consecutive
AlignConsecutiveDeclarations: None
AlignConsecutiveMacros: None
AlignEscapedNewlines: DontAlign
AlignEscapedNewlines: Left
AlignOperands: Align
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: false

View File

@ -359,14 +359,14 @@ void CPUIDEmu::SetupFeatures() {
return;
}
#define ENABLE_DISABLE_OPTION(FeatureName, name, enum_name) \
do { \
const bool Disable##name = (CPUIDFeatures() & FEXCore::Config::CPUID::DISABLE##enum_name) != 0; \
const bool Enable##name = (CPUIDFeatures() & FEXCore::Config::CPUID::ENABLE##enum_name) != 0; \
#define ENABLE_DISABLE_OPTION(FeatureName, name, enum_name) \
do { \
const bool Disable##name = (CPUIDFeatures() & FEXCore::Config::CPUID::DISABLE##enum_name) != 0; \
const bool Enable##name = (CPUIDFeatures() & FEXCore::Config::CPUID::ENABLE##enum_name) != 0; \
LogMan::Throw::AFmt(!(Disable##name && Enable##name), "Disabling and Enabling CPU feature (" #name ") is mutually exclusive"); \
const bool AlreadyEnabled = Features.FeatureName; \
const bool Result = (AlreadyEnabled | Enable##name) & !Disable##name; \
Features.FeatureName = Result; \
const bool AlreadyEnabled = Features.FeatureName; \
const bool Result = (AlreadyEnabled | Enable##name) & !Disable##name; \
Features.FeatureName = Result; \
} while (0)
ENABLE_DISABLE_OPTION(SHA, SHA, SHA);

View File

@ -59,19 +59,19 @@ static void OverrideFeatures(HostFeatures* Features) {
return;
}
#define ENABLE_DISABLE_OPTION(FeatureName, name, enum_name) \
do { \
const bool Disable##name = (HostFeatures() & FEXCore::Config::HostFeatures::DISABLE##enum_name) != 0; \
const bool Enable##name = (HostFeatures() & FEXCore::Config::HostFeatures::ENABLE##enum_name) != 0; \
#define ENABLE_DISABLE_OPTION(FeatureName, name, enum_name) \
do { \
const bool Disable##name = (HostFeatures() & FEXCore::Config::HostFeatures::DISABLE##enum_name) != 0; \
const bool Enable##name = (HostFeatures() & FEXCore::Config::HostFeatures::ENABLE##enum_name) != 0; \
LogMan::Throw::AFmt(!(Disable##name && Enable##name), "Disabling and Enabling CPU feature (" #name ") is mutually exclusive"); \
const bool AlreadyEnabled = Features->FeatureName; \
const bool Result = (AlreadyEnabled | Enable##name) & !Disable##name; \
Features->FeatureName = Result; \
const bool AlreadyEnabled = Features->FeatureName; \
const bool Result = (AlreadyEnabled | Enable##name) & !Disable##name; \
Features->FeatureName = Result; \
} while (0)
#define GET_SINGLE_OPTION(name, enum_name) \
#define GET_SINGLE_OPTION(name, enum_name) \
const bool Disable##name = (HostFeatures() & FEXCore::Config::HostFeatures::DISABLE##enum_name) != 0; \
const bool Enable##name = (HostFeatures() & FEXCore::Config::HostFeatures::ENABLE##enum_name) != 0; \
const bool Enable##name = (HostFeatures() & FEXCore::Config::HostFeatures::ENABLE##enum_name) != 0; \
LogMan::Throw::AFmt(!(Disable##name && Enable##name), "Disabling and Enabling CPU feature (" #name ") is mutually exclusive");
ENABLE_DISABLE_OPTION(SupportsAVX, AVX, AVX);

View File

@ -185,22 +185,22 @@ bool InterpreterOps::GetFallbackHandler(bool SupportsPreserveAllABI, const IR::I
break;
}
#define COMMON_UNARY_X87_OP(OP) \
case IR::OP_F80##OP: { \
#define COMMON_UNARY_X87_OP(OP) \
case IR::OP_F80##OP: { \
*Info = {FABI_F80_I16_F80, (void*)&FEXCore::CPU::OpHandlers<IR::OP_F80##OP>::handle, Core::OPINDEX_F80##OP, SupportsPreserveAllABI}; \
return true; \
return true; \
}
#define COMMON_BINARY_X87_OP(OP) \
case IR::OP_F80##OP: { \
#define COMMON_BINARY_X87_OP(OP) \
case IR::OP_F80##OP: { \
*Info = {FABI_F80_I16_F80_F80, (void*)&FEXCore::CPU::OpHandlers<IR::OP_F80##OP>::handle, Core::OPINDEX_F80##OP, SupportsPreserveAllABI}; \
return true; \
return true; \
}
#define COMMON_F64_OP(OP) \
case IR::OP_F64##OP: { \
#define COMMON_F64_OP(OP) \
case IR::OP_F64##OP: { \
*Info = GetFallbackInfo(&FEXCore::CPU::OpHandlers<IR::OP_F64##OP>::handle, Core::OPINDEX_F64##OP); \
return true; \
return true; \
}
// Unary

View File

@ -384,15 +384,15 @@ DEF_OP(Vector_FToI) {
// frinti having AdvSIMD, AdvSIMD scalar, and an SVE version),
// we can't just use a lambda without some seriously ugly casting.
// This is fairly self-contained otherwise.
#define ROUNDING_FN(name) \
if (ElementSize == 2) { \
name(Dst.H(), Vector.H()); \
#define ROUNDING_FN(name) \
if (ElementSize == 2) { \
name(Dst.H(), Vector.H()); \
} else if (ElementSize == 4) { \
name(Dst.S(), Vector.S()); \
name(Dst.S(), Vector.S()); \
} else if (ElementSize == 8) { \
name(Dst.D(), Vector.D()); \
} else { \
FEX_UNREACHABLE; \
name(Dst.D(), Vector.D()); \
} else { \
FEX_UNREACHABLE; \
}
switch (Op->Round) {

View File

@ -1580,9 +1580,9 @@ private:
// replaced with NewOp. Useful for generic building code. Not safe in general.
// but does the right handling of ImplicitFlagClobber at least and must be
// used instead of raw Op mutation.
#define DeriveOp(Dest, NewOp, Expr) \
#define DeriveOp(Dest, NewOp, Expr) \
if (ImplicitFlagClobber(NewOp)) SaveNZCV(NewOp); \
auto Dest = (Expr); \
auto Dest = (Expr); \
Dest.first->Header.Op = (NewOp)
// Named constant cache for the current block.

View File

@ -22,13 +22,13 @@ namespace FEXCore::Utils::SpinWaitLock {
*/
#ifdef _M_ARM_64
#define LOADEXCLUSIVE(LoadExclusiveOp, RegSize) \
#define LOADEXCLUSIVE(LoadExclusiveOp, RegSize) \
/* Prime the exclusive monitor with the passed in address. */ \
#LoadExclusiveOp " %" #RegSize "[Result], [%[Futex]];"
#define SPINLOOP_BODY(LoadAtomicOp, RegSize) \
#define SPINLOOP_BODY(LoadAtomicOp, RegSize) \
/* WFE will wait for either the memory to change or spurious wake-up. */ \
"wfe;" /* Load with acquire to get the result of memory. */ \
"wfe;" /* Load with acquire to get the result of memory. */ \
#LoadAtomicOp " %" #RegSize "[Result], [%[Futex]]; "
#define SPINLOOP_WFE_LDX_8BIT LOADEXCLUSIVE(ldaxrb, w)

View File

@ -136,10 +136,10 @@ namespace DefaultValues {
#define OPT_STRARRAY(group, enum, json, default) OPT_STR(group, enum, json, default)
#include <FEXCore/Config/ConfigValues.inl>
} // namespace Type
#define FEX_CONFIG_OPT(name, enum) \
#define FEX_CONFIG_OPT(name, enum) \
FEXCore::Config::Value<FEXCore::Config::DefaultValues::Type::enum> name { \
FEXCore::Config::CONFIG_##enum, \
FEXCore::Config::DefaultValues::enum \
FEXCore::Config::CONFIG_##enum, \
FEXCore::Config::DefaultValues::enum \
}
#undef P

View File

@ -2,27 +2,27 @@
#pragma once
#include <type_traits>
#define FEX_DEF_ENUM_CLASS_BIN_OP(Enum, Op) \
[[maybe_unused]] static constexpr Enum operator Op(Enum lhs, Enum rhs) { \
using Type = std::underlying_type_t<Enum>; \
Type _lhs = static_cast<Type>(lhs); \
Type _rhs = static_cast<Type>(rhs); \
return static_cast<Enum>(_lhs Op _rhs); \
} \
#define FEX_DEF_ENUM_CLASS_BIN_OP(Enum, Op) \
[[maybe_unused]] static constexpr Enum operator Op(Enum lhs, Enum rhs) { \
using Type = std::underlying_type_t<Enum>; \
Type _lhs = static_cast<Type>(lhs); \
Type _rhs = static_cast<Type>(rhs); \
return static_cast<Enum>(_lhs Op _rhs); \
} \
[[maybe_unused]] static constexpr uint64_t operator Op(uint64_t lhs, Enum rhs) { \
using Type = std::underlying_type_t<Enum>; \
Type _rhs = static_cast<Type>(rhs); \
return lhs Op _rhs; \
using Type = std::underlying_type_t<Enum>; \
Type _rhs = static_cast<Type>(rhs); \
return lhs Op _rhs; \
}
#define FEX_DEF_ENUM_CLASS_UNARY_OP(Enum, Op) \
#define FEX_DEF_ENUM_CLASS_UNARY_OP(Enum, Op) \
[[maybe_unused]] static constexpr Enum operator Op(Enum rhs) { \
using Type = std::underlying_type_t<Enum>; \
Type _rhs = static_cast<Type>(rhs); \
return static_cast<Enum>(Op _rhs); \
using Type = std::underlying_type_t<Enum>; \
Type _rhs = static_cast<Type>(rhs); \
return static_cast<Enum>(Op _rhs); \
}
#define FEX_DEF_NUM_OPS(Enum) \
#define FEX_DEF_NUM_OPS(Enum) \
FEX_DEF_ENUM_CLASS_BIN_OP(Enum, |) \
FEX_DEF_ENUM_CLASS_BIN_OP(Enum, &) \
FEX_DEF_ENUM_CLASS_BIN_OP(Enum, ^) \

View File

@ -10,52 +10,52 @@ namespace FEXCore {
// Macro that defines all of the built in operators for conveniently using
// enum classes as flag types without needing to define all of the basic
// boilerplate.
#define FEX_DECLARE_ENUM_FLAG_OPERATORS(type) \
[[nodiscard]] \
constexpr type \
operator|(type a, type b) noexcept { \
using T = std::underlying_type_t<type>; \
#define FEX_DECLARE_ENUM_FLAG_OPERATORS(type) \
[[nodiscard]] \
constexpr type \
operator|(type a, type b) noexcept { \
using T = std::underlying_type_t<type>; \
return static_cast<type>(static_cast<T>(a) | static_cast<T>(b)); \
} \
[[nodiscard]] \
constexpr type \
operator&(type a, type b) noexcept { \
using T = std::underlying_type_t<type>; \
} \
[[nodiscard]] \
constexpr type \
operator&(type a, type b) noexcept { \
using T = std::underlying_type_t<type>; \
return static_cast<type>(static_cast<T>(a) & static_cast<T>(b)); \
} \
[[nodiscard]] \
constexpr type \
operator^(type a, type b) noexcept { \
using T = std::underlying_type_t<type>; \
} \
[[nodiscard]] \
constexpr type \
operator^(type a, type b) noexcept { \
using T = std::underlying_type_t<type>; \
return static_cast<type>(static_cast<T>(a) ^ static_cast<T>(b)); \
} \
constexpr type& operator|=(type& a, type b) noexcept { \
a = a | b; \
return a; \
} \
constexpr type& operator&=(type& a, type b) noexcept { \
a = a & b; \
return a; \
} \
constexpr type& operator^=(type& a, type b) noexcept { \
a = a ^ b; \
return a; \
} \
[[nodiscard]] \
constexpr type \
operator~(type key) noexcept { \
using T = std::underlying_type_t<type>; \
return static_cast<type>(~static_cast<T>(key)); \
} \
[[nodiscard]] \
constexpr bool True(type key) noexcept { \
using T = std::underlying_type_t<type>; \
return static_cast<T>(key) != 0; \
} \
[[nodiscard]] \
constexpr bool False(type key) noexcept { \
using T = std::underlying_type_t<type>; \
return static_cast<T>(key) == 0; \
} \
constexpr type& operator|=(type& a, type b) noexcept { \
a = a | b; \
return a; \
} \
constexpr type& operator&=(type& a, type b) noexcept { \
a = a & b; \
return a; \
} \
constexpr type& operator^=(type& a, type b) noexcept { \
a = a ^ b; \
return a; \
} \
[[nodiscard]] \
constexpr type \
operator~(type key) noexcept { \
using T = std::underlying_type_t<type>; \
return static_cast<type>(~static_cast<T>(key)); \
} \
[[nodiscard]] \
constexpr bool True(type key) noexcept { \
using T = std::underlying_type_t<type>; \
return static_cast<T>(key) != 0; \
} \
[[nodiscard]] \
constexpr bool False(type key) noexcept { \
using T = std::underlying_type_t<type>; \
return static_cast<T>(key) == 0; \
}
// Equivalent to C++23's std::to_underlying.

View File

@ -63,25 +63,25 @@ namespace Throw {
MFmt(fmt, fmt::make_format_args(args...));
}
#define LOGMAN_THROW_A_FMT(pred, ...) \
do { \
#define LOGMAN_THROW_A_FMT(pred, ...) \
do { \
LogMan::Throw::AFmt(pred, __VA_ARGS__); \
} while (0)
#define LOGMAN_THROW_AA_FMT(pred, ...) \
do { \
#define LOGMAN_THROW_AA_FMT(pred, ...) \
do { \
LogMan::Throw::AFmt(pred, __VA_ARGS__); \
} while (0)
#else
static inline void AFmt(bool, const char*, ...) {}
#define LOGMAN_THROW_A_FMT(pred, ...) \
do { \
do { \
} while (0)
static inline void AAFmt(bool pred, const char*, ...) {
__builtin_assume(pred);
}
#define LOGMAN_THROW_AA_FMT(pred, ...) \
do { \
__builtin_assume(pred); \
do { \
__builtin_assume(pred); \
} while (0)
#endif
@ -144,31 +144,31 @@ namespace Msg {
MFmtImpl(ASSERT, fmt, fmt::make_format_args(args...));
FEX_TRAP_EXECUTION;
}
#define LOGMAN_MSG_A_FMT(...) \
do { \
#define LOGMAN_MSG_A_FMT(...) \
do { \
LogMan::Msg::AFmt(__VA_ARGS__); \
} while (0)
#else
template<typename... Args>
static inline void AFmt(const char*, const Args&...) {}
#define LOGMAN_MSG_A_FMT(...) \
do { \
do { \
} while (0)
#endif
#define WARN_ONCE_FMT(...) \
do { \
static bool Warned {}; \
if (!Warned) { \
#define WARN_ONCE_FMT(...) \
do { \
static bool Warned {}; \
if (!Warned) { \
LogMan::Msg::DFmt(__VA_ARGS__); \
Warned = true; \
} \
Warned = true; \
} \
} while (0);
#define ERROR_AND_DIE_FMT(...) \
do { \
#define ERROR_AND_DIE_FMT(...) \
do { \
LogMan::Msg::EFmt(__VA_ARGS__); \
FEX_TRAP_EXECUTION; \
FEX_TRAP_EXECUTION; \
} while (0)
} // namespace Msg

View File

@ -54,10 +54,10 @@ static void TraceObject(std::string_view const Format) {}
static void TraceObject(std::string_view const, uint64_t) {}
#define FEXCORE_PROFILE_INSTANT(...) \
do { \
do { \
} while (0)
#define FEXCORE_PROFILE_SCOPED(...) \
do { \
do { \
} while (0)
#endif
} // namespace FEXCore::Profiler

View File

@ -92,16 +92,16 @@ static inline void Shutdown(const fextl::string& ApplicationName) {}
#define FEXCORE_TELEMETRY_STATIC_INIT(Name, Type)
#define FEXCORE_TELEMETRY_INIT(Name, Type)
#define FEXCORE_TELEMETRY(Name, Value) \
do { \
do { \
} while (0)
#define FEXCORE_TELEMETRY_SET(Name, Value) \
do { \
do { \
} while (0)
#define FEXCORE_TELEMETRY_OR(Name, Value) \
do { \
do { \
} while (0)
#define FEXCORE_TELEMETRY_INC(Name) \
do { \
do { \
} while (0)
#define FEXCORE_TELEMETRY_Addr(Name) reinterpret_cast<std::atomic<uint64_t>*>(nullptr)
#endif

View File

@ -105,17 +105,17 @@ bool OpenFile(fextl::string Filename, bool LoadDefault = false) {
LoadedConfig->Load();
// Load default options and only overwrite only if the option didn't exist
#define OPT_BASE(type, group, enum, json, default) \
if (!LoadedConfig->OptionExists(FEXCore::Config::ConfigOption::CONFIG_##enum)) { \
#define OPT_BASE(type, group, enum, json, default) \
if (!LoadedConfig->OptionExists(FEXCore::Config::ConfigOption::CONFIG_##enum)) { \
LoadedConfig->EraseSet(FEXCore::Config::ConfigOption::CONFIG_##enum, std::to_string(default)); \
}
#define OPT_STR(group, enum, json, default) \
#define OPT_STR(group, enum, json, default) \
if (!LoadedConfig->OptionExists(FEXCore::Config::ConfigOption::CONFIG_##enum)) { \
LoadedConfig->EraseSet(FEXCore::Config::ConfigOption::CONFIG_##enum, default); \
}
#define OPT_STRARRAY(group, enum, json, default) // Do nothing
#define OPT_STRENUM(group, enum, json, default) \
if (!LoadedConfig->OptionExists(FEXCore::Config::ConfigOption::CONFIG_##enum)) { \
#define OPT_STRENUM(group, enum, json, default) \
if (!LoadedConfig->OptionExists(FEXCore::Config::ConfigOption::CONFIG_##enum)) { \
LoadedConfig->EraseSet(FEXCore::Config::ConfigOption::CONFIG_##enum, std::to_string(FEXCore::ToUnderlying(default))); \
}
#include <FEXCore/Config/ConfigValues.inl>

View File

@ -124,8 +124,8 @@ fextl::string GenerateCPUInfo(FEXCore::Context::Context* ctx, uint32_t CPUCores)
// Generate the flags data up front
// This is the same per core
{
#define FLAG(flag, name) \
if (flag) { \
#define FLAG(flag, name) \
if (flag) { \
flags_data << name << " "; \
}
FLAG(res_1.edx & (1 << 0), "fpu")

View File

@ -393,15 +393,15 @@ private:
uint64_t HandleSyscall(SyscallHandler* Handler, FEXCore::Core::CpuStateFrame* Frame, FEXCore::HLE::SyscallArguments* Args);
#define SYSCALL_ERRNO() \
do { \
#define SYSCALL_ERRNO() \
do { \
if (Result == -1) return -errno; \
return Result; \
return Result; \
} while (0)
#define SYSCALL_ERRNO_NULL() \
do { \
#define SYSCALL_ERRNO_NULL() \
do { \
if (Result == 0) return -errno; \
return Result; \
return Result; \
} while (0)
extern FEX::HLE::SyscallHandler* _SyscallHandler;
@ -414,9 +414,9 @@ extern FEX::HLE::SyscallHandler* _SyscallHandler;
template<typename T>
struct ArgToFmtString;
#define ARG_TO_STR(tpy, str) \
template<> \
struct FEX::HLE::ArgToFmtString<tpy> { \
#define ARG_TO_STR(tpy, str) \
template<> \
struct FEX::HLE::ArgToFmtString<tpy> { \
inline static const char* const Format = str; \
};
@ -614,8 +614,8 @@ namespace FaultSafeMemcpy {
#define REGISTER_SYSCALL_IMPL_PASS_FLAGS(name, flags, lambda) REGISTER_SYSCALL_IMPL_INTERNAL(name, SYSCALL_DEF(name), flags, lambda)
#define REGISTER_SYSCALL_IMPL_INTERNAL(name, number, flags, lambda) \
do { \
#define REGISTER_SYSCALL_IMPL_INTERNAL(name, number, flags, lambda) \
do { \
FEX::HLE::x64::RegisterSyscall(Handler, FEX::HLE::x64::SYSCALL_x64_##name, (number), (flags), #name, (lambda)); \
FEX::HLE::x32::RegisterSyscall(Handler, FEX::HLE::x32::SYSCALL_x86_##name, (number), (flags), #name, (lambda)); \
} while (false)

View File

@ -13,10 +13,10 @@ $end_info$
#include <stdint.h>
#include <sys/epoll.h>
#define REGISTER_SYSCALL_NOT_IMPL(name) \
#define REGISTER_SYSCALL_NOT_IMPL(name) \
REGISTER_SYSCALL_IMPL(name, [](FEXCore::Core::CpuStateFrame* Frame) -> uint64_t { \
LogMan::Msg::DFmt("Using deprecated/removed syscall: " #name); \
return -ENOSYS; \
LogMan::Msg::DFmt("Using deprecated/removed syscall: " #name); \
return -ENOSYS; \
});
#define REGISTER_SYSCALL_NO_PERM(name) REGISTER_SYSCALL_IMPL(name, [](FEXCore::Core::CpuStateFrame* Frame) -> uint64_t { return -EPERM; });

View File

@ -15,10 +15,10 @@ $end_info$
#include <stdint.h>
#include <sys/types.h>
#define SYSCALL_STUB(name) \
do { \
#define SYSCALL_STUB(name) \
do { \
ERROR_AND_DIE_FMT("Syscall: " #name " stub!"); \
return -ENOSYS; \
return -ENOSYS; \
} while (0)
namespace FEXCore::Core {

View File

@ -10,14 +10,14 @@
#ifndef _BASIC_META
// Meta typedef variable in unnamed and matches upstream
// Use this for the super basic ioctl passthrough path
#define _BASIC_META(x) \
#define _BASIC_META(x) \
__attribute__((annotate("fex-match"))) \
__attribute__((annotate("ioctl-alias-x86_32-_" #x STRINGY1(__LINE__)))) typedef uint8_t STRINGY(_##x, __LINE__)[x];
#endif
#ifndef _BASIC_META_VAR
// This is similar to _BASIC_META except that it allows you to pass variadic arguments to the original ioctl definition
#define _BASIC_META_VAR(x, args...) \
#define _BASIC_META_VAR(x, args...) \
__attribute__((annotate("fex-match"))) \
__attribute__((annotate("ioctl-alias-x86_32-_" #x STRINGY1(__LINE__)))) typedef uint8_t STRINGY(_##x, __LINE__)[x(args)];
#endif
@ -27,8 +27,8 @@
// Generates a FEX_<name> version of the ioctl with custom ioctl definition
// eg: _CUSTOM_META(DRM_IOCTL_AMDGPU_GEM_METADATA, DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_METADATA, FEX::HLE::x32::AMDGPU::fex_drm_amdgpu_gem_metadata));
// Allows you to effectively pass in the original ioctl definition with custom type replacing the upstream type
#define _CUSTOM_META(name, ioctl_num) \
typedef uint8_t _meta_##name[name]; \
#define _CUSTOM_META(name, ioctl_num) \
typedef uint8_t _meta_##name[name]; \
__attribute__((annotate("ioctl-alias-x86_32-_meta_" #name))) typedef uint8_t _##name[ioctl_num]; \
constexpr static uint32_t FEX_##name = ioctl_num;
#endif
@ -36,8 +36,8 @@
#ifndef _CUSTOM_META_OFFSET
// Same as _CUSTOM_META but allows you to define multiple types from an offset
// Required to have an ioctl covering a range which some ioctls do
#define _CUSTOM_META_OFFSET(name, ioctl_num, offset) \
typedef uint8_t _meta_##name[ioctl_num + offset]; \
#define _CUSTOM_META_OFFSET(name, ioctl_num, offset) \
typedef uint8_t _meta_##name[ioctl_num + offset]; \
__attribute__((annotate("ioctl-alias-x86_32-_meta_" #name))) typedef uint8_t _##name[ioctl_num + offset]; \
constexpr static uint32_t FEX_##name = ioctl_num + offset;
#endif

View File

@ -379,16 +379,16 @@ namespace DRM {
}
uint32_t I915_Handler(int fd, uint32_t cmd, uint32_t args) {
#define SIMPLE(enum, type) \
case _IOC_NR(FEX_##enum): { \
#define SIMPLE(enum, type) \
case _IOC_NR(FEX_##enum): { \
I915::fex_##type* guest = reinterpret_cast<I915::fex_##type*>(args); \
type host = *guest; \
uint64_t Result = ::ioctl(fd, enum, &host); \
if (Result != -1) { \
*guest = host; \
} \
SYSCALL_ERRNO(); \
break; \
type host = *guest; \
uint64_t Result = ::ioctl(fd, enum, &host); \
if (Result != -1) { \
*guest = host; \
} \
SYSCALL_ERRNO(); \
break; \
}
@ -606,16 +606,16 @@ namespace DRM {
}
uint32_t Handler(int fd, uint32_t cmd, uint32_t args) {
#define SIMPLE(enum, type) \
case _IOC_NR(FEX_##enum): { \
#define SIMPLE(enum, type) \
case _IOC_NR(FEX_##enum): { \
DRM::fex_##type* guest = reinterpret_cast<DRM::fex_##type*>(args); \
type host = *guest; \
uint64_t Result = ::ioctl(fd, enum, &host); \
if (Result != -1) { \
*guest = host; \
} \
SYSCALL_ERRNO(); \
break; \
type host = *guest; \
uint64_t Result = ::ioctl(fd, enum, &host); \
if (Result != -1) { \
*guest = host; \
} \
SYSCALL_ERRNO(); \
break; \
}
switch (_IOC_NR(cmd)) {

View File

@ -16,10 +16,10 @@ struct CpuStateFrame;
}
namespace FEX::HLE::x32 {
#define REGISTER_SYSCALL_NOT_IMPL_X32(name) \
#define REGISTER_SYSCALL_NOT_IMPL_X32(name) \
REGISTER_SYSCALL_IMPL_X32(name, [](FEXCore::Core::CpuStateFrame* Frame) -> uint64_t { \
LogMan::Msg::DFmt("Using deprecated/removed syscall: " #name); \
return -ENOSYS; \
LogMan::Msg::DFmt("Using deprecated/removed syscall: " #name); \
return -ENOSYS; \
});
#define REGISTER_SYSCALL_NO_PERM_X32(name) \
REGISTER_SYSCALL_IMPL_X32(name, [](FEXCore::Core::CpuStateFrame* Frame) -> uint64_t { return -EPERM; });

View File

@ -14,10 +14,10 @@ $end_info$
#include <stdint.h>
#include <sys/types.h>
#define SYSCALL_STUB(name) \
do { \
#define SYSCALL_STUB(name) \
do { \
ERROR_AND_DIE_FMT("Syscall: " #name " stub!"); \
return -ENOSYS; \
return -ENOSYS; \
} while (0)
namespace FEXCore::Core {

View File

@ -124,7 +124,7 @@ void RegisterSyscall(SyscallHandler* _Handler, int num, int32_t HostSyscallNumbe
#define REGISTER_SYSCALL_IMPL_X32_PASS_MANUAL_FLAGS(name, hostname, flags, lambda) \
REGISTER_SYSCALL_IMPL_X32_INTERNAL(name, SYSCALL_DEF(hostname), flags, lambda)
#define REGISTER_SYSCALL_IMPL_X32_INTERNAL(name, number, flags, lambda) \
do { \
#define REGISTER_SYSCALL_IMPL_X32_INTERNAL(name, number, flags, lambda) \
do { \
FEX::HLE::x32::RegisterSyscall(Handler, x32::SYSCALL_x86_##name, number, flags, #name, lambda); \
} while (false)

View File

@ -10,14 +10,14 @@
#ifndef _BASIC_META
// Meta typedef variable in unnamed and matches upstream
// Use this for the super basic ioctl passthrough path
#define _BASIC_META(x) \
#define _BASIC_META(x) \
__attribute__((annotate("fex-match"))) \
__attribute__((annotate("ioctl-alias-x86_64-_" #x STRINGY1(__LINE__)))) typedef uint8_t STRINGY(_##x, __LINE__)[x];
#endif
#ifndef _BASIC_META_VAR
// This is similar to _BASIC_META except that it allows you to pass variadic arguments to the original ioctl definition
#define _BASIC_META_VAR(x, args...) \
#define _BASIC_META_VAR(x, args...) \
__attribute__((annotate("fex-match"))) \
__attribute__((annotate("ioctl-alias-x86_64-_" #x STRINGY1(__LINE__)))) typedef uint8_t STRINGY(_##x, __LINE__)[x(args)];
#endif
@ -27,8 +27,8 @@
// Generates a FEX_<name> version of the ioctl with custom ioctl definition
// eg: _CUSTOM_META(DRM_IOCTL_AMDGPU_GEM_METADATA, DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_METADATA, FEX::HLE::x64::AMDGPU::fex_drm_amdgpu_gem_metadata));
// Allows you to effectively pass in the original ioctl definition with custom type replacing the upstream type
#define _CUSTOM_META(name, ioctl_num) \
typedef uint8_t _meta_##name[name]; \
#define _CUSTOM_META(name, ioctl_num) \
typedef uint8_t _meta_##name[name]; \
__attribute__((annotate("ioctl-alias-x86_64-_meta_" #name))) typedef uint8_t _##name[ioctl_num]; \
constexpr static uint32_t FEX_##name = ioctl_num;
#endif
@ -38,8 +38,8 @@
// Generates a FEX_<name> version of the ioctl with custom ioctl definition
// eg: _CUSTOM_META(DRM_IOCTL_AMDGPU_GEM_METADATA, DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_METADATA, FEX::HLE::x64::AMDGPU::fex_drm_amdgpu_gem_metadata));
// Allows you to effectively pass in the original ioctl definition with custom type replacing the upstream type
#define _CUSTOM_META_MATCH(name, ioctl_num) \
typedef uint8_t _meta_##name[ioctl_num]; \
#define _CUSTOM_META_MATCH(name, ioctl_num) \
typedef uint8_t _meta_##name[ioctl_num]; \
__attribute__((annotate("fex-match"))) typedef uint8_t _##name[ioctl_num]; \
constexpr static uint32_t FEX_##name = ioctl_num;
#endif
@ -47,8 +47,8 @@
#ifndef _CUSTOM_META_OFFSET
// Same as _CUSTOM_META but allows you to define multiple types from an offset
// Required to have an ioctl covering a range which some ioctls do
#define _CUSTOM_META_OFFSET(name, ioctl_num, offset) \
typedef uint8_t _meta_##name[ioctl_num + offset]; \
#define _CUSTOM_META_OFFSET(name, ioctl_num, offset) \
typedef uint8_t _meta_##name[ioctl_num + offset]; \
__attribute__((annotate("ioctl-alias-x86_64-_meta_" #name))) typedef uint8_t _##name[ioctl_num + offset]; \
constexpr static uint32_t FEX_##name = ioctl_num + offset;
#endif

View File

@ -17,10 +17,10 @@ struct CpuStateFrame;
}
namespace FEX::HLE::x64 {
#define REGISTER_SYSCALL_NOT_IMPL_X64(name) \
#define REGISTER_SYSCALL_NOT_IMPL_X64(name) \
REGISTER_SYSCALL_IMPL_X64(name, [](FEXCore::Core::CpuStateFrame* Frame) -> uint64_t { \
LogMan::Msg::DFmt("Using deprecated/removed syscall: " #name); \
return -ENOSYS; \
LogMan::Msg::DFmt("Using deprecated/removed syscall: " #name); \
return -ENOSYS; \
});
#define REGISTER_SYSCALL_NO_PERM_X64(name) \
REGISTER_SYSCALL_IMPL_X64(name, [](FEXCore::Core::CpuStateFrame* Frame) -> uint64_t { return -EPERM; });

View File

@ -112,7 +112,7 @@ void RegisterSyscall(SyscallHandler* _Handler, int num, int32_t HostSyscallNumbe
#define REGISTER_SYSCALL_IMPL_X64_PASS_FLAGS(name, flags, lambda) REGISTER_SYSCALL_IMPL_X64_INTERNAL(name, SYSCALL_DEF(name), flags, lambda)
#define REGISTER_SYSCALL_IMPL_X64_INTERNAL(name, number, flags, lambda) \
do { \
#define REGISTER_SYSCALL_IMPL_X64_INTERNAL(name, number, flags, lambda) \
do { \
FEX::HLE::x64::RegisterSyscall(Handler, x64::SYSCALL_x64_##name, (number), (flags), #name, (lambda)); \
} while (false)

View File

@ -18,28 +18,28 @@ template<typename signature>
THUNK_ABI const int (*fexthunks_invoke_callback)(void*);
#ifndef _M_ARM_64
#define MAKE_THUNK(lib, name, hash) \
#define MAKE_THUNK(lib, name, hash) \
extern "C" __attribute__((visibility("hidden"))) THUNK_ABI int fexthunks_##lib##_##name(void* args); \
asm(".text\nfexthunks_" #lib "_" #name ":\n.byte 0xF, 0x3F\n.byte " hash);
#define MAKE_CALLBACK_THUNK(name, signature, hash) \
#define MAKE_CALLBACK_THUNK(name, signature, hash) \
extern "C" __attribute__((visibility("hidden"))) THUNK_ABI int fexthunks_##name(void* args); \
asm(".text\nfexthunks_" #name ":\n.byte 0xF, 0x3F\n.byte " hash); \
template<> \
asm(".text\nfexthunks_" #name ":\n.byte 0xF, 0x3F\n.byte " hash); \
template<> \
THUNK_ABI inline constexpr int (*fexthunks_invoke_callback<signature>)(void*) = fexthunks_##name;
#else
// We're compiling for IDE integration, so provide a dummy-implementation that just calls an undefined function.
// The name of that function serves as an error message if this library somehow gets loaded at runtime.
extern "C" void BROKEN_INSTALL___TRIED_LOADING_AARCH64_BUILD_OF_GUEST_THUNK();
#define MAKE_THUNK(lib, name, hash) \
extern "C" int fexthunks_##lib##_##name(void* args) { \
#define MAKE_THUNK(lib, name, hash) \
extern "C" int fexthunks_##lib##_##name(void* args) { \
BROKEN_INSTALL___TRIED_LOADING_AARCH64_BUILD_OF_GUEST_THUNK(); \
return 0; \
return 0; \
}
#define MAKE_CALLBACK_THUNK(name, signature, hash) \
extern "C" int fexthunks_##name(void* args); \
template<> \
extern "C" int fexthunks_##name(void* args); \
template<> \
inline constexpr int (*fexthunks_invoke_callback<signature>)(void*) = fexthunks_##name;
#endif
@ -73,11 +73,11 @@ MAKE_THUNK(fex, allocate_host_trampoline_for_guest_function,
"0x9b, 0xb2, 0xf4, 0xb4, 0x83, 0x7d, 0x28, 0x93, 0x40, 0xcb, 0xf4, 0x7a, 0x0b, 0x47, 0x85, 0x87, 0xf9, 0xbc, 0xb5, 0x27, 0xca, "
"0xa6, 0x93, 0xa5, 0xc0, 0x73, 0x27, 0x24, 0xae, 0xc8, 0xb8, 0x5a")
#define LOAD_LIB_BASE(name, init_fn) \
#define LOAD_LIB_BASE(name, init_fn) \
__attribute__((constructor)) static void loadlib() { \
LoadlibArgs args = {#name}; \
fexthunks_fex_loadlib(&args); \
if ((init_fn)) ((void (*)())init_fn)(); \
LoadlibArgs args = {#name}; \
fexthunks_fex_loadlib(&args); \
if ((init_fn)) ((void (*)())init_fn)(); \
}
#define LOAD_LIB(name) LOAD_LIB_BASE(name, nullptr)

View File

@ -53,19 +53,19 @@ struct ExportEntry {
typedef void fex_call_callback_t(uintptr_t callback, void* arg0, void* arg1);
#define EXPORTS(name) \
extern "C" { \
#define EXPORTS(name) \
extern "C" { \
ExportEntry* fexthunks_exports_##name() { \
if (!fexldr_init_##name()) { \
return nullptr; \
} \
return exports; \
} \
if (!fexldr_init_##name()) { \
return nullptr; \
} \
return exports; \
} \
}
#define LOAD_LIB_INIT(init_fn) \
#define LOAD_LIB_INIT(init_fn) \
__attribute__((constructor)) static void loadlib() { \
init_fn(); \
init_fn(); \
}
struct GuestcallInfo {

View File

@ -19,40 +19,40 @@ enum trapno {
};
#define CONCAT(x, y) x##y
#define TestSymbols(num) \
#define TestSymbols(num) \
extern "C" uint64_t CONCAT(TestBegin_, num); \
extern "C" uint64_t CONCAT(TestEnd_, num);
#define Test(num, asm, trapno, errno, si_code, signal) \
#define Test(num, asm, trapno, errno, si_code, signal) \
capturing_handler_skip = (unsigned long)&CONCAT(TestEnd_, num) - (unsigned long)&CONCAT(TestBegin_, num); \
const unsigned long EXPECTED_RIP = (unsigned long)&CONCAT(TestBegin_, num); \
const int EXPECTED_TRAPNO = trapno; \
const int EXPECTED_ERR = errno; \
const int EXPECTED_SI_CODE = si_code; \
const int EXPECTED_SIGNAL = signal; \
__asm volatile("TestBegin_" #num ":" asm ";" \
"TestEnd_" #num ":" :: \
const unsigned long EXPECTED_RIP = (unsigned long)&CONCAT(TestBegin_, num); \
const int EXPECTED_TRAPNO = trapno; \
const int EXPECTED_ERR = errno; \
const int EXPECTED_SI_CODE = si_code; \
const int EXPECTED_SIGNAL = signal; \
__asm volatile("TestBegin_" #num ":" asm ";" \
"TestEnd_" #num ":" :: \
: "memory");
#define TEST(num, name, asm, trapno, errno, _si_code, _signal) \
TestSymbols(num); \
TEST_CASE("Signals: " #name) { \
struct sigaction act {}; \
act.sa_sigaction = CapturingHandler; \
act.sa_flags = SA_SIGINFO; \
sigaction(SIGSEGV, &act, nullptr); \
sigaction(SIGTRAP, &act, nullptr); \
sigaction(SIGILL, &act, nullptr); \
\
Test(num, asm, trapno, errno, _si_code, _signal); \
\
REQUIRE(from_handler.has_value()); \
CHECK(from_handler->mctx.gregs[REG_RIP] == EXPECTED_RIP); \
#define TEST(num, name, asm, trapno, errno, _si_code, _signal) \
TestSymbols(num); \
TEST_CASE("Signals: " #name) { \
struct sigaction act {}; \
act.sa_sigaction = CapturingHandler; \
act.sa_flags = SA_SIGINFO; \
sigaction(SIGSEGV, &act, nullptr); \
sigaction(SIGTRAP, &act, nullptr); \
sigaction(SIGILL, &act, nullptr); \
\
Test(num, asm, trapno, errno, _si_code, _signal); \
\
REQUIRE(from_handler.has_value()); \
CHECK(from_handler->mctx.gregs[REG_RIP] == EXPECTED_RIP); \
CHECK(from_handler->mctx.gregs[REG_TRAPNO] == EXPECTED_TRAPNO); \
CHECK(from_handler->mctx.gregs[REG_ERR] == EXPECTED_ERR); \
CHECK(from_handler->si_code == EXPECTED_SI_CODE); \
CHECK(from_handler->signal == EXPECTED_SIGNAL); \
CHECK(from_handler->mctx.gregs[REG_ERR] == EXPECTED_ERR); \
CHECK(from_handler->si_code == EXPECTED_SI_CODE); \
CHECK(from_handler->signal == EXPECTED_SIGNAL); \
}
// Instructions that explicitly are supported but must only work in CPL-0

View File

@ -9,27 +9,27 @@
#include <linux/futex.h>
#if __SIZEOF_POINTER__ == 4
#define DO_ASM(x, y) \
#define DO_ASM(x, y) \
__asm volatile(x /* Need to late move syscall number since incoming asm will overwrite eax */ \
" mov eax, %[Syscall];" /* Notify we are ready (Without touching flags) */ \
"mov dword ptr [%[ReadyNotify]], 1;" /* Do a futex */ \
"int 0x80;" y \
: \
: [Syscall] "i"(SYS_futex), "b"(Futex), "c"(FUTEX_WAIT), "d"(0), "S"(0), [ReadyNotify] "r"(ReadyNotify) \
" mov eax, %[Syscall];" /* Notify we are ready (Without touching flags) */ \
"mov dword ptr [%[ReadyNotify]], 1;" /* Do a futex */ \
"int 0x80;" y \
: \
: [Syscall] "i"(SYS_futex), "b"(Futex), "c"(FUTEX_WAIT), "d"(0), "S"(0), [ReadyNotify] "r"(ReadyNotify) \
: "cc", "memory", "eax")
#else
#define DO_ASM(x, y) \
__asm volatile( \
x /* Do a futex */ \
" mov rax, %[Syscall];" \
" mov rdi, %[FutexAddr];" \
" mov rsi, %[FutexOp];" \
" mov rdx, %[ExpectedValue];" \
" mov r10, %[TimeoutAddr];" /* Notify we are ready (Without touching flags) */ \
"mov dword ptr [%[ReadyNotify]], 1;" \
"syscall;" y \
: \
#define DO_ASM(x, y) \
__asm volatile( \
x /* Do a futex */ \
" mov rax, %[Syscall];" \
" mov rdi, %[FutexAddr];" \
" mov rsi, %[FutexOp];" \
" mov rdx, %[ExpectedValue];" \
" mov r10, %[TimeoutAddr];" /* Notify we are ready (Without touching flags) */ \
"mov dword ptr [%[ReadyNotify]], 1;" \
"syscall;" y \
: \
: [Syscall] "i"(SYS_futex), [FutexAddr] "r"(Futex), [FutexOp] "i"(FUTEX_WAIT), [ExpectedValue] "i"(0), [TimeoutAddr] "i"(0), [ReadyNotify] "r"(ReadyNotify) \
: "cc", "memory", "rax", "rdi", "rsi", "rdx", "r10")
#endif

View File

@ -21,10 +21,10 @@ void key_dtor(void* ptr) {
}
#define handle_error_en(en, msg) \
do { \
errno = en; \
perror(msg); \
exit(EXIT_FAILURE); \
do { \
errno = en; \
perror(msg); \
exit(EXIT_FAILURE); \
} while (0)
static void* thread_func(void* ignored_argument) {