# define FOLLY_ALWAYS_INLINE inline
#endif
-// target
-#ifdef _MSC_VER
-# define FOLLY_TARGET_ATTRIBUTE(target)
-#else
-# define FOLLY_TARGET_ATTRIBUTE(target) __attribute__((__target__(target)))
-#endif
-
// detection for 64 bit
#if defined(__x86_64__) || defined(_M_X64)
# define FOLLY_X64 1
#pragma once
#include <glog/logging.h>
-#include <immintrin.h>
#include <folly/CpuId.h>
-#include <folly/portability/Builtins.h>
namespace folly { namespace compression { namespace instructions {
static bool supported(const folly::CpuId& cpuId = {}) {
return cpuId.popcnt();
}
- static inline uint64_t popcount(uint64_t value)
- FOLLY_TARGET_ATTRIBUTE("popcnt") {
+ static inline uint64_t popcount(uint64_t value) {
// POPCNT is supported starting with Intel Nehalem, AMD K10.
-#if defined(__GNUC__) && !__GNUC_PREREQ(4, 9)
- // GCC 4.8 doesn't support the intrinsics.
uint64_t result;
asm ("popcntq %1, %0" : "=r" (result) : "r" (value));
return result;
-#else
- return _mm_popcnt_u64(value);
-#endif
}
};
static bool supported(const folly::CpuId& cpuId = {}) {
return Nehalem::supported(cpuId) && cpuId.bmi1();
}
- static inline uint64_t blsr(uint64_t value) FOLLY_TARGET_ATTRIBUTE("bmi") {
+ static inline uint64_t blsr(uint64_t value) {
// BMI1 is supported starting with Intel Haswell, AMD Piledriver.
// BLSR combines two instuctions into one and reduces register pressure.
-#if defined(__GNUC__) && !__GNUC_PREREQ(4, 9)
- // GCC 4.8 doesn't support the intrinsics.
uint64_t result;
asm ("blsrq %1, %0" : "=r" (result) : "r" (value));
return result;
-#else
- return _blsr_u64(value);
-#endif
}
};
return place + detail::kSelectInByte[((x >> place) & 0xFF) | (byteRank << 8)];
}
-template <>
-uint64_t select64<compression::instructions::Haswell>(uint64_t x, uint64_t k)
- FOLLY_TARGET_ATTRIBUTE("bmi,bmi2");
-
template <>
inline uint64_t select64<compression::instructions::Haswell>(uint64_t x,
uint64_t k) {
-#if defined(__GNUC__) && !__GNUC_PREREQ(4, 9)
- // GCC 4.8 doesn't support the intrinsics.
uint64_t result = uint64_t(1) << k;
asm("pdep %1, %0, %0\n\t"
: "r"(x));
return result;
-#else
- return _tzcnt_u64(_pdep_u64(x, 1ULL << k));
-#endif
}
} // namespace folly