summaryrefslogtreecommitdiff
path: root/include/llvm/Support/MathExtras.h
blob: 8209445f15e931a9e62c98a98e521f2245855b0b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
//===-- llvm/Support/MathExtras.h - Useful math functions -------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains some functions that are useful for math stuff.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_SUPPORT_MATHEXTRAS_H
#define LLVM_SUPPORT_MATHEXTRAS_H

#include "llvm/Support/DataTypes.h"

namespace llvm {

// NOTE: The following support functions use the _32/_64 extensions instead of  
// type overloading so that signed and unsigned integers can be used without
// ambiguity.


// Hi_32 - This function returns the high 32 bits of a 64 bit value.
inline unsigned Hi_32(uint64_t Value) {
  return (unsigned)(Value >> 32);
}

// Lo_32 - This function returns the low 32 bits of a 64 bit value.
inline unsigned Lo_32(uint64_t Value) {
  return (unsigned)Value;
}

// is?Type - these functions produce optimal testing for integer data types.
inline bool isInt8  (int Value)     { return (  signed char )Value == Value; }
inline bool isUInt8 (int Value)     { return (unsigned char )Value == Value; }
inline bool isInt16 (int Value)     { return (  signed short)Value == Value; }
inline bool isUInt16(int Value)     { return (unsigned short)Value == Value; }
inline bool isInt32 (int64_t Value) { return (  signed int  )Value == Value; }
inline bool isUInt32(int64_t Value) { return (unsigned int  )Value == Value; }

// isMask_32 - This function returns true if the argument is a sequence of ones  
// starting at the least significant bit with the remainder zero (32 bit version.)
// Ex. isMask_32(0x0000FFFFU) == true.
inline const bool isMask_32(unsigned Value) {
  return Value && ((Value + 1) & Value) == 0;
}

// isMask_64 - This function returns true if the argument is a sequence of ones  
// starting at the least significant bit with the remainder zero (64 bit version.)
inline const bool isMask_64(uint64_t Value) {
  return Value && ((Value + 1) & Value) == 0;
}

// isShiftedMask_32 - This function returns true if the argument contains a  
// sequence of ones with the remainder zero (32 bit version.)
// Ex. isShiftedMask_32(0x0000FF00U) == true.
inline const bool isShiftedMask_32(unsigned Value) {
  return isMask_32((Value - 1) | Value);
}

// isShiftedMask_64 - This function returns true if the argument contains a  
// sequence of ones with the remainder zero (64 bit version.)
inline const bool isShiftedMask_64(uint64_t Value) {
  return isMask_64((Value - 1) | Value);
}

// isPowerOf2_32 - This function returns true if the argument is a power of 
// two > 0. Ex. isPowerOf2_32(0x00100000U) == true (32 bit edition.)
inline bool isPowerOf2_32(unsigned Value) {
  return Value && !(Value & (Value - 1));
}

// isPowerOf2_64 - This function returns true if the argument is a power of two
// > 0 (64 bit edition.)
inline bool isPowerOf2_64(uint64_t Value) {
  return Value && !(Value & (Value - 1LL));
}

// CountLeadingZeros_32 - this function performs the platform optimal form of
// counting the number of zeros from the most significant bit to the first one
// bit.  Ex. CountLeadingZeros_32(0x00F000FF) == 8.
// Returns 32 if the word is zero.
// CountLeadingZeros_32 - this function performs the platform optimal form
// of counting the number of zeros from the most significant bit to the first
// one bit.  Ex. CountLeadingZeros_32(0x00F000FF) == 8.
// Returns 32 if the word is zero.
inline unsigned CountLeadingZeros_32(unsigned Value) {
  unsigned Count; // result
#if __GNUC__ >= 4
  // PowerPC is defined for __builtin_clz(0)
#if !defined(__ppc__) && !defined(__ppc64__)
  if (!Value) return 32;
#endif
  Count = __builtin_clz(Value);
#else
  if (!Value) return 32;
  Count = 0;
  // bisecton method for count leading zeros
  for (unsigned Shift = 32 >> 1; Shift; Shift >>= 1) {
    unsigned Tmp = Value >> Shift;
    if (Tmp) {
      Value = Tmp;
    } else {
      Count |= Shift;
    }
  }
#endif
  return Count;
}

// CountLeadingZeros_64 - This function performs the platform optimal form
// of counting the number of zeros from the most significant bit to the first 
// one bit (64 bit edition.)
// Returns 64 if the word is zero.
inline unsigned CountLeadingZeros_64(uint64_t Value) {
  unsigned Count; // result
#if __GNUC__ >= 4
  // PowerPC is defined for __builtin_clzll(0)
#if !defined(__ppc__) && !defined(__ppc64__)
  if (!Value) return 64;
#endif
  Count = __builtin_clzll(Value);
#else
  if (sizeof(long) == sizeof(int64_t)) {
    if (!Value) return 64;
    Count = 0;
    // bisecton method for count leading zeros
    for (uint64_t Shift = 64 >> 1; Shift; Shift >>= 1) {
      uint64_t Tmp = Value >> Shift;
      if (Tmp) {
        Value = Tmp;
      } else {
        Count |= Shift;
      }
    }
  } else {
    // get hi portion
    unsigned Hi = Hi_32(Value);

    // if some bits in hi portion
    if (Hi) {
        // leading zeros in hi portion plus all bits in lo portion
        Count = CountLeadingZeros_32(Hi);
    } else {
        // get lo portion
        unsigned Lo = Lo_32(Value);
        // same as 32 bit value
        Count = CountLeadingZeros_32(Lo)+32;
    }
  }
#endif
  return Count;
}

// Log2_32 - This function returns the floor log base 2 of the specified value, 
// -1 if the value is zero. (32 bit edition.)
// Ex. Log2_32(32) == 5, Log2_32(1) == 0, Log2_32(0) == -1
inline unsigned Log2_32(unsigned Value) {
    return 31 - CountLeadingZeros_32(Value);
  }

// Log2_64 - This function returns the floor log base 2 of the specified value, 
// -1 if the value is zero. (64 bit edition.)
inline unsigned Log2_64(uint64_t Value) {
    return 63 - CountLeadingZeros_64(Value);
}

// BitsToDouble - This function takes a 64-bit integer and returns the bit
// equivalent double.
inline double BitsToDouble(uint64_t Bits) {
  union {
    uint64_t L;
    double D;
  } T;
  T.L = Bits;
  return T.D;
}

// BitsToFloat - This function takes a 32-bit integer and returns the bit
// equivalent float.
inline float BitsToFloat(uint32_t Bits) {
  union {
    uint32_t I;
    float F;
  } T;
  T.I = Bits;
  return T.F;
}

// DoubleToBits - This function takes a double and returns the bit
// equivalent 64-bit integer.
inline uint64_t DoubleToBits(double Double) {
  union {
    uint64_t L;
    double D;
  } T;
  T.D = Double;
  return T.L;
}

// FloatToBits - This function takes a float and returns the bit
// equivalent 32-bit integer.
inline uint32_t FloatToBits(float Float) {
  union {
    uint32_t I;
    float F;
  } T;
  T.F = Float;
  return T.I;
}

// Platform-independent wrappers for the C99 isnan() function.
int IsNAN (float f);
int IsNAN (double d);

// Platform-independent wrappers for the C99 isinf() function.
int IsInf (float f);
int IsInf (double d);

} // End llvm namespace

#endif