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>
81 #elif defined (AK_OUNCE)
85 #error AkPlatformFuncs.h: Undefined platform
88 #ifndef AkPrefetchZero
89 #define AkPrefetchZero(___Dest, ___Size)
92 #ifndef AkPrefetchZeroAligned
93 #define AkPrefetchZeroAligned(___Dest, ___Size)
96 #ifndef AkZeroMemAligned
97 #define AkZeroMemAligned(___Dest, ___Size) AKPLATFORM::AkMemSet(___Dest, 0, ___Size);
99 #ifndef AkZeroMemLarge
100 #define AkZeroMemLarge(___Dest, ___Size) AKPLATFORM::AkMemSet(___Dest, 0, ___Size);
102 #ifndef AkZeroMemSmall
103 #define AkZeroMemSmall(___Dest, ___Size) AKPLATFORM::AkMemSet(___Dest, 0, ___Size);
108 #if __has_builtin( __builtin_alloca_with_align )
109 #define AkAllocaSIMD( _size_ ) __builtin_alloca_with_align( _size_, 128 )
112 #define AkAllocaSIMD( _size_ ) (void*)( ( ( uintptr_t )AkAlloca( _size_ + 16 ) + 0xF ) & ~0xF )
115 #define AkAllocaSIMD( _size_ ) AkAlloca( _size_ )
119 #ifndef AK_THREAD_INIT_CODE
120 #define AK_THREAD_INIT_CODE(_threadProperties)
131 while( in_uWord ){ ++num; in_uWord &= in_uWord-1; }
140 in_uValue |= in_uValue >> 1;
141 in_uValue |= in_uValue >> 2;
142 in_uValue |= in_uValue >> 4;
143 in_uValue |= in_uValue >> 8;
144 in_uValue |= in_uValue >> 16;
151 return ( x << r ) | ( x >> ( 32 - r ) );
156 return ( x << r ) | ( x >> ( 64 - r ) );
170 #if !defined(AK_BIT_SCAN_INSTRUCTIONS)
174 #if defined(__clang__) || defined (__GNUC__)
177 return __builtin_popcountll(in_bits);
183 while (in_bits) { ++num; in_bits &= in_bits - 1; }
190 #if defined(__clang__) || defined (__GNUC__)
193 return __builtin_popcount(in_bits);
199 while (in_bits) { ++num; in_bits &= in_bits - 1; }
207 #if defined _MSC_VER && (defined AK_CPU_X86_64 || defined AK_CPU_ARM_64)
210 unsigned long ret = 0;
211 _BitScanForward64(&ret, in_bits);
212 return in_bits ? ret : 64;
214 #elif defined(__clang__) || defined (__GNUC__)
217 return in_bits ? __builtin_ctzll(in_bits) : 64;
222 if (in_bits == 0)
return 64;
224 if ((in_bits & 0x00000000FFFFFFFFULL) == 0) { ret += 32; in_bits >>= 32; }
225 if ((in_bits & 0x000000000000FFFFULL) == 0) { ret += 16; in_bits >>= 16; }
226 if ((in_bits & 0x00000000000000FFULL) == 0) { ret += 8; in_bits >>= 8; }
227 if ((in_bits & 0x000000000000000FULL) == 0) { ret += 4; in_bits >>= 4; }
228 if ((in_bits & 0x0000000000000003ULL) == 0) { ret += 2; in_bits >>= 2; }
229 if ((in_bits & 0x0000000000000001ULL) == 0) { ret += 1; in_bits >>= 1; }
237 unsigned long ret = 0;
238 _BitScanForward(&ret, in_bits);
239 return in_bits ? ret : 32;
242 #elif defined(__clang__) || defined (__GNUC__)
245 return in_bits ? __builtin_ctz(in_bits) : 32;
250 if (in_bits == 0)
return 32;
252 if ((in_bits & 0x0000FFFFULL) == 0) { ret += 16; in_bits >>= 16; }
253 if ((in_bits & 0x000000FFULL) == 0) { ret += 8; in_bits >>= 8; }
254 if ((in_bits & 0x0000000FULL) == 0) { ret += 4; in_bits >>= 4; }
255 if ((in_bits & 0x00000003ULL) == 0) { ret += 2; in_bits >>= 2; }
256 if ((in_bits & 0x00000001ULL) == 0) { ret += 1; in_bits >>= 1; }
264 #if defined _MSC_VER && (defined AK_CPU_X86_64 || defined AK_CPU_ARM_64)
267 unsigned long ret = 0;
268 _BitScanReverse64(&ret, in_bits);
269 return in_bits ? 63 - ret : 64;
271 #elif defined(__clang__) || defined (__GNUC__)
274 return in_bits ? __builtin_clzll(in_bits) : 64;
279 if (in_bits == 0)
return 64;
281 if ((in_bits & 0xFFFFFFFF00000000ULL) == 0) { ret += 32; in_bits <<= 32; }
282 if ((in_bits & 0xFFFF000000000000ULL) == 0) { ret += 16; in_bits <<= 16; }
283 if ((in_bits & 0xFF00000000000000ULL) == 0) { ret += 8; in_bits <<= 8; }
284 if ((in_bits & 0xF000000000000000ULL) == 0) { ret += 4; in_bits <<= 4; }
285 if ((in_bits & 0xC000000000000000ULL) == 0) { ret += 2; in_bits <<= 2; }
286 if ((in_bits & 0x8000000000000000ULL) == 0) { ret += 1; in_bits <<= 1; }
294 unsigned long ret = 0;
295 _BitScanReverse(&ret, in_bits);
296 return in_bits ? 31 - ret : 32;
298 #elif defined(__clang__) || defined (__GNUC__)
301 return in_bits ? __builtin_clz(in_bits) : 32;
306 if (in_bits == 0)
return 32;
308 if ((in_bits & 0xFFFF0000ULL) == 0) { ret += 16; in_bits <<= 16; }
309 if ((in_bits & 0xFF000000ULL) == 0) { ret += 8; in_bits <<= 8; }
310 if ((in_bits & 0xF0000000ULL) == 0) { ret += 4; in_bits <<= 4; }
311 if ((in_bits & 0xC0000000ULL) == 0) { ret += 2; in_bits <<= 2; }
312 if ((in_bits & 0x80000000ULL) == 0) { ret += 1; in_bits <<= 1; }
317 #endif // defined(AK_BIT_SCAN_INSTRUCTIONS)
320 #if !defined(AK_LIMITEDSPINFORZERO)
339 if (currentTime > endSpinTime)
371 if (currentTime > endSpinTime)
406 #ifndef AK_PERF_RECORDING_RESET
407 #define AK_PERF_RECORDING_RESET()
409 #ifndef AK_PERF_RECORDING_START
410 #define AK_PERF_RECORDING_START( __StorageName__, __uExecutionCountStart__, __uExecutionCountStop__ )
412 #ifndef AK_PERF_RECORDING_STOP
413 #define AK_PERF_RECORDING_STOP( __StorageName__, __uExecutionCountStart__, __uExecutionCountStop__ )
416 #endif // _AK_TOOLS_COMMON_AKPLATFORMFUNCS_H