2 #ifndef BT_CPU_UTILITY_H
3 #define BT_CPU_UTILITY_H
5 #include "LinearMath/btScalar.h"
7 #include <string.h>//memset
12 #endif //BT_ALLOW_SSE4
15 #if defined BT_USE_NEON
16 #define ARM_NEON_GCC_COMPATIBILITY 1
18 #include <sys/types.h>
19 #include <sys/sysctl.h> //for sysctlbyname
22 ///Rudimentary btCpuFeatureUtility for CPU features: only report the features that Bullet actually uses (SSE4/FMA3, NEON_HPFP)
23 ///We assume SSE2 in case BT_USE_SSE2 is defined in LinearMath/btScalar.h
24 class btCpuFeatureUtility
31 CPU_FEATURE_NEON_HPFP
=4
34 static int getCpuFeatures()
37 static int capabilities
= 0;
38 static bool testedCapabilities
= false;
39 if (0 != testedCapabilities
)
46 uint32_t hasFeature
= 0;
47 size_t featureSize
= sizeof(hasFeature
);
48 int err
= sysctlbyname("hw.optional.neon_hpfp", &hasFeature
, &featureSize
, NULL
, 0);
49 if (0 == err
&& hasFeature
)
50 capabilities
|= CPU_FEATURE_NEON_HPFP
;
57 memset(cpuInfo
, 0, sizeof(cpuInfo
));
58 unsigned long long sseExt
= 0;
61 bool osUsesXSAVE_XRSTORE
= cpuInfo
[2] & (1 << 27) || false;
62 bool cpuAVXSuport
= cpuInfo
[2] & (1 << 28) || false;
64 if (osUsesXSAVE_XRSTORE
&& cpuAVXSuport
)
68 const int OSXSAVEFlag
= (1UL << 27);
69 const int AVXFlag
= ((1UL << 28) | OSXSAVEFlag
);
70 const int FMAFlag
= ((1UL << 12) | AVXFlag
| OSXSAVEFlag
);
71 if ((cpuInfo
[2] & FMAFlag
) == FMAFlag
&& (sseExt
& 6) == 6)
73 capabilities
|= btCpuFeatureUtility::CPU_FEATURE_FMA3
;
76 const int SSE41Flag
= (1 << 19);
77 if (cpuInfo
[2] & SSE41Flag
)
79 capabilities
|= btCpuFeatureUtility::CPU_FEATURE_SSE4_1
;
84 testedCapabilities
= true;
92 #endif //BT_CPU_UTILITY_H