//===- 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/IR/InlineAsm.h"
#include "ConstantsContext.h"
#include "LLVMContextImpl.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include <algorithm>
#include <cassert>
#include <cctype>
#include <cstddef>
#include <cstdlib>

using namespace llvm;

InlineAsm::InlineAsm(FunctionType *FTy, const std::string &asmString,
                     const std::string &constraints, bool hasSideEffects,
                     bool isAlignStack, AsmDialect 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) &&
         "Function type not legal for constraints!");
}

InlineAsm *InlineAsm::get(FunctionType *FTy, StringRef AsmString,
                          StringRef Constraints, bool hasSideEffects,
                          bool isAlignStack, AsmDialect asmDialect) {
  InlineAsmKeyType Key(AsmString, Constraints, FTy, hasSideEffects,
                       isAlignStack, asmDialect);
  LLVMContextImpl *pImpl = FTy->getContext().pImpl;
  return pImpl->InlineAsms.getOrCreate(PointerType::getUnqual(FTy), Key);
}

void InlineAsm::destroyConstant() {
  getType()->getContext().pImpl->InlineAsms.remove(this);
  delete this;
}

FunctionType *InlineAsm::getFunctionType() const {
  return FTy;
}
    
/// 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;
  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;

    // '{' 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.
  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(StringRef(I, ConstraintEnd+1 - I));
      I = ConstraintEnd+1;
    } else if (isdigit(static_cast<unsigned char>(*I))) { // Matching Constraint
      // Maximal munch numbers.
      StringRef::iterator NumStart = I;
      while (I != E && isdigit(static_cast<unsigned char>(*I)))
        ++I;
      pCodes->push_back(StringRef(NumStart, I - NumStart));
      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) {
        if (multipleAlternativeIndex >=
            ConstraintsSoFar[N].multipleAlternatives.size())
          return true;
        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();
        assert(scInfo.MatchingInput >= 0);
      } else {
        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();
        assert(ConstraintsSoFar[N].MatchingInput >= 0);
        }
    } 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(StringRef(I+1, 2));
      I += 3;
    } else {
      // Single letter constraint.
      pCodes->push_back(StringRef(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;
      LLVM_FALLTHROUGH; // We fall through 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 || STy->getNumElements() != NumOutputs)
      return false;
    break;
  }      
  
  if (Ty->getNumParams() != NumInputs) return false;
  return true;
}
