32 #ifndef _AK_TOOLS_COMMON_AKPLATFORMFUNCS_H
33 #define _AK_TOOLS_COMMON_AKPLATFORMFUNCS_H
44 #elif defined (AK_XBOX)
45 #include <AK/Tools/XboxOne/AkPlatformFuncs.h>
47 #elif defined (AK_APPLE)
49 #include <AK/Tools/POSIX/AkPlatformFuncs.h>
51 #elif defined( AK_ANDROID ) || defined ( AK_LINUX_AOSP )
54 #elif defined ( AK_HARMONY )
57 #elif defined (AK_PS4)
60 #elif defined (AK_PS5)
63 #elif defined (AK_EMSCRIPTEN)
64 #include <AK/Tools/Emscripten/AkPlatformFuncs.h>
66 #elif defined (AK_LINUX)
69 #include <AK/Tools/GGP/AkPlatformFuncs.h>
72 #include <AK/Tools/POSIX/AkPlatformFuncs.h>
74 #elif defined (AK_QNX)
75 #include <AK/Tools/QNX/AkPlatformFuncs.h>
76 #include <AK/Tools/POSIX/AkPlatformFuncs.h>
82 #error AkPlatformFuncs.h: Undefined platform
85 #ifndef AkPrefetchZero
86 #define AkPrefetchZero(___Dest, ___Size)
89 #ifndef AkPrefetchZeroAligned
90 #define AkPrefetchZeroAligned(___Dest, ___Size)
93 #ifndef AkZeroMemAligned
94 #define AkZeroMemAligned(___Dest, ___Size) AKPLATFORM::AkMemSet(___Dest, 0, ___Size);
96 #ifndef AkZeroMemLarge
97 #define AkZeroMemLarge(___Dest, ___Size) AKPLATFORM::AkMemSet(___Dest, 0, ___Size);
99 #ifndef AkZeroMemSmall
100 #define AkZeroMemSmall(___Dest, ___Size) AKPLATFORM::AkMemSet(___Dest, 0, ___Size);
105 #if __has_builtin( __builtin_alloca_with_align )
106 #define AkAllocaSIMD( _size_ ) __builtin_alloca_with_align( _size_, 128 )
109 #define AkAllocaSIMD( _size_ ) (void*)( ( ( uintptr_t )AkAlloca( _size_ + 16 ) + 0xF ) & ~0xF )
112 #define AkAllocaSIMD( _size_ ) AkAlloca( _size_ )
116 #ifndef AK_THREAD_INIT_CODE
117 #define AK_THREAD_INIT_CODE(_threadProperties)
128 while( in_uWord ){ ++num; in_uWord &= in_uWord-1; }
137 in_uValue |= in_uValue >> 1;
138 in_uValue |= in_uValue >> 2;
139 in_uValue |= in_uValue >> 4;
140 in_uValue |= in_uValue >> 8;
141 in_uValue |= in_uValue >> 16;
148 return ( x << r ) | ( x >> ( 32 - r ) );
153 return ( x << r ) | ( x >> ( 64 - r ) );
167 #if !defined(AK_BIT_SCAN_INSTRUCTIONS)
171 #if defined(__clang__) || defined (__GNUC__)
174 return __builtin_popcountll(in_bits);
180 while (in_bits) { ++num; in_bits &= in_bits - 1; }
187 #if defined(__clang__) || defined (__GNUC__)
190 return __builtin_popcount(in_bits);
196 while (in_bits) { ++num; in_bits &= in_bits - 1; }
204 #if defined _MSC_VER && (defined AK_CPU_X86_64 || defined AK_CPU_ARM_64)
207 unsigned long ret = 0;
208 _BitScanForward64(&ret, in_bits);
209 return in_bits ? ret : 64;
211 #elif defined(__clang__) || defined (__GNUC__)
214 return in_bits ? __builtin_ctzll(in_bits) : 64;
219 if (in_bits == 0)
return 64;
221 if ((in_bits & 0x00000000FFFFFFFFULL) == 0) { ret += 32; in_bits >>= 32; }
222 if ((in_bits & 0x000000000000FFFFULL) == 0) { ret += 16; in_bits >>= 16; }
223 if ((in_bits & 0x00000000000000FFULL) == 0) { ret += 8; in_bits >>= 8; }
224 if ((in_bits & 0x000000000000000FULL) == 0) { ret += 4; in_bits >>= 4; }
225 if ((in_bits & 0x0000000000000003ULL) == 0) { ret += 2; in_bits >>= 2; }
226 if ((in_bits & 0x0000000000000001ULL) == 0) { ret += 1; in_bits >>= 1; }
234 unsigned long ret = 0;
235 _BitScanForward(&ret, in_bits);
236 return in_bits ? ret : 32;
239 #elif defined(__clang__) || defined (__GNUC__)
242 return in_bits ? __builtin_ctz(in_bits) : 32;
247 if (in_bits == 0)
return 32;
249 if ((in_bits & 0x0000FFFFULL) == 0) { ret += 16; in_bits >>= 16; }
250 if ((in_bits & 0x000000FFULL) == 0) { ret += 8; in_bits >>= 8; }
251 if ((in_bits & 0x0000000FULL) == 0) { ret += 4; in_bits >>= 4; }
252 if ((in_bits & 0x00000003ULL) == 0) { ret += 2; in_bits >>= 2; }
253 if ((in_bits & 0x00000001ULL) == 0) { ret += 1; in_bits >>= 1; }
261 #if defined _MSC_VER && (defined AK_CPU_X86_64 || defined AK_CPU_ARM_64)
264 unsigned long ret = 0;
265 _BitScanReverse64(&ret, in_bits);
266 return in_bits ? 63 - ret : 64;
268 #elif defined(__clang__) || defined (__GNUC__)
271 return in_bits ? __builtin_clzll(in_bits) : 64;
276 if (in_bits == 0)
return 64;
278 if ((in_bits & 0xFFFFFFFF00000000ULL) == 0) { ret += 32; in_bits <<= 32; }
279 if ((in_bits & 0xFFFF000000000000ULL) == 0) { ret += 16; in_bits <<= 16; }
280 if ((in_bits & 0xFF00000000000000ULL) == 0) { ret += 8; in_bits <<= 8; }
281 if ((in_bits & 0xF000000000000000ULL) == 0) { ret += 4; in_bits <<= 4; }
282 if ((in_bits & 0xC000000000000000ULL) == 0) { ret += 2; in_bits <<= 2; }
283 if ((in_bits & 0x8000000000000000ULL) == 0) { ret += 1; in_bits <<= 1; }
291 unsigned long ret = 0;
292 _BitScanReverse(&ret, in_bits);
293 return in_bits ? 31 - ret : 32;
295 #elif defined(__clang__) || defined (__GNUC__)
298 return in_bits ? __builtin_clz(in_bits) : 32;
303 if (in_bits == 0)
return 32;
305 if ((in_bits & 0xFFFF0000ULL) == 0) { ret += 16; in_bits <<= 16; }
306 if ((in_bits & 0xFF000000ULL) == 0) { ret += 8; in_bits <<= 8; }
307 if ((in_bits & 0xF0000000ULL) == 0) { ret += 4; in_bits <<= 4; }
308 if ((in_bits & 0xC0000000ULL) == 0) { ret += 2; in_bits <<= 2; }
309 if ((in_bits & 0x80000000ULL) == 0) { ret += 1; in_bits <<= 1; }
314 #endif // defined(AK_BIT_SCAN_INSTRUCTIONS)
317 #if !defined(AK_LIMITEDSPINFORZERO)
336 if (currentTime > endSpinTime)
368 if (currentTime > endSpinTime)
403 #ifndef AK_PERF_RECORDING_RESET
404 #define AK_PERF_RECORDING_RESET()
406 #ifndef AK_PERF_RECORDING_START
407 #define AK_PERF_RECORDING_START( __StorageName__, __uExecutionCountStart__, __uExecutionCountStop__ )
409 #ifndef AK_PERF_RECORDING_STOP
410 #define AK_PERF_RECORDING_STOP( __StorageName__, __uExecutionCountStart__, __uExecutionCountStop__ )
413 #endif // _AK_TOOLS_COMMON_AKPLATFORMFUNCS_H