Create the Builtins portability header
authorChristopher Dykes <cdykes@fb.com>
Fri, 1 Apr 2016 18:19:53 +0000 (11:19 -0700)
committerFacebook Github Bot 8 <facebook-github-bot-8-bot@fb.com>
Fri, 1 Apr 2016 18:20:30 +0000 (11:20 -0700)
Summary: Because we don't have these builtins under MSVC, and not having to deal with the differences in API in the places that use these builtins is good.

Reviewed By: yfeldblum

Differential Revision: D2984842

fb-gh-sync-id: 34db7455debf81e4abffe57c154eb731ae097ff6
fbshipit-source-id: 34db7455debf81e4abffe57c154eb731ae097ff6

folly/Makefile.am
folly/portability/Builtins.h [new file with mode: 0755]

index 96ff566526df8905cc61dfde8d61050fc5b53937..9ac7c446f1006935128bc52173478710869ee783 100644 (file)
@@ -268,6 +268,7 @@ nobase_follyinclude_HEADERS = \
        PicoSpinLock.h \
        Portability.h \
        portability/Asm.h \
+       portability/Builtins.h \
        portability/Config.h \
        portability/Constexpr.h \
        portability/Dirent.h \
diff --git a/folly/portability/Builtins.h b/folly/portability/Builtins.h
new file mode 100755 (executable)
index 0000000..959ce5c
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#ifdef _WIN32
+#include <assert.h>
+#include <intrin.h>
+#include <folly/Portability.h>
+
+FOLLY_ALWAYS_INLINE int __builtin_clz(unsigned int x) {
+  unsigned long index;
+  return (int)(_BitScanReverse(&index, (unsigned long)x) ? 31 - index : 32);
+}
+
+FOLLY_ALWAYS_INLINE int __builtin_clzl(unsigned long x) {
+  return __builtin_clz((unsigned int)x);
+}
+
+FOLLY_ALWAYS_INLINE int __builtin_clzll(unsigned long long x) {
+  unsigned long index;
+  return (int)(_BitScanReverse64(&index, x) ? 63 - index : 64);
+}
+
+FOLLY_ALWAYS_INLINE int __builtin_ffs(int x) {
+  unsigned long index;
+  return (int)(_BitScanForward(&index, (unsigned long)x) ? index : 0);
+}
+
+FOLLY_ALWAYS_INLINE int __builtin_ffsl(long x) { return __builtin_ffs((int)x); }
+
+FOLLY_ALWAYS_INLINE int __builtin_ffsll(long long x) {
+  unsigned long index;
+  return (int)(_BitScanForward64(&index, (unsigned long long)x) ? index : 0);
+}
+
+FOLLY_ALWAYS_INLINE int __builtin_popcountll(unsigned long long x) {
+  return (int)__popcnt64(x);
+}
+
+FOLLY_ALWAYS_INLINE void* __builtin_return_address(unsigned int frame) {
+  // I really hope frame is zero...
+  assert(frame == 0);
+  return _ReturnAddress();
+}
+#endif