Skip to content

Commit 75785e5

Browse files
committed
use Windows intrinsics when the CPU supports them
1 parent f4fca08 commit 75785e5

1 file changed

Lines changed: 21 additions & 12 deletions

File tree

c/alloc.c

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@
1515
*/
1616

1717
#include "system.h"
18-
#if defined(_MSC_VER)
18+
#ifdef _MSC_VER
1919
#include <intrin.h> /* for Spopcount below */
20+
static int has_popcnt = 0;
2021
#endif
2122

2223
/* locally defined functions */
@@ -26,6 +27,11 @@ void S_alloc_init(void) {
2627
ISPC s; IGEN g; UINT i;
2728

2829
if (S_boot_time) {
30+
#ifdef _MSC_VER
31+
int cpuinfo[4];
32+
__cpuid(cpuinfo, 1);
33+
has_popcnt = (cpuinfo[2] & (1 << 23)) != 0; /* ECX bit 23 */
34+
#endif
2935
ptr tc = TO_PTR(S_G.thread_context);
3036

3137
GCDATA(tc) = TO_PTR(&S_G.main_thread_gc);
@@ -802,18 +808,21 @@ ptr S_null_immutable_string(void) {
802808

803809
int Spopcount(uptr x) {
804810
#if defined(__clang__) || defined(__GNUC__)
805-
#if ptr_bits == 32
806-
return __builtin_popcount(x);
807-
#else
808-
return __builtin_popcountl(x);
809-
#endif
810-
#elif defined(_MSC_VER)
811-
#if ptr_bits == 32
812-
return (int)__popcnt(x);
813-
#else
814-
return (int)__popcnt64(x);
815-
#endif
811+
if (sizeof(x) <= sizeof(unsigned long))
812+
return __builtin_popcountl((unsigned long)x);
813+
else
814+
return __builtin_popcountll((unsigned long long)x);
816815
#else
816+
# if defined(_MSC_VER)
817+
if (has_popcnt) {
818+
# if defined(_WIN64)
819+
return (int)__popcnt64((unsigned __int64)x);
820+
# else
821+
return (int)__popcnt((unsigned int)x);
822+
# endif
823+
# endif
824+
}
825+
817826
/* Kernighan's method */
818827
int count = 0;
819828
while (x != 0) {

0 commit comments

Comments
 (0)