diff --git a/docs/LangRef.html b/docs/LangRef.html index 7032a198141..eea1f030609 100644 --- a/docs/LangRef.html +++ b/docs/LangRef.html @@ -1215,6 +1215,13 @@ target datalayout = "layout specification"
ssize:abi:pref
This specifies the alignment for a stack object of a given bit size.
+ +
nsize1:size2:size3...
+
This specifies a set of native integer widths for the target CPU + in bits. For example, it might contain "n32" for 32-bit PowerPC, + "n32:64" for PowerPC 64, or "n8:16:32:64" for X86-64. Elements of + this set are considered to support most general arithmetic + operations efficiently.

When constructing the data layout for a given target, LLVM starts with a diff --git a/include/llvm/Target/TargetData.h b/include/llvm/Target/TargetData.h index 1ad058ce54f..96308778582 100644 --- a/include/llvm/Target/TargetData.h +++ b/include/llvm/Target/TargetData.h @@ -70,6 +70,8 @@ private: unsigned char PointerABIAlign; ///< Pointer ABI alignment unsigned char PointerPrefAlign; ///< Pointer preferred alignment + SmallVector LegalIntWidths; ///< Legal Integers. + /// Alignments- Where the primitive type alignment data is stored. /// /// @sa init(). @@ -78,12 +80,8 @@ private: /// we don't. SmallVector Alignments; - - - /*! - This member is a signal that a requested alignment type and bit width were - not found in the SmallVector. - */ + /// InvalidAlignmentElem - This member is a signal that a requested alignment + /// type and bit width were not found in the SmallVector. static const TargetAlignElem InvalidAlignmentElem; // Opaque pointer for the StructType -> StructLayout map. @@ -127,6 +125,7 @@ public: PointerMemSize(TD.PointerMemSize), PointerABIAlign(TD.PointerABIAlign), PointerPrefAlign(TD.PointerPrefAlign), + LegalIntWidths(TD.LegalIntWidths), Alignments(TD.Alignments), LayoutMap(0) { } @@ -137,13 +136,33 @@ public: void init(StringRef TargetDescription); /// Target endianness... - bool isLittleEndian() const { return LittleEndian; } - bool isBigEndian() const { return !LittleEndian; } + bool isLittleEndian() const { return LittleEndian; } + bool isBigEndian() const { return !LittleEndian; } /// getStringRepresentation - Return the string representation of the /// TargetData. This representation is in the same format accepted by the /// string constructor above. std::string getStringRepresentation() const; + + + /// isIllegalInteger - This function returns true if the specified type is + /// known to not be a native integer type supported by the CPU. For example, + /// i64 is not native on most 32-bit CPUs and i37 is not native on any known + /// one. This returns false if the integer width is legal or we don't know. + /// + /// The width is specified in bits. + /// + bool isIllegalInteger(unsigned Width) const { + // If we don't have information about legal integer types, don't claim the + // type is illegal. + if (LegalIntWidths.empty()) return false; + + for (unsigned i = 0, e = LegalIntWidths.size(); i != e; ++i) + if (LegalIntWidths[i] == Width) + return false; + return true; + } + /// Target pointer alignment unsigned char getPointerABIAlignment() const { return PointerABIAlign; } /// Return target's alignment for stack-based pointers diff --git a/lib/Target/TargetData.cpp b/lib/Target/TargetData.cpp index 06c493fe0d1..b6b84c52956 100644 --- a/lib/Target/TargetData.cpp +++ b/lib/Target/TargetData.cpp @@ -139,45 +139,7 @@ static unsigned getInt(StringRef R) { return Result; } -/*! - A TargetDescription string consists of a sequence of hyphen-delimited - specifiers for target endianness, pointer size and alignments, and various - primitive type sizes and alignments. A typical string looks something like: -

- "E-p:32:32:32-i1:8:8-i8:8:8-i32:32:32-i64:32:64-f32:32:32-f64:32:64" -

- (note: this string is not fully specified and is only an example.) - \p - Alignments come in two flavors: ABI and preferred. ABI alignment (abi_align, - below) dictates how a type will be aligned within an aggregate and when used - as an argument. Preferred alignment (pref_align, below) determines a type's - alignment when emitted as a global. - \p - Specifier string details: -

- [E|e]: Endianness. "E" specifies a big-endian target data model, "e" - specifies a little-endian target data model. -

- p:@verbatim::@endverbatim: Pointer size, - ABI and preferred alignment. -

- @verbatim::@endverbatim: Numeric type - alignment. Type is - one of i|f|v|a, corresponding to integer, floating point, vector, or - aggregate. Size indicates the size, e.g., 32 or 64 bits. - \p - The default string, fully specified, is: -

- "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64" - "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64" - "-v64:64:64-v128:128:128" -

- Note that in the case of aggregates, 0 is the default ABI and preferred - alignment. This is a special case, where the aggregate's computed worst-case - alignment will be used. - */ void TargetData::init(StringRef Desc) { - LayoutMap = 0; LittleEndian = false; PointerMemSize = 8; @@ -210,7 +172,7 @@ void TargetData::init(StringRef Desc) { assert(!Specifier.empty() && "Can't be empty here"); - switch(Specifier[0]) { + switch (Specifier[0]) { case 'E': LittleEndian = false; break; @@ -252,6 +214,17 @@ void TargetData::init(StringRef Desc) { setAlignment(AlignType, ABIAlign, PrefAlign, Size); break; } + case 'n': // Native integer types. + Specifier = Specifier.substr(1); + do { + if (unsigned Width = getInt(Specifier)) + LegalIntWidths.push_back(Width); + Split = Token.split(':'); + Specifier = Split.first; + Token = Split.second; + } while (!Specifier.empty() || !Token.empty()); + break; + default: break; }