1 2 #ifndef BT_CPU_UTILITY_H 3 #define BT_CPU_UTILITY_H 4 5 #include "LinearMath/btScalar.h" 6 7 #include <string.h>//memset 8 #ifdef USE_SIMD 9 #include <emmintrin.h> 10 #ifdef BT_ALLOW_SSE4 11 #include <intrin.h> 12 #endif //BT_ALLOW_SSE4 13 #endif //USE_SIMD 14 15 #if defined BT_USE_NEON 16 #define ARM_NEON_GCC_COMPATIBILITY 1 17 #include <arm_neon.h> 18 #include <sys/types.h> 19 #include <sys/sysctl.h> //for sysctlbyname 20 #endif //BT_USE_NEON 21 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 25 { 26 public: 27 enum btCpuFeature 28 { 29 CPU_FEATURE_FMA3=1, 30 CPU_FEATURE_SSE4_1=2, 31 CPU_FEATURE_NEON_HPFP=4 32 }; 33 34 static int getCpuFeatures() 35 { 36 37 static int capabilities = 0; 38 static bool testedCapabilities = false; 39 if (0 != testedCapabilities) 40 { 41 return capabilities; 42 } 43 44 #ifdef BT_USE_NEON 45 { 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; 51 } 52 #endif //BT_USE_NEON 53 54 #ifdef BT_ALLOW_SSE4 55 { 56 int cpuInfo[4]; 57 memset(cpuInfo, 0, sizeof(cpuInfo)); 58 unsigned long long sseExt = 0; 59 __cpuid(cpuInfo, 1); 60 61 bool osUsesXSAVE_XRSTORE = cpuInfo[2] & (1 << 27) || false; 62 bool cpuAVXSuport = cpuInfo[2] & (1 << 28) || false; 63 64 if (osUsesXSAVE_XRSTORE && cpuAVXSuport) 65 { 66 sseExt = _xgetbv(0); 67 } 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) 72 { 73 capabilities |= btCpuFeatureUtility::CPU_FEATURE_FMA3; 74 } 75 76 const int SSE41Flag = (1 << 19); 77 if (cpuInfo[2] & SSE41Flag) 78 { 79 capabilities |= btCpuFeatureUtility::CPU_FEATURE_SSE4_1; 80 } 81 } 82 #endif//BT_ALLOW_SSE4 83 84 testedCapabilities = true; 85 return capabilities; 86 } 87 88 89 }; 90 91 92 #endif //BT_CPU_UTILITY_H 93