blob: 1152dbe289ab44dcc540245e50e02f9ee52b8447 [file] [log] [blame]
Brian Silvermanf7bd1c22015-12-24 16:07:11 -08001//===-- 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
21namespace llvm {
22/// \brief The behavior an operation has on an input of 0.
23enum ZeroBehavior {
24 /// \brief The returned value is undefined.
25 ZB_Undefined,
26 /// \brief The returned value is numeric_limits<T>::max()
27 ZB_Max,
28 /// \brief The returned value is numeric_limits<T>::digits
29 ZB_Width
30};
31
32namespace detail {
33template <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
52template <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)
68template <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
86/// \brief Count number of 0's from the most significant bit to the least
87/// stopping at the first 1.
88///
89/// Only unsigned integral types are allowed.
90///
91/// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are
92/// valid arguments.
93template <typename T>
94std::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
101/// Log2_32 - This function returns the floor log base 2 of the specified value,
102/// -1 if the value is zero. (32 bit edition.)
103/// Ex. Log2_32(32) == 5, Log2_32(1) == 0, Log2_32(0) == -1, Log2_32(6) == 2
104inline unsigned Log2_32(uint32_t Value) {
105 return 31 - countLeadingZeros(Value);
106}
107
108/// Log2_64 - This function returns the floor log base 2 of the specified value,
109/// -1 if the value is zero. (64 bit edition.)
110inline unsigned Log2_64(uint64_t Value) {
111 return 63 - countLeadingZeros(Value);
112}
113
114/// Log2_32_Ceil - This function returns the ceil log base 2 of the specified
115/// value, 32 if the value is zero. (32 bit edition).
116/// Ex. Log2_32_Ceil(32) == 5, Log2_32_Ceil(1) == 0, Log2_32_Ceil(6) == 3
117inline unsigned Log2_32_Ceil(uint32_t Value) {
118 return 32 - countLeadingZeros(Value - 1);
119}
120
121/// Log2_64_Ceil - This function returns the ceil log base 2 of the specified
122/// value, 64 if the value is zero. (64 bit edition.)
123inline unsigned Log2_64_Ceil(uint64_t Value) {
124 return 64 - countLeadingZeros(Value - 1);
125}
126
127/// BitsToDouble - This function takes a 64-bit integer and returns the bit
128/// equivalent double.
129inline 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
138/// BitsToFloat - This function takes a 32-bit integer and returns the bit
139/// equivalent float.
140inline 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
149/// DoubleToBits - This function takes a double and returns the bit
150/// equivalent 64-bit integer. Note that copying doubles around
151/// changes the bits of NaNs on some hosts, notably x86, so this
152/// routine cannot be used if these bits are needed.
153inline 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
162/// FloatToBits - This function takes a float and returns the bit
163/// equivalent 32-bit integer. Note that copying floats around
164/// changes the bits of NaNs on some hosts, notably x86, so this
165/// routine cannot be used if these bits are needed.
166inline 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
175/// NextPowerOf2 - Returns the next power of two (in 64-bits)
176/// that is strictly greater than A. Returns zero on overflow.
177inline 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