checking for cpu features can be handy so that one doesn't have to resort to inline asm
to compile with gcc do
gcc -c -O2 built_in.c
then to build the lib do
ar rcs libbuilt_in.a built_in.o
or you can get the binaries here https://u.pcloud.link/publink/show?code ... HBWyjsC1tV
built_in.c
Code: Select all
#include <cpuid.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
extern int __builtin_cpu_supports (const char *feature);
extern int __builtin_ia32_rdrand16_step (uint16_t *);
extern int __builtin_ia32_rdrand32_step (uint32_t *);
#if __SIZEOF_POINTER__ == 8
extern int __builtin_ia32_rdrand64_step (uint64_t *);
#endif
int cpu_supports_cmov (void)
{
return __builtin_cpu_supports ("cmov");
}
int cpu_supports_mmx (void)
{
return __builtin_cpu_supports ("mmx");
}
int cpu_supports_popcnt (void)
{
return __builtin_cpu_supports ("popcnt");
}
int cpu_supports_sse (void)
{
return __builtin_cpu_supports ("sse");
}
int cpu_supports_sse2 (void)
{
return __builtin_cpu_supports ("sse2");
}
int cpu_supports_sse3 (void)
{
return __builtin_cpu_supports ("sse3");
}
int cpu_supports_sse41 (void)
{
return __builtin_cpu_supports ("sse4.1");
}
int cpu_supports_sse42 (void)
{
return __builtin_cpu_supports ("sse4.2");
}
int cpu_supports_sse4a (void)
{
return __builtin_cpu_supports ("sse4a");
}
int cpu_supports_avx (void)
{
return __builtin_cpu_supports ("avx");
}
int cpu_supports_avx2 (void)
{
return __builtin_cpu_supports ("avx2");
}
int cpu_supports_fma4 (void)
{
return __builtin_cpu_supports ("fma4");
}
int cpu_supports_xop (void)
{
return __builtin_cpu_supports ("xop");
}
int cpu_supports_fma (void)
{
return __builtin_cpu_supports ("fma");
}
int cpu_supports_avx512f (void)
{
return __builtin_cpu_supports ("avx512f");
}
int cpu_supports_bmi (void)
{
return __builtin_cpu_supports ("bmi");
}
int cpu_supports_bmi2 (void)
{
return __builtin_cpu_supports ("bmi2");
}
int cpu_supports_aes (void)
{
return __builtin_cpu_supports ("aes");
}
int cpu_supports_pclmul (void)
{
return __builtin_cpu_supports ("pclmul");
}
int cpu_supports_avx512vl (void)
{
return __builtin_cpu_supports ("avx512vl");
}
int cpu_supports_avx512bw (void)
{
return __builtin_cpu_supports ("avx512bw");
}
int cpu_supports_avx512dq (void)
{
return __builtin_cpu_supports ("avx512dq");
}
int cpu_supports_avx512cd (void)
{
return __builtin_cpu_supports ("avx512cd");
}
int cpu_supports_avx512er (void)
{
return __builtin_cpu_supports ("avx512er");
}
int cpu_supports_avx512pf (void)
{
return __builtin_cpu_supports ("avx512pf");
}
int cpu_supports_avx512vbmi (void)
{
return __builtin_cpu_supports ("avx512vbmi");
}
int cpu_supports_avx512ifma (void)
{
return __builtin_cpu_supports ("avx512ifma");
}
int cpu_supports_avx5124vnniw (void)
{
return __builtin_cpu_supports ("avx5124vnniw");
}
int cpu_supports_avx5124fmaps (void)
{
return __builtin_cpu_supports ("avx5124fmaps");
}
int cpu_supports_avx512vpopcntdq (void)
{
return __builtin_cpu_supports ("avx512vpopcntdq");
}
int cpu_supports_avx512vbmi2 (void)
{
return __builtin_cpu_supports ("avx512vbmi2");
}
int cpu_supports_gfni (void)
{
return __builtin_cpu_supports ("gfni");
}
int cpu_supports_vpclmulqdq (void)
{
return __builtin_cpu_supports ("vpclmulqdq");
}
int cpu_supports_avx512vnni (void)
{
return __builtin_cpu_supports ("avx512vnni");
}
int cpu_supports_avx512bitalg (void)
{
return __builtin_cpu_supports ("avx512bitalg");
}
int cpu_supports_x86_64 (void)
{
return __builtin_cpu_supports ("x86-64");
}
int cpu_supports_x86_64_v2 (void)
{
return __builtin_cpu_supports ("x86-64-v2");
}
int cpu_supports_x86_64_v3 (void)
{
return __builtin_cpu_supports ("x86-64-v3");
}
int cpu_supports_x86_64_v4 (void)
{
return __builtin_cpu_supports ("x86-64-v4");
}
void call_cpuid(unsigned int EAX_input, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) {
unsigned int ret;
ret = __get_cpuid(EAX_input, eax, ebx, ecx, edx);
if (ret != 1) {
printf( "Failed to call CPUID with EAX=%d", EAX_input);
}
}
int ia32_rdrand16_step (uint16_t *r)
{
return __builtin_ia32_rdrand16_step (r);
}
int ia32_rdrand32_step (uint32_t *r)
{
return __builtin_ia32_rdrand32_step (r);
}
#if __SIZEOF_POINTER__ == 8
int ia32_rdrand64_step (uint64_t *r)
{
return __builtin_ia32_rdrand64_step (r);
}
#endif
/*
int main(void)
{
#if __SIZEOF_POINTER__ == 8
uint64_t r;
unsigned int f;
f=ia32_rdrand64_step (&r);
printf("%lld\n",r);
#else
uint32_t r;
unsigned int f;
f=ia32_rdrand32_step (&r);
printf("%ld\n",r);
#endif
return 0;
}
*/
Code: Select all
#inclib "built_in"
extern "C"
declare function cpu_supports_cmov() as long
declare function cpu_supports_mmx() as long
declare function cpu_supports_popcnt() as long
declare function cpu_supports_sse() as long
declare function cpu_supports_sse2() as long
declare function cpu_supports_sse3() as long
declare function cpu_supports_sse41() as long
declare function cpu_supports_sse42() as long
declare function cpu_supports_sse4a() as long
declare function cpu_supports_avx() as long
declare function cpu_supports_avx2() as long
declare function cpu_supports_fma4() as long
declare function cpu_supports_xop() as long
declare function cpu_supports_fma() as long
declare function cpu_supports_avx512f() as long
declare function cpu_supports_bmi() as long
declare function cpu_supports_bmi2() as long
declare function cpu_supports_aes() as long
declare function cpu_supports_pclmul() as long
declare function cpu_supports_avx512vl() as long
declare function cpu_supports_avx512bw() as long
declare function cpu_supports_avx512dq() as long
declare function cpu_supports_avx512cd() as long
declare function cpu_supports_avx512er() as long
declare function cpu_supports_avx512pf() as long
declare function cpu_supports_avx512vbmi() as long
declare function cpu_supports_avx512ifma() as long
declare function cpu_supports_avx5124vnniw() as long
declare function cpu_supports_avx5124fmaps() as long
declare function cpu_supports_avx512vpopcntdq() as long
declare function cpu_supports_avx512vbmi2() as long
declare function cpu_supports_gfni() as long
declare function cpu_supports_vpclmulqdq() as long
declare function cpu_supports_avx512vnni() as long
declare function cpu_supports_avx512bitalg() as long
declare function cpu_supports_x86_64() as long
declare function cpu_supports_x86_64_v2() as long
declare function cpu_supports_x86_64_v3() as long
declare function cpu_supports_x86_64_v4() as long
declare sub call_cpuid(byval EAX_input as ulong, byref eax as ulong, byref ebx as ulong, byref ecx as ulong, byref edx as ulong)
declare function ia32_rdrand16_step (byref as ushort) as ulong
declare function ia32_rdrand32_step (byref as ulong) as ulong
declare function ia32_rdrand64_step (byref as ulongint) as ulong
end extern
Code: Select all
'#cmdline "-asm att -w all -arch native -gen clang -Wc -O2"
#include "built_in.bi"
union cpuid
as ulong r(2)
as string*12 id
end union
function cpu_id() as string
dim as cpuid id
dim as ulong Reax
call_cpuid(0, Reax, id.r(0), id.r(2), id.r(1))
return id.id
end function
Print "cpu_supports_aes = ";cpu_supports_aes
Print "cpu_supports_avx = ";cpu_supports_avx
Print "cpu_supports_avx2 = ";cpu_supports_avx2
Print "cpu_supports_sse42 = ";cpu_supports_sse42
Print "cpu id = ";cpu_id
dim as ulong r
dim as ulongint rr
if ia32_rdrand32_step (r)<>0 then
Print "r = ";r
end if
#ifdef __FB_64BIT__
if ia32_rdrand64_step(rr)<>0 then
Print "rr = ";rr
end if
#endif
Sleep
a zero result means that the function is not supported
see https://gcc.gnu.org/onlinedocs/gcc/x86- ... tions.html
https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
https://gcc.gnu.org/onlinedocs/gcc/Inte ... ltins.html
<edit> added binaries and added the __builtin_ia32_rdrandxx functions