aboutsummaryrefslogtreecommitdiff
path: root/C/CpuArch.c
diff options
context:
space:
mode:
Diffstat (limited to 'C/CpuArch.c')
-rw-r--r--C/CpuArch.c94
1 files changed, 73 insertions, 21 deletions
diff --git a/C/CpuArch.c b/C/CpuArch.c
index 33f8a3a..d51b38a 100644
--- a/C/CpuArch.c
+++ b/C/CpuArch.c
@@ -1,5 +1,5 @@
1/* CpuArch.c -- CPU specific code 1/* CpuArch.c -- CPU specific code
22023-05-18 : Igor Pavlov : Public domain */ 22024-03-02 : Igor Pavlov : Public domain */
3 3
4#include "Precomp.h" 4#include "Precomp.h"
5 5
@@ -226,7 +226,7 @@ void __declspec(naked) Z7_FASTCALL z7_x86_cpuid(UInt32 p[4], UInt32 func)
226DON'T remove Z7_NO_INLINE and Z7_FASTCALL for MY_cpuidex_HACK(): !!! 226DON'T remove Z7_NO_INLINE and Z7_FASTCALL for MY_cpuidex_HACK(): !!!
227*/ 227*/
228static 228static
229Z7_NO_INLINE void Z7_FASTCALL MY_cpuidex_HACK(UInt32 subFunction, UInt32 func, int *CPUInfo) 229Z7_NO_INLINE void Z7_FASTCALL MY_cpuidex_HACK(Int32 subFunction, Int32 func, Int32 *CPUInfo)
230{ 230{
231 UNUSED_VAR(subFunction) 231 UNUSED_VAR(subFunction)
232 __cpuid(CPUInfo, func); 232 __cpuid(CPUInfo, func);
@@ -242,13 +242,13 @@ Z7_NO_INLINE
242#endif 242#endif
243void Z7_FASTCALL z7_x86_cpuid(UInt32 p[4], UInt32 func) 243void Z7_FASTCALL z7_x86_cpuid(UInt32 p[4], UInt32 func)
244{ 244{
245 MY_cpuidex((int *)p, (int)func, 0); 245 MY_cpuidex((Int32 *)p, (Int32)func, 0);
246} 246}
247 247
248Z7_NO_INLINE 248Z7_NO_INLINE
249UInt32 Z7_FASTCALL z7_x86_cpuid_GetMaxFunc(void) 249UInt32 Z7_FASTCALL z7_x86_cpuid_GetMaxFunc(void)
250{ 250{
251 int a[4]; 251 Int32 a[4];
252 MY_cpuidex(a, 0, 0); 252 MY_cpuidex(a, 0, 0);
253 return a[0]; 253 return a[0];
254} 254}
@@ -384,7 +384,7 @@ BoolInt CPU_IsSupported_CMOV(void)
384 UInt32 a[4]; 384 UInt32 a[4];
385 if (!x86cpuid_Func_1(&a[0])) 385 if (!x86cpuid_Func_1(&a[0]))
386 return 0; 386 return 0;
387 return (a[3] >> 15) & 1; 387 return (BoolInt)(a[3] >> 15) & 1;
388} 388}
389 389
390BoolInt CPU_IsSupported_SSE(void) 390BoolInt CPU_IsSupported_SSE(void)
@@ -393,7 +393,7 @@ BoolInt CPU_IsSupported_SSE(void)
393 CHECK_SYS_SSE_SUPPORT 393 CHECK_SYS_SSE_SUPPORT
394 if (!x86cpuid_Func_1(&a[0])) 394 if (!x86cpuid_Func_1(&a[0]))
395 return 0; 395 return 0;
396 return (a[3] >> 25) & 1; 396 return (BoolInt)(a[3] >> 25) & 1;
397} 397}
398 398
399BoolInt CPU_IsSupported_SSE2(void) 399BoolInt CPU_IsSupported_SSE2(void)
@@ -402,7 +402,7 @@ BoolInt CPU_IsSupported_SSE2(void)
402 CHECK_SYS_SSE_SUPPORT 402 CHECK_SYS_SSE_SUPPORT
403 if (!x86cpuid_Func_1(&a[0])) 403 if (!x86cpuid_Func_1(&a[0]))
404 return 0; 404 return 0;
405 return (a[3] >> 26) & 1; 405 return (BoolInt)(a[3] >> 26) & 1;
406} 406}
407 407
408#endif 408#endif
@@ -419,17 +419,17 @@ static UInt32 x86cpuid_Func_1_ECX(void)
419 419
420BoolInt CPU_IsSupported_AES(void) 420BoolInt CPU_IsSupported_AES(void)
421{ 421{
422 return (x86cpuid_Func_1_ECX() >> 25) & 1; 422 return (BoolInt)(x86cpuid_Func_1_ECX() >> 25) & 1;
423} 423}
424 424
425BoolInt CPU_IsSupported_SSSE3(void) 425BoolInt CPU_IsSupported_SSSE3(void)
426{ 426{
427 return (x86cpuid_Func_1_ECX() >> 9) & 1; 427 return (BoolInt)(x86cpuid_Func_1_ECX() >> 9) & 1;
428} 428}
429 429
430BoolInt CPU_IsSupported_SSE41(void) 430BoolInt CPU_IsSupported_SSE41(void)
431{ 431{
432 return (x86cpuid_Func_1_ECX() >> 19) & 1; 432 return (BoolInt)(x86cpuid_Func_1_ECX() >> 19) & 1;
433} 433}
434 434
435BoolInt CPU_IsSupported_SHA(void) 435BoolInt CPU_IsSupported_SHA(void)
@@ -441,7 +441,7 @@ BoolInt CPU_IsSupported_SHA(void)
441 { 441 {
442 UInt32 d[4]; 442 UInt32 d[4];
443 z7_x86_cpuid(d, 7); 443 z7_x86_cpuid(d, 7);
444 return (d[1] >> 29) & 1; 444 return (BoolInt)(d[1] >> 29) & 1;
445 } 445 }
446} 446}
447 447
@@ -640,8 +640,8 @@ BoolInt CPU_IsSupported_AVX(void)
640 const UInt32 bm = (UInt32)x86_xgetbv_0(MY_XCR_XFEATURE_ENABLED_MASK); 640 const UInt32 bm = (UInt32)x86_xgetbv_0(MY_XCR_XFEATURE_ENABLED_MASK);
641 // printf("\n=== XGetBV=%d\n", bm); 641 // printf("\n=== XGetBV=%d\n", bm);
642 return 1 642 return 1
643 & (bm >> 1) // SSE state is supported (set by OS) for storing/restoring 643 & (BoolInt)(bm >> 1) // SSE state is supported (set by OS) for storing/restoring
644 & (bm >> 2); // AVX state is supported (set by OS) for storing/restoring 644 & (BoolInt)(bm >> 2); // AVX state is supported (set by OS) for storing/restoring
645 } 645 }
646 // since Win7SP1: we can use GetEnabledXStateFeatures(); 646 // since Win7SP1: we can use GetEnabledXStateFeatures();
647} 647}
@@ -658,10 +658,29 @@ BoolInt CPU_IsSupported_AVX2(void)
658 z7_x86_cpuid(d, 7); 658 z7_x86_cpuid(d, 7);
659 // printf("\ncpuid(7): ebx=%8x ecx=%8x\n", d[1], d[2]); 659 // printf("\ncpuid(7): ebx=%8x ecx=%8x\n", d[1], d[2]);
660 return 1 660 return 1
661 & (d[1] >> 5); // avx2 661 & (BoolInt)(d[1] >> 5); // avx2
662 } 662 }
663} 663}
664 664
665/*
666// fix it:
667BoolInt CPU_IsSupported_AVX512F_AVX512VL(void)
668{
669 if (!CPU_IsSupported_AVX())
670 return False;
671 if (z7_x86_cpuid_GetMaxFunc() < 7)
672 return False;
673 {
674 UInt32 d[4];
675 z7_x86_cpuid(d, 7);
676 // printf("\ncpuid(7): ebx=%8x ecx=%8x\n", d[1], d[2]);
677 return 1
678 & (BoolInt)(d[1] >> 16) // avx512-f
679 & (BoolInt)(d[1] >> 31); // avx512-Vl
680 }
681}
682*/
683
665BoolInt CPU_IsSupported_VAES_AVX2(void) 684BoolInt CPU_IsSupported_VAES_AVX2(void)
666{ 685{
667 if (!CPU_IsSupported_AVX()) 686 if (!CPU_IsSupported_AVX())
@@ -673,9 +692,9 @@ BoolInt CPU_IsSupported_VAES_AVX2(void)
673 z7_x86_cpuid(d, 7); 692 z7_x86_cpuid(d, 7);
674 // printf("\ncpuid(7): ebx=%8x ecx=%8x\n", d[1], d[2]); 693 // printf("\ncpuid(7): ebx=%8x ecx=%8x\n", d[1], d[2]);
675 return 1 694 return 1
676 & (d[1] >> 5) // avx2 695 & (BoolInt)(d[1] >> 5) // avx2
677 // & (d[1] >> 31) // avx512vl 696 // & (d[1] >> 31) // avx512vl
678 & (d[2] >> 9); // vaes // VEX-256/EVEX 697 & (BoolInt)(d[2] >> 9); // vaes // VEX-256/EVEX
679 } 698 }
680} 699}
681 700
@@ -688,7 +707,7 @@ BoolInt CPU_IsSupported_PageGB(void)
688 if (d[0] < 0x80000001) 707 if (d[0] < 0x80000001)
689 return False; 708 return False;
690 z7_x86_cpuid(d, 0x80000001); 709 z7_x86_cpuid(d, 0x80000001);
691 return (d[3] >> 26) & 1; 710 return (BoolInt)(d[3] >> 26) & 1;
692 } 711 }
693} 712}
694 713
@@ -760,32 +779,65 @@ BoolInt CPU_IsSupported_AES (void) { return APPLE_CRYPTO_SUPPORT_VAL; }
760 779
761#else // __APPLE__ 780#else // __APPLE__
762 781
763#include <sys/auxv.h> 782#if defined(__GLIBC__) && (__GLIBC__ * 100 + __GLIBC_MINOR__ >= 216)
783 #define Z7_GETAUXV_AVAILABLE
784#else
785// #pragma message("=== is not NEW GLIBC === ")
786 #if defined __has_include
787 #if __has_include (<sys/auxv.h>)
788// #pragma message("=== sys/auxv.h is avail=== ")
789 #define Z7_GETAUXV_AVAILABLE
790 #endif
791 #endif
792#endif
764 793
794#ifdef Z7_GETAUXV_AVAILABLE
795// #pragma message("=== Z7_GETAUXV_AVAILABLE === ")
796#include <sys/auxv.h>
765#define USE_HWCAP 797#define USE_HWCAP
798#endif
766 799
767#ifdef USE_HWCAP 800#ifdef USE_HWCAP
768 801
802#if defined(__FreeBSD__)
803static unsigned long MY_getauxval(int aux)
804{
805 unsigned long val;
806 if (elf_aux_info(aux, &val, sizeof(val)))
807 return 0;
808 return val;
809}
810#else
811#define MY_getauxval getauxval
812 #if defined __has_include
813 #if __has_include (<asm/hwcap.h>)
769#include <asm/hwcap.h> 814#include <asm/hwcap.h>
815 #endif
816 #endif
817#endif
770 818
771 #define MY_HWCAP_CHECK_FUNC_2(name1, name2) \ 819 #define MY_HWCAP_CHECK_FUNC_2(name1, name2) \
772 BoolInt CPU_IsSupported_ ## name1() { return (getauxval(AT_HWCAP) & (HWCAP_ ## name2)) ? 1 : 0; } 820 BoolInt CPU_IsSupported_ ## name1(void) { return (MY_getauxval(AT_HWCAP) & (HWCAP_ ## name2)); }
773 821
774#ifdef MY_CPU_ARM64 822#ifdef MY_CPU_ARM64
775 #define MY_HWCAP_CHECK_FUNC(name) \ 823 #define MY_HWCAP_CHECK_FUNC(name) \
776 MY_HWCAP_CHECK_FUNC_2(name, name) 824 MY_HWCAP_CHECK_FUNC_2(name, name)
825#if 1 || defined(__ARM_NEON)
826 BoolInt CPU_IsSupported_NEON(void) { return True; }
827#else
777 MY_HWCAP_CHECK_FUNC_2(NEON, ASIMD) 828 MY_HWCAP_CHECK_FUNC_2(NEON, ASIMD)
829#endif
778// MY_HWCAP_CHECK_FUNC (ASIMD) 830// MY_HWCAP_CHECK_FUNC (ASIMD)
779#elif defined(MY_CPU_ARM) 831#elif defined(MY_CPU_ARM)
780 #define MY_HWCAP_CHECK_FUNC(name) \ 832 #define MY_HWCAP_CHECK_FUNC(name) \
781 BoolInt CPU_IsSupported_ ## name() { return (getauxval(AT_HWCAP2) & (HWCAP2_ ## name)) ? 1 : 0; } 833 BoolInt CPU_IsSupported_ ## name(void) { return (MY_getauxval(AT_HWCAP2) & (HWCAP2_ ## name)); }
782 MY_HWCAP_CHECK_FUNC_2(NEON, NEON) 834 MY_HWCAP_CHECK_FUNC_2(NEON, NEON)
783#endif 835#endif
784 836
785#else // USE_HWCAP 837#else // USE_HWCAP
786 838
787 #define MY_HWCAP_CHECK_FUNC(name) \ 839 #define MY_HWCAP_CHECK_FUNC(name) \
788 BoolInt CPU_IsSupported_ ## name() { return 0; } 840 BoolInt CPU_IsSupported_ ## name(void) { return 0; }
789 MY_HWCAP_CHECK_FUNC(NEON) 841 MY_HWCAP_CHECK_FUNC(NEON)
790 842
791#endif // USE_HWCAP 843#endif // USE_HWCAP