WPILibC++  unspecified
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Pages
MathExtras.h
1 //===-- llvm/Support/MathExtras.h - Useful math functions -------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains some functions that are useful for math stuff.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_SUPPORT_MATHEXTRAS_H
15 #define LLVM_SUPPORT_MATHEXTRAS_H
16 
17 #include "llvm/Compiler.h"
18 #include <cstdint>
19 #include <limits>
20 
21 namespace llvm {
23 enum ZeroBehavior {
25  ZB_Undefined,
27  ZB_Max,
29  ZB_Width
30 };
31 
32 namespace detail {
33 template <typename T, std::size_t SizeOfT> struct LeadingZerosCounter {
34  static std::size_t count(T Val, ZeroBehavior) {
35  if (!Val)
36  return std::numeric_limits<T>::digits;
37 
38  // Bisection method.
39  std::size_t ZeroBits = 0;
40  for (T Shift = std::numeric_limits<T>::digits >> 1; Shift; Shift >>= 1) {
41  T Tmp = Val >> Shift;
42  if (Tmp)
43  Val = Tmp;
44  else
45  ZeroBits |= Shift;
46  }
47  return ZeroBits;
48  }
49 };
50 
51 #if __GNUC__ >= 4 || _MSC_VER
52 template <typename T> struct LeadingZerosCounter<T, 4> {
53  static std::size_t count(T Val, ZeroBehavior ZB) {
54  if (ZB != ZB_Undefined && Val == 0)
55  return 32;
56 
57 #if __has_builtin(__builtin_clz) || LLVM_GNUC_PREREQ(4, 0, 0)
58  return __builtin_clz(Val);
59 #elif _MSC_VER
60  unsigned long Index;
61  _BitScanReverse(&Index, Val);
62  return Index ^ 31;
63 #endif
64  }
65 };
66 
67 #if !defined(_MSC_VER) || defined(_M_X64)
68 template <typename T> struct LeadingZerosCounter<T, 8> {
69  static std::size_t count(T Val, ZeroBehavior ZB) {
70  if (ZB != ZB_Undefined && Val == 0)
71  return 64;
72 
73 #if __has_builtin(__builtin_clzll) || LLVM_GNUC_PREREQ(4, 0, 0)
74  return __builtin_clzll(Val);
75 #elif _MSC_VER
76  unsigned long Index;
77  _BitScanReverse64(&Index, Val);
78  return Index ^ 63;
79 #endif
80  }
81 };
82 #endif
83 #endif
84 } // namespace detail
85 
93 template <typename T>
94 std::size_t countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) {
95  static_assert(std::numeric_limits<T>::is_integer &&
96  !std::numeric_limits<T>::is_signed,
97  "Only unsigned integral types are allowed.");
98  return detail::LeadingZerosCounter<T, sizeof(T)>::count(Val, ZB);
99 }
100 
104 inline unsigned Log2_32(uint32_t Value) {
105  return 31 - countLeadingZeros(Value);
106 }
107 
110 inline unsigned Log2_64(uint64_t Value) {
111  return 63 - countLeadingZeros(Value);
112 }
113 
117 inline unsigned Log2_32_Ceil(uint32_t Value) {
118  return 32 - countLeadingZeros(Value - 1);
119 }
120 
123 inline unsigned Log2_64_Ceil(uint64_t Value) {
124  return 64 - countLeadingZeros(Value - 1);
125 }
126 
129 inline double BitsToDouble(uint64_t Bits) {
130  union {
131  uint64_t L;
132  double D;
133  } T;
134  T.L = Bits;
135  return T.D;
136 }
137 
140 inline float BitsToFloat(uint32_t Bits) {
141  union {
142  uint32_t I;
143  float F;
144  } T;
145  T.I = Bits;
146  return T.F;
147 }
148 
153 inline uint64_t DoubleToBits(double Double) {
154  union {
155  uint64_t L;
156  double D;
157  } T;
158  T.D = Double;
159  return T.L;
160 }
161 
166 inline uint32_t FloatToBits(float Float) {
167  union {
168  uint32_t I;
169  float F;
170  } T;
171  T.F = Float;
172  return T.I;
173 }
174 
177 inline uint64_t NextPowerOf2(uint64_t A) {
178  A |= (A >> 1);
179  A |= (A >> 2);
180  A |= (A >> 4);
181  A |= (A >> 8);
182  A |= (A >> 16);
183  A |= (A >> 32);
184  return A + 1;
185 }
186 
187 } // namespace llvm
188 
189 #endif
Definition: MathExtras.h:33