X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FTargetData.cpp;h=cc6dc1e25998eb4379d0c9fb05b8e33f8a428c41;hb=5cd95e1478ddb8f3f1efde56a1cd2db47b312d72;hp=bd6a6b67beb9710d7b2265d585cc22a5675ae2dd;hpb=d8ffe5bb162bf97a7b0a323d2edcf8b83ca5dada;p=oota-llvm.git diff --git a/lib/Target/TargetData.cpp b/lib/Target/TargetData.cpp index bd6a6b67beb..cc6dc1e2599 100644 --- a/lib/Target/TargetData.cpp +++ b/lib/Target/TargetData.cpp @@ -117,23 +117,23 @@ TargetAlignElem::operator==(const TargetAlignElem &rhs) const { && 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; @@ -147,11 +147,19 @@ void TargetData::init(StringRef Desc) { 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 Split = Desc.split('-'); @@ -169,28 +177,54 @@ void TargetData::init(StringRef Desc) { 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; @@ -198,37 +232,66 @@ void TargetData::init(StringRef Desc) { 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. @@ -242,7 +305,9 @@ TargetData::TargetData() : ImmutablePass(ID) { 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 @@ -308,7 +373,7 @@ unsigned TargetData::getAlignmentInfo(AlignTypeEnum AlignType, // 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; } } @@ -414,6 +479,8 @@ uint64_t TargetData::getTypeSizeInBits(Type *Ty) const { return cast(Ty)->getBitWidth(); case Type::VoidTyID: return 8; + case Type::HalfTyID: + return 16; case Type::FloatTyID: return 32; case Type::DoubleTyID: @@ -430,9 +497,7 @@ uint64_t TargetData::getTypeSizeInBits(Type *Ty) const { return cast(Ty)->getBitWidth(); default: llvm_unreachable("TargetData::getTypeSizeInBits(): Unsupported type"); - break; } - return 0; } /*! @@ -471,6 +536,7 @@ unsigned TargetData::getAlignment(Type *Ty, bool abi_or_pref) const { 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 @@ -486,7 +552,6 @@ unsigned TargetData::getAlignment(Type *Ty, bool abi_or_pref) const { break; default: llvm_unreachable("Bad type for getAlignment!!!"); - break; } return getAlignmentInfo((AlignTypeEnum)AlignType, getTypeSizeInBits(Ty),