//===----------------------------------------------------------------------===//
/// 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;
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(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.
- StackNaturalAlign = getInt(Specifier.substr(1));
- StackNaturalAlign /= 8;
- // FIXME: Should we really be truncating these alingments and
- // sizes silently?
+ 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
return cast<IntegerType>(Ty)->getBitWidth();
case Type::VoidTyID:
return 8;
+ case Type::HalfTyID:
+ return 16;
case Type::FloatTyID:
return 32;
case Type::DoubleTyID:
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