diff options
Diffstat (limited to 'lib/VMCore/InlineAsm.cpp')
-rw-r--r-- | lib/VMCore/InlineAsm.cpp | 295 |
1 files changed, 0 insertions, 295 deletions
diff --git a/lib/VMCore/InlineAsm.cpp b/lib/VMCore/InlineAsm.cpp deleted file mode 100644 index 2e636aa..0000000 --- a/lib/VMCore/InlineAsm.cpp +++ /dev/null @@ -1,295 +0,0 @@ -//===-- InlineAsm.cpp - Implement the InlineAsm class ---------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the InlineAsm class. -// -//===----------------------------------------------------------------------===// - -#include "llvm/InlineAsm.h" -#include "ConstantsContext.h" -#include "LLVMContextImpl.h" -#include "llvm/DerivedTypes.h" -#include <algorithm> -#include <cctype> -using namespace llvm; - -// Implement the first virtual method in this class in this file so the -// InlineAsm vtable is emitted here. -InlineAsm::~InlineAsm() { -} - - -InlineAsm *InlineAsm::get(FunctionType *Ty, 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); -} - -InlineAsm::InlineAsm(PointerType *Ty, 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) { - - // Do various checks on the constraint string and type. - assert(Verify(getFunctionType(), constraints) && - "Function type not legal for constraints!"); -} - -void InlineAsm::destroyConstant() { - getType()->getContext().pImpl->InlineAsms.remove(this); - delete this; -} - -FunctionType *InlineAsm::getFunctionType() const { - return cast<FunctionType>(getType()->getElementType()); -} - -///Default constructor. -InlineAsm::ConstraintInfo::ConstraintInfo() : - Type(isInput), isEarlyClobber(false), - MatchingInput(-1), isCommutative(false), - isIndirect(false), isMultipleAlternative(false), - 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. -bool InlineAsm::ConstraintInfo::Parse(StringRef Str, - InlineAsm::ConstraintInfoVector &ConstraintsSoFar) { - StringRef::iterator I = Str.begin(), E = Str.end(); - unsigned multipleAlternativeCount = Str.count('|') + 1; - unsigned multipleAlternativeIndex = 0; - ConstraintCodeVector *pCodes = &Codes; - - // Initialize - isMultipleAlternative = (multipleAlternativeCount > 1 ? true : false); - if (isMultipleAlternative) { - multipleAlternatives.resize(multipleAlternativeCount); - pCodes = &multipleAlternatives[0].Codes; - } - Type = isInput; - isEarlyClobber = false; - MatchingInput = -1; - isCommutative = false; - isIndirect = false; - currentAlternativeIndex = 0; - - // Parse prefixes. - if (*I == '~') { - Type = isClobber; - ++I; - } else if (*I == '=') { - ++I; - Type = isOutput; - } - - if (*I == '*') { - isIndirect = true; - ++I; - } - - if (I == E) return true; // Just a prefix, like "==" or "~". - - // Parse the modifiers. - bool DoneWithModifiers = false; - while (!DoneWithModifiers) { - switch (*I) { - default: - DoneWithModifiers = true; - break; - case '&': // Early clobber. - if (Type != isOutput || // Cannot early clobber anything but output. - isEarlyClobber) // Reject &&&&&& - return true; - isEarlyClobber = true; - break; - case '%': // Commutative. - if (Type == isClobber || // Cannot commute clobbers. - isCommutative) // Reject %%%%% - return true; - isCommutative = true; - break; - case '#': // Comment. - case '*': // Register preferencing. - return true; // Not supported. - } - - if (!DoneWithModifiers) { - ++I; - if (I == E) return true; // Just prefixes and modifiers! - } - } - - // Parse the various constraints. - while (I != E) { - if (*I == '{') { // Physical register reference. - // Find the end of the register name. - StringRef::iterator ConstraintEnd = std::find(I+1, E, '}'); - if (ConstraintEnd == E) return true; // "{foo" - pCodes->push_back(std::string(I, ConstraintEnd+1)); - I = ConstraintEnd+1; - } else if (isdigit(*I)) { // Matching Constraint - // Maximal munch numbers. - StringRef::iterator NumStart = I; - while (I != E && isdigit(*I)) - ++I; - pCodes->push_back(std::string(NumStart, I)); - unsigned N = atoi(pCodes->back().c_str()); - // Check that this is a valid matching constraint! - if (N >= ConstraintsSoFar.size() || ConstraintsSoFar[N].Type != isOutput|| - Type != isInput) - return true; // Invalid constraint number. - - // 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) { - InlineAsm::SubConstraintInfo &scInfo = - ConstraintsSoFar[N].multipleAlternatives[multipleAlternativeIndex]; - if (scInfo.MatchingInput != -1) - return true; - // Note that operand #n has a matching input. - scInfo.MatchingInput = ConstraintsSoFar.size(); - } else { - if (ConstraintsSoFar[N].hasMatchingInput()) - return true; - // Note that operand #n has a matching input. - ConstraintsSoFar[N].MatchingInput = ConstraintsSoFar.size(); - } - } else if (*I == '|') { - multipleAlternativeIndex++; - pCodes = &multipleAlternatives[multipleAlternativeIndex].Codes; - ++I; - } else if (*I == '^') { - // Multi-letter constraint - // FIXME: For now assuming these are 2-character constraints. - pCodes->push_back(std::string(I+1, I+3)); - I += 3; - } else { - // Single letter constraint. - pCodes->push_back(std::string(I, I+1)); - ++I; - } - } - - return false; -} - -/// selectAlternative - Point this constraint to the alternative constraint -/// indicated by the index. -void InlineAsm::ConstraintInfo::selectAlternative(unsigned index) { - if (index < multipleAlternatives.size()) { - currentAlternativeIndex = index; - InlineAsm::SubConstraintInfo &scInfo = - multipleAlternatives[currentAlternativeIndex]; - MatchingInput = scInfo.MatchingInput; - Codes = scInfo.Codes; - } -} - -InlineAsm::ConstraintInfoVector -InlineAsm::ParseConstraints(StringRef Constraints) { - ConstraintInfoVector Result; - - // Scan the constraints string. - for (StringRef::iterator I = Constraints.begin(), - E = Constraints.end(); I != E; ) { - ConstraintInfo Info; - - // Find the end of this constraint. - StringRef::iterator ConstraintEnd = std::find(I, E, ','); - - if (ConstraintEnd == I || // Empty constraint like ",," - Info.Parse(StringRef(I, ConstraintEnd-I), Result)) { - Result.clear(); // Erroneous constraint? - break; - } - - Result.push_back(Info); - - // ConstraintEnd may be either the next comma or the end of the string. In - // the former case, we skip the comma. - I = ConstraintEnd; - if (I != E) { - ++I; - if (I == E) { Result.clear(); break; } // don't allow "xyz," - } - } - - return Result; -} - -/// Verify - Verify that the specified constraint string is reasonable for the -/// specified function type, and otherwise validate the constraint string. -bool InlineAsm::Verify(FunctionType *Ty, StringRef ConstStr) { - if (Ty->isVarArg()) return false; - - ConstraintInfoVector Constraints = ParseConstraints(ConstStr); - - // Error parsing constraints. - if (Constraints.empty() && !ConstStr.empty()) return false; - - unsigned NumOutputs = 0, NumInputs = 0, NumClobbers = 0; - unsigned NumIndirect = 0; - - for (unsigned i = 0, e = Constraints.size(); i != e; ++i) { - switch (Constraints[i].Type) { - case InlineAsm::isOutput: - if ((NumInputs-NumIndirect) != 0 || NumClobbers != 0) - return false; // outputs before inputs and clobbers. - if (!Constraints[i].isIndirect) { - ++NumOutputs; - break; - } - ++NumIndirect; - // FALLTHROUGH for Indirect Outputs. - case InlineAsm::isInput: - if (NumClobbers) return false; // inputs before clobbers. - ++NumInputs; - break; - case InlineAsm::isClobber: - ++NumClobbers; - break; - } - } - - switch (NumOutputs) { - case 0: - if (!Ty->getReturnType()->isVoidTy()) return false; - break; - case 1: - if (Ty->getReturnType()->isStructTy()) return false; - break; - default: - StructType *STy = dyn_cast<StructType>(Ty->getReturnType()); - if (STy == 0 || STy->getNumElements() != NumOutputs) - return false; - break; - } - - if (Ty->getNumParams() != NumInputs) return false; - return true; -} - |