21 #include <winpr/config.h>
23 #include <winpr/sysinfo.h>
24 #include <winpr/platform.h>
27 #include "cpufeatures/cpu-features.h"
30 #if defined(__linux__)
31 #include <sys/types.h>
37 #if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 199309L)
39 #elif !defined(__APPLE__)
41 #include <sys/sysinfo.h>
46 #define TAG WINPR_TAG("sysinfo")
48 #define FILETIME_TO_UNIX_OFFSET_S 11644473600UL
50 #if defined(__MACH__) && defined(__APPLE__)
52 #include <mach/mach_time.h>
54 static UINT64 scaleHighPrecision(UINT64 i, UINT32 numer, UINT32 denom)
56 UINT64 high = (i >> 32) * numer;
57 UINT64 low = (i & 0xffffffffull) * numer / denom;
58 UINT64 highRem = ((high % denom) << 32) / denom;
60 return (high << 32) + highRem + low;
63 static UINT64 mac_get_time_ns(
void)
65 mach_timebase_info_data_t timebase = { 0 };
66 mach_timebase_info(&timebase);
67 UINT64 t = mach_absolute_time();
68 return scaleHighPrecision(t, timebase.numer, timebase.denom);
98 #ifdef WINPR_HAVE_UNISTD_H
102 #include <winpr/crt.h>
103 #include <winpr/platform.h>
105 #if defined(__MACOSX__) || defined(__IOS__) || defined(__FreeBSD__) || defined(__NetBSD__) || \
106 defined(__OpenBSD__) || defined(__DragonFly__)
107 #include <sys/sysctl.h>
110 static 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;
140 #elif defined(_M_ARM)
141 cpuArch = PROCESSOR_ARCHITECTURE_ARM;
142 #elif defined(_M_IX86)
143 cpuArch = PROCESSOR_ARCHITECTURE_INTEL;
144 #elif defined(_M_MIPS64)
146 cpuArch = PROCESSOR_ARCHITECTURE_MIPS64;
147 #elif defined(_M_MIPS)
148 cpuArch = PROCESSOR_ARCHITECTURE_MIPS;
149 #elif defined(_M_ARM64)
150 cpuArch = PROCESSOR_ARCHITECTURE_ARM64;
151 #elif defined(_M_AMD64)
152 cpuArch = PROCESSOR_ARCHITECTURE_AMD64;
153 #elif defined(_M_PPC)
154 cpuArch = PROCESSOR_ARCHITECTURE_PPC;
155 #elif defined(_M_ALPHA)
156 cpuArch = PROCESSOR_ARCHITECTURE_ALPHA;
157 #elif defined(_M_E2K)
158 cpuArch = PROCESSOR_ARCHITECTURE_E2K;
163 static DWORD GetNumberOfProcessors(
void)
167 return android_getCpuCount();
169 #elif defined(__linux__) || defined(__sun) || defined(_AIX)
170 numCPUs = (DWORD)sysconf(_SC_NPROCESSORS_ONLN);
171 #elif defined(__MACOSX__) || defined(__FreeBSD__) || defined(__NetBSD__) || \
172 defined(__OpenBSD__) || defined(__DragonFly__)
175 size_t length =
sizeof(numCPUs);
177 #if defined(__FreeBSD__) || defined(__OpenBSD__)
180 mib[1] = HW_AVAILCPU;
182 sysctl(mib, 2, &numCPUs, &length, NULL, 0);
187 sysctl(mib, 2, &numCPUs, &length, NULL, 0);
193 #elif defined(__hpux)
194 numCPUs = (DWORD)mpctl(MPC_GETNUMSPUS, NULL, NULL);
196 numCPUs = (DWORD)sysconf(_SC_NPROC_ONLN);
201 static DWORD GetSystemPageSize(
void)
203 DWORD dwPageSize = 0;
204 long sc_page_size = -1;
205 #if defined(_SC_PAGESIZE)
207 if (sc_page_size < 0)
208 sc_page_size = sysconf(_SC_PAGESIZE);
211 #if defined(_SC_PAGE_SIZE)
213 if (sc_page_size < 0)
214 sc_page_size = sysconf(_SC_PAGE_SIZE);
218 if (sc_page_size > 0)
219 dwPageSize = (DWORD)sc_page_size;
221 if (dwPageSize < 4096)
229 lpSystemInfo->wProcessorArchitecture = GetProcessorArchitecture();
230 lpSystemInfo->wReserved = 0;
231 lpSystemInfo->dwPageSize = GetSystemPageSize();
232 lpSystemInfo->lpMinimumApplicationAddress = NULL;
233 lpSystemInfo->lpMaximumApplicationAddress = NULL;
234 lpSystemInfo->dwActiveProcessorMask = 0;
235 lpSystemInfo->dwNumberOfProcessors = GetNumberOfProcessors();
236 lpSystemInfo->dwProcessorType = 0;
237 lpSystemInfo->dwAllocationGranularity = 0;
238 lpSystemInfo->wProcessorLevel = 0;
239 lpSystemInfo->wProcessorRevision = 0;
244 GetSystemInfo(lpSystemInfo);
247 void GetSystemTime(LPSYSTEMTIME lpSystemTime)
251 struct tm* stm = NULL;
252 WORD wMilliseconds = 0;
254 wMilliseconds = (WORD)(GetTickCount() % 1000);
255 stm = gmtime_r(&ct, &tres);
256 ZeroMemory(lpSystemTime,
sizeof(SYSTEMTIME));
260 lpSystemTime->wYear = (WORD)(stm->tm_year + 1900);
261 lpSystemTime->wMonth = (WORD)(stm->tm_mon + 1);
262 lpSystemTime->wDayOfWeek = (WORD)stm->tm_wday;
263 lpSystemTime->wDay = (WORD)stm->tm_mday;
264 lpSystemTime->wHour = (WORD)stm->tm_hour;
265 lpSystemTime->wMinute = (WORD)stm->tm_min;
266 lpSystemTime->wSecond = (WORD)stm->tm_sec;
267 lpSystemTime->wMilliseconds = wMilliseconds;
271 BOOL SetSystemTime(CONST SYSTEMTIME* lpSystemTime)
277 VOID GetLocalTime(LPSYSTEMTIME lpSystemTime)
281 struct tm* ltm = NULL;
282 WORD wMilliseconds = 0;
284 wMilliseconds = (WORD)(GetTickCount() % 1000);
285 ltm = localtime_r(&ct, &tres);
286 ZeroMemory(lpSystemTime,
sizeof(SYSTEMTIME));
290 lpSystemTime->wYear = (WORD)(ltm->tm_year + 1900);
291 lpSystemTime->wMonth = (WORD)(ltm->tm_mon + 1);
292 lpSystemTime->wDayOfWeek = (WORD)ltm->tm_wday;
293 lpSystemTime->wDay = (WORD)ltm->tm_mday;
294 lpSystemTime->wHour = (WORD)ltm->tm_hour;
295 lpSystemTime->wMinute = (WORD)ltm->tm_min;
296 lpSystemTime->wSecond = (WORD)ltm->tm_sec;
297 lpSystemTime->wMilliseconds = wMilliseconds;
301 BOOL SetLocalTime(CONST SYSTEMTIME* lpSystemTime)
307 VOID GetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime)
315 t.u64 = (winpr_GetUnixTimeNS() / 100ull) + FILETIME_TO_UNIX_OFFSET_S * 10000000ull;
316 *lpSystemTimeAsFileTime = t.ft;
319 BOOL GetSystemTimeAdjustment(PDWORD lpTimeAdjustment, PDWORD lpTimeIncrement,
320 PBOOL lpTimeAdjustmentDisabled)
326 #ifndef CLOCK_MONOTONIC_RAW
327 #define CLOCK_MONOTONIC_RAW 4
330 DWORD GetTickCount(
void)
332 return (DWORD)GetTickCount64();
336 #if !defined(_WIN32) || defined(_UWP)
338 #if defined(WITH_WINPR_DEPRECATED)
343 BOOL GetVersionExA(LPOSVERSIONINFOA lpVersionInformation)
348 if ((lpVersionInformation->dwOSVersionInfoSize ==
sizeof(OSVERSIONINFOA)) ||
349 (lpVersionInformation->dwOSVersionInfoSize ==
sizeof(OSVERSIONINFOEXA)))
351 lpVersionInformation->dwMajorVersion = 10;
352 lpVersionInformation->dwMinorVersion = 0;
353 lpVersionInformation->dwBuildNumber = 0;
354 lpVersionInformation->dwPlatformId = VER_PLATFORM_WIN32_NT;
355 ZeroMemory(lpVersionInformation->szCSDVersion,
sizeof(lpVersionInformation->szCSDVersion));
357 if (lpVersionInformation->dwOSVersionInfoSize ==
sizeof(OSVERSIONINFOEXA))
359 LPOSVERSIONINFOEXA lpVersionInformationEx = (LPOSVERSIONINFOEXA)lpVersionInformation;
360 lpVersionInformationEx->wServicePackMajor = 0;
361 lpVersionInformationEx->wServicePackMinor = 0;
362 lpVersionInformationEx->wSuiteMask = 0;
363 lpVersionInformationEx->wProductType = VER_NT_WORKSTATION;
364 lpVersionInformationEx->wReserved = 0;
373 if ((lpVersionInformation->dwOSVersionInfoSize ==
sizeof(OSVERSIONINFOA)) ||
374 (lpVersionInformation->dwOSVersionInfoSize ==
sizeof(OSVERSIONINFOEXA)))
376 lpVersionInformation->dwMajorVersion = 6;
377 lpVersionInformation->dwMinorVersion = 1;
378 lpVersionInformation->dwBuildNumber = 7601;
379 lpVersionInformation->dwPlatformId = VER_PLATFORM_WIN32_NT;
380 ZeroMemory(lpVersionInformation->szCSDVersion,
sizeof(lpVersionInformation->szCSDVersion));
382 if (lpVersionInformation->dwOSVersionInfoSize ==
sizeof(OSVERSIONINFOEXA))
384 LPOSVERSIONINFOEXA lpVersionInformationEx = (LPOSVERSIONINFOEXA)lpVersionInformation;
385 lpVersionInformationEx->wServicePackMajor = 1;
386 lpVersionInformationEx->wServicePackMinor = 0;
387 lpVersionInformationEx->wSuiteMask = 0;
388 lpVersionInformationEx->wProductType = VER_NT_WORKSTATION;
389 lpVersionInformationEx->wReserved = 0;
399 BOOL GetVersionExW(LPOSVERSIONINFOW lpVersionInformation)
401 ZeroMemory(lpVersionInformation->szCSDVersion,
sizeof(lpVersionInformation->szCSDVersion));
402 return GetVersionExA((LPOSVERSIONINFOA)lpVersionInformation);
409 #if !defined(_WIN32) || defined(_UWP)
411 BOOL GetComputerNameW(LPWSTR lpBuffer, LPDWORD lpnSize)
415 if (!lpnSize || (*lpnSize > INT_MAX))
420 buffer = malloc(*lpnSize);
424 rc = GetComputerNameA(buffer, lpnSize);
426 if (rc && (*lpnSize > 0))
428 const SSIZE_T res = ConvertUtf8NToWChar(buffer, *lpnSize, lpBuffer, *lpnSize);
437 BOOL GetComputerNameA(LPSTR lpBuffer, LPDWORD lpnSize)
441 char hostname[256] = { 0 };
445 SetLastError(ERROR_BAD_ARGUMENTS);
449 if (gethostname(hostname,
sizeof(hostname)) == -1)
452 length = strnlen(hostname,
sizeof(hostname));
453 dot = strchr(hostname,
'.');
456 length = (dot - hostname);
458 if ((*lpnSize <= (DWORD)length) || !lpBuffer)
460 SetLastError(ERROR_BUFFER_OVERFLOW);
461 *lpnSize = (DWORD)(length + 1);
465 CopyMemory(lpBuffer, hostname, length);
466 lpBuffer[length] =
'\0';
467 *lpnSize = (DWORD)length;
471 BOOL GetComputerNameExA(COMPUTER_NAME_FORMAT NameType, LPSTR lpBuffer, LPDWORD lpnSize)
474 char hostname[256] = { 0 };
478 SetLastError(ERROR_BAD_ARGUMENTS);
482 if ((NameType == ComputerNameNetBIOS) || (NameType == ComputerNamePhysicalNetBIOS))
484 BOOL rc = GetComputerNameA(lpBuffer, lpnSize);
488 if (GetLastError() == ERROR_BUFFER_OVERFLOW)
489 SetLastError(ERROR_MORE_DATA);
495 if (gethostname(hostname,
sizeof(hostname)) == -1)
498 length = strnlen(hostname,
sizeof(hostname));
502 case ComputerNameDnsHostname:
503 case ComputerNameDnsDomain:
504 case ComputerNameDnsFullyQualified:
505 case ComputerNamePhysicalDnsHostname:
506 case ComputerNamePhysicalDnsDomain:
507 case ComputerNamePhysicalDnsFullyQualified:
508 if ((*lpnSize <= (DWORD)length) || !lpBuffer)
510 *lpnSize = (DWORD)(length + 1);
511 SetLastError(ERROR_MORE_DATA);
515 CopyMemory(lpBuffer, hostname, length);
516 lpBuffer[length] =
'\0';
517 *lpnSize = (DWORD)length;
527 BOOL GetComputerNameExW(COMPUTER_NAME_FORMAT NameType, LPWSTR lpBuffer, LPDWORD lpnSize)
530 LPSTR lpABuffer = NULL;
534 SetLastError(ERROR_BAD_ARGUMENTS);
540 lpABuffer = calloc(*lpnSize,
sizeof(CHAR));
546 rc = GetComputerNameExA(NameType, lpABuffer, lpnSize);
548 if (rc && (*lpnSize > 0))
550 const SSIZE_T res = ConvertUtf8NToWChar(lpABuffer, *lpnSize, lpBuffer, *lpnSize);
562 DWORD GetTickCount(
void)
564 return (DWORD)GetTickCount64();
569 #if (!defined(_WIN32)) || (defined(_WIN32) && (_WIN32_WINNT < 0x0600))
571 ULONGLONG winpr_GetTickCount64(
void)
573 const UINT64 ns = winpr_GetTickCount64NS();
574 return WINPR_TIME_NS_TO_MS(ns);
579 UINT64 winpr_GetTickCount64NS(
void)
582 #if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 199309L)
583 struct timespec ts = { 0 };
585 if (clock_gettime(CLOCK_MONOTONIC_RAW, &ts) == 0)
586 ticks = (ts.tv_sec * 1000000000ull) + ts.tv_nsec;
587 #elif defined(__MACH__) && defined(__APPLE__)
588 ticks = mac_get_time_ns();
589 #elif defined(_WIN32)
590 LARGE_INTEGER li = { 0 };
591 LARGE_INTEGER freq = { 0 };
592 if (QueryPerformanceFrequency(&freq) && QueryPerformanceCounter(&li))
593 ticks = li.QuadPart * 1000000000ull / freq.QuadPart;
595 struct timeval tv = { 0 };
597 if (gettimeofday(&tv, NULL) == 0)
598 ticks = (tv.tv_sec * 1000000000ull) + (tv.tv_usec * 1000ull);
607 static UINT64 first = 0;
608 static UINT64 uptime = 0;
611 struct sysinfo info = { 0 };
612 if (sysinfo(&info) == 0)
615 uptime = 1000000000ull * info.uptime;
619 ticks = ticks - first + uptime;
624 UINT64 winpr_GetUnixTimeNS(
void)
633 GetSystemTimeAsFileTime(&t.ft);
634 return (t.u64 - FILETIME_TO_UNIX_OFFSET_S * 10000000ull) * 100ull;
635 #elif defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 199309L)
636 struct timespec ts = { 0 };
637 if (clock_gettime(CLOCK_REALTIME, &ts) != 0)
639 return ts.tv_sec * 1000000000ull + ts.tv_nsec;
641 struct timeval tv = { 0 };
642 if (gettimeofday(&tv, NULL) != 0)
644 return tv.tv_sec * 1000000000ULL + tv.tv_usec * 1000ull;
651 #if defined(__GNUC__)
652 #define xgetbv(_func_, _lo_, _hi_) \
653 __asm__ __volatile__("xgetbv" : "=a"(_lo_), "=d"(_hi_) : "c"(_func_))
654 #elif defined(_MSC_VER)
655 #define xgetbv(_func_, _lo_, _hi_) \
657 unsigned __int64 val = _xgetbv(_func_); \
658 _lo_ = val & 0xFFFFFFFF; \
659 _hi_ = (val >> 32); \
663 #define B_BIT_AVX2 (1 << 5)
664 #define B_BIT_AVX512F (1 << 16)
665 #define D_BIT_MMX (1 << 23)
666 #define D_BIT_SSE (1 << 25)
667 #define D_BIT_SSE2 (1 << 26)
668 #define D_BIT_3DN (1 << 30)
669 #define C_BIT_SSE3 (1 << 0)
670 #define C_BIT_PCLMULQDQ (1 << 1)
671 #define C81_BIT_LZCNT (1 << 5)
672 #define C_BIT_3DNP (1 << 8)
673 #define C_BIT_3DNP (1 << 8)
674 #define C_BIT_SSSE3 (1 << 9)
675 #define C_BIT_SSE41 (1 << 19)
676 #define C_BIT_SSE42 (1 << 20)
677 #define C_BIT_FMA (1 << 12)
678 #define C_BIT_AES (1 << 25)
679 #define C_BIT_XGETBV (1 << 27)
680 #define C_BIT_AVX (1 << 28)
681 #define E_BIT_XMM (1 << 1)
682 #define E_BIT_YMM (1 << 2)
683 #define E_BITS_AVX (E_BIT_XMM | E_BIT_YMM)
685 static void cpuid(
unsigned info,
unsigned* eax,
unsigned* ebx,
unsigned* ecx,
unsigned* edx)
688 *eax = *ebx = *ecx = *edx = 0;
702 :
"=a"(*eax),
"=S"(*ebx),
"=c"(*ecx),
"=d"(*edx)
703 :
"a"(info),
"c"(0));
704 #elif defined(_MSC_VER)
713 #elif defined(_M_ARM) || defined(_M_ARM64)
714 #if defined(__linux__)
716 #define HWCAP_SWP (1 << 0)
717 #define HWCAP_HALF (1 << 1)
718 #define HWCAP_THUMB (1 << 2)
719 #define HWCAP_26BIT (1 << 3)
720 #define HWCAP_FAST_MULT (1 << 4)
721 #define HWCAP_FPA (1 << 5)
722 #define HWCAP_VFP (1 << 6)
723 #define HWCAP_EDSP (1 << 7)
724 #define HWCAP_JAVA (1 << 8)
725 #define HWCAP_IWMMXT (1 << 9)
726 #define HWCAP_CRUNCH (1 << 10)
727 #define HWCAP_THUMBEE (1 << 11)
728 #define HWCAP_NEON (1 << 12)
729 #define HWCAP_VFPv3 (1 << 13)
730 #define HWCAP_VFPv3D16 (1 << 14)
731 #define HWCAP_TLS (1 << 15)
732 #define HWCAP_VFPv4 (1 << 16)
733 #define HWCAP_IDIVA (1 << 17)
734 #define HWCAP_IDIVT (1 << 18)
735 #define HWCAP_VFPD32 (1 << 19)
736 #define HWCAP_IDIV (HWCAP_IDIVA | HWCAP_IDIVT)
741 static unsigned GetARMCPUCaps(
void)
744 int fd = open(
"/proc/self/auxv", O_RDONLY);
758 num = read(fd, (
char*)&auxvec,
sizeof(auxvec));
760 if (num < 1 || (auxvec.a_type == 0 && auxvec.a_val == 0))
763 if (auxvec.a_type == AT_HWCAP)
778 #if defined(_M_ARM) || defined(_M_ARM64)
780 #include <sys/auxv.h>
784 BOOL IsProcessorFeaturePresent(DWORD ProcessorFeature)
788 const uint64_t features = android_getCpuFeatures();
790 switch (ProcessorFeature)
792 case PF_ARM_NEON_INSTRUCTIONS_AVAILABLE:
794 return features & ANDROID_CPU_ARM_FEATURE_NEON;
797 WLog_WARN(TAG,
"feature 0x%08" PRIx32
" check not implemented", ProcessorFeature);
801 #elif defined(_M_ARM) || defined(_M_ARM64)
803 const unsigned long caps = getauxval(AT_HWCAP);
805 switch (ProcessorFeature)
807 case PF_ARM_NEON_INSTRUCTIONS_AVAILABLE:
810 if (caps & HWCAP_NEON)
816 if (caps & HWCAP_THUMB)
819 case PF_ARM_VFP_32_REGISTERS_AVAILABLE:
820 if (caps & HWCAP_VFPD32)
823 case PF_ARM_DIVIDE_INSTRUCTION_AVAILABLE:
824 if ((caps & HWCAP_IDIVA) || (caps & HWCAP_IDIVT))
828 if (caps & HWCAP_VFPv3)
834 if (caps & HWCAP_JAVA)
840 if (caps & HWCAP_EDSP)
846 if (caps & HWCAP_EDSP)
852 if ((caps & HWCAP_IDIVT) || (caps & HWCAP_VFPv4))
858 if (caps & HWCAP_THUMBEE)
863 case PF_ARM_INTEL_WMMX:
864 if (caps & HWCAP_IWMMXT)
868 case PF_ARM_V8_INSTRUCTIONS_AVAILABLE:
869 case PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE:
870 case PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE:
871 case PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE:
872 case PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE:
873 case PF_ARM_V83_JSCVT_INSTRUCTIONS_AVAILABLE:
874 case PF_ARM_V83_LRCPC_INSTRUCTIONS_AVAILABLE:
876 WLog_WARN(TAG,
"feature 0x%08" PRIx32
" check not implemented", ProcessorFeature);
882 switch (ProcessorFeature)
884 case PF_ARM_NEON_INSTRUCTIONS_AVAILABLE:
890 case PF_ARM_V8_INSTRUCTIONS_AVAILABLE:
891 case PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE:
892 case PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE:
893 case PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE:
894 case PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE:
895 case PF_ARM_V83_JSCVT_INSTRUCTIONS_AVAILABLE:
896 case PF_ARM_V83_LRCPC_INSTRUCTIONS_AVAILABLE:
898 WLog_WARN(TAG,
"feature 0x%08" PRIx32
" check not implemented", ProcessorFeature);
905 #if defined(_M_IX86_AMD64)
911 cpuid(1, &a, &b, &c, &d);
913 switch (ProcessorFeature)
915 case PF_MMX_INSTRUCTIONS_AVAILABLE:
921 case PF_XMMI_INSTRUCTIONS_AVAILABLE:
927 case PF_XMMI64_INSTRUCTIONS_AVAILABLE:
933 case PF_3DNOW_INSTRUCTIONS_AVAILABLE:
939 case PF_SSE3_INSTRUCTIONS_AVAILABLE:
940 ret = __builtin_cpu_supports(
"sse3");
943 case PF_SSSE3_INSTRUCTIONS_AVAILABLE:
944 ret = __builtin_cpu_supports(
"ssse3");
946 case PF_SSE4_1_INSTRUCTIONS_AVAILABLE:
947 ret = __builtin_cpu_supports(
"sse4.1");
949 case PF_SSE4_2_INSTRUCTIONS_AVAILABLE:
950 ret = __builtin_cpu_supports(
"sse4.2");
952 case PF_AVX_INSTRUCTIONS_AVAILABLE:
953 ret = __builtin_cpu_supports(
"avx");
955 case PF_AVX2_INSTRUCTIONS_AVAILABLE:
956 ret = __builtin_cpu_supports(
"avx2");
958 case PF_AVX512F_INSTRUCTIONS_AVAILABLE:
959 ret = __builtin_cpu_supports(
"avx512f");
962 WLog_WARN(TAG,
"feature 0x%08" PRIx32
" check not implemented", ProcessorFeature);
971 switch (ProcessorFeature)
973 case PF_MMX_INSTRUCTIONS_AVAILABLE:
979 case PF_3DNOW_INSTRUCTIONS_AVAILABLE:
985 case PF_SSE3_INSTRUCTIONS_AVAILABLE:
1001 DWORD GetTickCountPrecise(
void)
1004 LARGE_INTEGER freq = { 0 };
1005 LARGE_INTEGER current = { 0 };
1006 QueryPerformanceFrequency(&freq);
1007 QueryPerformanceCounter(¤t);
1008 return (DWORD)(current.QuadPart * 1000LL / freq.QuadPart);
1010 return GetTickCount();
1014 BOOL IsProcessorFeaturePresentEx(DWORD ProcessorFeature)
1017 #if defined(_M_ARM) || defined(_M_ARM64)
1020 caps = GetARMCPUCaps();
1022 switch (ProcessorFeature)
1024 case PF_EX_ARM_VFP1:
1025 if (caps & HWCAP_VFP)
1030 case PF_EX_ARM_VFP3D16:
1031 if (caps & HWCAP_VFPv3D16)
1036 case PF_EX_ARM_VFP4:
1037 if (caps & HWCAP_VFPv4)
1042 case PF_EX_ARM_IDIVA:
1043 if (caps & HWCAP_IDIVA)
1048 case PF_EX_ARM_IDIVT:
1049 if (caps & HWCAP_IDIVT)
1056 #elif defined(_M_IX86_AMD64)
1061 cpuid(1, &a, &b, &c, &d);
1063 switch (ProcessorFeature)
1071 cpuid(0x80000001, &a81, &b81, &c81, &d81);
1073 if (c81 & C81_BIT_LZCNT)
1078 case PF_EX_3DNOW_PREFETCH:
1085 if (c & C_BIT_SSSE3)
1091 if (c & C_BIT_SSE41)
1097 if (c & C_BIT_SSE42)
1101 #if defined(__GNUC__) || defined(_MSC_VER)
1108 case PF_EX_AVX_PCLMULQDQ:
1111 if (!(c & C_BIT_AVX))
1115 if (!(c & C_BIT_XGETBV))
1123 if ((e & E_BITS_AVX) == E_BITS_AVX)
1125 switch (ProcessorFeature)
1133 cpuid(7, &a, &b, &c, &d);
1134 switch (ProcessorFeature)
1142 if (b & B_BIT_AVX512F)
1163 case PF_EX_AVX_PCLMULQDQ:
1164 if (c & C_BIT_PCLMULQDQ)
1179 #elif defined(_M_E2K)
1181 switch (ProcessorFeature)