Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 33 additions & 87 deletions cpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ inline bool IsVIA(const word32 output[4])

#if defined(__APPLE__)

#if defined(__POWERPC__)
// http://stackoverflow.com/questions/45637888/how-to-determine-armv8-features-at-runtime-on-ios
class AppleMachineInfo
{
Expand Down Expand Up @@ -226,31 +227,8 @@ class AppleMachineInfo
}
else if (machine.find("arm64") != std::string::npos)
{
// M1 machine?
std::string brand;
size_t size = 32;

// Supply an oversized buffer, and avoid
// an extra call to sysctlbyname.
brand.resize(size);
if (sysctlbyname("machdep.cpu.brand_string", &brand[0], &size, NULL, 0) == 0 && size > 0)
{
if (brand[size-1] == '\0')
size--;
brand.resize(size);
}

if (brand == "Apple M1")
{
m_device = Mac;
m_arch = ARMV82;
}
else
{
// ???
m_device = 0;
m_arch = ARMV8;
}
m_device = Mac;
m_arch = ARMV8;
}
else
{
Expand Down Expand Up @@ -303,50 +281,20 @@ void GetAppleMachineInfo(unsigned int& device, unsigned int& version, unsigned i
version = info.Version();
arch = info.Arch();
}

inline bool IsAppleMachineARM32()
{
static unsigned int arch;
if (arch == 0)
{
unsigned int unused;
GetAppleMachineInfo(unused, unused, arch);
}
return arch == AppleMachineInfo::ARM32;
}

inline bool IsAppleMachineARMv8()
{
static unsigned int arch;
if (arch == 0)
{
unsigned int unused;
GetAppleMachineInfo(unused, unused, arch);
}
return arch >= AppleMachineInfo::ARMV8;
}

inline bool IsAppleMachineARMv82()
#endif // __POWERPC__

#if defined(__aarch64__)
// Apple publishes one hw.optional sysctl per optional Armv8 extension.
// A missing key means the feature is absent or the OS predates the key,
// and both cases answer false. The FEAT_ names date from macOS 12 and
// iOS 15; the older armv8_ names are still published and cover macOS 11.
inline bool IsAppleFeaturePresent(const char* name)
{
static unsigned int arch;
if (arch == 0)
{
unsigned int unused;
GetAppleMachineInfo(unused, unused, arch);
}
return arch >= AppleMachineInfo::ARMV82;
}

inline bool IsAppleMachineARMv83()
{
static unsigned int arch;
if (arch == 0)
{
unsigned int unused;
GetAppleMachineInfo(unused, unused, arch);
}
return arch >= AppleMachineInfo::ARMV83;
int value = 0;
size_t size = sizeof(value);
return sysctlbyname(name, &value, &size, NULL, 0) == 0 && value != 0;
}
#endif // __aarch64__

#endif // __APPLE__

Expand Down Expand Up @@ -882,8 +830,7 @@ inline bool CPU_QueryNEON()
return true;
#elif defined(__APPLE__) && defined(__aarch64__)
// Core feature set for Aarch32 and Aarch64.
if (IsAppleMachineARMv8())
return true;
return true;
#elif defined(_WIN32) && defined(_M_ARM64)
// Windows 10 ARM64 is only supported on Armv8a and above
if (IsProcessorFeaturePresent(PF_ARM_V8_INSTRUCTIONS_AVAILABLE) != 0)
Expand All @@ -909,8 +856,7 @@ inline bool CPU_QueryCRC32()
if ((getauxval(AT_HWCAP2) & HWCAP2_CRC32) != 0)
return true;
#elif defined(__APPLE__) && defined(__aarch64__)
// M1 processor
if (IsAppleMachineARMv82())
if (IsAppleFeaturePresent("hw.optional.armv8_crc32"))
return true;
#elif defined(_WIN32) && defined(_M_ARM64)
if (IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE) != 0)
Expand All @@ -936,9 +882,9 @@ inline bool CPU_QueryPMULL()
if ((getauxval(AT_HWCAP2) & HWCAP2_PMULL) != 0)
return true;
#elif defined(__APPLE__) && defined(__aarch64__)
// M1 processor
if (IsAppleMachineARMv82())
return true;
// Present on every 64-bit Apple core; see the Apple entries in
// LLVM's AArch64Processors.td.
return true;
#elif defined(_WIN32) && defined(_M_ARM64)
if (IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) != 0)
return true;
Expand All @@ -963,9 +909,9 @@ inline bool CPU_QueryAES()
if ((getauxval(AT_HWCAP2) & HWCAP2_AES) != 0)
return true;
#elif defined(__APPLE__) && defined(__aarch64__)
// M1 processor
if (IsAppleMachineARMv82())
return true;
// Present on every 64-bit Apple core; see the Apple entries in
// LLVM's AArch64Processors.td.
return true;
#elif defined(_WIN32) && defined(_M_ARM64)
if (IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) != 0)
return true;
Expand All @@ -990,9 +936,9 @@ inline bool CPU_QuerySHA1()
if ((getauxval(AT_HWCAP2) & HWCAP2_SHA1) != 0)
return true;
#elif defined(__APPLE__) && defined(__aarch64__)
// M1 processor
if (IsAppleMachineARMv82())
return true;
// Present on every 64-bit Apple core; see the Apple entries in
// LLVM's AArch64Processors.td.
return true;
#elif defined(_WIN32) && defined(_M_ARM64)
if (IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) != 0)
return true;
Expand All @@ -1017,9 +963,9 @@ inline bool CPU_QuerySHA256()
if ((getauxval(AT_HWCAP2) & HWCAP2_SHA2) != 0)
return true;
#elif defined(__APPLE__) && defined(__aarch64__)
// M1 processor
if (IsAppleMachineARMv82())
return true;
// Present on every 64-bit Apple core; see the Apple entries in
// LLVM's AArch64Processors.td.
return true;
#elif defined(_WIN32) && defined(_M_ARM64)
if (IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) != 0)
return true;
Expand Down Expand Up @@ -1051,8 +997,8 @@ inline bool CPU_QuerySHA3()
if ((getauxval(AT_HWCAP2) & HWCAP2_SHA3) != 0)
return true;
#elif defined(__APPLE__) && defined(__aarch64__)
// M1 processor
if (IsAppleMachineARMv82())
if (IsAppleFeaturePresent("hw.optional.arm.FEAT_SHA3") ||
IsAppleFeaturePresent("hw.optional.armv8_2_sha3"))
return true;
#endif
return false;
Expand Down Expand Up @@ -1082,8 +1028,8 @@ inline bool CPU_QuerySHA512()
if ((getauxval(AT_HWCAP2) & HWCAP2_SHA512) != 0)
return true;
#elif defined(__APPLE__) && defined(__aarch64__)
// M1 processor
if (IsAppleMachineARMv82())
if (IsAppleFeaturePresent("hw.optional.arm.FEAT_SHA512") ||
IsAppleFeaturePresent("hw.optional.armv8_2_sha512"))
return true;
#endif
return false;
Expand Down
Loading