Hello.  This patch adds support for the Microsoft __popcnt16, __popcnt, and 
__popcnt64 intrinsics, which are documented here:

https://msdn.microsoft.com/en-us/library/bb385231.aspx

I was trying to compile ANGLE recently and one of the first errors I 
encountered was due to both GCC/mingw-w64 not supporting __popcnt.

I attached the simple C++ program I used to test this patch.

I am not totally sure, but it looks like Clang already supports the __popcnt 
intrinsics because I saw code for it in the clang repository.  So that is why 
this patch has "#if !defined(__clang__)" around it.

I read the documentation for intrin.h and intrin-impl.h and I believe this 
patch follows all the rules.  It would be great if it could be merged in.  
Thanks!

--David Grayson
diff --git a/mingw-w64-headers/include/psdk_inc/intrin-impl.h 
b/mingw-w64-headers/include/psdk_inc/intrin-impl.h
index f8dc78f..fc781ff 100644
--- a/mingw-w64-headers/include/psdk_inc/intrin-impl.h
+++ b/mingw-w64-headers/include/psdk_inc/intrin-impl.h
@@ -971,6 +971,40 @@ __buildbittesti(InterlockedBitTestAndComplement, __LONG32, 
"eor", "M", volatile)
 
 #if defined(__x86_64__) || defined(_AMD64_) || defined(__i386__) || 
defined(_X86_) || defined(__arm__) || defined(_ARM_)
 
+#if !defined(__clang__)
+
+#if __INTRINSIC_PROLOG(__popcnt16)
+unsigned short __popcnt16(unsigned short);
+__INTRINSICS_USEINLINE
+unsigned short __popcnt16(unsigned short value)
+{
+    return __builtin_popcount(value);
+}
+#define __INTRINSIC_DEFINED___popcnt16
+#endif /* __INTRINSIC_PROLOG */
+
+#if __INTRINSIC_PROLOG(__popcnt)
+unsigned int __popcnt(unsigned int);
+__INTRINSICS_USEINLINE
+unsigned int __popcnt(unsigned int value)
+{
+    return __builtin_popcount(value);
+}
+#define __INTRINSIC_DEFINED___popcnt
+#endif /* __INTRINSIC_PROLOG */
+
+#if __INTRINSIC_PROLOG(__popcnt64)
+unsigned __int64 __popcnt64(unsigned __int64);
+__INTRINSICS_USEINLINE
+unsigned __int64 __popcnt64(unsigned __int64 value)
+{
+    return __builtin_popcountll(value);
+}
+#define __INTRINSIC_DEFINED___popcnt64
+#endif /* __INTRINSIC_PROLOG */
+
+#endif /* !defined(__clang__) */
+
 #if __INTRINSIC_PROLOG(_InterlockedAnd)
 __LONG32 _InterlockedAnd(__LONG32 volatile *, __LONG32);
 __INTRINSICS_USEINLINE 
#include <intrin.h>   
#include <iostream>   
  
int main()   
{
  // Test __popcnt16
  unsigned short us[3] = {0, 0xFF, 0xFFFF};  
  for (int i = 0; i < 3; i++) {  
    unsigned short usr = __popcnt16(us[i]);  
    std::cout << "__popcnt16(0x" << std::hex << us[i] <<
      ") = " << std::dec << usr << std::endl;  
  }
  
  // Test __popcnt
  unsigned int ui[4] = {0, 0xFF, 0xFFFF, 0xFFFFFFFF};  
  for (int i = 0; i < 4; i++) {  
    unsigned int uir = __popcnt(ui[i]);  
    std::cout << "__popcnt(0x" << std::hex << ui[i] <<
      ") = " << std::dec << uir << std::endl;
  }

  // Test __popcnt64
  unsigned __int64 ul[5] = {0, 0xFF, 0xFFFF, 0xFFFFFFFF, 0xFF00FF00FF00FF00};  
  for (int i = 0; i < 5; i++) {  
    unsigned __int64 ulr = __popcnt64(ul[i]);  
    std::cout << "__popcnt(0x" << std::hex << ul[i] <<
      ") = " << std::dec << ulr << std::endl;
  }

  std::cout << "sizeof(unsigned long) = " << sizeof(unsigned long) << std::endl;
  std::cout << "sizeof(unsigned long long) = " << sizeof(unsigned long long) << 
std::endl;
}
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to