cog/Frameworks/OpenMPT/OpenMPT/common/mptCPU.h

124 lines
2.5 KiB
C++

/*
* mptCPU.h
* --------
* Purpose: CPU feature detection.
* Notes : (currently none)
* Authors: OpenMPT Devs
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
*/
#pragma once
#include "openmpt/all/BuildSettings.hpp"
#include "mpt/base/macros.hpp"
#ifdef MPT_ENABLE_ARCH_INTRINSICS
#include "mpt/arch/arch.hpp"
#endif
OPENMPT_NAMESPACE_BEGIN
namespace CPU
{
#ifdef MPT_ENABLE_ARCH_INTRINSICS
#if defined(MODPLUG_TRACKER) && !defined(MPT_BUILD_WINESUPPORT)
namespace detail
{
inline MPT_CONSTINIT mpt::arch::current::feature_flags EnabledFeatures;
inline MPT_CONSTINIT mpt::arch::current::mode_flags EnabledModes;
} // namespace detail
inline void EnableAvailableFeatures() noexcept
{
CPU::detail::EnabledFeatures = mpt::arch::get_cpu_info().get_features();
CPU::detail::EnabledModes = mpt::arch::get_cpu_info().get_modes();
}
// enabled processor features for inline asm and intrinsics
[[nodiscard]] MPT_FORCEINLINE mpt::arch::current::feature_flags GetEnabledFeatures() noexcept
{
return CPU::detail::EnabledFeatures;
}
[[nodiscard]] MPT_FORCEINLINE mpt::arch::current::mode_flags GetEnabledModes() noexcept
{
return CPU::detail::EnabledModes;
}
struct Info
{
[[nodiscard]] MPT_FORCEINLINE bool HasFeatureSet(mpt::arch::current::feature_flags features) const noexcept
{
return features == (GetEnabledFeatures() & features);
}
[[nodiscard]] MPT_FORCEINLINE bool HasModesEnabled(mpt::arch::current::mode_flags modes) const noexcept
{
return modes == (GetEnabledModes() & modes);
}
};
#else // !MODPLUG_TRACKER
struct Info
{
private:
const mpt::arch::flags_cache m_flags{mpt::arch::get_cpu_info()};
public:
[[nodiscard]] MPT_FORCEINLINE bool HasFeatureSet(mpt::arch::current::feature_flags features) const noexcept
{
return m_flags[features];
}
[[nodiscard]] MPT_FORCEINLINE bool HasModesEnabled(mpt::arch::current::mode_flags modes) const noexcept
{
return m_flags[modes];
}
};
#endif // MODPLUG_TRACKER
// legacy interface
namespace feature = mpt::arch::current::feature;
namespace mode = mpt::arch::current::mode;
[[nodiscard]] MPT_FORCEINLINE bool HasFeatureSet(mpt::arch::current::feature_flags features) noexcept
{
return CPU::Info{}.HasFeatureSet(features);
}
[[nodiscard]] MPT_FORCEINLINE bool HasModesEnabled(mpt::arch::current::mode_flags modes) noexcept
{
return CPU::Info{}.HasModesEnabled(modes);
}
#endif // MPT_ENABLE_ARCH_INTRINSICS
} // namespace CPU
OPENMPT_NAMESPACE_END