21#include <winpr/config.h>
23#include <winpr/assert.h>
24#include <winpr/sysinfo.h>
25#include <winpr/platform.h>
28#include "cpufeatures/cpu-features.h"
38#if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 199309L)
40#elif !defined(__APPLE__)
42#include <sys/sysinfo.h>
47#define TAG WINPR_TAG("sysinfo")
49#define FILETIME_TO_UNIX_OFFSET_S 11644473600UL
51#if defined(__MACH__) && defined(__APPLE__)
53#include <mach/mach_time.h>
55static UINT64 scaleHighPrecision(UINT64 i, UINT32 numer, UINT32 denom)
57 UINT64 high = (i >> 32) * numer;
58 UINT64 low = (i & 0xffffffffull) * numer / denom;
59 UINT64 highRem = ((high % denom) << 32) / denom;
61 return (high << 32) + highRem + low;
64static UINT64 mac_get_time_ns(
void)
66 mach_timebase_info_data_t timebase = WINPR_C_ARRAY_INIT;
67 mach_timebase_info(&timebase);
68 UINT64 t = mach_absolute_time();
69 return scaleHighPrecision(t, timebase.numer, timebase.denom);
99#ifdef WINPR_HAVE_UNISTD_H
103#include <winpr/crt.h>
104#include <winpr/platform.h>
106#if defined(__MACOSX__) || defined(__IOS__)
107#include <sys/sysctl.h>
110static WORD GetProcessorArchitecture(
void)
112 WORD cpuArch = PROCESSOR_ARCHITECTURE_UNKNOWN;
114 AndroidCpuFamily family = android_getCpuFamily();
118 case ANDROID_CPU_FAMILY_ARM:
119 return PROCESSOR_ARCHITECTURE_ARM;
121 case ANDROID_CPU_FAMILY_X86:
122 return PROCESSOR_ARCHITECTURE_INTEL;
124 case ANDROID_CPU_FAMILY_MIPS:
125 return PROCESSOR_ARCHITECTURE_MIPS;
127 case ANDROID_CPU_FAMILY_ARM64:
128 return PROCESSOR_ARCHITECTURE_ARM64;
130 case ANDROID_CPU_FAMILY_X86_64:
131 return PROCESSOR_ARCHITECTURE_AMD64;
133 case ANDROID_CPU_FAMILY_MIPS64:
134 return PROCESSOR_ARCHITECTURE_MIPS64;
137 return PROCESSOR_ARCHITECTURE_UNKNOWN;
139#elif defined(__MACOSX__) || defined(__IOS__)
141 size_t len =
sizeof(val);
143 const int rc = sysctlbyname(
"hw.cputype", &val, &len,
nullptr, 0);
145 return PROCESSOR_ARCHITECTURE_UNKNOWN;
150 return PROCESSOR_ARCHITECTURE_INTEL;
151 case CPU_TYPE_X86_64:
152 return PROCESSOR_ARCHITECTURE_AMD64;
154 return PROCESSOR_ARCHITECTURE_ARM;
156 return PROCESSOR_ARCHITECTURE_ARM64;
157 case CPU_TYPE_ARM64_32:
158 return PROCESSOR_ARCHITECTURE_ARM;
160 return PROCESSOR_ARCHITECTURE_UNKNOWN;
164 cpuArch = PROCESSOR_ARCHITECTURE_ARM;
165#elif defined(_M_IX86)
166 cpuArch = PROCESSOR_ARCHITECTURE_INTEL;
167#elif defined(_M_MIPS64)
169 cpuArch = PROCESSOR_ARCHITECTURE_MIPS64;
170#elif defined(_M_MIPS)
171 cpuArch = PROCESSOR_ARCHITECTURE_MIPS;
172#elif defined(_M_ARM64)
173 cpuArch = PROCESSOR_ARCHITECTURE_ARM64;
174#elif defined(_M_AMD64)
175 cpuArch = PROCESSOR_ARCHITECTURE_AMD64;
177 cpuArch = PROCESSOR_ARCHITECTURE_PPC;
178#elif defined(_M_ALPHA)
179 cpuArch = PROCESSOR_ARCHITECTURE_ALPHA;
181 cpuArch = PROCESSOR_ARCHITECTURE_E2K;
186static DWORD GetNumberOfProcessors(
void)
190 return android_getCpuCount();
191#elif defined(__MACOSX__) || defined(__IOS__)
193 size_t len =
sizeof(val);
194 const int rc = sysctlbyname(
"hw.logicalcpu", &val, &len,
nullptr, 0);
196 numCPUs = WINPR_ASSERTING_INT_CAST(DWORD, val);
198 numCPUs = (DWORD)mpctl(MPC_GETNUMSPUS,
nullptr,
nullptr);
200 numCPUs = (DWORD)sysconf(_SC_NPROC_ONLN);
201#elif defined(_SC_NPROCESSORS_ONLN)
202 numCPUs = (DWORD)sysconf(_SC_NPROCESSORS_ONLN);
207static DWORD GetSystemPageSize(
void)
209 DWORD dwPageSize = 0;
210 long sc_page_size = -1;
211#if defined(_SC_PAGESIZE)
213 if (sc_page_size < 0)
214 sc_page_size = sysconf(_SC_PAGESIZE);
217#if defined(_SC_PAGE_SIZE)
219 if (sc_page_size < 0)
220 sc_page_size = sysconf(_SC_PAGE_SIZE);
224 if (sc_page_size > 0)
225 dwPageSize = (DWORD)sc_page_size;
227 if (dwPageSize < 4096)
236 WINPR_ASSERT(lpSystemInfo);
238 *lpSystemInfo = empty;
239 lpSystemInfo->DUMMYUNIONNAME.DUMMYSTRUCTNAME.wProcessorArchitecture =
240 GetProcessorArchitecture();
241 lpSystemInfo->dwPageSize = GetSystemPageSize();
242 lpSystemInfo->dwNumberOfProcessors = GetNumberOfProcessors();
247 GetSystemInfo(lpSystemInfo);
250void GetSystemTime(LPSYSTEMTIME lpSystemTime)
254 struct tm* stm =
nullptr;
255 WORD wMilliseconds = 0;
256 UINT64 now = winpr_GetUnixTimeNS();
257 ct = WINPR_TIME_NS_TO_S(now);
258 wMilliseconds = (WORD)(WINPR_TIME_NS_REM_MS(now));
259 stm = gmtime_r(&ct, &tres);
264 lpSystemTime->wYear = (WORD)(stm->tm_year + 1900);
265 lpSystemTime->wMonth = (WORD)(stm->tm_mon + 1);
266 lpSystemTime->wDayOfWeek = (WORD)stm->tm_wday;
267 lpSystemTime->wDay = (WORD)stm->tm_mday;
268 lpSystemTime->wHour = (WORD)stm->tm_hour;
269 lpSystemTime->wMinute = (WORD)stm->tm_min;
270 lpSystemTime->wSecond = (WORD)stm->tm_sec;
271 lpSystemTime->wMilliseconds = wMilliseconds;
275BOOL SetSystemTime(WINPR_ATTR_UNUSED CONST
SYSTEMTIME* lpSystemTime)
278 WLog_ERR(
"TODO",
"TODO: Implement");
282VOID GetLocalTime(LPSYSTEMTIME lpSystemTime)
286 struct tm* ltm =
nullptr;
287 WORD wMilliseconds = 0;
288 UINT64 now = winpr_GetUnixTimeNS();
289 ct = WINPR_TIME_NS_TO_S(now);
290 wMilliseconds = (WORD)(WINPR_TIME_NS_REM_MS(now));
291 ltm = localtime_r(&ct, &tres);
296 lpSystemTime->wYear = (WORD)(ltm->tm_year + 1900);
297 lpSystemTime->wMonth = (WORD)(ltm->tm_mon + 1);
298 lpSystemTime->wDayOfWeek = (WORD)ltm->tm_wday;
299 lpSystemTime->wDay = (WORD)ltm->tm_mday;
300 lpSystemTime->wHour = (WORD)ltm->tm_hour;
301 lpSystemTime->wMinute = (WORD)ltm->tm_min;
302 lpSystemTime->wSecond = (WORD)ltm->tm_sec;
303 lpSystemTime->wMilliseconds = wMilliseconds;
307BOOL SetLocalTime(WINPR_ATTR_UNUSED CONST
SYSTEMTIME* lpSystemTime)
310 WLog_ERR(
"TODO",
"TODO: Implement");
314VOID GetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime)
322 t.u64 = (winpr_GetUnixTimeNS() / 100ull) + FILETIME_TO_UNIX_OFFSET_S * 10000000ull;
323 *lpSystemTimeAsFileTime = t.ft;
326BOOL GetSystemTimeAdjustment(WINPR_ATTR_UNUSED PDWORD lpTimeAdjustment,
327 WINPR_ATTR_UNUSED PDWORD lpTimeIncrement,
328 WINPR_ATTR_UNUSED PBOOL lpTimeAdjustmentDisabled)
331 WLog_ERR(
"TODO",
"TODO: Implement");
335#ifdef CLOCK_MONOTONIC_RAW
336#define CLOCK_ID CLOCK_MONOTONIC_RAW
338#define CLOCK_ID CLOCK_MONOTONIC
341DWORD GetTickCount(
void)
343 return (DWORD)GetTickCount64();
347#if !defined(_WIN32) || defined(_UWP)
349#if defined(WITH_WINPR_DEPRECATED)
354BOOL GetVersionExA(LPOSVERSIONINFOA lpVersionInformation)
359 if ((lpVersionInformation->dwOSVersionInfoSize ==
sizeof(OSVERSIONINFOA)) ||
360 (lpVersionInformation->dwOSVersionInfoSize ==
sizeof(OSVERSIONINFOEXA)))
362 lpVersionInformation->dwMajorVersion = 10;
363 lpVersionInformation->dwMinorVersion = 0;
364 lpVersionInformation->dwBuildNumber = 0;
365 lpVersionInformation->dwPlatformId = VER_PLATFORM_WIN32_NT;
366 ZeroMemory(lpVersionInformation->szCSDVersion,
sizeof(lpVersionInformation->szCSDVersion));
368 if (lpVersionInformation->dwOSVersionInfoSize ==
sizeof(OSVERSIONINFOEXA))
370 LPOSVERSIONINFOEXA lpVersionInformationEx = (LPOSVERSIONINFOEXA)lpVersionInformation;
371 lpVersionInformationEx->wServicePackMajor = 0;
372 lpVersionInformationEx->wServicePackMinor = 0;
373 lpVersionInformationEx->wSuiteMask = 0;
374 lpVersionInformationEx->wProductType = VER_NT_WORKSTATION;
375 lpVersionInformationEx->wReserved = 0;
384 if ((lpVersionInformation->dwOSVersionInfoSize ==
sizeof(OSVERSIONINFOA)) ||
385 (lpVersionInformation->dwOSVersionInfoSize ==
sizeof(OSVERSIONINFOEXA)))
387 lpVersionInformation->dwMajorVersion = 6;
388 lpVersionInformation->dwMinorVersion = 1;
389 lpVersionInformation->dwBuildNumber = 7601;
390 lpVersionInformation->dwPlatformId = VER_PLATFORM_WIN32_NT;
391 ZeroMemory(lpVersionInformation->szCSDVersion,
sizeof(lpVersionInformation->szCSDVersion));
393 if (lpVersionInformation->dwOSVersionInfoSize ==
sizeof(OSVERSIONINFOEXA))
395 LPOSVERSIONINFOEXA lpVersionInformationEx = (LPOSVERSIONINFOEXA)lpVersionInformation;
396 lpVersionInformationEx->wServicePackMajor = 1;
397 lpVersionInformationEx->wServicePackMinor = 0;
398 lpVersionInformationEx->wSuiteMask = 0;
399 lpVersionInformationEx->wProductType = VER_NT_WORKSTATION;
400 lpVersionInformationEx->wReserved = 0;
410BOOL GetVersionExW(LPOSVERSIONINFOW lpVersionInformation)
412 ZeroMemory(lpVersionInformation->szCSDVersion,
sizeof(lpVersionInformation->szCSDVersion));
413 return GetVersionExA((LPOSVERSIONINFOA)lpVersionInformation);
420#if !defined(_WIN32) || defined(_UWP)
422BOOL GetComputerNameW(LPWSTR lpBuffer, LPDWORD lpnSize)
425 LPSTR buffer =
nullptr;
426 if (!lpnSize || (*lpnSize > INT_MAX))
431 buffer = malloc(*lpnSize);
435 rc = GetComputerNameA(buffer, lpnSize);
437 if (rc && (*lpnSize > 0))
439 const SSIZE_T res = ConvertUtf8NToWChar(buffer, *lpnSize, lpBuffer, *lpnSize);
448BOOL GetComputerNameA(LPSTR lpBuffer, LPDWORD lpnSize)
452 SetLastError(ERROR_BAD_ARGUMENTS);
456 char hostname[256 + 1] = WINPR_C_ARRAY_INIT;
457 if (gethostname(hostname, ARRAYSIZE(hostname) - 1) == -1)
460 size_t length = strnlen(hostname, MAX_COMPUTERNAME_LENGTH);
461 const char* dot = strchr(hostname,
'.');
464 const size_t dotlen = WINPR_ASSERTING_INT_CAST(
size_t, (dot - hostname));
469 if ((*lpnSize <= (DWORD)length) || !lpBuffer)
471 SetLastError(ERROR_BUFFER_OVERFLOW);
472 *lpnSize = (DWORD)(length + 1);
476 strncpy(lpBuffer, hostname, length);
477 lpBuffer[length] =
'\0';
478 *lpnSize = (DWORD)length;
482BOOL GetComputerNameExA(COMPUTER_NAME_FORMAT NameType, LPSTR lpBuffer, LPDWORD lpnSize)
485 char hostname[256] = WINPR_C_ARRAY_INIT;
489 SetLastError(ERROR_BAD_ARGUMENTS);
493 if ((NameType == ComputerNameNetBIOS) || (NameType == ComputerNamePhysicalNetBIOS))
495 BOOL rc = GetComputerNameA(lpBuffer, lpnSize);
499 if (GetLastError() == ERROR_BUFFER_OVERFLOW)
500 SetLastError(ERROR_MORE_DATA);
506 if (gethostname(hostname,
sizeof(hostname)) == -1)
509 length = strnlen(hostname,
sizeof(hostname));
513 case ComputerNameDnsHostname:
514 case ComputerNameDnsDomain:
515 case ComputerNameDnsFullyQualified:
516 case ComputerNamePhysicalDnsHostname:
517 case ComputerNamePhysicalDnsDomain:
518 case ComputerNamePhysicalDnsFullyQualified:
519 if ((*lpnSize <= (DWORD)length) || !lpBuffer)
521 *lpnSize = (DWORD)(length + 1);
522 SetLastError(ERROR_MORE_DATA);
526 CopyMemory(lpBuffer, hostname, length);
527 lpBuffer[length] =
'\0';
528 *lpnSize = (DWORD)length;
538BOOL GetComputerNameExW(COMPUTER_NAME_FORMAT NameType, LPWSTR lpBuffer, LPDWORD lpnSize)
541 LPSTR lpABuffer =
nullptr;
545 SetLastError(ERROR_BAD_ARGUMENTS);
551 lpABuffer = calloc(*lpnSize,
sizeof(CHAR));
557 rc = GetComputerNameExA(NameType, lpABuffer, lpnSize);
559 if (rc && (*lpnSize > 0))
561 const SSIZE_T res = ConvertUtf8NToWChar(lpABuffer, *lpnSize, lpBuffer, *lpnSize);
573DWORD GetTickCount(
void)
575 return (DWORD)GetTickCount64();
580#if (!defined(_WIN32)) || (defined(_WIN32) && (_WIN32_WINNT < 0x0600))
582ULONGLONG winpr_GetTickCount64(
void)
584 const UINT64 ns = winpr_GetTickCount64NS();
585 return WINPR_TIME_NS_TO_MS(ns);
590UINT64 winpr_GetTickCount64NS(
void)
593#if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 199309L)
594 struct timespec ts = WINPR_C_ARRAY_INIT;
596 if (clock_gettime(CLOCK_ID, &ts) == 0)
597 ticks = (WINPR_ASSERTING_INT_CAST(uint64_t, ts.tv_sec) * 1000000000ull) +
598 WINPR_ASSERTING_INT_CAST(uint64_t, ts.tv_nsec);
599#elif defined(__MACH__) && defined(__APPLE__)
600 ticks = mac_get_time_ns();
604 if (QueryPerformanceFrequency(&freq) && QueryPerformanceCounter(&li))
605 ticks = li.QuadPart * 1000000000ull / freq.QuadPart;
607 struct timeval tv = WINPR_C_ARRAY_INIT;
609 if (gettimeofday(&tv,
nullptr) == 0)
610 ticks = (tv.tv_sec * 1000000000ull) + (tv.tv_usec * 1000ull);
619 static UINT64 first = 0;
620 static UINT64 uptime = 0;
623 struct sysinfo info = WINPR_C_ARRAY_INIT;
624 if (sysinfo(&info) == 0)
627 uptime = 1000000000ull * info.uptime;
631 ticks = ticks - first + uptime;
636UINT64 winpr_GetUnixTimeNS(
void)
644 } t = WINPR_C_ARRAY_INIT;
645 GetSystemTimeAsFileTime(&t.ft);
646 return (t.u64 - FILETIME_TO_UNIX_OFFSET_S * 10000000ull) * 100ull;
647#elif defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 199309L)
648 struct timespec ts = WINPR_C_ARRAY_INIT;
649 if (clock_gettime(CLOCK_REALTIME, &ts) != 0)
651 return WINPR_ASSERTING_INT_CAST(uint64_t, ts.tv_sec) * 1000000000ull +
652 WINPR_ASSERTING_INT_CAST(uint64_t, ts.tv_nsec);
654 struct timeval tv = WINPR_C_ARRAY_INIT;
655 if (gettimeofday(&tv,
nullptr) != 0)
657 return tv.tv_sec * 1000000000ULL + tv.tv_usec * 1000ull;
665#define xgetbv(_func_, _lo_, _hi_) \
666 __asm__ __volatile__("xgetbv" : "=a"(_lo_), "=d"(_hi_) : "c"(_func_))
667#elif defined(_MSC_VER)
668#define xgetbv(_func_, _lo_, _hi_) \
670 unsigned __int64 val = _xgetbv(_func_); \
671 _lo_ = val & 0xFFFFFFFF; \
672 _hi_ = (val >> 32); \
676#define B_BIT_AVX2 (1 << 5)
677#define B_BIT_AVX512F (1 << 16)
678#define D_BIT_MMX (1 << 23)
679#define D_BIT_SSE (1 << 25)
680#define D_BIT_SSE2 (1 << 26)
681#define D_BIT_3DN (1 << 30)
683#define C_BIT_PCLMULQDQ (1 << 1)
684#define C81_BIT_LZCNT (1 << 5)
686#define C_BIT_3DNP (1 << 8)
687#define C_BIT_SSSE3 (1 << 9)
688#define C_BIT_SSE41 (1 << 19)
689#define C_BIT_SSE42 (1 << 20)
690#define C_BIT_FMA (1 << 12)
691#define C_BIT_AES (1 << 25)
692#define C_BIT_XGETBV (1 << 27)
693#define C_BIT_AVX (1 << 28)
694#define E_BIT_XMM (1 << 1)
695#define E_BIT_YMM (1 << 2)
696#define E_BITS_AVX (E_BIT_XMM | E_BIT_YMM)
698static void cpuid(
unsigned info,
unsigned* eax,
unsigned* ebx,
unsigned* ecx,
unsigned* edx)
701 *eax = *ebx = *ecx = *edx = 0;
715 :
"=a"(*eax),
"=S"(*ebx),
"=c"(*ecx),
"=d"(*edx)
716 :
"a"(info),
"c"(0));
717#elif defined(_MSC_VER)
726#elif defined(_M_ARM) || defined(_M_ARM64)
727#if defined(__linux__)
729#define HWCAP_SWP (1 << 0)
730#define HWCAP_HALF (1 << 1)
731#define HWCAP_THUMB (1 << 2)
732#define HWCAP_26BIT (1 << 3)
733#define HWCAP_FAST_MULT (1 << 4)
734#define HWCAP_FPA (1 << 5)
735#define HWCAP_VFP (1 << 6)
736#define HWCAP_EDSP (1 << 7)
737#define HWCAP_JAVA (1 << 8)
738#define HWCAP_IWMMXT (1 << 9)
739#define HWCAP_CRUNCH (1 << 10)
740#define HWCAP_THUMBEE (1 << 11)
741#define HWCAP_NEON (1 << 12)
742#define HWCAP_VFPv3 (1 << 13)
743#define HWCAP_VFPv3D16 (1 << 14)
744#define HWCAP_TLS (1 << 15)
745#define HWCAP_VFPv4 (1 << 16)
746#define HWCAP_IDIVA (1 << 17)
747#define HWCAP_IDIVT (1 << 18)
748#define HWCAP_VFPD32 (1 << 19)
749#define HWCAP_IDIV (HWCAP_IDIVA | HWCAP_IDIVT)
754static unsigned GetARMCPUCaps(
void)
757 int fd = open(
"/proc/self/auxv", O_RDONLY);
771 num = read(fd, (
char*)&auxvec,
sizeof(auxvec));
773 if (num < 1 || (auxvec.a_type == 0 && auxvec.a_val == 0))
776 if (auxvec.a_type == AT_HWCAP)
791#if defined(_M_ARM) || defined(_M_ARM64)
797BOOL IsProcessorFeaturePresent(DWORD ProcessorFeature)
801 const uint64_t features = android_getCpuFeatures();
802 const AndroidCpuFamily family = android_getCpuFamily();
803 const BOOL isArm = (family == ANDROID_CPU_FAMILY_ARM) || (family == ANDROID_CPU_FAMILY_ARM64);
804 const BOOL isX86 = (family == ANDROID_CPU_FAMILY_X86) || (family == ANDROID_CPU_FAMILY_X86_64);
808 switch (ProcessorFeature)
810 case PF_MMX_INSTRUCTIONS_AVAILABLE:
811 case PF_XMMI_INSTRUCTIONS_AVAILABLE:
812 case PF_XMMI64_INSTRUCTIONS_AVAILABLE:
813 case PF_3DNOW_INSTRUCTIONS_AVAILABLE:
814 case PF_SSE3_INSTRUCTIONS_AVAILABLE:
816 case PF_SSSE3_INSTRUCTIONS_AVAILABLE:
817 return features & ANDROID_CPU_X86_FEATURE_SSSE3;
818 case PF_SSE4_1_INSTRUCTIONS_AVAILABLE:
819 return features & ANDROID_CPU_X86_FEATURE_SSE4_1;
820 case PF_SSE4_2_INSTRUCTIONS_AVAILABLE:
821 return features & ANDROID_CPU_X86_FEATURE_SSE4_2;
822 case PF_AVX_INSTRUCTIONS_AVAILABLE:
823 return features & ANDROID_CPU_X86_FEATURE_AVX;
824 case PF_AVX2_INSTRUCTIONS_AVAILABLE:
825 return features & ANDROID_CPU_X86_FEATURE_AVX2;
826 case PF_AVX512F_INSTRUCTIONS_AVAILABLE:
828 WLog_WARN(TAG,
"feature 0x%08" PRIx32
" check not implemented", ProcessorFeature);
835 switch (ProcessorFeature)
837 case PF_ARM_NEON_INSTRUCTIONS_AVAILABLE:
839 return features & ANDROID_CPU_ARM_FEATURE_NEON;
842 WLog_WARN(TAG,
"feature 0x%08" PRIx32
" check not implemented", ProcessorFeature);
847 WLog_WARN(TAG,
"Unsupported Android CPU family 0x%08" PRIx32, family);
850#elif defined(_M_ARM) || defined(_M_ARM64)
852 const unsigned long caps = getauxval(AT_HWCAP);
854 switch (ProcessorFeature)
856 case PF_ARM_NEON_INSTRUCTIONS_AVAILABLE:
859 if (caps & HWCAP_NEON)
865 if (caps & HWCAP_THUMB)
868 case PF_ARM_VFP_32_REGISTERS_AVAILABLE:
869 if (caps & HWCAP_VFPD32)
872 case PF_ARM_DIVIDE_INSTRUCTION_AVAILABLE:
873 if ((caps & HWCAP_IDIVA) || (caps & HWCAP_IDIVT))
877 if (caps & HWCAP_VFPv3)
883 if (caps & HWCAP_JAVA)
889 if (caps & HWCAP_EDSP)
895 if (caps & HWCAP_EDSP)
901 if ((caps & HWCAP_IDIVT) || (caps & HWCAP_VFPv4))
907 if (caps & HWCAP_THUMBEE)
912 case PF_ARM_INTEL_WMMX:
913 if (caps & HWCAP_IWMMXT)
917 case PF_MMX_INSTRUCTIONS_AVAILABLE:
918 case PF_XMMI_INSTRUCTIONS_AVAILABLE:
919 case PF_XMMI64_INSTRUCTIONS_AVAILABLE:
920 case PF_3DNOW_INSTRUCTIONS_AVAILABLE:
921 case PF_SSE3_INSTRUCTIONS_AVAILABLE:
922 case PF_SSSE3_INSTRUCTIONS_AVAILABLE:
923 case PF_SSE4_1_INSTRUCTIONS_AVAILABLE:
924 case PF_SSE4_2_INSTRUCTIONS_AVAILABLE:
925 case PF_AVX_INSTRUCTIONS_AVAILABLE:
926 case PF_AVX2_INSTRUCTIONS_AVAILABLE:
927 case PF_AVX512F_INSTRUCTIONS_AVAILABLE:
930 case PF_ARM_V8_INSTRUCTIONS_AVAILABLE:
931 case PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE:
932 case PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE:
933 case PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE:
934 case PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE:
935 case PF_ARM_V83_JSCVT_INSTRUCTIONS_AVAILABLE:
936 case PF_ARM_V83_LRCPC_INSTRUCTIONS_AVAILABLE:
938 WLog_WARN(TAG,
"feature 0x%08" PRIx32
" check not implemented", ProcessorFeature);
944 switch (ProcessorFeature)
946 case PF_MMX_INSTRUCTIONS_AVAILABLE:
947 case PF_XMMI_INSTRUCTIONS_AVAILABLE:
948 case PF_XMMI64_INSTRUCTIONS_AVAILABLE:
949 case PF_3DNOW_INSTRUCTIONS_AVAILABLE:
950 case PF_SSE3_INSTRUCTIONS_AVAILABLE:
951 case PF_SSSE3_INSTRUCTIONS_AVAILABLE:
952 case PF_SSE4_1_INSTRUCTIONS_AVAILABLE:
953 case PF_SSE4_2_INSTRUCTIONS_AVAILABLE:
954 case PF_AVX_INSTRUCTIONS_AVAILABLE:
955 case PF_AVX2_INSTRUCTIONS_AVAILABLE:
956 case PF_AVX512F_INSTRUCTIONS_AVAILABLE:
959 case PF_ARM_NEON_INSTRUCTIONS_AVAILABLE:
965 case PF_ARM_V8_INSTRUCTIONS_AVAILABLE:
966 case PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE:
967 case PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE:
968 case PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE:
969 case PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE:
970 case PF_ARM_V83_JSCVT_INSTRUCTIONS_AVAILABLE:
971 case PF_ARM_V83_LRCPC_INSTRUCTIONS_AVAILABLE:
973 WLog_WARN(TAG,
"feature 0x%08" PRIx32
" check not implemented", ProcessorFeature);
980#if defined(_M_IX86_AMD64)
986 cpuid(1, &a, &b, &c, &d);
988 switch (ProcessorFeature)
990 case PF_MMX_INSTRUCTIONS_AVAILABLE:
996 case PF_XMMI_INSTRUCTIONS_AVAILABLE:
1002 case PF_XMMI64_INSTRUCTIONS_AVAILABLE:
1008 case PF_3DNOW_INSTRUCTIONS_AVAILABLE:
1014 case PF_SSE3_INSTRUCTIONS_AVAILABLE:
1015 ret = __builtin_cpu_supports(
"sse3");
1018 case PF_SSSE3_INSTRUCTIONS_AVAILABLE:
1019 ret = __builtin_cpu_supports(
"ssse3");
1021 case PF_SSE4_1_INSTRUCTIONS_AVAILABLE:
1022 ret = __builtin_cpu_supports(
"sse4.1");
1024 case PF_SSE4_2_INSTRUCTIONS_AVAILABLE:
1025 ret = __builtin_cpu_supports(
"sse4.2");
1027 case PF_AVX_INSTRUCTIONS_AVAILABLE:
1028 ret = __builtin_cpu_supports(
"avx");
1030 case PF_AVX2_INSTRUCTIONS_AVAILABLE:
1031 ret = __builtin_cpu_supports(
"avx2");
1033 case PF_AVX512F_INSTRUCTIONS_AVAILABLE:
1034 ret = __builtin_cpu_supports(
"avx512f");
1036 case PF_ARM_NEON_INSTRUCTIONS_AVAILABLE:
1037#if defined(__ARM_NEON__)
1042 WLog_WARN(TAG,
"feature 0x%08" PRIx32
" check not implemented", ProcessorFeature);
1051 switch (ProcessorFeature)
1053 case PF_MMX_INSTRUCTIONS_AVAILABLE:
1059 case PF_3DNOW_INSTRUCTIONS_AVAILABLE:
1065 case PF_SSE3_INSTRUCTIONS_AVAILABLE:
1081DWORD GetTickCountPrecise(
void)
1086 QueryPerformanceFrequency(&freq);
1087 QueryPerformanceCounter(¤t);
1088 return (DWORD)(current.QuadPart * 1000LL / freq.QuadPart);
1090 return GetTickCount();
1094BOOL IsProcessorFeaturePresentEx(DWORD ProcessorFeature)
1097#if defined(_M_ARM) || defined(_M_ARM64)
1100 caps = GetARMCPUCaps();
1102 switch (ProcessorFeature)
1104 case PF_EX_ARM_VFP1:
1105 if (caps & HWCAP_VFP)
1110 case PF_EX_ARM_VFP3D16:
1111 if (caps & HWCAP_VFPv3D16)
1116 case PF_EX_ARM_VFP4:
1117 if (caps & HWCAP_VFPv4)
1122 case PF_EX_ARM_IDIVA:
1123 if (caps & HWCAP_IDIVA)
1128 case PF_EX_ARM_IDIVT:
1129 if (caps & HWCAP_IDIVT)
1136#elif defined(_M_IX86_AMD64)
1141 cpuid(1, &a, &b, &c, &d);
1143 switch (ProcessorFeature)
1151 cpuid(0x80000001, &a81, &b81, &c81, &d81);
1153 if (c81 & C81_BIT_LZCNT)
1158 case PF_EX_3DNOW_PREFETCH:
1165 if (c & C_BIT_SSSE3)
1171 if (c & C_BIT_SSE41)
1177 if (c & C_BIT_SSE42)
1181#if defined(__GNUC__) || defined(_MSC_VER)
1188 case PF_EX_AVX_PCLMULQDQ:
1191 if (!(c & C_BIT_AVX))
1195 if (!(c & C_BIT_XGETBV))
1203 if ((e & E_BITS_AVX) == E_BITS_AVX)
1205 switch (ProcessorFeature)
1213 cpuid(7, &a, &b, &c, &d);
1214 switch (ProcessorFeature)
1222 if (b & B_BIT_AVX512F)
1243 case PF_EX_AVX_PCLMULQDQ:
1244 if (c & C_BIT_PCLMULQDQ)
1259#elif defined(_M_E2K)
1261 switch (ProcessorFeature)