1//===- CodeGen/ValueTypes.h - Low-Level Target independ. types --*- 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 defines the set of low-level target independent types which various
11// values in the code generator are.  This allows the target specific behavior
12// of instructions to be described to target independent passes.
13//
14//===----------------------------------------------------------------------===//
15
16#ifndef LLVM_CODEGEN_VALUETYPES_H
17#define LLVM_CODEGEN_VALUETYPES_H
18
19#include "llvm/CodeGen/MachineValueType.h"
20#include <cassert>
21#include <string>
22
23namespace llvm {
24
25  class LLVMContext;
26  class Type;
27
28  /// EVT - Extended Value Type.  Capable of holding value types which are not
29  /// native for any processor (such as the i12345 type), as well as the types
30  /// a MVT can represent.
31  struct EVT {
32  private:
33    MVT V;
34    Type *LLVMTy;
35
36  public:
37    EVT() : V((MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE)),
38            LLVMTy(nullptr) {}
39    EVT(MVT::SimpleValueType SVT) : V(SVT), LLVMTy(nullptr) { }
40    EVT(MVT S) : V(S), LLVMTy(nullptr) {}
41
42    bool operator==(EVT VT) const {
43      return !(*this != VT);
44    }
45    bool operator!=(EVT VT) const {
46      if (V.SimpleTy != VT.V.SimpleTy)
47        return true;
48      if (V.SimpleTy < 0)
49        return LLVMTy != VT.LLVMTy;
50      return false;
51    }
52
53    /// getFloatingPointVT - Returns the EVT that represents a floating point
54    /// type with the given number of bits.  There are two floating point types
55    /// with 128 bits - this returns f128 rather than ppcf128.
56    static EVT getFloatingPointVT(unsigned BitWidth) {
57      return MVT::getFloatingPointVT(BitWidth);
58    }
59
60    /// getIntegerVT - Returns the EVT that represents an integer with the given
61    /// number of bits.
62    static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth) {
63      MVT M = MVT::getIntegerVT(BitWidth);
64      if (M.SimpleTy >= 0)
65        return M;
66      return getExtendedIntegerVT(Context, BitWidth);
67    }
68
69    /// getVectorVT - Returns the EVT that represents a vector NumElements in
70    /// length, where each element is of type VT.
71    static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements) {
72      MVT M = MVT::getVectorVT(VT.V, NumElements);
73      if (M.SimpleTy >= 0)
74        return M;
75      return getExtendedVectorVT(Context, VT, NumElements);
76    }
77
78    /// changeVectorElementTypeToInteger - Return a vector with the same number
79    /// of elements as this vector, but with the element type converted to an
80    /// integer type with the same bitwidth.
81    EVT changeVectorElementTypeToInteger() const {
82      if (!isSimple())
83        return changeExtendedVectorElementTypeToInteger();
84      MVT EltTy = getSimpleVT().getVectorElementType();
85      unsigned BitWidth = EltTy.getSizeInBits();
86      MVT IntTy = MVT::getIntegerVT(BitWidth);
87      MVT VecTy = MVT::getVectorVT(IntTy, getVectorNumElements());
88      assert(VecTy.SimpleTy >= 0 &&
89             "Simple vector VT not representable by simple integer vector VT!");
90      return VecTy;
91    }
92
93    /// isSimple - Test if the given EVT is simple (as opposed to being
94    /// extended).
95    bool isSimple() const {
96      return V.SimpleTy >= 0;
97    }
98
99    /// isExtended - Test if the given EVT is extended (as opposed to
100    /// being simple).
101    bool isExtended() const {
102      return !isSimple();
103    }
104
105    /// isFloatingPoint - Return true if this is a FP, or a vector FP type.
106    bool isFloatingPoint() const {
107      return isSimple() ? V.isFloatingPoint() : isExtendedFloatingPoint();
108    }
109
110    /// isInteger - Return true if this is an integer, or a vector integer type.
111    bool isInteger() const {
112      return isSimple() ? V.isInteger() : isExtendedInteger();
113    }
114
115    /// isVector - Return true if this is a vector value type.
116    bool isVector() const {
117      return isSimple() ? V.isVector() : isExtendedVector();
118    }
119
120    /// is16BitVector - Return true if this is a 16-bit vector type.
121    bool is16BitVector() const {
122      return isSimple() ? V.is16BitVector() : isExtended16BitVector();
123    }
124
125    /// is32BitVector - Return true if this is a 32-bit vector type.
126    bool is32BitVector() const {
127      return isSimple() ? V.is32BitVector() : isExtended32BitVector();
128    }
129
130    /// is64BitVector - Return true if this is a 64-bit vector type.
131    bool is64BitVector() const {
132      return isSimple() ? V.is64BitVector() : isExtended64BitVector();
133    }
134
135    /// is128BitVector - Return true if this is a 128-bit vector type.
136    bool is128BitVector() const {
137      return isSimple() ? V.is128BitVector() : isExtended128BitVector();
138    }
139
140    /// is256BitVector - Return true if this is a 256-bit vector type.
141    bool is256BitVector() const {
142      return isSimple() ? V.is256BitVector() : isExtended256BitVector();
143    }
144
145    /// is512BitVector - Return true if this is a 512-bit vector type.
146    bool is512BitVector() const {
147      return isSimple() ? V.is512BitVector() : isExtended512BitVector();
148    }
149
150    /// is1024BitVector - Return true if this is a 1024-bit vector type.
151    bool is1024BitVector() const {
152      return isSimple() ? V.is1024BitVector() : isExtended1024BitVector();
153    }
154
155    /// isOverloaded - Return true if this is an overloaded type for TableGen.
156    bool isOverloaded() const {
157      return (V==MVT::iAny || V==MVT::fAny || V==MVT::vAny || V==MVT::iPTRAny);
158    }
159
160    /// isByteSized - Return true if the bit size is a multiple of 8.
161    bool isByteSized() const {
162      return (getSizeInBits() & 7) == 0;
163    }
164
165    /// isRound - Return true if the size is a power-of-two number of bytes.
166    bool isRound() const {
167      unsigned BitSize = getSizeInBits();
168      return BitSize >= 8 && !(BitSize & (BitSize - 1));
169    }
170
171    /// bitsEq - Return true if this has the same number of bits as VT.
172    bool bitsEq(EVT VT) const {
173      if (EVT::operator==(VT)) return true;
174      return getSizeInBits() == VT.getSizeInBits();
175    }
176
177    /// bitsGT - Return true if this has more bits than VT.
178    bool bitsGT(EVT VT) const {
179      if (EVT::operator==(VT)) return false;
180      return getSizeInBits() > VT.getSizeInBits();
181    }
182
183    /// bitsGE - Return true if this has no less bits than VT.
184    bool bitsGE(EVT VT) const {
185      if (EVT::operator==(VT)) return true;
186      return getSizeInBits() >= VT.getSizeInBits();
187    }
188
189    /// bitsLT - Return true if this has less bits than VT.
190    bool bitsLT(EVT VT) const {
191      if (EVT::operator==(VT)) return false;
192      return getSizeInBits() < VT.getSizeInBits();
193    }
194
195    /// bitsLE - Return true if this has no more bits than VT.
196    bool bitsLE(EVT VT) const {
197      if (EVT::operator==(VT)) return true;
198      return getSizeInBits() <= VT.getSizeInBits();
199    }
200
201
202    /// getSimpleVT - Return the SimpleValueType held in the specified
203    /// simple EVT.
204    MVT getSimpleVT() const {
205      assert(isSimple() && "Expected a SimpleValueType!");
206      return V;
207    }
208
209    /// getScalarType - If this is a vector type, return the element type,
210    /// otherwise return this.
211    EVT getScalarType() const {
212      return isVector() ? getVectorElementType() : *this;
213    }
214
215    /// getVectorElementType - Given a vector type, return the type of
216    /// each element.
217    EVT getVectorElementType() const {
218      assert(isVector() && "Invalid vector type!");
219      if (isSimple())
220        return V.getVectorElementType();
221      return getExtendedVectorElementType();
222    }
223
224    /// getVectorNumElements - Given a vector type, return the number of
225    /// elements it contains.
226    unsigned getVectorNumElements() const {
227      assert(isVector() && "Invalid vector type!");
228      if (isSimple())
229        return V.getVectorNumElements();
230      return getExtendedVectorNumElements();
231    }
232
233    /// getSizeInBits - Return the size of the specified value type in bits.
234    unsigned getSizeInBits() const {
235      if (isSimple())
236        return V.getSizeInBits();
237      return getExtendedSizeInBits();
238    }
239
240    unsigned getScalarSizeInBits() const {
241      return getScalarType().getSizeInBits();
242    }
243
244    /// getStoreSize - Return the number of bytes overwritten by a store
245    /// of the specified value type.
246    unsigned getStoreSize() const {
247      return (getSizeInBits() + 7) / 8;
248    }
249
250    /// getStoreSizeInBits - Return the number of bits overwritten by a store
251    /// of the specified value type.
252    unsigned getStoreSizeInBits() const {
253      return getStoreSize() * 8;
254    }
255
256    /// getRoundIntegerType - Rounds the bit-width of the given integer EVT up
257    /// to the nearest power of two (and at least to eight), and returns the
258    /// integer EVT with that number of bits.
259    EVT getRoundIntegerType(LLVMContext &Context) const {
260      assert(isInteger() && !isVector() && "Invalid integer type!");
261      unsigned BitWidth = getSizeInBits();
262      if (BitWidth <= 8)
263        return EVT(MVT::i8);
264      return getIntegerVT(Context, 1 << Log2_32_Ceil(BitWidth));
265    }
266
267    /// getHalfSizedIntegerVT - Finds the smallest simple value type that is
268    /// greater than or equal to half the width of this EVT. If no simple
269    /// value type can be found, an extended integer value type of half the
270    /// size (rounded up) is returned.
271    EVT getHalfSizedIntegerVT(LLVMContext &Context) const {
272      assert(isInteger() && !isVector() && "Invalid integer type!");
273      unsigned EVTSize = getSizeInBits();
274      for (unsigned IntVT = MVT::FIRST_INTEGER_VALUETYPE;
275          IntVT <= MVT::LAST_INTEGER_VALUETYPE; ++IntVT) {
276        EVT HalfVT = EVT((MVT::SimpleValueType)IntVT);
277        if (HalfVT.getSizeInBits() * 2 >= EVTSize)
278          return HalfVT;
279      }
280      return getIntegerVT(Context, (EVTSize + 1) / 2);
281    }
282
283    /// \brief Return a VT for an integer vector type with the size of the
284    /// elements doubled. The typed returned may be an extended type.
285    EVT widenIntegerVectorElementType(LLVMContext &Context) const {
286      EVT EltVT = getVectorElementType();
287      EltVT = EVT::getIntegerVT(Context, 2 * EltVT.getSizeInBits());
288      return EVT::getVectorVT(Context, EltVT, getVectorNumElements());
289    }
290
291    /// isPow2VectorType - Returns true if the given vector is a power of 2.
292    bool isPow2VectorType() const {
293      unsigned NElts = getVectorNumElements();
294      return !(NElts & (NElts - 1));
295    }
296
297    /// getPow2VectorType - Widens the length of the given vector EVT up to
298    /// the nearest power of 2 and returns that type.
299    EVT getPow2VectorType(LLVMContext &Context) const {
300      if (!isPow2VectorType()) {
301        unsigned NElts = getVectorNumElements();
302        unsigned Pow2NElts = 1 <<  Log2_32_Ceil(NElts);
303        return EVT::getVectorVT(Context, getVectorElementType(), Pow2NElts);
304      }
305      else {
306        return *this;
307      }
308    }
309
310    /// getEVTString - This function returns value type as a string,
311    /// e.g. "i32".
312    std::string getEVTString() const;
313
314    /// getTypeForEVT - This method returns an LLVM type corresponding to the
315    /// specified EVT.  For integer types, this returns an unsigned type.  Note
316    /// that this will abort for types that cannot be represented.
317    Type *getTypeForEVT(LLVMContext &Context) const;
318
319    /// getEVT - Return the value type corresponding to the specified type.
320    /// This returns all pointers as iPTR.  If HandleUnknown is true, unknown
321    /// types are returned as Other, otherwise they are invalid.
322    static EVT getEVT(Type *Ty, bool HandleUnknown = false);
323
324    intptr_t getRawBits() const {
325      if (isSimple())
326        return V.SimpleTy;
327      else
328        return (intptr_t)(LLVMTy);
329    }
330
331    /// compareRawBits - A meaningless but well-behaved order, useful for
332    /// constructing containers.
333    struct compareRawBits {
334      bool operator()(EVT L, EVT R) const {
335        if (L.V.SimpleTy == R.V.SimpleTy)
336          return L.LLVMTy < R.LLVMTy;
337        else
338          return L.V.SimpleTy < R.V.SimpleTy;
339      }
340    };
341
342  private:
343    // Methods for handling the Extended-type case in functions above.
344    // These are all out-of-line to prevent users of this header file
345    // from having a dependency on Type.h.
346    EVT changeExtendedVectorElementTypeToInteger() const;
347    static EVT getExtendedIntegerVT(LLVMContext &C, unsigned BitWidth);
348    static EVT getExtendedVectorVT(LLVMContext &C, EVT VT,
349                                   unsigned NumElements);
350    bool isExtendedFloatingPoint() const LLVM_READONLY;
351    bool isExtendedInteger() const LLVM_READONLY;
352    bool isExtendedVector() const LLVM_READONLY;
353    bool isExtended16BitVector() const LLVM_READONLY;
354    bool isExtended32BitVector() const LLVM_READONLY;
355    bool isExtended64BitVector() const LLVM_READONLY;
356    bool isExtended128BitVector() const LLVM_READONLY;
357    bool isExtended256BitVector() const LLVM_READONLY;
358    bool isExtended512BitVector() const LLVM_READONLY;
359    bool isExtended1024BitVector() const LLVM_READONLY;
360    EVT getExtendedVectorElementType() const;
361    unsigned getExtendedVectorNumElements() const LLVM_READONLY;
362    unsigned getExtendedSizeInBits() const;
363  };
364
365} // End llvm namespace
366
367#endif
368