#include <cassert>
#include <string>
-#include "llvm/Support/DataTypes.h"
+#include "llvm/System/DataTypes.h"
#include "llvm/Support/MathExtras.h"
namespace llvm {
class Type;
- struct LLVMContext;
+ class LLVMContext;
+ struct EVT;
- struct EVT { // EVT = Machine Value Type
+ class MVT { // MVT = Machine Value Type
public:
enum SimpleValueType {
// If you change this numbering, you must change the values in
iPTR = 255,
// LastSimpleValueType - The greatest valid SimpleValueType value.
- LastSimpleValueType = 255
- };
+ LastSimpleValueType = 255,
- private:
- /// This union holds low-level value types. Valid values include any of
- /// the values in the SimpleValueType enum, or any value returned from one
- /// of the EVT methods. Any value type equal to one of the SimpleValueType
- /// enum values is a "simple" value type. All others are "extended".
- ///
- /// Note that simple doesn't necessary mean legal for the target machine.
- /// All legal value types must be simple, but often there are some simple
- /// value types that are not legal.
- ///
- union {
- uintptr_t V;
- const Type *LLVMTy;
+ // INVALID_SIMPLE_VALUE_TYPE - Simple value types greater than or equal
+ // to this are considered extended value types.
+ INVALID_SIMPLE_VALUE_TYPE = LastSimpleValueType + 1
};
- public:
- EVT() {}
- EVT(SimpleValueType S) : V(S) {}
+ SimpleValueType SimpleTy;
+
+ MVT() : SimpleTy((SimpleValueType)(INVALID_SIMPLE_VALUE_TYPE)) {}
+ MVT(SimpleValueType SVT) : SimpleTy(SVT) { }
+
+ bool operator>(const MVT& S) const { return SimpleTy > S.SimpleTy; }
+ bool operator<(const MVT& S) const { return SimpleTy < S.SimpleTy; }
+ bool operator==(const MVT& S) const { return SimpleTy == S.SimpleTy; }
+ bool operator>=(const MVT& S) const { return SimpleTy >= S.SimpleTy; }
+ bool operator<=(const MVT& S) const { return SimpleTy <= S.SimpleTy; }
+
+ /// isFloatingPoint - Return true if this is a FP, or a vector FP type.
+ bool isFloatingPoint() const {
+ return ((SimpleTy >= MVT::f32 && SimpleTy <= MVT::ppcf128) ||
+ (SimpleTy >= MVT::v2f32 && SimpleTy <= MVT::v4f64));
+ }
- bool operator==(const EVT VT) const {
- return getRawBits() == VT.getRawBits();
+ /// isInteger - Return true if this is an integer, or a vector integer type.
+ bool isInteger() const {
+ return ((SimpleTy >= MVT::FIRST_INTEGER_VALUETYPE &&
+ SimpleTy <= MVT::LAST_INTEGER_VALUETYPE) ||
+ (SimpleTy >= MVT::v2i8 && SimpleTy <= MVT::v4i64));
}
- bool operator!=(const EVT VT) const {
- return getRawBits() != VT.getRawBits();
+
+ /// isVector - Return true if this is a vector value type.
+ bool isVector() const {
+ return (SimpleTy >= MVT::FIRST_VECTOR_VALUETYPE &&
+ SimpleTy <= MVT::LAST_VECTOR_VALUETYPE);
+ }
+
+ /// isPow2VectorType - Retuns true if the given vector is a power of 2.
+ bool isPow2VectorType() const {
+ unsigned NElts = getVectorNumElements();
+ return !(NElts & (NElts - 1));
}
- /// getFloatingPointVT - Returns the EVT that represents a floating point
- /// type with the given number of bits. There are two floating point types
- /// with 128 bits - this returns f128 rather than ppcf128.
- static EVT getFloatingPointVT(unsigned BitWidth) {
+ /// getPow2VectorType - Widens the length of the given vector EVT up to
+ /// the nearest power of 2 and returns that type.
+ MVT getPow2VectorType() const {
+ if (!isPow2VectorType()) {
+ unsigned NElts = getVectorNumElements();
+ unsigned Pow2NElts = 1 << Log2_32_Ceil(NElts);
+ return MVT::getVectorVT(getVectorElementType(), Pow2NElts);
+ }
+ else {
+ return *this;
+ }
+ }
+
+ MVT getVectorElementType() const {
+ switch (SimpleTy) {
+ default:
+ return (MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE);
+ case v2i8 :
+ case v4i8 :
+ case v8i8 :
+ case v16i8:
+ case v32i8: return i8;
+ case v2i16:
+ case v4i16:
+ case v8i16:
+ case v16i16: return i16;
+ case v2i32:
+ case v4i32:
+ case v8i32: return i32;
+ case v1i64:
+ case v2i64:
+ case v4i64: return i64;
+ case v2f32:
+ case v4f32:
+ case v8f32: return f32;
+ case v2f64:
+ case v4f64: return f64;
+ }
+ }
+
+ unsigned getVectorNumElements() const {
+ switch (SimpleTy) {
+ default:
+ return ~0U;
+ case v32i8: return 32;
+ case v16i8:
+ case v16i16: return 16;
+ case v8i8 :
+ case v8i16:
+ case v8i32:
+ case v8f32: return 8;
+ case v4i8:
+ case v4i16:
+ case v4i32:
+ case v4i64:
+ case v4f32:
+ case v4f64: return 4;
+ case v2i8:
+ case v2i16:
+ case v2i32:
+ case v2i64:
+ case v2f32:
+ case v2f64: return 2;
+ case v1i64: return 1;
+ }
+ }
+
+ unsigned getSizeInBits() const {
+ switch (SimpleTy) {
+ case iPTR:
+ assert(0 && "Value type size is target-dependent. Ask TLI.");
+ case iPTRAny:
+ case iAny:
+ case fAny:
+ assert(0 && "Value type is overloaded.");
+ default:
+ assert(0 && "getSizeInBits called on extended MVT.");
+ case i1 : return 1;
+ case i8 : return 8;
+ case i16 :
+ case v2i8: return 16;
+ case f32 :
+ case i32 :
+ case v4i8:
+ case v2i16: return 32;
+ case f64 :
+ case i64 :
+ case v8i8:
+ case v4i16:
+ case v2i32:
+ case v1i64:
+ case v2f32: return 64;
+ case f80 : return 80;
+ case f128:
+ case ppcf128:
+ case i128:
+ case v16i8:
+ case v8i16:
+ case v4i32:
+ case v2i64:
+ case v4f32:
+ case v2f64: return 128;
+ case v32i8:
+ case v16i16:
+ case v8i32:
+ case v4i64:
+ case v8f32:
+ case v4f64: return 256;
+ }
+ }
+
+ static MVT getFloatingPointVT(unsigned BitWidth) {
switch (BitWidth) {
default:
assert(false && "Bad bit width!");
case 32:
- return f32;
+ return MVT::f32;
case 64:
- return f64;
+ return MVT::f64;
case 80:
- return f80;
+ return MVT::f80;
case 128:
- return f128;
+ return MVT::f128;
}
}
-
- /// getIntegerVT - Returns the EVT that represents an integer with the given
- /// number of bits.
- static EVT getIntegerVT(unsigned BitWidth) {
+
+ static MVT getIntegerVT(unsigned BitWidth) {
switch (BitWidth) {
default:
- break;
+ return (MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE);
case 1:
- return i1;
+ return MVT::i1;
case 8:
- return i8;
+ return MVT::i8;
case 16:
- return i16;
+ return MVT::i16;
case 32:
- return i32;
+ return MVT::i32;
case 64:
- return i64;
+ return MVT::i64;
case 128:
- return i128;
+ return MVT::i128;
}
- return getExtendedIntegerVT(BitWidth);
}
-
- /// getVectorVT - Returns the EVT that represents a vector NumElements in
- /// length, where each element is of type VT.
- static EVT getVectorVT(EVT VT, unsigned NumElements) {
- switch (VT.V) {
+
+ static MVT getVectorVT(MVT VT, unsigned NumElements) {
+ switch (VT.SimpleTy) {
default:
break;
- case i8:
- if (NumElements == 2) return v2i8;
- if (NumElements == 4) return v4i8;
- if (NumElements == 8) return v8i8;
- if (NumElements == 16) return v16i8;
- if (NumElements == 32) return v32i8;
+ case MVT::i8:
+ if (NumElements == 2) return MVT::v2i8;
+ if (NumElements == 4) return MVT::v4i8;
+ if (NumElements == 8) return MVT::v8i8;
+ if (NumElements == 16) return MVT::v16i8;
+ if (NumElements == 32) return MVT::v32i8;
break;
- case i16:
- if (NumElements == 2) return v2i16;
- if (NumElements == 4) return v4i16;
- if (NumElements == 8) return v8i16;
- if (NumElements == 16) return v16i16;
+ case MVT::i16:
+ if (NumElements == 2) return MVT::v2i16;
+ if (NumElements == 4) return MVT::v4i16;
+ if (NumElements == 8) return MVT::v8i16;
+ if (NumElements == 16) return MVT::v16i16;
break;
- case i32:
- if (NumElements == 2) return v2i32;
- if (NumElements == 4) return v4i32;
- if (NumElements == 8) return v8i32;
+ case MVT::i32:
+ if (NumElements == 2) return MVT::v2i32;
+ if (NumElements == 4) return MVT::v4i32;
+ if (NumElements == 8) return MVT::v8i32;
break;
- case i64:
- if (NumElements == 1) return v1i64;
- if (NumElements == 2) return v2i64;
- if (NumElements == 4) return v4i64;
+ case MVT::i64:
+ if (NumElements == 1) return MVT::v1i64;
+ if (NumElements == 2) return MVT::v2i64;
+ if (NumElements == 4) return MVT::v4i64;
break;
- case f32:
- if (NumElements == 2) return v2f32;
- if (NumElements == 4) return v4f32;
- if (NumElements == 8) return v8f32;
+ case MVT::f32:
+ if (NumElements == 2) return MVT::v2f32;
+ if (NumElements == 4) return MVT::v4f32;
+ if (NumElements == 8) return MVT::v8f32;
break;
- case f64:
- if (NumElements == 2) return v2f64;
- if (NumElements == 4) return v4f64;
+ case MVT::f64:
+ if (NumElements == 2) return MVT::v2f64;
+ if (NumElements == 4) return MVT::v4f64;
break;
}
- return getExtendedVectorVT(VT, NumElements);
+ return (MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE);
+ }
+
+ static MVT getIntVectorWithNumElements(unsigned NumElts) {
+ switch (NumElts) {
+ default: return (MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE);
+ case 1: return MVT::v1i64;
+ case 2: return MVT::v2i32;
+ case 4: return MVT::v4i16;
+ case 8: return MVT::v8i8;
+ case 16: return MVT::v16i8;
+ }
+ }
+ };
+
+ struct EVT { // EVT = Extended Value Type
+ private:
+ MVT V;
+ const Type *LLVMTy;
+
+ public:
+ EVT() : V((MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE)),
+ LLVMTy(0) {}
+ EVT(MVT::SimpleValueType SVT) : V(SVT), LLVMTy(0) { }
+ EVT(MVT S) : V(S), LLVMTy(0) {}
+
+ bool operator==(const EVT VT) const {
+ if (V.SimpleTy == VT.V.SimpleTy) {
+ if (V.SimpleTy == MVT::INVALID_SIMPLE_VALUE_TYPE)
+ return LLVMTy == VT.LLVMTy;
+ return true;
+ }
+ return false;
+ }
+ bool operator!=(const EVT VT) const {
+ if (V.SimpleTy == VT.V.SimpleTy) {
+ if (V.SimpleTy == MVT::INVALID_SIMPLE_VALUE_TYPE)
+ return LLVMTy != VT.LLVMTy;
+ return false;
+ }
+ return true;
+ }
+
+ /// getFloatingPointVT - Returns the EVT that represents a floating point
+ /// type with the given number of bits. There are two floating point types
+ /// with 128 bits - this returns f128 rather than ppcf128.
+ static EVT getFloatingPointVT(unsigned BitWidth) {
+ return MVT::getFloatingPointVT(BitWidth);
+ }
+
+ /// getIntegerVT - Returns the EVT that represents an integer with the given
+ /// number of bits.
+ static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth) {
+ MVT M = MVT::getIntegerVT(BitWidth);
+ if (M.SimpleTy == MVT::INVALID_SIMPLE_VALUE_TYPE)
+ return getExtendedIntegerVT(Context, BitWidth);
+ else
+ return M;
+ }
+
+ /// getVectorVT - Returns the EVT that represents a vector NumElements in
+ /// length, where each element is of type VT.
+ static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements) {
+ MVT M = MVT::getVectorVT(VT.V, NumElements);
+ if (M.SimpleTy == MVT::INVALID_SIMPLE_VALUE_TYPE)
+ return getExtendedVectorVT(Context, VT, NumElements);
+ else
+ return M;
}
/// getIntVectorWithNumElements - Return any integer vector type that has
/// the specified number of elements.
- static EVT getIntVectorWithNumElements(unsigned NumElts) {
- switch (NumElts) {
- default: return getVectorVT(i8, NumElts);
- case 1: return v1i64;
- case 2: return v2i32;
- case 4: return v4i16;
- case 8: return v8i8;
- case 16: return v16i8;
- }
+ static EVT getIntVectorWithNumElements(LLVMContext &C, unsigned NumElts) {
+ MVT M = MVT::getIntVectorWithNumElements(NumElts);
+ if (M.SimpleTy == MVT::INVALID_SIMPLE_VALUE_TYPE)
+ return getVectorVT(C, MVT::i8, NumElts);
+ else
+ return M;
}
/// isSimple - Test if the given EVT is simple (as opposed to being
/// extended).
bool isSimple() const {
- return V <= LastSimpleValueType;
+ return V.SimpleTy <= MVT::LastSimpleValueType;
}
/// isExtended - Test if the given EVT is extended (as opposed to
/// isFloatingPoint - Return true if this is a FP, or a vector FP type.
bool isFloatingPoint() const {
return isSimple() ?
- ((V >= f32 && V <= ppcf128) ||
- (V >= v2f32 && V <= v4f64)) : isExtendedFloatingPoint();
+ ((V >= MVT::f32 && V <= MVT::ppcf128) ||
+ (V >= MVT::v2f32 && V <= MVT::v4f64)) : isExtendedFloatingPoint();
}
/// isInteger - Return true if this is an integer, or a vector integer type.
bool isInteger() const {
return isSimple() ?
- ((V >= FIRST_INTEGER_VALUETYPE && V <= LAST_INTEGER_VALUETYPE) ||
- (V >= v2i8 && V <= v4i64)) : isExtendedInteger();
+ ((V >= MVT::FIRST_INTEGER_VALUETYPE &&
+ V <= MVT::LAST_INTEGER_VALUETYPE) ||
+ (V >= MVT::v2i8 && V <= MVT::v4i64)) : isExtendedInteger();
}
/// isVector - Return true if this is a vector value type.
bool isVector() const {
return isSimple() ?
- (V >= FIRST_VECTOR_VALUETYPE && V <= LAST_VECTOR_VALUETYPE) :
+ (V >= MVT::FIRST_VECTOR_VALUETYPE && V <=
+ MVT::LAST_VECTOR_VALUETYPE) :
isExtendedVector();
}
/// is64BitVector - Return true if this is a 64-bit vector type.
bool is64BitVector() const {
return isSimple() ?
- (V==v8i8 || V==v4i16 || V==v2i32 || V==v1i64 || V==v2f32) :
+ (V==MVT::v8i8 || V==MVT::v4i16 || V==MVT::v2i32 ||
+ V==MVT::v1i64 || V==MVT::v2f32) :
isExtended64BitVector();
}
/// is128BitVector - Return true if this is a 128-bit vector type.
bool is128BitVector() const {
return isSimple() ?
- (V==v16i8 || V==v8i16 || V==v4i32 ||
- V==v2i64 || V==v4f32 || V==v2f64) :
+ (V==MVT::v16i8 || V==MVT::v8i16 || V==MVT::v4i32 ||
+ V==MVT::v2i64 || V==MVT::v4f32 || V==MVT::v2f64) :
isExtended128BitVector();
}
/// is256BitVector - Return true if this is a 256-bit vector type.
inline bool is256BitVector() const {
return isSimple() ?
- (V==v8f32 || V==v4f64 || V==v32i8 || V==v16i16 || V==v8i32 ||
- V==v4i64) : isExtended256BitVector();
+ (V==MVT::v8f32 || V==MVT::v4f64 || V==MVT::v32i8 ||
+ V==MVT::v16i16 || V==MVT::v8i32 || V==MVT::v4i64) :
+ isExtended256BitVector();
}
/// isOverloaded - Return true if this is an overloaded type for TableGen.
bool isOverloaded() const {
- return (V==iAny || V==fAny || V==vAny || V==iPTRAny);
+ return (V==MVT::iAny || V==MVT::fAny || V==MVT::vAny || V==MVT::iPTRAny);
}
/// isByteSized - Return true if the bit size is a multiple of 8.
/// getSimpleVT - Return the SimpleValueType held in the specified
/// simple EVT.
- SimpleValueType getSimpleVT() const {
+ MVT getSimpleVT() const {
assert(isSimple() && "Expected a SimpleValueType!");
- return SimpleValueType(V);
+ return V;
}
/// getVectorElementType - Given a vector type, return the type of
/// each element.
EVT getVectorElementType() const {
assert(isVector() && "Invalid vector type!");
- switch (V) {
- default:
+ if (isSimple())
+ return V.getVectorElementType();
+ else
return getExtendedVectorElementType();
- case v2i8 :
- case v4i8 :
- case v8i8 :
- case v16i8:
- case v32i8: return i8;
- case v2i16:
- case v4i16:
- case v8i16:
- case v16i16: return i16;
- case v2i32:
- case v4i32:
- case v8i32: return i32;
- case v1i64:
- case v2i64:
- case v4i64: return i64;
- case v2f32:
- case v4f32:
- case v8f32: return f32;
- case v2f64:
- case v4f64: return f64;
- }
}
/// getVectorNumElements - Given a vector type, return the number of
/// elements it contains.
unsigned getVectorNumElements() const {
assert(isVector() && "Invalid vector type!");
- switch (V) {
- default:
+ if (isSimple())
+ return V.getVectorNumElements();
+ else
return getExtendedVectorNumElements();
- case v32i8: return 32;
- case v16i8:
- case v16i16: return 16;
- case v8i8 :
- case v8i16:
- case v8i32:
- case v8f32: return 8;
- case v4i8:
- case v4i16:
- case v4i32:
- case v4i64:
- case v4f32:
- case v4f64: return 4;
- case v2i8:
- case v2i16:
- case v2i32:
- case v2i64:
- case v2f32:
- case v2f64: return 2;
- case v1i64: return 1;
- }
}
/// getSizeInBits - Return the size of the specified value type in bits.
unsigned getSizeInBits() const {
- switch (V) {
- case iPTR:
- assert(0 && "Value type size is target-dependent. Ask TLI.");
- case iPTRAny:
- case iAny:
- case fAny:
- case vAny:
- assert(0 && "Value type is overloaded.");
- default:
+ if (isSimple())
+ return V.getSizeInBits();
+ else
return getExtendedSizeInBits();
- case i1 : return 1;
- case i8 : return 8;
- case i16 :
- case v2i8: return 16;
- case f32 :
- case i32 :
- case v4i8:
- case v2i16: return 32;
- case f64 :
- case i64 :
- case v8i8:
- case v4i16:
- case v2i32:
- case v1i64:
- case v2f32: return 64;
- case f80 : return 80;
- case f128:
- case ppcf128:
- case i128:
- case v16i8:
- case v8i16:
- case v4i32:
- case v2i64:
- case v4f32:
- case v2f64: return 128;
- case v32i8:
- case v16i16:
- case v8i32:
- case v4i64:
- case v8f32:
- case v4f64: return 256;
- }
+ }
+
+ /// getStoreSize - Return the number of bytes overwritten by a store
+ /// of the specified value type.
+ unsigned getStoreSize() const {
+ return (getSizeInBits() + 7) / 8;
}
/// getStoreSizeInBits - Return the number of bits overwritten by a store
/// of the specified value type.
unsigned getStoreSizeInBits() const {
- return (getSizeInBits() + 7)/8*8;
+ return getStoreSize() * 8;
}
/// getRoundIntegerType - Rounds the bit-width of the given integer EVT up
/// to the nearest power of two (and at least to eight), and returns the
/// integer EVT with that number of bits.
- EVT getRoundIntegerType() const {
+ EVT getRoundIntegerType(LLVMContext &Context) const {
assert(isInteger() && !isVector() && "Invalid integer type!");
unsigned BitWidth = getSizeInBits();
if (BitWidth <= 8)
- return i8;
+ return EVT(MVT::i8);
else
- return getIntegerVT(1 << Log2_32_Ceil(BitWidth));
+ return getIntegerVT(Context, 1 << Log2_32_Ceil(BitWidth));
}
/// isPow2VectorType - Retuns true if the given vector is a power of 2.
/// getPow2VectorType - Widens the length of the given vector EVT up to
/// the nearest power of 2 and returns that type.
- EVT getPow2VectorType() const {
+ EVT getPow2VectorType(LLVMContext &Context) const {
if (!isPow2VectorType()) {
unsigned NElts = getVectorNumElements();
unsigned Pow2NElts = 1 << Log2_32_Ceil(NElts);
- return EVT::getVectorVT(getVectorElementType(), Pow2NElts);
+ return EVT::getVectorVT(Context, getVectorElementType(), Pow2NElts);
}
else {
return *this;
/// getTypeForEVT - This method returns an LLVM type corresponding to the
/// specified EVT. For integer types, this returns an unsigned type. Note
/// that this will abort for types that cannot be represented.
- const Type *getTypeForEVT() const;
+ const Type *getTypeForEVT(LLVMContext &Context) const;
/// getEVT - Return the value type corresponding to the specified type.
/// This returns all pointers as iPTR. If HandleUnknown is true, unknown
/// types are returned as Other, otherwise they are invalid.
static EVT getEVT(const Type *Ty, bool HandleUnknown = false);
- /// getRawBits - Represent the type as a bunch of bits.
- uintptr_t getRawBits() const { return V; }
+ intptr_t getRawBits() {
+ if (V.SimpleTy <= MVT::LastSimpleValueType)
+ return V.SimpleTy;
+ else
+ return (intptr_t)(LLVMTy);
+ }
/// compareRawBits - A meaningless but well-behaved order, useful for
/// constructing containers.
struct compareRawBits {
bool operator()(EVT L, EVT R) const {
- return L.getRawBits() < R.getRawBits();
+ if (L.V.SimpleTy == R.V.SimpleTy)
+ return L.LLVMTy < R.LLVMTy;
+ else
+ return L.V.SimpleTy < R.V.SimpleTy;
}
};
// Methods for handling the Extended-type case in functions above.
// These are all out-of-line to prevent users of this header file
// from having a dependency on Type.h.
- static EVT getExtendedIntegerVT(unsigned BitWidth);
- static EVT getExtendedVectorVT(EVT VT, unsigned NumElements);
+ static EVT getExtendedIntegerVT(LLVMContext &C, unsigned BitWidth);
+ static EVT getExtendedVectorVT(LLVMContext &C, EVT VT,
+ unsigned NumElements);
bool isExtendedFloatingPoint() const;
bool isExtendedInteger() const;
bool isExtendedVector() const;