blob: 6d65ade76379d4854825de8685e266bbd1c06310 [file] [log] [blame]
Jan Voung8acded02014-09-22 18:02:25 -07001//===- subzero/src/IceUtils.h - Utility functions ---------------*- C++ -*-===//
2//
3// The Subzero Code Generator
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
Andrew Scull9612d322015-07-06 14:53:25 -07009///
10/// \file
11/// This file declares some utility functions.
12///
Jan Voung8acded02014-09-22 18:02:25 -070013//===----------------------------------------------------------------------===//
14
15#ifndef SUBZERO_SRC_ICEUTILS_H
16#define SUBZERO_SRC_ICEUTILS_H
John Porto67f8de92015-06-25 10:14:17 -070017
Jan Voung8acded02014-09-22 18:02:25 -070018#include <climits>
19
20namespace Ice {
21
Andrew Scull9612d322015-07-06 14:53:25 -070022/// Similar to bit_cast, but allows copying from types of unrelated
23/// sizes. This method was introduced to enable the strict aliasing
24/// optimizations of GCC 4.4. Basically, GCC mindlessly relies on
25/// obscure details in the C++ standard that make reinterpret_cast
26/// virtually useless.
Jan Voung8acded02014-09-22 18:02:25 -070027template <class D, class S> inline D bit_copy(const S &source) {
28 D destination;
29 // This use of memcpy is safe: source and destination cannot overlap.
30 memcpy(&destination, reinterpret_cast<const void *>(&source),
31 sizeof(destination));
32 return destination;
33}
34
35class Utils {
Jim Stichnothc6ead202015-02-24 09:30:30 -080036 Utils() = delete;
37 Utils(const Utils &) = delete;
38 Utils &operator=(const Utils &) = delete;
39
Jan Voung8acded02014-09-22 18:02:25 -070040public:
Andrew Scull9612d322015-07-06 14:53:25 -070041 /// Check whether an N-bit two's-complement representation can hold value.
Jan Voung8acded02014-09-22 18:02:25 -070042 template <typename T> static inline bool IsInt(int N, T value) {
43 assert((0 < N) &&
44 (static_cast<unsigned int>(N) < (CHAR_BIT * sizeof(value))));
45 T limit = static_cast<T>(1) << (N - 1);
46 return (-limit <= value) && (value < limit);
47 }
48
49 template <typename T> static inline bool IsUint(int N, T value) {
50 assert((0 < N) &&
51 (static_cast<unsigned int>(N) < (CHAR_BIT * sizeof(value))));
52 T limit = static_cast<T>(1) << N;
53 return (0 <= value) && (value < limit);
54 }
55
Andrew Scull9612d322015-07-06 14:53:25 -070056 /// Check whether the magnitude of value fits in N bits, i.e., whether an
57 /// (N+1)-bit sign-magnitude representation can hold value.
Jan Voungb2d50842015-05-12 09:53:50 -070058 template <typename T> static inline bool IsAbsoluteUint(int N, T Value) {
59 assert((0 < N) &&
60 (static_cast<unsigned int>(N) < (CHAR_BIT * sizeof(Value))));
61 if (Value < 0)
62 Value = -Value;
63 return IsUint(N, Value);
64 }
65
Andrew Scull9612d322015-07-06 14:53:25 -070066 /// Return true if the addition X + Y will cause integer overflow for
67 /// integers of type T.
Jan Voung8acded02014-09-22 18:02:25 -070068 template <typename T> static inline bool WouldOverflowAdd(T X, T Y) {
69 return ((X > 0 && Y > 0 && (X > std::numeric_limits<T>::max() - Y)) ||
70 (X < 0 && Y < 0 && (X < std::numeric_limits<T>::min() - Y)));
71 }
Jan Voung72984d82015-01-29 14:42:38 -080072
Andrew Scull9612d322015-07-06 14:53:25 -070073 /// Return true if X is already aligned by N, where N is a power of 2.
Jan Voungb2d50842015-05-12 09:53:50 -070074 template <typename T> static inline bool IsAligned(T X, intptr_t N) {
75 assert(llvm::isPowerOf2_64(N));
76 return (X & (N - 1)) == 0;
77 }
78
Andrew Scull9612d322015-07-06 14:53:25 -070079 /// Return Value adjusted to the next highest multiple of Alignment.
Jan Voung55500db2015-05-26 14:25:40 -070080 static inline uint32_t applyAlignment(uint32_t Value, uint32_t Alignment) {
81 assert(llvm::isPowerOf2_32(Alignment));
82 return (Value + Alignment - 1) & -Alignment;
83 }
84
Andrew Scull9612d322015-07-06 14:53:25 -070085 /// Return amount which must be added to adjust Pos to the next highest
86 /// multiple of Align.
Jan Voung72984d82015-01-29 14:42:38 -080087 static inline uint64_t OffsetToAlignment(uint64_t Pos, uint64_t Align) {
88 assert(llvm::isPowerOf2_64(Align));
89 uint64_t Mod = Pos & (Align - 1);
90 if (Mod == 0)
91 return 0;
92 return Align - Mod;
93 }
Jan Voungb3401d22015-05-18 09:38:21 -070094
Andrew Scull9612d322015-07-06 14:53:25 -070095 /// Rotate the value bit pattern to the left by shift bits.
96 /// Precondition: 0 <= shift < 32
Jan Voungb3401d22015-05-18 09:38:21 -070097 static inline uint32_t rotateLeft32(uint32_t value, uint32_t shift) {
98 if (shift == 0)
99 return value;
100 return (value << shift) | (value >> (32 - shift));
101 }
102
Andrew Scull9612d322015-07-06 14:53:25 -0700103 /// Rotate the value bit pattern to the right by shift bits.
Jan Voungb3401d22015-05-18 09:38:21 -0700104 static inline uint32_t rotateRight32(uint32_t value, uint32_t shift) {
105 if (shift == 0)
106 return value;
107 return (value >> shift) | (value << (32 - shift));
108 }
Jan Voung8acded02014-09-22 18:02:25 -0700109};
110
Jan Voung8acded02014-09-22 18:02:25 -0700111} // end of namespace Ice
112
113#endif // SUBZERO_SRC_ICEUTILS_H