#ifndef GEODE_CORE_META_X86_HPP #define GEODE_CORE_META_X86_HPP #include "common.hpp" #include namespace geode::core::meta::x86 { // Logic needed by x86 calling conventions for stack fixing / filtering. template static constexpr bool sse_passable = any_of, float, double>; template static constexpr bool gpr_passable = ((sizeof(Class) <= sizeof(void*) && !std::is_class_v && !sse_passable) || std::is_member_function_pointer_v); template static inline constexpr std::array reorder_pack() { constexpr size_t length = sizeof...(Classes); constexpr bool should_reorder[] = { std::is_class_v && sizeof(Classes) > sizeof(void*)... }; std::array reordered = {}; size_t out = 0; // Non-reordered go first. for (size_t in = 0; in < length; ++in) { if (!should_reorder[in]) { reordered[out] = in; ++out; } } // Reordered go last. for (size_t in = 0; in < length; ++in) { if (should_reorder[in]) { reordered[out] = in; ++out; } } return reordered; } template static constexpr size_t stack_fix = (((sizeof(Stack) % sizeof(void*) == 0) ? sizeof(Stack) : sizeof(Stack) - (sizeof(Stack) % sizeof(void*)) + sizeof(void*)) + ...); template <> static constexpr size_t stack_fix<> = 0; template <> static constexpr size_t stack_fix = 0; template class Register { public: From raw; public: template explicit operator To() { static_assert( sizeof(From) >= sizeof(To), "Please report a bug to the Geode developers! This should never be reached.\n" "Size of Register is smaller than the size of the destination type!" ); union { From from; To to; } u; u.from = raw; return u.to; } }; // Ignore this for now, it's for discarding calling convention qualifier later. #if 0 template class remove_conv { public: using result = Func; }; // We all hate macros but I'd say this is a good use case. #define REMOVE_FOR(CC) \ template \ class remove_conv { \ public: \ using result = Ret (*)(Args...); \ }; \ \ template \ class remove_conv { \ public: \ using result = Ret (Parent::*)(Args...); \ } REMOVE_FOR(__cdecl); REMOVE_FOR(__stdcall); REMOVE_FOR(__thiscall); REMOVE_FOR(__fastcall); REMOVE_FOR(__vectorcall); #undef REMOVE_FOR #endif } #endif /* GEODE_CORE_META_X86_HPP */