1193323Sed//===- CodeGen/ValueTypes.h - Low-Level Target independ. types --*- C++ -*-===//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed//
10193323Sed// This file defines the set of low-level target independent types which various
11193323Sed// values in the code generator are.  This allows the target specific behavior
12193323Sed// of instructions to be described to target independent passes.
13193323Sed//
14193323Sed//===----------------------------------------------------------------------===//
15193323Sed
16193323Sed#ifndef LLVM_CODEGEN_VALUETYPES_H
17193323Sed#define LLVM_CODEGEN_VALUETYPES_H
18193323Sed
19276479Sdim#include "llvm/CodeGen/MachineValueType.h"
20193323Sed#include <cassert>
21193323Sed#include <string>
22193323Sed
23193323Sednamespace llvm {
24276479Sdim
25276479Sdim  class LLVMContext;
26193323Sed  class Type;
27193323Sed
28218893Sdim  /// EVT - Extended Value Type.  Capable of holding value types which are not
29218893Sdim  /// native for any processor (such as the i12345 type), as well as the types
30218893Sdim  /// a MVT can represent.
31218893Sdim  struct EVT {
32198090Srdivacky  private:
33198090Srdivacky    MVT V;
34226633Sdim    Type *LLVMTy;
35198090Srdivacky
36198090Srdivacky  public:
37288943Sdim    LLVM_CONSTEXPR EVT() : V(MVT::INVALID_SIMPLE_VALUE_TYPE), LLVMTy(nullptr) {}
38288943Sdim    LLVM_CONSTEXPR EVT(MVT::SimpleValueType SVT) : V(SVT), LLVMTy(nullptr) {}
39288943Sdim    LLVM_CONSTEXPR EVT(MVT S) : V(S), LLVMTy(nullptr) {}
40198090Srdivacky
41212904Sdim    bool operator==(EVT VT) const {
42212904Sdim      return !(*this != VT);
43212904Sdim    }
44212904Sdim    bool operator!=(EVT VT) const {
45212904Sdim      if (V.SimpleTy != VT.V.SimpleTy)
46198090Srdivacky        return true;
47249423Sdim      if (V.SimpleTy < 0)
48212904Sdim        return LLVMTy != VT.LLVMTy;
49198090Srdivacky      return false;
50198090Srdivacky    }
51198090Srdivacky
52198090Srdivacky    /// getFloatingPointVT - Returns the EVT that represents a floating point
53198090Srdivacky    /// type with the given number of bits.  There are two floating point types
54198090Srdivacky    /// with 128 bits - this returns f128 rather than ppcf128.
55198090Srdivacky    static EVT getFloatingPointVT(unsigned BitWidth) {
56198090Srdivacky      return MVT::getFloatingPointVT(BitWidth);
57198090Srdivacky    }
58198090Srdivacky
59198090Srdivacky    /// getIntegerVT - Returns the EVT that represents an integer with the given
60198090Srdivacky    /// number of bits.
61198090Srdivacky    static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth) {
62198090Srdivacky      MVT M = MVT::getIntegerVT(BitWidth);
63249423Sdim      if (M.SimpleTy >= 0)
64198090Srdivacky        return M;
65212904Sdim      return getExtendedIntegerVT(Context, BitWidth);
66198090Srdivacky    }
67198090Srdivacky
68198090Srdivacky    /// getVectorVT - Returns the EVT that represents a vector NumElements in
69198090Srdivacky    /// length, where each element is of type VT.
70198090Srdivacky    static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements) {
71198090Srdivacky      MVT M = MVT::getVectorVT(VT.V, NumElements);
72249423Sdim      if (M.SimpleTy >= 0)
73198090Srdivacky        return M;
74212904Sdim      return getExtendedVectorVT(Context, VT, NumElements);
75198090Srdivacky    }
76198090Srdivacky
77226633Sdim    /// changeVectorElementTypeToInteger - Return a vector with the same number
78226633Sdim    /// of elements as this vector, but with the element type converted to an
79226633Sdim    /// integer type with the same bitwidth.
80226633Sdim    EVT changeVectorElementTypeToInteger() const {
81226633Sdim      if (!isSimple())
82226633Sdim        return changeExtendedVectorElementTypeToInteger();
83226633Sdim      MVT EltTy = getSimpleVT().getVectorElementType();
84226633Sdim      unsigned BitWidth = EltTy.getSizeInBits();
85226633Sdim      MVT IntTy = MVT::getIntegerVT(BitWidth);
86226633Sdim      MVT VecTy = MVT::getVectorVT(IntTy, getVectorNumElements());
87249423Sdim      assert(VecTy.SimpleTy >= 0 &&
88226633Sdim             "Simple vector VT not representable by simple integer vector VT!");
89226633Sdim      return VecTy;
90226633Sdim    }
91226633Sdim
92296417Sdim    /// Return the type converted to an equivalently sized integer or vector
93296417Sdim    /// with integer element type. Similar to changeVectorElementTypeToInteger,
94296417Sdim    /// but also handles scalars.
95296417Sdim    EVT changeTypeToInteger() {
96296417Sdim      if (isVector())
97296417Sdim        return changeVectorElementTypeToInteger();
98296417Sdim
99296417Sdim      if (isSimple())
100296417Sdim        return MVT::getIntegerVT(getSizeInBits());
101296417Sdim
102296417Sdim      return changeExtendedTypeToInteger();
103296417Sdim    }
104296417Sdim
105198090Srdivacky    /// isSimple - Test if the given EVT is simple (as opposed to being
106193323Sed    /// extended).
107193323Sed    bool isSimple() const {
108249423Sdim      return V.SimpleTy >= 0;
109193323Sed    }
110193323Sed
111198090Srdivacky    /// isExtended - Test if the given EVT is extended (as opposed to
112193323Sed    /// being simple).
113193323Sed    bool isExtended() const {
114193323Sed      return !isSimple();
115193323Sed    }
116193323Sed
117193323Sed    /// isFloatingPoint - Return true if this is a FP, or a vector FP type.
118193323Sed    bool isFloatingPoint() const {
119202375Srdivacky      return isSimple() ? V.isFloatingPoint() : isExtendedFloatingPoint();
120193323Sed    }
121193323Sed
122193323Sed    /// isInteger - Return true if this is an integer, or a vector integer type.
123193323Sed    bool isInteger() const {
124202375Srdivacky      return isSimple() ? V.isInteger() : isExtendedInteger();
125193323Sed    }
126193323Sed
127193323Sed    /// isVector - Return true if this is a vector value type.
128193323Sed    bool isVector() const {
129202375Srdivacky      return isSimple() ? V.isVector() : isExtendedVector();
130193323Sed    }
131193323Sed
132243830Sdim    /// is16BitVector - Return true if this is a 16-bit vector type.
133243830Sdim    bool is16BitVector() const {
134243830Sdim      return isSimple() ? V.is16BitVector() : isExtended16BitVector();
135243830Sdim    }
136243830Sdim
137243830Sdim    /// is32BitVector - Return true if this is a 32-bit vector type.
138243830Sdim    bool is32BitVector() const {
139243830Sdim      return isSimple() ? V.is32BitVector() : isExtended32BitVector();
140243830Sdim    }
141243830Sdim
142193323Sed    /// is64BitVector - Return true if this is a 64-bit vector type.
143193323Sed    bool is64BitVector() const {
144239462Sdim      return isSimple() ? V.is64BitVector() : isExtended64BitVector();
145193323Sed    }
146193323Sed
147193323Sed    /// is128BitVector - Return true if this is a 128-bit vector type.
148193323Sed    bool is128BitVector() const {
149239462Sdim      return isSimple() ? V.is128BitVector() : isExtended128BitVector();
150193323Sed    }
151193323Sed
152195340Sed    /// is256BitVector - Return true if this is a 256-bit vector type.
153239462Sdim    bool is256BitVector() const {
154239462Sdim      return isSimple() ? V.is256BitVector() : isExtended256BitVector();
155195340Sed    }
156195340Sed
157208599Srdivacky    /// is512BitVector - Return true if this is a 512-bit vector type.
158239462Sdim    bool is512BitVector() const {
159239462Sdim      return isSimple() ? V.is512BitVector() : isExtended512BitVector();
160208599Srdivacky    }
161208599Srdivacky
162239462Sdim    /// is1024BitVector - Return true if this is a 1024-bit vector type.
163239462Sdim    bool is1024BitVector() const {
164239462Sdim      return isSimple() ? V.is1024BitVector() : isExtended1024BitVector();
165239462Sdim    }
166239462Sdim
167296417Sdim    /// is2048BitVector - Return true if this is a 2048-bit vector type.
168296417Sdim    bool is2048BitVector() const {
169296417Sdim      return isSimple() ? V.is2048BitVector() : isExtended2048BitVector();
170296417Sdim    }
171296417Sdim
172198090Srdivacky    /// isOverloaded - Return true if this is an overloaded type for TableGen.
173198090Srdivacky    bool isOverloaded() const {
174198090Srdivacky      return (V==MVT::iAny || V==MVT::fAny || V==MVT::vAny || V==MVT::iPTRAny);
175198090Srdivacky    }
176198090Srdivacky
177193323Sed    /// isByteSized - Return true if the bit size is a multiple of 8.
178193323Sed    bool isByteSized() const {
179193323Sed      return (getSizeInBits() & 7) == 0;
180193323Sed    }
181193323Sed
182193323Sed    /// isRound - Return true if the size is a power-of-two number of bytes.
183193323Sed    bool isRound() const {
184193323Sed      unsigned BitSize = getSizeInBits();
185193323Sed      return BitSize >= 8 && !(BitSize & (BitSize - 1));
186193323Sed    }
187193323Sed
188193323Sed    /// bitsEq - Return true if this has the same number of bits as VT.
189198090Srdivacky    bool bitsEq(EVT VT) const {
190203954Srdivacky      if (EVT::operator==(VT)) return true;
191193323Sed      return getSizeInBits() == VT.getSizeInBits();
192193323Sed    }
193193323Sed
194193323Sed    /// bitsGT - Return true if this has more bits than VT.
195198090Srdivacky    bool bitsGT(EVT VT) const {
196203954Srdivacky      if (EVT::operator==(VT)) return false;
197193323Sed      return getSizeInBits() > VT.getSizeInBits();
198193323Sed    }
199193323Sed
200193323Sed    /// bitsGE - Return true if this has no less bits than VT.
201198090Srdivacky    bool bitsGE(EVT VT) const {
202203954Srdivacky      if (EVT::operator==(VT)) return true;
203193323Sed      return getSizeInBits() >= VT.getSizeInBits();
204193323Sed    }
205193323Sed
206193323Sed    /// bitsLT - Return true if this has less bits than VT.
207198090Srdivacky    bool bitsLT(EVT VT) const {
208203954Srdivacky      if (EVT::operator==(VT)) return false;
209193323Sed      return getSizeInBits() < VT.getSizeInBits();
210193323Sed    }
211193323Sed
212193323Sed    /// bitsLE - Return true if this has no more bits than VT.
213198090Srdivacky    bool bitsLE(EVT VT) const {
214203954Srdivacky      if (EVT::operator==(VT)) return true;
215193323Sed      return getSizeInBits() <= VT.getSizeInBits();
216193323Sed    }
217193323Sed
218193323Sed
219193323Sed    /// getSimpleVT - Return the SimpleValueType held in the specified
220198090Srdivacky    /// simple EVT.
221198090Srdivacky    MVT getSimpleVT() const {
222193323Sed      assert(isSimple() && "Expected a SimpleValueType!");
223198090Srdivacky      return V;
224193323Sed    }
225193323Sed
226200581Srdivacky    /// getScalarType - If this is a vector type, return the element type,
227200581Srdivacky    /// otherwise return this.
228200581Srdivacky    EVT getScalarType() const {
229200581Srdivacky      return isVector() ? getVectorElementType() : *this;
230200581Srdivacky    }
231218893Sdim
232193323Sed    /// getVectorElementType - Given a vector type, return the type of
233193323Sed    /// each element.
234198090Srdivacky    EVT getVectorElementType() const {
235193323Sed      assert(isVector() && "Invalid vector type!");
236198090Srdivacky      if (isSimple())
237198090Srdivacky        return V.getVectorElementType();
238212904Sdim      return getExtendedVectorElementType();
239193323Sed    }
240193323Sed
241193323Sed    /// getVectorNumElements - Given a vector type, return the number of
242193323Sed    /// elements it contains.
243193323Sed    unsigned getVectorNumElements() const {
244193323Sed      assert(isVector() && "Invalid vector type!");
245198090Srdivacky      if (isSimple())
246198090Srdivacky        return V.getVectorNumElements();
247212904Sdim      return getExtendedVectorNumElements();
248193323Sed    }
249193323Sed
250193323Sed    /// getSizeInBits - Return the size of the specified value type in bits.
251193323Sed    unsigned getSizeInBits() const {
252198090Srdivacky      if (isSimple())
253198090Srdivacky        return V.getSizeInBits();
254212904Sdim      return getExtendedSizeInBits();
255193323Sed    }
256193323Sed
257276479Sdim    unsigned getScalarSizeInBits() const {
258276479Sdim      return getScalarType().getSizeInBits();
259276479Sdim    }
260276479Sdim
261198090Srdivacky    /// getStoreSize - Return the number of bytes overwritten by a store
262198090Srdivacky    /// of the specified value type.
263198090Srdivacky    unsigned getStoreSize() const {
264198090Srdivacky      return (getSizeInBits() + 7) / 8;
265198090Srdivacky    }
266198090Srdivacky
267193323Sed    /// getStoreSizeInBits - Return the number of bits overwritten by a store
268193323Sed    /// of the specified value type.
269193323Sed    unsigned getStoreSizeInBits() const {
270198090Srdivacky      return getStoreSize() * 8;
271193323Sed    }
272193323Sed
273198090Srdivacky    /// getRoundIntegerType - Rounds the bit-width of the given integer EVT up
274193323Sed    /// to the nearest power of two (and at least to eight), and returns the
275198090Srdivacky    /// integer EVT with that number of bits.
276198090Srdivacky    EVT getRoundIntegerType(LLVMContext &Context) const {
277193323Sed      assert(isInteger() && !isVector() && "Invalid integer type!");
278193323Sed      unsigned BitWidth = getSizeInBits();
279193323Sed      if (BitWidth <= 8)
280198090Srdivacky        return EVT(MVT::i8);
281212904Sdim      return getIntegerVT(Context, 1 << Log2_32_Ceil(BitWidth));
282193323Sed    }
283193323Sed
284201360Srdivacky    /// getHalfSizedIntegerVT - Finds the smallest simple value type that is
285201360Srdivacky    /// greater than or equal to half the width of this EVT. If no simple
286201360Srdivacky    /// value type can be found, an extended integer value type of half the
287201360Srdivacky    /// size (rounded up) is returned.
288201360Srdivacky    EVT getHalfSizedIntegerVT(LLVMContext &Context) const {
289201360Srdivacky      assert(isInteger() && !isVector() && "Invalid integer type!");
290201360Srdivacky      unsigned EVTSize = getSizeInBits();
291201360Srdivacky      for (unsigned IntVT = MVT::FIRST_INTEGER_VALUETYPE;
292212904Sdim          IntVT <= MVT::LAST_INTEGER_VALUETYPE; ++IntVT) {
293201360Srdivacky        EVT HalfVT = EVT((MVT::SimpleValueType)IntVT);
294212904Sdim        if (HalfVT.getSizeInBits() * 2 >= EVTSize)
295201360Srdivacky          return HalfVT;
296201360Srdivacky      }
297201360Srdivacky      return getIntegerVT(Context, (EVTSize + 1) / 2);
298201360Srdivacky    }
299201360Srdivacky
300276479Sdim    /// \brief Return a VT for an integer vector type with the size of the
301276479Sdim    /// elements doubled. The typed returned may be an extended type.
302276479Sdim    EVT widenIntegerVectorElementType(LLVMContext &Context) const {
303276479Sdim      EVT EltVT = getVectorElementType();
304276479Sdim      EltVT = EVT::getIntegerVT(Context, 2 * EltVT.getSizeInBits());
305276479Sdim      return EVT::getVectorVT(Context, EltVT, getVectorNumElements());
306276479Sdim    }
307276479Sdim
308201360Srdivacky    /// isPow2VectorType - Returns true if the given vector is a power of 2.
309193323Sed    bool isPow2VectorType() const {
310193323Sed      unsigned NElts = getVectorNumElements();
311193323Sed      return !(NElts & (NElts - 1));
312193323Sed    }
313193323Sed
314198090Srdivacky    /// getPow2VectorType - Widens the length of the given vector EVT up to
315193323Sed    /// the nearest power of 2 and returns that type.
316198090Srdivacky    EVT getPow2VectorType(LLVMContext &Context) const {
317193323Sed      if (!isPow2VectorType()) {
318193323Sed        unsigned NElts = getVectorNumElements();
319193323Sed        unsigned Pow2NElts = 1 <<  Log2_32_Ceil(NElts);
320198090Srdivacky        return EVT::getVectorVT(Context, getVectorElementType(), Pow2NElts);
321193323Sed      }
322193323Sed      else {
323193323Sed        return *this;
324193323Sed      }
325193323Sed    }
326193323Sed
327198090Srdivacky    /// getEVTString - This function returns value type as a string,
328193323Sed    /// e.g. "i32".
329198090Srdivacky    std::string getEVTString() const;
330193323Sed
331198090Srdivacky    /// getTypeForEVT - This method returns an LLVM type corresponding to the
332198090Srdivacky    /// specified EVT.  For integer types, this returns an unsigned type.  Note
333193323Sed    /// that this will abort for types that cannot be represented.
334226633Sdim    Type *getTypeForEVT(LLVMContext &Context) const;
335193323Sed
336198090Srdivacky    /// getEVT - Return the value type corresponding to the specified type.
337193323Sed    /// This returns all pointers as iPTR.  If HandleUnknown is true, unknown
338193323Sed    /// types are returned as Other, otherwise they are invalid.
339226633Sdim    static EVT getEVT(Type *Ty, bool HandleUnknown = false);
340193323Sed
341249423Sdim    intptr_t getRawBits() const {
342202375Srdivacky      if (isSimple())
343198090Srdivacky        return V.SimpleTy;
344198090Srdivacky      else
345198090Srdivacky        return (intptr_t)(LLVMTy);
346198090Srdivacky    }
347193323Sed
348193323Sed    /// compareRawBits - A meaningless but well-behaved order, useful for
349193323Sed    /// constructing containers.
350193323Sed    struct compareRawBits {
351198090Srdivacky      bool operator()(EVT L, EVT R) const {
352198090Srdivacky        if (L.V.SimpleTy == R.V.SimpleTy)
353198090Srdivacky          return L.LLVMTy < R.LLVMTy;
354198090Srdivacky        else
355198090Srdivacky          return L.V.SimpleTy < R.V.SimpleTy;
356193323Sed      }
357193323Sed    };
358193323Sed
359193323Sed  private:
360193323Sed    // Methods for handling the Extended-type case in functions above.
361193323Sed    // These are all out-of-line to prevent users of this header file
362193323Sed    // from having a dependency on Type.h.
363296417Sdim    EVT changeExtendedTypeToInteger() const;
364226633Sdim    EVT changeExtendedVectorElementTypeToInteger() const;
365198090Srdivacky    static EVT getExtendedIntegerVT(LLVMContext &C, unsigned BitWidth);
366198090Srdivacky    static EVT getExtendedVectorVT(LLVMContext &C, EVT VT,
367198090Srdivacky                                   unsigned NumElements);
368276479Sdim    bool isExtendedFloatingPoint() const LLVM_READONLY;
369276479Sdim    bool isExtendedInteger() const LLVM_READONLY;
370276479Sdim    bool isExtendedVector() const LLVM_READONLY;
371276479Sdim    bool isExtended16BitVector() const LLVM_READONLY;
372276479Sdim    bool isExtended32BitVector() const LLVM_READONLY;
373276479Sdim    bool isExtended64BitVector() const LLVM_READONLY;
374276479Sdim    bool isExtended128BitVector() const LLVM_READONLY;
375276479Sdim    bool isExtended256BitVector() const LLVM_READONLY;
376276479Sdim    bool isExtended512BitVector() const LLVM_READONLY;
377276479Sdim    bool isExtended1024BitVector() const LLVM_READONLY;
378296417Sdim    bool isExtended2048BitVector() const LLVM_READONLY;
379198090Srdivacky    EVT getExtendedVectorElementType() const;
380276479Sdim    unsigned getExtendedVectorNumElements() const LLVM_READONLY;
381193323Sed    unsigned getExtendedSizeInBits() const;
382193323Sed  };
383193323Sed
384193323Sed} // End llvm namespace
385193323Sed
386193323Sed#endif
387