Platform.hpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583
  1. /*
  2. Copyright (c) 2009-2010 Christopher A. Taylor. All rights reserved.
  3. Redistribution and use in source and binary forms, with or without
  4. modification, are permitted provided that the following conditions are met:
  5. * Redistributions of source code must retain the above copyright notice,
  6. this list of conditions and the following disclaimer.
  7. * Redistributions in binary form must reproduce the above copyright notice,
  8. this list of conditions and the following disclaimer in the documentation
  9. and/or other materials provided with the distribution.
  10. * Neither the name of LibCat nor the names of its contributors may be used
  11. to endorse or promote products derived from this software without
  12. specific prior written permission.
  13. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  14. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  15. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  16. ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
  17. LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  18. CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  19. SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  20. INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  21. CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  22. ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  23. POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #ifndef CAT_PLATFORM_HPP
  26. #define CAT_PLATFORM_HPP
  27. #include <cat/Config.hpp>
  28. #include <string.h>
  29. namespace cat {
  30. //// Compiler ////
  31. // Mac OS X additional compilation flags
  32. #ifdef __APPLE__
  33. # include <TargetConditionals.h>
  34. #endif
  35. //-----------------------------------------------------------------------------
  36. // Intel C++ Compiler : Interoperates with MSVC and GCC
  37. #if defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC)
  38. # define CAT_COMPILER_ICC
  39. # define CAT_FENCE_COMPILER __memory_barrier();
  40. #endif
  41. //-----------------------------------------------------------------------------
  42. // Borland C++ Compiler : Compatible with MSVC syntax
  43. #if defined(__BORLANDC__)
  44. # define CAT_COMPILER_BORLAND
  45. # define CAT_COMPILER_COMPAT_MSVC
  46. # define CAT_INLINE __inline
  47. # define CAT_ASM_EMIT __emit__
  48. //-----------------------------------------------------------------------------
  49. // Digital Mars C++ Compiler (previously known as Symantec C++)
  50. #elif defined(__DMC__) || defined(__SC__) || defined(__SYMANTECC__)
  51. # define CAT_COMPILER_DMARS
  52. # define CAT_COMPILER_COMPAT_MSVC
  53. # define CAT_INLINE __inline
  54. # define CAT_ASM_EMIT __emit__
  55. //-----------------------------------------------------------------------------
  56. // Codeplay VectorC C++ Compiler : Compatible with GCC and MSVC syntax, prefer GCC
  57. #elif defined(__VECTORC__)
  58. # define CAT_COMPILER_CODEPLAY
  59. # define CAT_COMPILER_COMPAT_GCC
  60. //-----------------------------------------------------------------------------
  61. // Pathscale C++ Compiler : Compatible with GCC syntax
  62. #elif defined(__PATHSCALE__)
  63. # define CAT_COMPILER_PATHSCALE
  64. # define CAT_COMPILER_COMPAT_GCC
  65. //-----------------------------------------------------------------------------
  66. // Watcom C++ Compiler : Compatible with GCC and MSVC syntax, prefer GCC
  67. #elif defined(__WATCOMC__)
  68. # define CAT_COMPILER_WATCOM
  69. # define CAT_COMPILER_COMPAT_GCC
  70. //-----------------------------------------------------------------------------
  71. // SUN C++ Compiler : Compatible with GCC syntax
  72. #elif defined(__SUNPRO_CC)
  73. # define CAT_COMPILER_SUN
  74. # define CAT_COMPILER_COMPAT_GCC
  75. //-----------------------------------------------------------------------------
  76. // Metrowerks C++ Compiler : Compatible with MSVC syntax
  77. #elif defined(__MWERKS__)
  78. # define CAT_COMPILER_MWERKS
  79. # define CAT_COMPILER_COMPAT_MSVC
  80. # define CAT_INLINE inline
  81. # define CAT_ASM_BEGIN _asm {
  82. # define CAT_ASM_EMIT __emit__
  83. //-----------------------------------------------------------------------------
  84. // GNU C++ Compiler
  85. // SN Systems ProDG C++ Compiler : Compatible with GCC
  86. #elif defined(__GNUC__) || defined(__APPLE_CC__) || defined(__SNC__)
  87. # define CAT_COMPILER_GCC
  88. # define CAT_COMPILER_COMPAT_GCC
  89. # define CAT_FASTCALL __attribute__ ((fastcall))
  90. //-----------------------------------------------------------------------------
  91. // Microsoft Visual Studio C++ Compiler
  92. #elif defined(_MSC_VER)
  93. # define CAT_COMPILER_MSVC
  94. # define CAT_COMPILER_COMPAT_MSVC
  95. # define CAT_FASTCALL __fastcall
  96. } // namespace cat
  97. # include <cstdlib> // Intrinsics
  98. # include <intrin.h> // Intrinsics
  99. namespace cat {
  100. //-----------------------------------------------------------------------------
  101. // Otherwise unknown compiler
  102. #else
  103. # define CAT_COMPILER_UNKNOWN
  104. # define CAT_ALIGNED(n) /* no way to detect alignment syntax */
  105. # define CAT_PACKED /* no way to detect packing syntax */
  106. # define CAT_INLINE inline
  107. // No way to support inline assembly code here
  108. # define CAT_RESTRICT
  109. #endif
  110. /*
  111. A lot of compilers have similar syntax to MSVC or GCC,
  112. so for simplicity I have those two defined below, and
  113. any deviations are implemented with overrides above.
  114. */
  115. // MSVC-compatible compilers
  116. #if defined(CAT_COMPILER_COMPAT_MSVC)
  117. #if !defined(CAT_ALIGNED)
  118. # define CAT_ALIGNED(n) __declspec(align(n))
  119. #endif
  120. #if !defined(CAT_PACKED)
  121. # define CAT_PACKED
  122. # define CAT_PRAGMA_PACK
  123. #endif
  124. #if !defined(CAT_INLINE)
  125. # define CAT_INLINE __forceinline
  126. #endif
  127. #if !defined(CAT_ASM_INTEL)
  128. # define CAT_ASM_INTEL
  129. #endif
  130. #if !defined(CAT_ASM_BEGIN)
  131. # define CAT_ASM_BEGIN __asm {
  132. #endif
  133. #if !defined(CAT_ASM_EMIT)
  134. # define CAT_ASM_EMIT _emit
  135. #endif
  136. #if !defined(CAT_ASM_END)
  137. # define CAT_ASM_END }
  138. #endif
  139. #if !defined(CAT_TLS)
  140. # define CAT_TLS __declspec( thread )
  141. #endif
  142. #if !defined(CAT_RESTRICT)
  143. # define CAT_RESTRICT __restrict
  144. #endif
  145. #if !defined(CAT_FENCE_COMPILER)
  146. # if defined(CAT_COMPILER_MSVC)
  147. # pragma intrinsic(_ReadWriteBarrier)
  148. # endif
  149. # define CAT_FENCE_COMPILER _ReadWriteBarrier();
  150. #endif
  151. #if !defined(CAT_DLL_EXPORT)
  152. # define CAT_DLL_EXPORT __declspec(dllexport)
  153. #endif
  154. #if !defined(CAT_DLL_IMPORT)
  155. # define CAT_DLL_IMPORT __declspec(dllimport)
  156. #endif
  157. // GCC-compatible compilers
  158. #elif defined(CAT_COMPILER_COMPAT_GCC)
  159. #if !defined(CAT_ALIGNED)
  160. # define CAT_ALIGNED(n) __attribute__ ((aligned (n)))
  161. #endif
  162. #if !defined(CAT_PACKED)
  163. # define CAT_PACKED __attribute__ ((packed))
  164. #endif
  165. #if !defined(CAT_INLINE)
  166. # define CAT_INLINE inline /* __inline__ __attribute__((always_inline)) */
  167. #endif
  168. #if !defined(CAT_ASM_ATT)
  169. # define CAT_ASM_ATT
  170. #endif
  171. #if !defined(CAT_ASM_BEGIN)
  172. # define CAT_ASM_BEGIN __asm__ __volatile__ (
  173. #endif
  174. #if !defined(CAT_ASM_EMIT)
  175. # define CAT_ASM_EMIT .byte
  176. #endif
  177. #if !defined(CAT_ASM_END)
  178. # define CAT_ASM_END );
  179. #endif
  180. #if !defined(CAT_TLS)
  181. # define CAT_TLS __thread
  182. #endif
  183. #if !defined(CAT_RESTRICT)
  184. # define CAT_RESTRICT __restrict__
  185. #endif
  186. #if !defined(CAT_FENCE_COMPILER)
  187. # define CAT_FENCE_COMPILER CAT_ASM_BEGIN "" ::: "memory" CAT_ASM_END
  188. #endif
  189. #if !defined(CAT_DLL_EXPORT)
  190. # define CAT_DLL_EXPORT __attribute__((dllexport))
  191. #endif
  192. #if !defined(CAT_DLL_IMPORT)
  193. # define CAT_DLL_IMPORT __attribute__((dllimport))
  194. #endif
  195. #endif // CAT_COMPILER_COMPAT_*
  196. //// Debug Flag ////
  197. #if defined(CAT_COMPILER_MSVC)
  198. # if defined(_DEBUG)
  199. # define CAT_DEBUG
  200. # endif
  201. #else
  202. # if !defined(NDEBUG)
  203. # define CAT_DEBUG
  204. # endif
  205. #endif
  206. //// Instruction Set Architecture ////
  207. #if defined(__powerpc__) || defined(__ppc__) || defined(_POWER) || defined(_M_PPC) || \
  208. defined(_M_MPPC) || defined(__POWERPC) || defined(powerpc) || defined(__ppc64__) || \
  209. defined(_PS3) || defined(__PS3__) || defined(SN_TARGET_PS3) || defined(__POWERPC__)
  210. # define CAT_ISA_PPC
  211. #elif defined(__i386__) || defined(i386) || defined(intel) || defined(_M_IX86) || \
  212. defined(__ia64) || defined(__ia64__) || defined(__x86_64) || defined(_M_IA64) || \
  213. defined(_M_X64)
  214. # define CAT_ISA_X86
  215. #elif defined(TARGET_CPU_ARM)
  216. # define CAT_ISA_ARM
  217. #elif defined(__mips__)
  218. # define CAT_ISA_MIPS
  219. #elif defined(__ALPHA__)
  220. # define CAT_ISA_ALPHA
  221. #else
  222. # define CAT_ISA_UNKNOWN
  223. #endif
  224. //// Endianness ////
  225. // Okay -- Technically IA64 and PPC can switch endianness with an MSR bit
  226. // flip, but come on no one does that! ...Right?
  227. // If it's not right, make sure that one of the first two flags are defined.
  228. #if defined(__LITTLE_ENDIAN__)
  229. # define CAT_ENDIAN_LITTLE
  230. #elif defined(__BIG_ENDIAN__)
  231. # define CAT_ENDIAN_BIG
  232. #elif defined(CAT_ISA_X86)
  233. # define CAT_ENDIAN_LITTLE
  234. #elif defined(CAT_ISA_PPC)
  235. # define CAT_ENDIAN_BIG
  236. #else
  237. # define CAT_ENDIAN_UNKNOWN /* Must be detected at runtime */
  238. #endif
  239. //// Word Size ////
  240. #if defined(_LP64) || defined(__LP64__) || defined(__arch64__) || \
  241. defined(_WIN64) || defined(_M_X64) || defined(__ia64) || \
  242. defined(__ia64__) || defined(__x86_64) || defined(_M_IA64) || \
  243. defined(__mips64)
  244. # define CAT_WORD_64
  245. // 64-bit MSVC does not support inline assembly
  246. # if defined(CAT_COMPILER_MSVC)
  247. # undef CAT_ASM_INTEL
  248. # endif
  249. #else // Assuming 32-bit otherwise!
  250. # define CAT_WORD_32
  251. #endif
  252. // __fastcall calling convention is rarely supported, and doesn't make sense for 64-bit targets
  253. #if !defined(CAT_FASTCALL)
  254. # define CAT_FASTCALL
  255. #elif !defined(CAT_ISA_X86) || defined(CAT_WORD_64)
  256. # undef CAT_FASTCALL
  257. # define CAT_FASTCALL
  258. #endif
  259. //// Operating System ////
  260. #if defined(__APPLE__) && defined(TARGET_OS_IPHONE)
  261. # define CAT_OS_IPHONE
  262. # define CAT_OS_APPLE
  263. #elif defined(__APPLE__) && (defined(__MACH__) || defined(__DARWIN__))
  264. # define CAT_OS_OSX
  265. # define CAT_OS_APPLE
  266. #elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__)
  267. # define CAT_OS_BSD
  268. #elif defined(__linux__) || defined(__unix__)
  269. # define CAT_OS_LINUX
  270. #elif defined(_WIN32_WCE)
  271. # define CAT_OS_WINDOWS_CE
  272. # define CAT_OS_WINDOWS /* Also defined */
  273. #elif defined(_WIN32)
  274. # define CAT_OS_WINDOWS
  275. #elif defined(_XBOX) || defined(_X360)
  276. # define CAT_OS_XBOX
  277. #elif defined(_PS3) || defined(__PS3__) || defined(SN_TARGET_PS3)
  278. # define CAT_OS_PS3
  279. #elif defined(__OS2__)
  280. # define CAT_OS_OS2
  281. #elif defined(__APPLE__)
  282. # define CAT_OS_APPLE
  283. #else
  284. # define CAT_OS_UNKNOWN
  285. #endif
  286. // Detect CYGWIN environment
  287. #if defined(__CYGWIN__) || defined(__CYGWIN32__)
  288. # define CAT_CYGWIN
  289. #endif
  290. // DLL import/export macros based on OS
  291. #if defined(CAT_OS_WINDOWS) || defined(CAT_CYGWIN)
  292. # if defined(CAT_NEUTER_EXPORT)
  293. # define CAT_EXPORT /* Do not import or export any symbols */
  294. # elif defined(CAT_BUILD_DLL)
  295. # define CAT_EXPORT CAT_DLL_EXPORT /* Implementing a DLL so export this symbol */
  296. # else
  297. # define CAT_EXPORT CAT_DLL_IMPORT /* Using a DLL so import this symbol, faster on Windows */
  298. # endif
  299. #else
  300. # undef CAT_DLL_EXPORT
  301. # undef CAT_DLL_IMPORT
  302. # define CAT_DLL_EXPORT
  303. # define CAT_DLL_IMPORT
  304. # define CAT_EXPORT
  305. #endif
  306. //// Basic types ////
  307. #if defined(CAT_COMPILER_MSVC)
  308. // MSVC does not ship with stdint.h (C99 standard...)
  309. typedef unsigned __int8 u8;
  310. typedef signed __int8 s8;
  311. typedef unsigned __int16 u16;
  312. typedef signed __int16 s16;
  313. typedef unsigned __int32 u32;
  314. typedef signed __int32 s32;
  315. typedef unsigned __int64 u64;
  316. typedef signed __int64 s64;
  317. #else
  318. } // namespace cat
  319. #include <stdint.h>
  320. namespace cat {
  321. // All other compilers use this
  322. typedef uint8_t u8;
  323. typedef int8_t s8;
  324. typedef uint16_t u16;
  325. typedef int16_t s16;
  326. typedef uint32_t u32;
  327. typedef int32_t s32;
  328. typedef uint64_t u64;
  329. typedef int64_t s64;
  330. #endif
  331. #if defined(CAT_COMPILER_GCC) && defined(CAT_WORD_64)
  332. // GCC also adds 128-bit types :D
  333. typedef __uint128_t u128;
  334. typedef __int128_t s128;
  335. #endif
  336. typedef float f32;
  337. typedef double f64;
  338. union Float32 {
  339. float f;
  340. u32 i;
  341. Float32(float n) { f = n; }
  342. Float32(u32 n) { i = n; }
  343. };
  344. //// String and buffer macros ////
  345. // Same as strncpy() in all ways except that the result is guaranteed to
  346. // be a nul-terminated C string
  347. #if defined(CAT_COMPILER_MSVC)
  348. # define CAT_STRNCPY(dest, src, size) { strncpy_s(dest, size, src, size); (dest)[(size)-1] = '\0'; }
  349. #else
  350. # define CAT_STRNCPY(dest, src, size) { strncpy(dest, src, size); (dest)[(size)-1] = '\0'; }
  351. #endif
  352. // Because memory clearing is a frequent operation
  353. #define CAT_CLR(dest, size) memset(dest, 0, size)
  354. // Works for arrays, also
  355. #define CAT_OBJCLR(object) memset((void*)&(object), 0, sizeof(object))
  356. // Stringize
  357. #define CAT_STRINGIZE(X) DO_CAT_STRINGIZE(X)
  358. #define DO_CAT_STRINGIZE(X) #X
  359. // Variable-length data trailing a struct
  360. template<typename T> CAT_INLINE u8 *GetTrailingBytes(T *t) { return reinterpret_cast<u8*>( t ) + sizeof(T); }
  361. // Bounds
  362. template<typename T> CAT_INLINE T BoundMin(const T &minimum, const T &x)
  363. {
  364. if (x < minimum) return minimum;
  365. return x;
  366. }
  367. template<typename T> CAT_INLINE T BoundMax(const T &maximum, const T &x)
  368. {
  369. if (x > maximum) return maximum;
  370. return x;
  371. }
  372. template<typename T> CAT_INLINE T Bound(const T &minimum, const T &maximum, const T &x)
  373. {
  374. if (x < minimum) return minimum;
  375. if (x > maximum) return maximum;
  376. return x;
  377. }
  378. //// Miscellaneous bitwise macros ////
  379. #define CAT_BITCLRHI8(reg, count) ((u8)((u8)(reg) << (count)) >> (count)) /* sets to zero a number of high bits in a byte */
  380. #define CAT_BITCLRLO8(reg, count) ((u8)((u8)(reg) >> (count)) << (count)) /* sets to zero a number of low bits in a byte */
  381. #define CAT_BITCLRHI16(reg, count) ((u16)((u16)(reg) << (count)) >> (count)) /* sets to zero a number of high bits in a 16-bit word */
  382. #define CAT_BITCLRLO16(reg, count) ((u16)((u16)(reg) >> (count)) << (count)) /* sets to zero a number of low bits in a 16-bit word */
  383. #define CAT_BITCLRHI32(reg, count) ((u32)((u32)(reg) << (count)) >> (count)) /* sets to zero a number of high bits in a 32-bit word */
  384. #define CAT_BITCLRLO32(reg, count) ((u32)((u32)(reg) >> (count)) << (count)) /* sets to zero a number of low bits in a 32-bit word */
  385. //// Integer macros ////
  386. #define CAT_AT_LEAST_2_BITS(n) ( (n) & ((n) - 1) )
  387. #define CAT_LEAST_SIGNIFICANT_BIT(n) ( (n) & (u32)(-(s32)(n)) ) /* 0 -> 0 */
  388. #define CAT_IS_POWER_OF_2(n) ( n && !CAT_AT_LEAST_2_BITS(n) )
  389. // Safely take the average of two numbers without possibility of overflow
  390. #define CAT_SAFE_AVERAGE(A, B) (((A) & (B)) + (((A) ^ (B)) >> 1))
  391. // Bump 'n' to the next unit of 'width'
  392. // 0=CAT_CEIL_UNIT(0, 16), 1=CAT_CEIL_UNIT(1, 16), 1=CAT_CEIL_UNIT(16, 16), 2=CAT_CEIL_UNIT(17, 16)
  393. #define CAT_CEIL_UNIT(n, width) ( ( (n) + (width) - 1 ) / (width) )
  394. // 0=CAT_CEIL(0, 16), 16=CAT_CEIL(1, 16), 16=CAT_CEIL(16, 16), 32=CAT_CEIL(17, 16)
  395. #define CAT_CEIL(n, width) ( CAT_CEIL_UNIT(n, width) * (width) )
  396. //// Rotation macros ////
  397. #define CAT_ROL8(n, r) ( ((u8)(n) << (r)) | ((u8)(n) >> ( 8 - (r))) ) /* only works for u8 */
  398. #define CAT_ROR8(n, r) ( ((u8)(n) >> (r)) | ((u8)(n) << ( 8 - (r))) ) /* only works for u8 */
  399. #define CAT_ROL16(n, r) ( ((u16)(n) << (r)) | ((u16)(n) >> (16 - (r))) ) /* only works for u16 */
  400. #define CAT_ROR16(n, r) ( ((u16)(n) >> (r)) | ((u16)(n) << (16 - (r))) ) /* only works for u16 */
  401. #define CAT_ROL32(n, r) ( ((u32)(n) << (r)) | ((u32)(n) >> (32 - (r))) ) /* only works for u32 */
  402. #define CAT_ROR32(n, r) ( ((u32)(n) >> (r)) | ((u32)(n) << (32 - (r))) ) /* only works for u32 */
  403. #define CAT_ROL64(n, r) ( ((u64)(n) << (r)) | ((u64)(n) >> (64 - (r))) ) /* only works for u64 */
  404. #define CAT_ROR64(n, r) ( ((u64)(n) >> (r)) | ((u64)(n) << (64 - (r))) ) /* only works for u64 */
  405. //// Byte-order swapping ////
  406. #define CAT_BOSWAP16(n) CAT_ROL16(n, 8)
  407. #define CAT_BOSWAP32(n) ( (CAT_ROL32(n, 8) & 0x00ff00ff) | (CAT_ROL32(n, 24) & 0xff00ff00) )
  408. #define CAT_BOSWAP64(n) ( ((u64)CAT_BOSWAP32((u32)n) << 32) | CAT_BOSWAP32((u32)(n >> 32)) )
  409. //// Intrinsics ////
  410. #if defined(CAT_OS_WINDOWS_CE)
  411. #pragma intrinsic(_lrotl)
  412. #pragma intrinsic(_lrotr)
  413. #undef CAT_ROL32
  414. #undef CAT_ROR32
  415. #define CAT_ROL32(n, r) _lrotl(n, r)
  416. #define CAT_ROR32(n, r) _lrotr(n, r)
  417. #elif defined(CAT_COMPILER_MSVC)
  418. #pragma intrinsic(_rotl)
  419. #pragma intrinsic(_rotr)
  420. #pragma intrinsic(_rotl64)
  421. #pragma intrinsic(_rotr64)
  422. #pragma intrinsic(_byteswap_ushort)
  423. #pragma intrinsic(_byteswap_ulong)
  424. #pragma intrinsic(_byteswap_uint64)
  425. #pragma intrinsic(_BitScanForward)
  426. #pragma intrinsic(_BitScanReverse)
  427. #pragma intrinsic(__emulu)
  428. #pragma intrinsic(_InterlockedExchange)
  429. #pragma intrinsic(_interlockedbittestandset)
  430. #pragma intrinsic(_interlockedbittestandreset)
  431. #if defined(CAT_WORD_64)
  432. #pragma intrinsic(__rdtsc)
  433. #pragma intrinsic(_umul128)
  434. #pragma intrinsic(_BitScanForward64)
  435. #pragma intrinsic(_BitScanReverse64)
  436. #pragma intrinsic(_InterlockedCompareExchange128)
  437. #else
  438. #pragma intrinsic(_InterlockedCompareExchange64)
  439. #endif
  440. #undef CAT_ROL32
  441. #undef CAT_ROR32
  442. #undef CAT_ROL64
  443. #undef CAT_ROR64
  444. #undef CAT_BOSWAP16
  445. #undef CAT_BOSWAP32
  446. #undef CAT_BOSWAP64
  447. #define CAT_ROL32(n, r) _rotl(n, r)
  448. #define CAT_ROR32(n, r) _rotr(n, r)
  449. #define CAT_ROL64(n, r) _rotl64(n, r)
  450. #define CAT_ROR64(n, r) _rotr64(n, r)
  451. #define CAT_BOSWAP16(n) _byteswap_ushort(n)
  452. #define CAT_BOSWAP32(n) _byteswap_ulong(n)
  453. #define CAT_BOSWAP64(n) _byteswap_uint64(n)
  454. #endif
  455. } // namespace cat
  456. #endif // CAT_PLATFORM_HPP
粤ICP备19079148号