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