changeset 11241:3b5cf99c0f67 draft bitmath

-Codechange: Use builtins with MSVC for bitmath functions.
author Michael Lutz <michi@icosahedron.de>
date Wed, 03 Sep 2008 15:29:45 +0200
parents 320cc407142b
children
files src/core/bitmath_func.cpp src/core/bitmath_func.hpp
diffstat 2 files changed, 53 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/core/bitmath_func.cpp
+++ b/src/core/bitmath_func.cpp
@@ -16,6 +16,7 @@
 	3,  0,  1,  0,  2,  0,  1,  0,
 };
 
+#if !defined(_MSC_VER) || _MSC_VER < 1300
 /**
  * Search the first set bit in a 32 bit variable.
  *
@@ -43,7 +44,9 @@
 
 	return pos;
 }
+#endif
 
+#if !defined(_MSC_VER) || _MSC_VER < 1300 || (!defined(_M_AMD64) && !defined(_M_IA64))
 /**
  * Search the last set bit in a 64 bit variable.
  *
@@ -70,3 +73,4 @@
 
 	return pos;
 }
+#endif
--- a/src/core/bitmath_func.hpp
+++ b/src/core/bitmath_func.hpp
@@ -220,6 +220,28 @@
 uint8 FindFirstBit(uint32 x);
 uint8 FindLastBit(uint64 x);
 
+#if defined(_MSC_VER) && _MSC_VER >= 1300
+/* MSVC has intrinsics for finding the first/last bit. */
+#include <intrin.h>
+#pragma intrinsic(_BitScanForward)
+
+inline uint8 FindFirstBit(uint32 x)
+{
+	unsigned long index;
+	return _BitScanForward(&index, x) ? index : 0;
+}
+
+#if defined(_M_AMD64) || defined(_M_IA64)
+#pragma intrinsic(_BitScanReverse64)
+inline uint8 FindLastBit(uint64 x)
+{
+	unsigned long index;
+	return _BitScanReverse64(&index, x) ? index : 0;
+}
+#endif /* defined(_M_AMD64) || defined(_M_IA64) */
+
+#endif /* defined(_MSC_VER) && _MSC_VER >= 1300 */
+
 /**
  * Clear the first bit in an integer.
  *
@@ -273,6 +295,16 @@
 	return (T)(x << n | x >> (sizeof(x) * 8 - n));
 }
 
+#if defined(_MSC_VER) && _MSC_VER >= 1300
+#pragma intrinsic(_rotl)
+/* Use the MSVC intrinsic to speed up the code. */
+template <>
+static FORCEINLINE uint32 ROL(const uint32 x, const uint8 n)
+{
+	return _rotl(x, n);
+}
+#endif
+
 /**
  * ROtate x Right by n
  *
@@ -287,6 +319,16 @@
 	return (T)(x >> n | x << (sizeof(x) * 8 - n));
 }
 
+#if defined(_MSC_VER) && _MSC_VER >= 1300
+#pragma intrinsic(_rotr)
+/* Use the MSVC intrinsic to speed up the code. */
+template <>
+static FORCEINLINE uint32 ROR(const uint32 x, const uint8 n)
+{
+	return _rotr(x, n);
+}
+#endif
+
 /**
  * Do an operation for each set set bit in a value.
  *
@@ -310,6 +352,12 @@
 	 * warnings if we don't cast those (why?) */
 	#define BSWAP32(x) ((uint32)Endian32_Swap(x))
 	#define BSWAP16(x) ((uint16)Endian16_Swap(x))
+#elif defined(_MSC_VER) && _MSC_VER >= 1300
+	#pragma intrinsic(_byteswap_ulong)
+	#pragma intrinsic(_byteswap_ushort)
+	/* Use the MSVC intrinsics to speed up the code. */
+	#define BSWAP32(x) ((uint32)_byteswap_ulong(x))
+	#define BSWAP16(x) ((uint16)_byteswap_ushort(x))
 #else
 	/**
 	 * Perform a 32 bits endianness bitswap on x.
@@ -335,6 +383,6 @@
 	{
 		return (x >> 8) | (x << 8);
 	}
-#endif /* __APPLE__ */
+#endif
 
 #endif /* BITMATH_FUNC_HPP */