/*
- * Copyright 2015 Facebook, Inc.
+ * Copyright 2016 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* limitations under the License.
*/
-#ifndef FOLLY_EXPERIMENTAL_INSTRUCTIONS_H
-#define FOLLY_EXPERIMENTAL_INSTRUCTIONS_H
+#pragma once
+
+#include <glog/logging.h>
#include <folly/CpuId.h>
+#include <folly/Portability.h>
+#include <folly/portability/Builtins.h>
+
+#if defined(__GNUC__) || defined(__clang__)
+// For compilers supporting AT&T assembly syntax.
+#define FOLLY_INSTRUCTIONS_SUPPORTED 1
+#else
+#define FOLLY_INSTRUCTIONS_SUPPORTED 0
+#endif
namespace folly { namespace compression { namespace instructions {
// use explicitly.
struct Default {
- static bool supported(const folly::CpuId& cpuId = {}) {
+ static bool supported(const folly::CpuId& /* cpuId */ = {}) {
return true;
}
- static inline uint64_t popcount(uint64_t value) {
+ static FOLLY_ALWAYS_INLINE uint64_t popcount(uint64_t value) {
return __builtin_popcountll(value);
}
- static inline int ctz(uint64_t value) {
+ static FOLLY_ALWAYS_INLINE int ctz(uint64_t value) {
DCHECK_GT(value, 0);
return __builtin_ctzll(value);
}
- static inline int clz(uint64_t value) {
+ static FOLLY_ALWAYS_INLINE int clz(uint64_t value) {
DCHECK_GT(value, 0);
return __builtin_clzll(value);
}
- static inline uint64_t blsr(uint64_t value) {
+ static FOLLY_ALWAYS_INLINE uint64_t blsr(uint64_t value) {
return value & (value - 1);
}
};
+#if FOLLY_INSTRUCTIONS_SUPPORTED
+
struct Nehalem : public Default {
static bool supported(const folly::CpuId& cpuId = {}) {
return cpuId.popcnt();
}
- static inline uint64_t popcount(uint64_t value) {
+
+ static FOLLY_ALWAYS_INLINE uint64_t popcount(uint64_t value) {
// POPCNT is supported starting with Intel Nehalem, AMD K10.
uint64_t result;
asm ("popcntq %1, %0" : "=r" (result) : "r" (value));
static bool supported(const folly::CpuId& cpuId = {}) {
return Nehalem::supported(cpuId) && cpuId.bmi1();
}
- static inline uint64_t blsr(uint64_t value) {
+
+ static FOLLY_ALWAYS_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.
uint64_t result;
}
};
-}}} // namespaces
+#else // FOLLY_INSTRUCTIONS_SUPPORTED
+
+struct Nehalem : public Default {};
+struct Haswell : public Nehalem {};
+
+#endif // FOLLY_INSTRUCTIONS_SUPPORTED
-#endif // FOLLY_EXPERIMENTAL_INSTRUCTIONS_H
+}}} // namespaces