Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(73)

Unified Diff: src/compiler-intrinsics.h

Issue 170383003: Merge a few A64 utils into the CompilerIntrinsics. Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fixes and cleaning Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/a64/utils-a64.cc ('k') | src/compiler-intrinsics.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler-intrinsics.h
diff --git a/src/compiler-intrinsics.h b/src/compiler-intrinsics.h
index b73e8ac750d0747b95693c8481b1592c65bd03c5..82973a21ebfeb5c3bda81515ed6b161a27ef1f42 100644
--- a/src/compiler-intrinsics.h
+++ b/src/compiler-intrinsics.h
@@ -28,21 +28,36 @@
#ifndef V8_COMPILER_INTRINSICS_H_
#define V8_COMPILER_INTRINSICS_H_
+#include "globals.h"
+#include "checks.h"
+
+
namespace v8 {
namespace internal {
+// C++ fallback implementations when builtins are not availble.
+int C_CountRedundantLeadingSignBits(int64_t value, int width);
+int C_CountSetBits(uint64_t value, int width);
+
class CompilerIntrinsics {
public:
// Returns number of zero bits preceding least significant 1 bit.
// Undefined for zero value.
INLINE(static int CountTrailingZeros(uint32_t value));
+ INLINE(static int CountTrailingZeros(uint64_t value));
// Returns number of zero bits following most significant 1 bit.
// Undefined for zero value.
INLINE(static int CountLeadingZeros(uint32_t value));
+ INLINE(static int CountLeadingZeros(uint64_t value));
+
+ // Returns the number of redundant leading sign bits.
+ INLINE(static int CountRedundantLeadingSignBits(int32_t value));
+ INLINE(static int CountRedundantLeadingSignBits(int64_t value));
// Returns the number of bits set.
INLINE(static int CountSetBits(uint32_t value));
+ INLINE(static int CountSetBits(uint64_t value));
};
#ifdef __GNUC__
@@ -50,18 +65,53 @@ int CompilerIntrinsics::CountTrailingZeros(uint32_t value) {
return __builtin_ctz(value);
}
+int CompilerIntrinsics::CountTrailingZeros(uint64_t value) {
+ return __builtin_ctzll(value);
+}
+
int CompilerIntrinsics::CountLeadingZeros(uint32_t value) {
return __builtin_clz(value);
}
+int CompilerIntrinsics::CountLeadingZeros(uint64_t value) {
+ return __builtin_clzll(value);
+}
+
+// __builtin_clrsb and derivatives are only availble since GCC4.7.0.
+#define GNUC_AVAILABLE_BUILTIN_CLRSB ((__GNUC__ >= 4) && (__GNUC_MINOR__ >= 7))
+int CompilerIntrinsics::CountRedundantLeadingSignBits(int32_t value) {
+#if GNUC_AVAILABLE_BUILTIN_CLRSB
+ return __builtin_clrsb(value);
+#else
+ return C_CountRedundantLeadingSignBits(value, 32);
+#endif
+}
+
+int CompilerIntrinsics::CountRedundantLeadingSignBits(int64_t value) {
+#if GNUC_AVAILABLE_BUILTIN_CLRSB
+ return __builtin_clrsbll(value);
+#else
+ return C_CountRedundantLeadingSignBits(value, 64);
+#endif
+}
+#undef GNUC_AVAILABLE_BUILTIN_CLRSB
+
int CompilerIntrinsics::CountSetBits(uint32_t value) {
return __builtin_popcount(value);
}
+int CompilerIntrinsics::CountSetBits(uint64_t value) {
+ return __builtin_popcountll(value);
+}
+
#elif defined(_MSC_VER)
#pragma intrinsic(_BitScanForward)
#pragma intrinsic(_BitScanReverse)
+#if V8_TARGET_ARCH_X64
+#pragma intrinsic(_BitScanForward64)
+#pragma intrinsic(_BitScanReverse64)
+#endif
int CompilerIntrinsics::CountTrailingZeros(uint32_t value) {
unsigned long result; //NOLINT
@@ -69,26 +119,147 @@ int CompilerIntrinsics::CountTrailingZeros(uint32_t value) {
return static_cast<int>(result);
}
+int CompilerIntrinsics::CountTrailingZeros(uint64_t value) {
+#if V8_TARGET_ARCH_X64
+ unsigned long result; //NOLINT
+ _BitScanForward64(&result, static_cast<__int64>(value)); //NOLINT
+ return static_cast<int>(result);
+#else
+ uint32_t low = value & kMaxUInt32;
+ uint32_t high = value >> 32;
+ if (low == 0) {
+ return 32 + CountTrailingZeros(high);
+ } else {
+ return CountTrailingZeros(low);
+ }
+#endif
+}
+
int CompilerIntrinsics::CountLeadingZeros(uint32_t value) {
unsigned long result; //NOLINT
_BitScanReverse(&result, static_cast<long>(value)); //NOLINT
return 31 - static_cast<int>(result);
}
+int CompilerIntrinsics::CountLeadingZeros(uint64_t value) {
+#if V8_TARGET_ARCH_X64
+ unsigned long result; //NOLINT
+ _BitScanReverse64(&result, static_cast<__int64>(value)); //NOLINT
+ return 63 - static_cast<int>(result);
+#else
+ uint32_t low = value & kMaxUInt32;
+ uint32_t high = value >> 32;
+ if (high == 0) {
+ return 32 + CountLeadingZeros(low);
+ } else {
+ return CountLeadingZeros(high);
+ }
+#endif
+}
+
+int CompilerIntrinsics::CountRedundantLeadingSignBits(int32_t value) {
+ uint32_t val = static_cast<uint32_t>((value >= 0) ? value : ~value);
+ return CountLeadingZeros(val, width) - 1;
+}
+
+int CompilerIntrinsics::CountRedundantLeadingSignBits(int64_t value) {
+ uint64_t val = static_cast<uint64_t>((value >= 0) ? value : ~value);
+ return CountLeadingZeros(val, width) - 1;
+}
+
int CompilerIntrinsics::CountSetBits(uint32_t value) {
- // Manually count set bits.
- value = ((value >> 1) & 0x55555555) + (value & 0x55555555);
- value = ((value >> 2) & 0x33333333) + (value & 0x33333333);
- value = ((value >> 4) & 0x0f0f0f0f) + (value & 0x0f0f0f0f);
- value = ((value >> 8) & 0x00ff00ff) + (value & 0x00ff00ff);
- value = ((value >> 16) & 0x0000ffff) + (value & 0x0000ffff);
- return value;
+ return C_CountSetBits(value, 32);
+}
+
+int CompilerIntrinsics::CountSetBits(uint64_t value) {
+ return C_CountSetBits(value, 64);
}
#else
#error Unsupported compiler
#endif
+
+// Inline function helpers use the intrinsics and disambiguate undefined
+// situations.
+
+inline int CountTrailingZeros(uint32_t value) {
+ if (value == 0) {
+ // The result of the intrinsics is undefined for 0.
+ return 32;
+ }
+ return CompilerIntrinsics::CountTrailingZeros(value);
+}
+inline int CountTrailingZeros(uint64_t value) {
+ if (value == 0) {
+ // The result of the intrinsics is undefined for 0.
+ return 64;
+ }
+ return CompilerIntrinsics::CountTrailingZeros(value);
+}
+inline int CountTrailingZeros(uint64_t value, int width) {
+ ASSERT((width == 32) || (width == 64));
+ if (width == 32) {
+ return CountTrailingZeros(static_cast<uint32_t>(value));
+ } else {
+ return CountTrailingZeros(static_cast<uint64_t>(value));
+ }
+}
+
+inline int CountLeadingZeros(uint32_t value) {
+ if (value == 0) {
+ // The result of the intrinsics is undefined for 0.
+ return 32;
+ }
+ return CompilerIntrinsics::CountLeadingZeros(value);
+}
+inline int CountLeadingZeros(uint64_t value) {
+ if (value == 0) {
+ // The result of the intrinsics is undefined for 0.
+ return 64;
+ }
+ return CompilerIntrinsics::CountLeadingZeros(value);
+}
+inline int CountLeadingZeros(uint64_t value, int width) {
+ ASSERT((width == 32) || (width == 64));
+ if (width == 32) {
+ return CountLeadingZeros(static_cast<uint32_t>(value));
+ } else {
+ return CountLeadingZeros(static_cast<uint64_t>(value));
+ }
+}
+
+inline int CountRedundantLeadingSignBits(int32_t value) {
+ return CompilerIntrinsics::CountRedundantLeadingSignBits(value);
+}
+inline int CountRedundantLeadingSignBits(int64_t value) {
+ return CompilerIntrinsics::CountRedundantLeadingSignBits(value);
+}
+inline int CountRedundantLeadingSignBits(int64_t value, int width) {
+ ASSERT((width == 32) || (width == 64));
+ if (width == 32) {
+ return CountRedundantLeadingSignBits(static_cast<int32_t>(value));
+ } else {
+ return CountRedundantLeadingSignBits(static_cast<int64_t>(value));
+ }
+}
+
+inline int CountSetBits(uint32_t value) {
+ return CompilerIntrinsics::CountSetBits(value);
+}
+inline int CountSetBits(uint64_t value) {
+ return CompilerIntrinsics::CountSetBits(value);
+}
+inline int CountSetBits(uint64_t value, int width) {
+ ASSERT((width == 32) || (width == 64));
+ if (width == 32) {
+ return CountSetBits(static_cast<uint32_t>(value));
+ } else {
+ return CountSetBits(static_cast<uint64_t>(value));
+ }
+}
+
+
} } // namespace v8::internal
#endif // V8_COMPILER_INTRINSICS_H_
« no previous file with comments | « src/a64/utils-a64.cc ('k') | src/compiler-intrinsics.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698