&& TypeBitWidth == rhs.TypeBitWidth);
}
-const TargetAlignElem TargetData::InvalidAlignmentElem =
- TargetAlignElem::get((AlignTypeEnum) -1, 0, 0, 0);
+const TargetAlignElem
+TargetData::InvalidAlignmentElem = { (AlignTypeEnum)0xFF, 0, 0, 0 };
//===----------------------------------------------------------------------===//
// TargetData Class Implementation
//===----------------------------------------------------------------------===//
/// getInt - Get an integer ignoring errors.
-static unsigned getInt(StringRef R) {
- unsigned Result = 0;
+static int getInt(StringRef R) {
+ int Result = 0;
R.getAsInteger(10, Result);
return Result;
}
-void TargetData::init(StringRef Desc) {
+void TargetData::init() {
initializeTargetDataPass(*PassRegistry::getPassRegistry());
-
+
LayoutMap = 0;
LittleEndian = false;
PointerMemSize = 8;
PointerABIAlign = 8;
PointerPrefAlign = PointerABIAlign;
+ StackNaturalAlign = 0;
// Default alignments
setAlignment(INTEGER_ALIGN, 1, 1, 1); // i1
setAlignment(INTEGER_ALIGN, 2, 2, 16); // i16
setAlignment(INTEGER_ALIGN, 4, 4, 32); // i32
setAlignment(INTEGER_ALIGN, 4, 8, 64); // i64
+ setAlignment(FLOAT_ALIGN, 2, 2, 16); // half
setAlignment(FLOAT_ALIGN, 4, 4, 32); // float
setAlignment(FLOAT_ALIGN, 8, 8, 64); // double
+ setAlignment(FLOAT_ALIGN, 16, 16, 128); // ppcf128, quad, ...
setAlignment(VECTOR_ALIGN, 8, 8, 64); // v2i32, v1i64, ...
setAlignment(VECTOR_ALIGN, 16, 16, 128); // v16i8, v8i16, v4i32, ...
setAlignment(AGGREGATE_ALIGN, 0, 8, 0); // struct
+}
+
+std::string TargetData::parseSpecifier(StringRef Desc, TargetData *td) {
+
+ if (td)
+ td->init();
while (!Desc.empty()) {
std::pair<StringRef, StringRef> Split = Desc.split('-');
switch (Specifier[0]) {
case 'E':
- LittleEndian = false;
+ if (td)
+ td->LittleEndian = false;
break;
case 'e':
- LittleEndian = true;
+ if (td)
+ td->LittleEndian = true;
break;
- case 'p':
+ case 'p': {
+ // Pointer size.
Split = Token.split(':');
- PointerMemSize = getInt(Split.first) / 8;
+ int PointerMemSizeBits = getInt(Split.first);
+ if (PointerMemSizeBits < 0 || PointerMemSizeBits % 8 != 0)
+ return "invalid pointer size, must be a positive 8-bit multiple";
+ if (td)
+ td->PointerMemSize = PointerMemSizeBits / 8;
+
+ // Pointer ABI alignment.
Split = Split.second.split(':');
- PointerABIAlign = getInt(Split.first) / 8;
+ int PointerABIAlignBits = getInt(Split.first);
+ if (PointerABIAlignBits < 0 || PointerABIAlignBits % 8 != 0) {
+ return "invalid pointer ABI alignment, "
+ "must be a positive 8-bit multiple";
+ }
+ if (td)
+ td->PointerABIAlign = PointerABIAlignBits / 8;
+
+ // Pointer preferred alignment.
Split = Split.second.split(':');
- PointerPrefAlign = getInt(Split.first) / 8;
- if (PointerPrefAlign == 0)
- PointerPrefAlign = PointerABIAlign;
+ int PointerPrefAlignBits = getInt(Split.first);
+ if (PointerPrefAlignBits < 0 || PointerPrefAlignBits % 8 != 0) {
+ return "invalid pointer preferred alignment, "
+ "must be a positive 8-bit multiple";
+ }
+ if (td) {
+ td->PointerPrefAlign = PointerPrefAlignBits / 8;
+ if (td->PointerPrefAlign == 0)
+ td->PointerPrefAlign = td->PointerABIAlign;
+ }
break;
+ }
case 'i':
case 'v':
case 'f':
case 'a':
case 's': {
AlignTypeEnum AlignType;
- switch (Specifier[0]) {
+ char field = Specifier[0];
+ switch (field) {
default:
case 'i': AlignType = INTEGER_ALIGN; break;
case 'v': AlignType = VECTOR_ALIGN; break;
case 'a': AlignType = AGGREGATE_ALIGN; break;
case 's': AlignType = STACK_ALIGN; break;
}
- unsigned Size = getInt(Specifier.substr(1));
+ int Size = getInt(Specifier.substr(1));
+ if (Size < 0) {
+ return std::string("invalid ") + field + "-size field, "
+ "must be positive";
+ }
+
Split = Token.split(':');
- unsigned ABIAlign = getInt(Split.first) / 8;
+ int ABIAlignBits = getInt(Split.first);
+ if (ABIAlignBits < 0 || ABIAlignBits % 8 != 0) {
+ return std::string("invalid ") + field +"-abi-alignment field, "
+ "must be a positive 8-bit multiple";
+ }
+ unsigned ABIAlign = ABIAlignBits / 8;
Split = Split.second.split(':');
- unsigned PrefAlign = getInt(Split.first) / 8;
+
+ int PrefAlignBits = getInt(Split.first);
+ if (PrefAlignBits < 0 || PrefAlignBits % 8 != 0) {
+ return std::string("invalid ") + field +"-preferred-alignment field, "
+ "must be a positive 8-bit multiple";
+ }
+ unsigned PrefAlign = PrefAlignBits / 8;
if (PrefAlign == 0)
PrefAlign = ABIAlign;
- setAlignment(AlignType, ABIAlign, PrefAlign, Size);
+
+ if (td)
+ td->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);
+ int Width = getInt(Specifier);
+ if (Width <= 0) {
+ return std::string("invalid native integer size \'") + Specifier.str() +
+ "\', must be a positive integer.";
+ }
+ if (td && Width != 0)
+ td->LegalIntWidths.push_back(Width);
Split = Token.split(':');
Specifier = Split.first;
Token = Split.second;
} while (!Specifier.empty() || !Token.empty());
break;
-
+ case 'S': { // Stack natural alignment.
+ int StackNaturalAlignBits = getInt(Specifier.substr(1));
+ if (StackNaturalAlignBits < 0 || StackNaturalAlignBits % 8 != 0) {
+ return "invalid natural stack alignment (S-field), "
+ "must be a positive 8-bit multiple";
+ }
+ if (td)
+ td->StackNaturalAlign = StackNaturalAlignBits / 8;
+ break;
+ }
default:
break;
}
}
+
+ return "";
}
/// Default ctor.
TargetData::TargetData(const Module *M)
: ImmutablePass(ID) {
- init(M->getDataLayout());
+ std::string errMsg = parseSpecifier(M->getDataLayout(), this);
+ assert(errMsg == "" && "Module M has malformed target data layout string.");
+ (void)errMsg;
}
void
// If the alignment is not a power of 2, round up to the next power of 2.
// This happens for non-power-of-2 length vectors.
if (Align & (Align-1))
- Align = llvm::NextPowerOf2(Align);
+ Align = NextPowerOf2(Align);
return Align;
}
}
OS << (LittleEndian ? "e" : "E")
<< "-p:" << PointerMemSize*8 << ':' << PointerABIAlign*8
- << ':' << PointerPrefAlign*8;
+ << ':' << PointerPrefAlign*8
+ << "-S" << StackNaturalAlign*8;
+
for (unsigned i = 0, e = Alignments.size(); i != e; ++i) {
const TargetAlignElem &AI = Alignments[i];
OS << '-' << (char)AI.AlignType << AI.TypeBitWidth << ':'
return cast<IntegerType>(Ty)->getBitWidth();
case Type::VoidTyID:
return 8;
+ case Type::HalfTyID:
+ return 16;
case Type::FloatTyID:
return 32;
case Type::DoubleTyID:
return cast<VectorType>(Ty)->getBitWidth();
default:
llvm_unreachable("TargetData::getTypeSizeInBits(): Unsupported type");
- break;
}
- return 0;
}
/*!
case Type::VoidTyID:
AlignType = INTEGER_ALIGN;
break;
+ case Type::HalfTyID:
case Type::FloatTyID:
case Type::DoubleTyID:
// PPC_FP128TyID and FP128TyID have different data contents, but the
break;
default:
llvm_unreachable("Bad type for getAlignment!!!");
- break;
}
return getAlignmentInfo((AlignTypeEnum)AlignType, getTypeSizeInBits(Ty),
uint64_t Result = 0;
generic_gep_type_iterator<Value* const*>
- TI = gep_type_begin(ptrTy, Indices.begin(), Indices.end());
+ TI = gep_type_begin(ptrTy, Indices);
for (unsigned CurIDX = 0, EndIDX = Indices.size(); CurIDX != EndIDX;
++CurIDX, ++TI) {
if (StructType *STy = dyn_cast<StructType>(*TI)) {