From d7d2c1b7e31f5b680ebb44e2ffcbfc4bcb2aecfd Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Sat, 30 Jan 2010 19:18:27 +0100 Subject: [PATCH] Add hardware POPCNT support for gcc With new target 'make gcc-popcnt' it is now possible to compile with enabled hardware POPCNT support also with gcc. Until now was possible only for Intel and MSVC compilers. When this instruction is supported by CPU, for instance on Intel i7 or i5 family, produced binary is a bit faster. Signed-off-by: Marco Costalba --- src/Makefile | 8 ++++++++ src/bitcount.h | 24 ++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/Makefile b/src/Makefile index 1388f465..3963e558 100644 --- a/src/Makefile +++ b/src/Makefile @@ -80,6 +80,7 @@ help: @echo "Makefile options:" @echo "" @echo "make > Default: Compiler = g++" + @echo "make gcc-popcnt > Compiler = g++ + popcnt-support" @echo "make icc > Compiler = icpc" @echo "make icc-profile > Compiler = icpc + automatic pgo-build" @echo "make icc-profile-popcnt > Compiler = icpc + automatic pgo-build + popcnt-support" @@ -108,6 +109,13 @@ gcc: CXXFLAGS="$(GCCFLAGS)" \ all +gcc-popcnt: + $(MAKE) \ + CXX='g++' \ + CXXFLAGS="$(GCCFLAGS) -DUSE_POPCNT" \ + all + + icc: $(MAKE) \ CXX='icpc' \ diff --git a/src/bitcount.h b/src/bitcount.h index aa27c049..b32314d8 100644 --- a/src/bitcount.h +++ b/src/bitcount.h @@ -53,6 +53,30 @@ inline bool cpu_has_popcnt() { #define POPCNT_INTRINSIC(x) __popcnt64(x) +#elif defined(__GNUC__) && defined(USE_POPCNT) // Gcc compiler + +inline void __cpuid(unsigned int op, + unsigned int *eax, unsigned int *ebx, + unsigned int *ecx, unsigned int *edx) +{ + *eax = op; + *ecx = 0; + __asm__("cpuid" : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx) + : "0" (*eax), "2" (*ecx)); +} + +inline bool cpu_has_popcnt() { + + unsigned int eax, ebx, ecx, edx; + __cpuid(1, &eax, &ebx, &ecx, &edx); + return (ecx >> 23) & 1; +} + +#define POPCNT_INTRINSIC(x) ({ \ + unsigned long __ret; \ + __asm__("popcnt %1, %0" : "=r" (__ret) : "r" (x)); \ + __ret; }) + #else // Safe fallback for unsupported compilers or when USE_POPCNT is disabled inline bool cpu_has_popcnt() { return false; } -- 2.39.2