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 = { 0 };
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__) || defined(__FreeBSD__) || defined(__NetBSD__) || \
107 defined(__OpenBSD__) || defined(__DragonFly__)
108#include <sys/sysctl.h>
111static WORD GetProcessorArchitecture(
void)
113 WORD cpuArch = PROCESSOR_ARCHITECTURE_UNKNOWN;
115 AndroidCpuFamily family = android_getCpuFamily();
119 case ANDROID_CPU_FAMILY_ARM:
120 return PROCESSOR_ARCHITECTURE_ARM;
122 case ANDROID_CPU_FAMILY_X86:
123 return PROCESSOR_ARCHITECTURE_INTEL;
125 case ANDROID_CPU_FAMILY_MIPS:
126 return PROCESSOR_ARCHITECTURE_MIPS;
128 case ANDROID_CPU_FAMILY_ARM64:
129 return PROCESSOR_ARCHITECTURE_ARM64;
131 case ANDROID_CPU_FAMILY_X86_64:
132 return PROCESSOR_ARCHITECTURE_AMD64;
134 case ANDROID_CPU_FAMILY_MIPS64:
135 return PROCESSOR_ARCHITECTURE_MIPS64;
138 return PROCESSOR_ARCHITECTURE_UNKNOWN;
142 cpuArch = PROCESSOR_ARCHITECTURE_ARM;
143#elif defined(_M_IX86)
144 cpuArch = PROCESSOR_ARCHITECTURE_INTEL;
145#elif defined(_M_MIPS64)
147 cpuArch = PROCESSOR_ARCHITECTURE_MIPS64;
148#elif defined(_M_MIPS)
149 cpuArch = PROCESSOR_ARCHITECTURE_MIPS;
150#elif defined(_M_ARM64)
151 cpuArch = PROCESSOR_ARCHITECTURE_ARM64;
152#elif defined(_M_AMD64)
153 cpuArch = PROCESSOR_ARCHITECTURE_AMD64;
155 cpuArch = PROCESSOR_ARCHITECTURE_PPC;
156#elif defined(_M_ALPHA)
157 cpuArch = PROCESSOR_ARCHITECTURE_ALPHA;
159 cpuArch = PROCESSOR_ARCHITECTURE_E2K;
164static DWORD GetNumberOfProcessors(
void)
168 return android_getCpuCount();
170#elif defined(__linux__) || defined(__sun) || defined(_AIX)
171 numCPUs = (DWORD)sysconf(_SC_NPROCESSORS_ONLN);
172#elif defined(__MACOSX__) || defined(__FreeBSD__) || defined(__NetBSD__) || \
173 defined(__OpenBSD__) || defined(__DragonFly__)
176 size_t length =
sizeof(numCPUs);
178#if defined(__FreeBSD__) || defined(__OpenBSD__)
181 mib[1] = HW_AVAILCPU;
183 sysctl(mib, 2, &numCPUs, &length, NULL, 0);
188 sysctl(mib, 2, &numCPUs, &length, NULL, 0);
195 numCPUs = (DWORD)mpctl(MPC_GETNUMSPUS, NULL, NULL);
197 numCPUs = (DWORD)sysconf(_SC_NPROC_ONLN);
202static DWORD GetSystemPageSize(
void)
204 DWORD dwPageSize = 0;
205 long sc_page_size = -1;
206#if defined(_SC_PAGESIZE)
208 if (sc_page_size < 0)
209 sc_page_size = sysconf(_SC_PAGESIZE);
212#if defined(_SC_PAGE_SIZE)
214 if (sc_page_size < 0)
215 sc_page_size = sysconf(_SC_PAGE_SIZE);
219 if (sc_page_size > 0)
220 dwPageSize = (DWORD)sc_page_size;
222 if (dwPageSize < 4096)
231 WINPR_ASSERT(lpSystemInfo);
233 *lpSystemInfo = empty;
234 lpSystemInfo->DUMMYUNIONNAME.DUMMYSTRUCTNAME.wProcessorArchitecture =
235 GetProcessorArchitecture();
236 lpSystemInfo->dwPageSize = GetSystemPageSize();
237 lpSystemInfo->dwNumberOfProcessors = GetNumberOfProcessors();
242 GetSystemInfo(lpSystemInfo);
245void GetSystemTime(LPSYSTEMTIME lpSystemTime)
249 struct tm* stm = NULL;
250 WORD wMilliseconds = 0;
251 UINT64 now = winpr_GetUnixTimeNS();
252 ct = WINPR_TIME_NS_TO_S(now);
253 wMilliseconds = (WORD)(WINPR_TIME_NS_REM_MS(now));
254 stm = gmtime_r(&ct, &tres);
259 lpSystemTime->wYear = (WORD)(stm->tm_year + 1900);
260 lpSystemTime->wMonth = (WORD)(stm->tm_mon + 1);
261 lpSystemTime->wDayOfWeek = (WORD)stm->tm_wday;
262 lpSystemTime->wDay = (WORD)stm->tm_mday;
263 lpSystemTime->wHour = (WORD)stm->tm_hour;
264 lpSystemTime->wMinute = (WORD)stm->tm_min;
265 lpSystemTime->wSecond = (WORD)stm->tm_sec;
266 lpSystemTime->wMilliseconds = wMilliseconds;
270BOOL SetSystemTime(WINPR_ATTR_UNUSED CONST
SYSTEMTIME* lpSystemTime)
273 WLog_ERR(
"TODO",
"TODO: Implement");
277VOID GetLocalTime(LPSYSTEMTIME lpSystemTime)
281 struct tm* ltm = NULL;
282 WORD wMilliseconds = 0;
283 UINT64 now = winpr_GetUnixTimeNS();
284 ct = WINPR_TIME_NS_TO_S(now);
285 wMilliseconds = (WORD)(WINPR_TIME_NS_REM_MS(now));
286 ltm = localtime_r(&ct, &tres);
291 lpSystemTime->wYear = (WORD)(ltm->tm_year + 1900);
292 lpSystemTime->wMonth = (WORD)(ltm->tm_mon + 1);
293 lpSystemTime->wDayOfWeek = (WORD)ltm->tm_wday;
294 lpSystemTime->wDay = (WORD)ltm->tm_mday;
295 lpSystemTime->wHour = (WORD)ltm->tm_hour;
296 lpSystemTime->wMinute = (WORD)ltm->tm_min;
297 lpSystemTime->wSecond = (WORD)ltm->tm_sec;
298 lpSystemTime->wMilliseconds = wMilliseconds;
302BOOL SetLocalTime(WINPR_ATTR_UNUSED CONST
SYSTEMTIME* lpSystemTime)
305 WLog_ERR(
"TODO",
"TODO: Implement");
309VOID GetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime)
317 t.u64 = (winpr_GetUnixTimeNS() / 100ull) + FILETIME_TO_UNIX_OFFSET_S * 10000000ull;
318 *lpSystemTimeAsFileTime = t.ft;
321BOOL GetSystemTimeAdjustment(WINPR_ATTR_UNUSED PDWORD lpTimeAdjustment,
322 WINPR_ATTR_UNUSED PDWORD lpTimeIncrement,
323 WINPR_ATTR_UNUSED PBOOL lpTimeAdjustmentDisabled)
326 WLog_ERR(
"TODO",
"TODO: Implement");
330#ifndef CLOCK_MONOTONIC_RAW
331#define CLOCK_MONOTONIC_RAW 4
334DWORD GetTickCount(
void)
336 return (DWORD)GetTickCount64();
340#if !defined(_WIN32) || defined(_UWP)
342#if defined(WITH_WINPR_DEPRECATED)
347BOOL GetVersionExA(LPOSVERSIONINFOA lpVersionInformation)
352 if ((lpVersionInformation->dwOSVersionInfoSize ==
sizeof(OSVERSIONINFOA)) ||
353 (lpVersionInformation->dwOSVersionInfoSize ==
sizeof(OSVERSIONINFOEXA)))
355 lpVersionInformation->dwMajorVersion = 10;
356 lpVersionInformation->dwMinorVersion = 0;
357 lpVersionInformation->dwBuildNumber = 0;
358 lpVersionInformation->dwPlatformId = VER_PLATFORM_WIN32_NT;
359 ZeroMemory(lpVersionInformation->szCSDVersion,
sizeof(lpVersionInformation->szCSDVersion));
361 if (lpVersionInformation->dwOSVersionInfoSize ==
sizeof(OSVERSIONINFOEXA))
363 LPOSVERSIONINFOEXA lpVersionInformationEx = (LPOSVERSIONINFOEXA)lpVersionInformation;
364 lpVersionInformationEx->wServicePackMajor = 0;
365 lpVersionInformationEx->wServicePackMinor = 0;
366 lpVersionInformationEx->wSuiteMask = 0;
367 lpVersionInformationEx->wProductType = VER_NT_WORKSTATION;
368 lpVersionInformationEx->wReserved = 0;
377 if ((lpVersionInformation->dwOSVersionInfoSize ==
sizeof(OSVERSIONINFOA)) ||
378 (lpVersionInformation->dwOSVersionInfoSize ==
sizeof(OSVERSIONINFOEXA)))
380 lpVersionInformation->dwMajorVersion = 6;
381 lpVersionInformation->dwMinorVersion = 1;
382 lpVersionInformation->dwBuildNumber = 7601;
383 lpVersionInformation->dwPlatformId = VER_PLATFORM_WIN32_NT;
384 ZeroMemory(lpVersionInformation->szCSDVersion,
sizeof(lpVersionInformation->szCSDVersion));
386 if (lpVersionInformation->dwOSVersionInfoSize ==
sizeof(OSVERSIONINFOEXA))
388 LPOSVERSIONINFOEXA lpVersionInformationEx = (LPOSVERSIONINFOEXA)lpVersionInformation;
389 lpVersionInformationEx->wServicePackMajor = 1;
390 lpVersionInformationEx->wServicePackMinor = 0;
391 lpVersionInformationEx->wSuiteMask = 0;
392 lpVersionInformationEx->wProductType = VER_NT_WORKSTATION;
393 lpVersionInformationEx->wReserved = 0;
403BOOL GetVersionExW(LPOSVERSIONINFOW lpVersionInformation)
405 ZeroMemory(lpVersionInformation->szCSDVersion,
sizeof(lpVersionInformation->szCSDVersion));
406 return GetVersionExA((LPOSVERSIONINFOA)lpVersionInformation);
413#if !defined(_WIN32) || defined(_UWP)
415BOOL GetComputerNameW(LPWSTR lpBuffer, LPDWORD lpnSize)
419 if (!lpnSize || (*lpnSize > INT_MAX))
424 buffer = malloc(*lpnSize);
428 rc = GetComputerNameA(buffer, lpnSize);
430 if (rc && (*lpnSize > 0))
432 const SSIZE_T res = ConvertUtf8NToWChar(buffer, *lpnSize, lpBuffer, *lpnSize);
441BOOL GetComputerNameA(LPSTR lpBuffer, LPDWORD lpnSize)
445 SetLastError(ERROR_BAD_ARGUMENTS);
449 char hostname[256 + 1] = { 0 };
450 if (gethostname(hostname, ARRAYSIZE(hostname) - 1) == -1)
453 size_t length = strnlen(hostname, MAX_COMPUTERNAME_LENGTH);
454 const char* dot = strchr(hostname,
'.');
457 const size_t dotlen = WINPR_ASSERTING_INT_CAST(
size_t, (dot - hostname));
462 if ((*lpnSize <= (DWORD)length) || !lpBuffer)
464 SetLastError(ERROR_BUFFER_OVERFLOW);
465 *lpnSize = (DWORD)(length + 1);
469 strncpy(lpBuffer, hostname, length);
470 lpBuffer[length] =
'\0';
471 *lpnSize = (DWORD)length;
475BOOL GetComputerNameExA(COMPUTER_NAME_FORMAT NameType, LPSTR lpBuffer, LPDWORD lpnSize)
478 char hostname[256] = { 0 };
482 SetLastError(ERROR_BAD_ARGUMENTS);
486 if ((NameType == ComputerNameNetBIOS) || (NameType == ComputerNamePhysicalNetBIOS))
488 BOOL rc = GetComputerNameA(lpBuffer, lpnSize);
492 if (GetLastError() == ERROR_BUFFER_OVERFLOW)
493 SetLastError(ERROR_MORE_DATA);
499 if (gethostname(hostname,
sizeof(hostname)) == -1)
502 length = strnlen(hostname,
sizeof(hostname));
506 case ComputerNameDnsHostname:
507 case ComputerNameDnsDomain:
508 case ComputerNameDnsFullyQualified:
509 case ComputerNamePhysicalDnsHostname:
510 case ComputerNamePhysicalDnsDomain:
511 case ComputerNamePhysicalDnsFullyQualified:
512 if ((*lpnSize <= (DWORD)length) || !lpBuffer)
514 *lpnSize = (DWORD)(length + 1);
515 SetLastError(ERROR_MORE_DATA);
519 CopyMemory(lpBuffer, hostname, length);
520 lpBuffer[length] =
'\0';
521 *lpnSize = (DWORD)length;
531BOOL GetComputerNameExW(COMPUTER_NAME_FORMAT NameType, LPWSTR lpBuffer, LPDWORD lpnSize)
534 LPSTR lpABuffer = NULL;
538 SetLastError(ERROR_BAD_ARGUMENTS);
544 lpABuffer = calloc(*lpnSize,
sizeof(CHAR));
550 rc = GetComputerNameExA(NameType, lpABuffer, lpnSize);
552 if (rc && (*lpnSize > 0))
554 const SSIZE_T res = ConvertUtf8NToWChar(lpABuffer, *lpnSize, lpBuffer, *lpnSize);
566DWORD GetTickCount(
void)
568 return (DWORD)GetTickCount64();
573#if (!defined(_WIN32)) || (defined(_WIN32) && (_WIN32_WINNT < 0x0600))
575ULONGLONG winpr_GetTickCount64(
void)
577 const UINT64 ns = winpr_GetTickCount64NS();
578 return WINPR_TIME_NS_TO_MS(ns);
583UINT64 winpr_GetTickCount64NS(
void)
586#if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 199309L)
587 struct timespec ts = { 0 };
589 if (clock_gettime(CLOCK_MONOTONIC_RAW, &ts) == 0)
590 ticks = (WINPR_ASSERTING_INT_CAST(uint64_t, ts.tv_sec) * 1000000000ull) +
591 WINPR_ASSERTING_INT_CAST(uint64_t, ts.tv_nsec);
592#elif defined(__MACH__) && defined(__APPLE__)
593 ticks = mac_get_time_ns();
597 if (QueryPerformanceFrequency(&freq) && QueryPerformanceCounter(&li))
598 ticks = li.QuadPart * 1000000000ull / freq.QuadPart;
600 struct timeval tv = { 0 };
602 if (gettimeofday(&tv, NULL) == 0)
603 ticks = (tv.tv_sec * 1000000000ull) + (tv.tv_usec * 1000ull);
612 static UINT64 first = 0;
613 static UINT64 uptime = 0;
616 struct sysinfo info = { 0 };
617 if (sysinfo(&info) == 0)
620 uptime = 1000000000ull * info.uptime;
624 ticks = ticks - first + uptime;
629UINT64 winpr_GetUnixTimeNS(
void)
638 GetSystemTimeAsFileTime(&t.ft);
639 return (t.u64 - FILETIME_TO_UNIX_OFFSET_S * 10000000ull) * 100ull;
640#elif defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 199309L)
641 struct timespec ts = { 0 };
642 if (clock_gettime(CLOCK_REALTIME, &ts) != 0)
644 return WINPR_ASSERTING_INT_CAST(uint64_t, ts.tv_sec) * 1000000000ull +
645 WINPR_ASSERTING_INT_CAST(uint64_t, ts.tv_nsec);
647 struct timeval tv = { 0 };
648 if (gettimeofday(&tv, NULL) != 0)
650 return tv.tv_sec * 1000000000ULL + tv.tv_usec * 1000ull;
658#define xgetbv(_func_, _lo_, _hi_) \
659 __asm__ __volatile__("xgetbv" : "=a"(_lo_), "=d"(_hi_) : "c"(_func_))
660#elif defined(_MSC_VER)
661#define xgetbv(_func_, _lo_, _hi_) \
663 unsigned __int64 val = _xgetbv(_func_); \
664 _lo_ = val & 0xFFFFFFFF; \
665 _hi_ = (val >> 32); \
669#define B_BIT_AVX2 (1 << 5)
670#define B_BIT_AVX512F (1 << 16)
671#define D_BIT_MMX (1 << 23)
672#define D_BIT_SSE (1 << 25)
673#define D_BIT_SSE2 (1 << 26)
674#define D_BIT_3DN (1 << 30)
676#define C_BIT_PCLMULQDQ (1 << 1)
677#define C81_BIT_LZCNT (1 << 5)
679#define C_BIT_3DNP (1 << 8)
680#define C_BIT_SSSE3 (1 << 9)
681#define C_BIT_SSE41 (1 << 19)
682#define C_BIT_SSE42 (1 << 20)
683#define C_BIT_FMA (1 << 12)
684#define C_BIT_AES (1 << 25)
685#define C_BIT_XGETBV (1 << 27)
686#define C_BIT_AVX (1 << 28)
687#define E_BIT_XMM (1 << 1)
688#define E_BIT_YMM (1 << 2)
689#define E_BITS_AVX (E_BIT_XMM | E_BIT_YMM)
691static void cpuid(
unsigned info,
unsigned* eax,
unsigned* ebx,
unsigned* ecx,
unsigned* edx)
694 *eax = *ebx = *ecx = *edx = 0;
708 :
"=a"(*eax),
"=S"(*ebx),
"=c"(*ecx),
"=d"(*edx)
709 :
"a"(info),
"c"(0));
710#elif defined(_MSC_VER)
719#elif defined(_M_ARM) || defined(_M_ARM64)
720#if defined(__linux__)
722#define HWCAP_SWP (1 << 0)
723#define HWCAP_HALF (1 << 1)
724#define HWCAP_THUMB (1 << 2)
725#define HWCAP_26BIT (1 << 3)
726#define HWCAP_FAST_MULT (1 << 4)
727#define HWCAP_FPA (1 << 5)
728#define HWCAP_VFP (1 << 6)
729#define HWCAP_EDSP (1 << 7)
730#define HWCAP_JAVA (1 << 8)
731#define HWCAP_IWMMXT (1 << 9)
732#define HWCAP_CRUNCH (1 << 10)
733#define HWCAP_THUMBEE (1 << 11)
734#define HWCAP_NEON (1 << 12)
735#define HWCAP_VFPv3 (1 << 13)
736#define HWCAP_VFPv3D16 (1 << 14)
737#define HWCAP_TLS (1 << 15)
738#define HWCAP_VFPv4 (1 << 16)
739#define HWCAP_IDIVA (1 << 17)
740#define HWCAP_IDIVT (1 << 18)
741#define HWCAP_VFPD32 (1 << 19)
742#define HWCAP_IDIV (HWCAP_IDIVA | HWCAP_IDIVT)
747static unsigned GetARMCPUCaps(
void)
750 int fd = open(
"/proc/self/auxv", O_RDONLY);
764 num = read(fd, (
char*)&auxvec,
sizeof(auxvec));
766 if (num < 1 || (auxvec.a_type == 0 && auxvec.a_val == 0))
769 if (auxvec.a_type == AT_HWCAP)
784#if defined(_M_ARM) || defined(_M_ARM64)
790BOOL IsProcessorFeaturePresent(DWORD ProcessorFeature)
794 const uint64_t features = android_getCpuFeatures();
795 const AndroidCpuFamily family = android_getCpuFamily();
796 const BOOL isArm = (family == ANDROID_CPU_FAMILY_ARM) || (family == ANDROID_CPU_FAMILY_ARM64);
797 const BOOL isX86 = (family == ANDROID_CPU_FAMILY_X86) || (family == ANDROID_CPU_FAMILY_X86_64);
801 switch (ProcessorFeature)
803 case PF_MMX_INSTRUCTIONS_AVAILABLE:
804 case PF_XMMI_INSTRUCTIONS_AVAILABLE:
805 case PF_XMMI64_INSTRUCTIONS_AVAILABLE:
806 case PF_3DNOW_INSTRUCTIONS_AVAILABLE:
807 case PF_SSE3_INSTRUCTIONS_AVAILABLE:
809 case PF_SSSE3_INSTRUCTIONS_AVAILABLE:
810 return features & ANDROID_CPU_X86_FEATURE_SSSE3;
811 case PF_SSE4_1_INSTRUCTIONS_AVAILABLE:
812 return features & ANDROID_CPU_X86_FEATURE_SSE4_1;
813 case PF_SSE4_2_INSTRUCTIONS_AVAILABLE:
814 return features & ANDROID_CPU_X86_FEATURE_SSE4_2;
815 case PF_AVX_INSTRUCTIONS_AVAILABLE:
816 return features & ANDROID_CPU_X86_FEATURE_AVX;
817 case PF_AVX2_INSTRUCTIONS_AVAILABLE:
818 return features & ANDROID_CPU_X86_FEATURE_AVX2;
819 case PF_AVX512F_INSTRUCTIONS_AVAILABLE:
821 WLog_WARN(TAG,
"feature 0x%08" PRIx32
" check not implemented", ProcessorFeature);
828 switch (ProcessorFeature)
830 case PF_ARM_NEON_INSTRUCTIONS_AVAILABLE:
832 return features & ANDROID_CPU_ARM_FEATURE_NEON;
835 WLog_WARN(TAG,
"feature 0x%08" PRIx32
" check not implemented", ProcessorFeature);
840 WLog_WARN(TAG,
"Unsupported Android CPU family 0x%08" PRIx32, family);
843#elif defined(_M_ARM) || defined(_M_ARM64)
845 const unsigned long caps = getauxval(AT_HWCAP);
847 switch (ProcessorFeature)
849 case PF_ARM_NEON_INSTRUCTIONS_AVAILABLE:
852 if (caps & HWCAP_NEON)
858 if (caps & HWCAP_THUMB)
861 case PF_ARM_VFP_32_REGISTERS_AVAILABLE:
862 if (caps & HWCAP_VFPD32)
865 case PF_ARM_DIVIDE_INSTRUCTION_AVAILABLE:
866 if ((caps & HWCAP_IDIVA) || (caps & HWCAP_IDIVT))
870 if (caps & HWCAP_VFPv3)
876 if (caps & HWCAP_JAVA)
882 if (caps & HWCAP_EDSP)
888 if (caps & HWCAP_EDSP)
894 if ((caps & HWCAP_IDIVT) || (caps & HWCAP_VFPv4))
900 if (caps & HWCAP_THUMBEE)
905 case PF_ARM_INTEL_WMMX:
906 if (caps & HWCAP_IWMMXT)
910 case PF_MMX_INSTRUCTIONS_AVAILABLE:
911 case PF_XMMI_INSTRUCTIONS_AVAILABLE:
912 case PF_XMMI64_INSTRUCTIONS_AVAILABLE:
913 case PF_3DNOW_INSTRUCTIONS_AVAILABLE:
914 case PF_SSE3_INSTRUCTIONS_AVAILABLE:
915 case PF_SSSE3_INSTRUCTIONS_AVAILABLE:
916 case PF_SSE4_1_INSTRUCTIONS_AVAILABLE:
917 case PF_SSE4_2_INSTRUCTIONS_AVAILABLE:
918 case PF_AVX_INSTRUCTIONS_AVAILABLE:
919 case PF_AVX2_INSTRUCTIONS_AVAILABLE:
920 case PF_AVX512F_INSTRUCTIONS_AVAILABLE:
923 case PF_ARM_V8_INSTRUCTIONS_AVAILABLE:
924 case PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE:
925 case PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE:
926 case PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE:
927 case PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE:
928 case PF_ARM_V83_JSCVT_INSTRUCTIONS_AVAILABLE:
929 case PF_ARM_V83_LRCPC_INSTRUCTIONS_AVAILABLE:
931 WLog_WARN(TAG,
"feature 0x%08" PRIx32
" check not implemented", ProcessorFeature);
937 switch (ProcessorFeature)
939 case PF_MMX_INSTRUCTIONS_AVAILABLE:
940 case PF_XMMI_INSTRUCTIONS_AVAILABLE:
941 case PF_XMMI64_INSTRUCTIONS_AVAILABLE:
942 case PF_3DNOW_INSTRUCTIONS_AVAILABLE:
943 case PF_SSE3_INSTRUCTIONS_AVAILABLE:
944 case PF_SSSE3_INSTRUCTIONS_AVAILABLE:
945 case PF_SSE4_1_INSTRUCTIONS_AVAILABLE:
946 case PF_SSE4_2_INSTRUCTIONS_AVAILABLE:
947 case PF_AVX_INSTRUCTIONS_AVAILABLE:
948 case PF_AVX2_INSTRUCTIONS_AVAILABLE:
949 case PF_AVX512F_INSTRUCTIONS_AVAILABLE:
952 case PF_ARM_NEON_INSTRUCTIONS_AVAILABLE:
958 case PF_ARM_V8_INSTRUCTIONS_AVAILABLE:
959 case PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE:
960 case PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE:
961 case PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE:
962 case PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE:
963 case PF_ARM_V83_JSCVT_INSTRUCTIONS_AVAILABLE:
964 case PF_ARM_V83_LRCPC_INSTRUCTIONS_AVAILABLE:
966 WLog_WARN(TAG,
"feature 0x%08" PRIx32
" check not implemented", ProcessorFeature);
973#if defined(_M_IX86_AMD64)
979 cpuid(1, &a, &b, &c, &d);
981 switch (ProcessorFeature)
983 case PF_MMX_INSTRUCTIONS_AVAILABLE:
989 case PF_XMMI_INSTRUCTIONS_AVAILABLE:
995 case PF_XMMI64_INSTRUCTIONS_AVAILABLE:
1001 case PF_3DNOW_INSTRUCTIONS_AVAILABLE:
1007 case PF_SSE3_INSTRUCTIONS_AVAILABLE:
1008 ret = __builtin_cpu_supports(
"sse3");
1011 case PF_SSSE3_INSTRUCTIONS_AVAILABLE:
1012 ret = __builtin_cpu_supports(
"ssse3");
1014 case PF_SSE4_1_INSTRUCTIONS_AVAILABLE:
1015 ret = __builtin_cpu_supports(
"sse4.1");
1017 case PF_SSE4_2_INSTRUCTIONS_AVAILABLE:
1018 ret = __builtin_cpu_supports(
"sse4.2");
1020 case PF_AVX_INSTRUCTIONS_AVAILABLE:
1021 ret = __builtin_cpu_supports(
"avx");
1023 case PF_AVX2_INSTRUCTIONS_AVAILABLE:
1024 ret = __builtin_cpu_supports(
"avx2");
1026 case PF_AVX512F_INSTRUCTIONS_AVAILABLE:
1027 ret = __builtin_cpu_supports(
"avx512f");
1029 case PF_ARM_NEON_INSTRUCTIONS_AVAILABLE:
1030#if defined(__ARM_NEON__)
1035 WLog_WARN(TAG,
"feature 0x%08" PRIx32
" check not implemented", ProcessorFeature);
1044 switch (ProcessorFeature)
1046 case PF_MMX_INSTRUCTIONS_AVAILABLE:
1052 case PF_3DNOW_INSTRUCTIONS_AVAILABLE:
1058 case PF_SSE3_INSTRUCTIONS_AVAILABLE:
1074DWORD GetTickCountPrecise(
void)
1079 QueryPerformanceFrequency(&freq);
1080 QueryPerformanceCounter(¤t);
1081 return (DWORD)(current.QuadPart * 1000LL / freq.QuadPart);
1083 return GetTickCount();
1087BOOL IsProcessorFeaturePresentEx(DWORD ProcessorFeature)
1090#if defined(_M_ARM) || defined(_M_ARM64)
1093 caps = GetARMCPUCaps();
1095 switch (ProcessorFeature)
1097 case PF_EX_ARM_VFP1:
1098 if (caps & HWCAP_VFP)
1103 case PF_EX_ARM_VFP3D16:
1104 if (caps & HWCAP_VFPv3D16)
1109 case PF_EX_ARM_VFP4:
1110 if (caps & HWCAP_VFPv4)
1115 case PF_EX_ARM_IDIVA:
1116 if (caps & HWCAP_IDIVA)
1121 case PF_EX_ARM_IDIVT:
1122 if (caps & HWCAP_IDIVT)
1129#elif defined(_M_IX86_AMD64)
1134 cpuid(1, &a, &b, &c, &d);
1136 switch (ProcessorFeature)
1144 cpuid(0x80000001, &a81, &b81, &c81, &d81);
1146 if (c81 & C81_BIT_LZCNT)
1151 case PF_EX_3DNOW_PREFETCH:
1158 if (c & C_BIT_SSSE3)
1164 if (c & C_BIT_SSE41)
1170 if (c & C_BIT_SSE42)
1174#if defined(__GNUC__) || defined(_MSC_VER)
1181 case PF_EX_AVX_PCLMULQDQ:
1184 if (!(c & C_BIT_AVX))
1188 if (!(c & C_BIT_XGETBV))
1196 if ((e & E_BITS_AVX) == E_BITS_AVX)
1198 switch (ProcessorFeature)
1206 cpuid(7, &a, &b, &c, &d);
1207 switch (ProcessorFeature)
1215 if (b & B_BIT_AVX512F)
1236 case PF_EX_AVX_PCLMULQDQ:
1237 if (c & C_BIT_PCLMULQDQ)
1252#elif defined(_M_E2K)
1254 switch (ProcessorFeature)