X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FIR%2FInlineAsm.cpp;h=15d3b830b8fc7695c9322ab6c21fdd75bd271339;hb=a4912f57559181c6ba848114c6e524fe62368fcb;hp=10d281bca8925f4775ab8fe1aedd2cdf574f2299;hpb=0b8c9a80f20772c3793201ab5b251d3520b9cea3;p=oota-llvm.git diff --git a/lib/IR/InlineAsm.cpp b/lib/IR/InlineAsm.cpp index 10d281bca89..15d3b830b8f 100644 --- a/lib/IR/InlineAsm.cpp +++ b/lib/IR/InlineAsm.cpp @@ -24,23 +24,22 @@ using namespace llvm; InlineAsm::~InlineAsm() { } - -InlineAsm *InlineAsm::get(FunctionType *Ty, StringRef AsmString, +InlineAsm *InlineAsm::get(FunctionType *FTy, StringRef AsmString, StringRef Constraints, bool hasSideEffects, bool isAlignStack, AsmDialect asmDialect) { - InlineAsmKeyType Key(AsmString, Constraints, hasSideEffects, isAlignStack, - asmDialect); - LLVMContextImpl *pImpl = Ty->getContext().pImpl; - return pImpl->InlineAsms.getOrCreate(PointerType::getUnqual(Ty), Key); + InlineAsmKeyType Key(AsmString, Constraints, FTy, hasSideEffects, + isAlignStack, asmDialect); + LLVMContextImpl *pImpl = FTy->getContext().pImpl; + return pImpl->InlineAsms.getOrCreate(PointerType::getUnqual(FTy), Key); } -InlineAsm::InlineAsm(PointerType *Ty, const std::string &asmString, +InlineAsm::InlineAsm(FunctionType *FTy, const std::string &asmString, const std::string &constraints, bool hasSideEffects, bool isAlignStack, AsmDialect asmDialect) - : Value(Ty, Value::InlineAsmVal), - AsmString(asmString), Constraints(constraints), - HasSideEffects(hasSideEffects), IsAlignStack(isAlignStack), - Dialect(asmDialect) { + : Value(PointerType::getUnqual(FTy), Value::InlineAsmVal), + AsmString(asmString), Constraints(constraints), FTy(FTy), + HasSideEffects(hasSideEffects), IsAlignStack(isAlignStack), + Dialect(asmDialect) { // Do various checks on the constraint string and type. assert(Verify(getFunctionType(), constraints) && @@ -53,7 +52,7 @@ void InlineAsm::destroyConstant() { } FunctionType *InlineAsm::getFunctionType() const { - return cast(getType()->getElementType()); + return FTy; } ///Default constructor. @@ -64,16 +63,6 @@ InlineAsm::ConstraintInfo::ConstraintInfo() : currentAlternativeIndex(0) { } -/// Copy constructor. -InlineAsm::ConstraintInfo::ConstraintInfo(const ConstraintInfo &other) : - Type(other.Type), isEarlyClobber(other.isEarlyClobber), - MatchingInput(other.MatchingInput), isCommutative(other.isCommutative), - isIndirect(other.isIndirect), Codes(other.Codes), - isMultipleAlternative(other.isMultipleAlternative), - multipleAlternatives(other.multipleAlternatives), - currentAlternativeIndex(other.currentAlternativeIndex) { -} - /// Parse - Analyze the specified string (e.g. "==&{eax}") and fill in the /// fields in this structure. If the constraint string is not understood, /// return true, otherwise return false. @@ -83,9 +72,9 @@ bool InlineAsm::ConstraintInfo::Parse(StringRef Str, unsigned multipleAlternativeCount = Str.count('|') + 1; unsigned multipleAlternativeIndex = 0; ConstraintCodeVector *pCodes = &Codes; - + // Initialize - isMultipleAlternative = (multipleAlternativeCount > 1 ? true : false); + isMultipleAlternative = multipleAlternativeCount > 1; if (isMultipleAlternative) { multipleAlternatives.resize(multipleAlternativeCount); pCodes = &multipleAlternatives[0].Codes; @@ -101,16 +90,20 @@ bool InlineAsm::ConstraintInfo::Parse(StringRef Str, if (*I == '~') { Type = isClobber; ++I; + + // '{' must immediately follow '~'. + if (I != E && *I != '{') + return true; } else if (*I == '=') { ++I; Type = isOutput; } - + if (*I == '*') { isIndirect = true; ++I; } - + if (I == E) return true; // Just a prefix, like "==" or "~". // Parse the modifiers. @@ -151,10 +144,10 @@ bool InlineAsm::ConstraintInfo::Parse(StringRef Str, if (ConstraintEnd == E) return true; // "{foo" pCodes->push_back(std::string(I, ConstraintEnd+1)); I = ConstraintEnd+1; - } else if (isdigit(*I)) { // Matching Constraint + } else if (isdigit(static_cast(*I))) { // Matching Constraint // Maximal munch numbers. StringRef::iterator NumStart = I; - while (I != E && isdigit(*I)) + while (I != E && isdigit(static_cast(*I))) ++I; pCodes->push_back(std::string(NumStart, I)); unsigned N = atoi(pCodes->back().c_str()); @@ -166,6 +159,9 @@ bool InlineAsm::ConstraintInfo::Parse(StringRef Str, // If Operand N already has a matching input, reject this. An output // can't be constrained to the same value as multiple inputs. if (isMultipleAlternative) { + if (multipleAlternativeIndex >= + ConstraintsSoFar[N].multipleAlternatives.size()) + return true; InlineAsm::SubConstraintInfo &scInfo = ConstraintsSoFar[N].multipleAlternatives[multipleAlternativeIndex]; if (scInfo.MatchingInput != -1) @@ -173,7 +169,9 @@ bool InlineAsm::ConstraintInfo::Parse(StringRef Str, // Note that operand #n has a matching input. scInfo.MatchingInput = ConstraintsSoFar.size(); } else { - if (ConstraintsSoFar[N].hasMatchingInput()) + if (ConstraintsSoFar[N].hasMatchingInput() && + (size_t)ConstraintsSoFar[N].MatchingInput != + ConstraintsSoFar.size()) return true; // Note that operand #n has a matching input. ConstraintsSoFar[N].MatchingInput = ConstraintsSoFar.size(); @@ -234,7 +232,10 @@ InlineAsm::ParseConstraints(StringRef Constraints) { I = ConstraintEnd; if (I != E) { ++I; - if (I == E) { Result.clear(); break; } // don't allow "xyz," + if (I == E) { + Result.clear(); + break; + } // don't allow "xyz," } } @@ -284,7 +285,7 @@ bool InlineAsm::Verify(FunctionType *Ty, StringRef ConstStr) { break; default: StructType *STy = dyn_cast(Ty->getReturnType()); - if (STy == 0 || STy->getNumElements() != NumOutputs) + if (!STy || STy->getNumElements() != NumOutputs) return false; break; } @@ -292,4 +293,3 @@ bool InlineAsm::Verify(FunctionType *Ty, StringRef ConstStr) { if (Ty->getNumParams() != NumInputs) return false; return true; } -