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