libecb: PATCH ecb_ld* to use MSC intrinsics

Zsbán Ambrus ambrus at math.bme.hu
Mon Nov 23 15:34:10 CET 2015


On Thu, Nov 19, 2015 at 2:32 PM, Zsbán Ambrus <ambrus at math.bme.hu> wrote:
> I attach an attempt to patch libecb so that it uses the MSC (MS
> compiler) intrinsic functions to implement the bit manipulation
> functions ecb_ld32, ecb_ld64, ecb_ctz32, ecb_ctz64.

Here's an updated patch that fixes the bug where I failed to check for
architecture (the 64 bit intrinsics are not supported when compiling
to x86_32 target), plus cleans up indentation.

Same test as I sent you previously should work.

Ambrus
-------------- next part --------------
Index: ecb.h
===================================================================
--- ecb.h	(revision 108)
+++ ecb.h	(working copy)
@@ -157,6 +157,10 @@
   #include <builtins.h>
 #endif
 
+#if 1400 <= _MSC_VER
+  #include <intrin.h> /* fence functions _ReadBarrier, also bit search functions _BitScanReverse */
+#endif
+
 #ifndef ECB_MEMORY_FENCE
   #if ECB_GCC_VERSION(2,5) || defined __INTEL_COMPILER || (__llvm__ && __GNUC__) || __SUNPRO_C >= 0x5110 || __SUNPRO_CC >= 0x5110
     #if __i386 || __i386__
@@ -445,6 +449,11 @@
   ecb_function_ ecb_const int
   ecb_ctz32 (uint32_t x)
   {
+#if 1400 <= _MSC_VER && (_M_IX86 || _M_X64 || _M_IA64 || _M_ARM)
+    unsigned long r = 0;
+    _BitScanForward(&r, x);
+    return (int)r;
+#else
     int r = 0;
 
     x &= ~x + 1; /* this isolates the lowest bit */
@@ -464,6 +473,7 @@
 #endif
 
     return r;
+#endif
   }
 
   ecb_function_ ecb_const int ecb_ctz64 (uint64_t x);
@@ -470,8 +480,14 @@
   ecb_function_ ecb_const int
   ecb_ctz64 (uint64_t x)
   {
+#if 1400 <= _MSC_VER && (_M_X64 || _M_IA64 || _M_ARM)
+    unsigned long r = 0;
+    _BitScanForward64(&r, x);
+    return (int)r;
+#else
     int shift = x & 0xffffffffU ? 0 : 32;
     return ecb_ctz32 (x >> shift) + shift;
+#endif
   }
 
   ecb_function_ ecb_const int ecb_popcount32 (uint32_t x);
@@ -489,6 +505,11 @@
   ecb_function_ ecb_const int ecb_ld32 (uint32_t x);
   ecb_function_ ecb_const int ecb_ld32 (uint32_t x)
   {
+#if 1400 <= _MSC_VER && (_M_IX86 || _M_X64 || _M_IA64 || _M_ARM)
+    unsigned long r = 0;
+    _BitScanReverse(&r, x);
+    return (int)r;
+#else
     int r = 0;
 
     if (x >> 16) { x >>= 16; r += 16; }
@@ -498,16 +519,23 @@
     if (x >>  1) {           r +=  1; }
 
     return r;
+#endif
   }
 
   ecb_function_ ecb_const int ecb_ld64 (uint64_t x);
   ecb_function_ ecb_const int ecb_ld64 (uint64_t x)
   {
+#if 1400 <= _MSC_VER && (_M_X64 || _M_IA64 || _M_ARM)
+    unsigned long r = 0;
+    _BitScanReverse64(&r, x);
+    return (int)r;
+#else
     int r = 0;
 
     if (x >> 32) { x >>= 32; r += 32; }
 
     return r + ecb_ld32 (x);
+#endif
   }
 #endif
 


More information about the libev mailing list