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;
}