Index: support.h
===================================================================
--- support.h	(revision 192181)
+++ support.h	(working copy)
@@ -15,16 +15,22 @@
    Functions and constants used in libc++ that are missing from the Windows C library.
   */
 
+#if !defined(_MSC_VER) || defined(__clang__)
+#pragma GCC system_header
+#endif
+
 #include <wchar.h>  // mbstate_t
 #include <cstdarg> // va_ macros
+#include <stdint.h> // uint32_t
+#if defined(_LIBCPP_MSVCRT)
+#include <xlocinfo.h> // _Stof etc.
+#endif
+#include <intrin.h> // _BitScanForward64 etc.
+#include <limits> // std::numeric_limits::digits
+
 #define swprintf _snwprintf
 #define vswprintf _vsnwprintf
 
-#ifndef NOMINMAX
-#define NOMINMAX
-#endif
-#include <Windows.h>
-
 extern "C" {
 
 int vasprintf( char **sptr, const char *__restrict fmt, va_list ap );
@@ -37,24 +43,21 @@
 
 #if defined(_LIBCPP_MSVCRT)
 #define snprintf _snprintf
-#include <xlocinfo.h>
 #define atoll _atoi64
 #define strtoll _strtoi64
 #define strtoull _strtoui64
 #define wcstoll _wcstoi64
 #define wcstoull _wcstoui64
-_LIBCPP_ALWAYS_INLINE float strtof( const char *nptr, char **endptr )
-{ return _Stof(nptr, endptr, 0); }
-_LIBCPP_ALWAYS_INLINE double strtod( const char *nptr, char **endptr )
-{ return _Stod(nptr, endptr, 0); }
-_LIBCPP_ALWAYS_INLINE long double strtold( const char *nptr, char **endptr )
-{ return _Stold(nptr, endptr, 0); }
-
 #define _Exit _exit
 
-#ifndef __clang__ // MSVC-based Clang also defines _MSC_VER
-#include <intrin.h>
+// clang && gcc support these intrinsics.
+#if defined(_LIBCPP_MSVC)
 
+// FIXME. I think these routines could be used here:
+// http://msdn.microsoft.com/en-us/library/bb385231%28v=vs.90%29.aspx
+// For SSE4 targets this could be used instead:
+// http://msdn.microsoft.com/en-us/library/bb531475%28v=VS.90%29.aspx
+
 _LIBCPP_ALWAYS_INLINE int __builtin_popcount(unsigned int x) {
    static const unsigned int m1 = 0x55555555; //binary: 0101...
    static const unsigned int m2 = 0x33333333; //binary: 00110011..
@@ -81,39 +84,96 @@
    return static_cast<int>((x * h01)>>56);  //returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24) + ...
 }
 
-_LIBCPP_ALWAYS_INLINE int __builtin_ctz( unsigned int x )
+// The_BitScanForward64 and _BitScanReverse64 intrinsics do not
+// currently exist in the MS 32 bit compiler. However it would be
+// useful since the 32 bit compiler supports 64 bit data types.
+// Implement these 64 bit intrinsics in terms of their 32 bit
+// counter parts when in 64 bit mode.
+
+// Note that the offset returned is from the LSB.
+_LIBCPP_ALWAYS_INLINE unsigned char _libcpp_bsf64( unsigned long* index, uint64_t mask ) _NOEXCEPT
 {
-   DWORD r = 0;
-   _BitScanReverse(&r, x);
-   return static_cast<int>(r);
+#if defined(_WIN64)
+    return _BitScanForward64(index, mask);
+#elif defined(_WIN32)
+    const uint32_t low = static_cast<uint32_t>(mask); // Low order 32 bits.
+    unsigned char ret =_BitScanForward(index, low);
+    if (ret)
+        return ret;
+    const uint32_t high = mask >> 32; // High order 32 bits.
+    ret = _BitScanForward(index, high);
+    if (ret)
+        *index += 32; // Create a bit offset from the LSB.
+    return ret;
+#else
+#   error "Implementation of _libcpp_bsf64 required"
+#endif
 }
 
+// Implementation of _BitScanReverse64 implemented in terms
+// of two _BitScanReverse 32 bit operations. See comment above.
+// Note that the offset returned is from the LSB.
+_LIBCPP_ALWAYS_INLINE unsigned char _libcpp_bsr64( unsigned long* index, uint64_t mask ) _NOEXCEPT
+{
+#if defined(_WIN64)
+    return _BitScanReverse64(index, mask);
+#elif defined(_WIN32)
+    const uint32_t high = mask >> 32; // High order 32 bits.
+    unsigned char ret =_BitScanReverse(index, high);
+    if (ret) {
+        *index += 32; // Create a bit offset from the MSB.
+        return ret;
+    }
+    const uint32_t low = static_cast<uint32_t>(mask); // Low order 32 bits.
+    ret = _BitScanReverse(index, low);
+    return ret;    
+#else
+#   error "Implementation of _libcpp_bsr64 required"
+#endif
+}
+
 // sizeof(long) == sizeof(int) on Windows
+_LIBCPP_ALWAYS_INLINE int __builtin_ctzll( unsigned long long x )
+{
+    unsigned long where;
+    _libcpp_bsf64(&where, x);
+    return static_cast<int>(where);
+}
+
 _LIBCPP_ALWAYS_INLINE int __builtin_ctzl( unsigned long x )
-{ return __builtin_ctz( static_cast<int>(x) ); }
+{
+    unsigned long where;
+    _BitScanReverse(&where, x);
+    return static_cast<int>(where);
+}
 
-_LIBCPP_ALWAYS_INLINE int __builtin_ctzll( unsigned long long x )
+_LIBCPP_ALWAYS_INLINE int __builtin_ctz( unsigned int x )
 {
-    DWORD r = 0;
-    _BitScanReverse64(&r, x);
-    return static_cast<int>(r);
+    return __builtin_ctzl( x );
 }
-_LIBCPP_ALWAYS_INLINE int __builtin_clz( unsigned int x )
+
+_LIBCPP_ALWAYS_INLINE int __builtin_clzll( unsigned long long x )
 {
-   DWORD r = 0;
-   _BitScanForward(&r, x);
-   return static_cast<int>(r);
+    unsigned long where;
+    _libcpp_bsr64(&where, x);
+    const int msbit = std::numeric_limits<unsigned long long>::digits - 1;
+    return static_cast<int>(msbit - where);
 }
+
 // sizeof(long) == sizeof(int) on Windows
 _LIBCPP_ALWAYS_INLINE int __builtin_clzl( unsigned long x )
-{ return __builtin_clz( static_cast<int>(x) ); }
-_LIBCPP_ALWAYS_INLINE int __builtin_clzll( unsigned long long x )
 {
-    DWORD r = 0;
-    _BitScanForward64(&r, x);
-    return static_cast<int>(r);
+    unsigned long where;
+    _BitScanForward(&where, x);
+    const int msbit = std::numeric_limits<unsigned long>::digits - 1;
+    return static_cast<int>(msbit - where);
 }
-#endif // !__clang__
+
+_LIBCPP_ALWAYS_INLINE int __builtin_clz( unsigned int x )
+{
+    return __builtin_clzl(x);
+}
+
+#endif // _LIBCPP_MSVC
 #endif // _LIBCPP_MSVCRT
-
 #endif // _LIBCPP_SUPPORT_WIN32_SUPPORT_H
