Home | History | Annotate | Download | only in LinearMath
      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