//===- CodeGenInstruction.cpp - CodeGen Instruction Class Wrapper ---------===//
//
//                     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 CodeGenInstruction class.
//
//===----------------------------------------------------------------------===//

#include "CodeGenInstruction.h"
#include "CodeGenTarget.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include <set>
using namespace llvm;

//===----------------------------------------------------------------------===//
// CGIOperandList Implementation
//===----------------------------------------------------------------------===//

CGIOperandList::CGIOperandList(Record *R) : TheDef(R) {
  isPredicable = false;
  hasOptionalDef = false;
  isVariadic = false;

  DagInit *OutDI = R->getValueAsDag("OutOperandList");

  if (DefInit *Init = dyn_cast<DefInit>(OutDI->getOperator())) {
    if (Init->getDef()->getName() != "outs")
      PrintFatalError(R->getName() + ": invalid def name for output list: use 'outs'");
  } else
    PrintFatalError(R->getName() + ": invalid output list: use 'outs'");

  NumDefs = OutDI->getNumArgs();

  DagInit *InDI = R->getValueAsDag("InOperandList");
  if (DefInit *Init = dyn_cast<DefInit>(InDI->getOperator())) {
    if (Init->getDef()->getName() != "ins")
      PrintFatalError(R->getName() + ": invalid def name for input list: use 'ins'");
  } else
    PrintFatalError(R->getName() + ": invalid input list: use 'ins'");

  unsigned MIOperandNo = 0;
  std::set<std::string> OperandNames;
  unsigned e = InDI->getNumArgs() + OutDI->getNumArgs();
  OperandList.reserve(e);
  for (unsigned i = 0; i != e; ++i){
    Init *ArgInit;
    StringRef ArgName;
    if (i < NumDefs) {
      ArgInit = OutDI->getArg(i);
      ArgName = OutDI->getArgNameStr(i);
    } else {
      ArgInit = InDI->getArg(i-NumDefs);
      ArgName = InDI->getArgNameStr(i-NumDefs);
    }

    DefInit *Arg = dyn_cast<DefInit>(ArgInit);
    if (!Arg)
      PrintFatalError("Illegal operand for the '" + R->getName() + "' instruction!");

    Record *Rec = Arg->getDef();
    std::string PrintMethod = "printOperand";
    std::string EncoderMethod;
    std::string OperandType = "OPERAND_UNKNOWN";
    std::string OperandNamespace = "MCOI";
    unsigned NumOps = 1;
    DagInit *MIOpInfo = nullptr;
    if (Rec->isSubClassOf("RegisterOperand")) {
      PrintMethod = Rec->getValueAsString("PrintMethod");
      OperandType = Rec->getValueAsString("OperandType");
      OperandNamespace = Rec->getValueAsString("OperandNamespace");
      EncoderMethod = Rec->getValueAsString("EncoderMethod");
    } else if (Rec->isSubClassOf("Operand")) {
      PrintMethod = Rec->getValueAsString("PrintMethod");
      OperandType = Rec->getValueAsString("OperandType");
      OperandNamespace = Rec->getValueAsString("OperandNamespace");
      // If there is an explicit encoder method, use it.
      EncoderMethod = Rec->getValueAsString("EncoderMethod");
      MIOpInfo = Rec->getValueAsDag("MIOperandInfo");

      // Verify that MIOpInfo has an 'ops' root value.
      if (!isa<DefInit>(MIOpInfo->getOperator()) ||
          cast<DefInit>(MIOpInfo->getOperator())->getDef()->getName() != "ops")
        PrintFatalError("Bad value for MIOperandInfo in operand '" + Rec->getName() +
          "'\n");

      // If we have MIOpInfo, then we have #operands equal to number of entries
      // in MIOperandInfo.
      if (unsigned NumArgs = MIOpInfo->getNumArgs())
        NumOps = NumArgs;

      if (Rec->isSubClassOf("PredicateOp"))
        isPredicable = true;
      else if (Rec->isSubClassOf("OptionalDefOperand"))
        hasOptionalDef = true;
    } else if (Rec->getName() == "variable_ops") {
      isVariadic = true;
      continue;
    } else if (Rec->isSubClassOf("RegisterClass")) {
      OperandType = "OPERAND_REGISTER";
    } else if (!Rec->isSubClassOf("PointerLikeRegClass") &&
               !Rec->isSubClassOf("unknown_class"))
      PrintFatalError("Unknown operand class '" + Rec->getName() +
        "' in '" + R->getName() + "' instruction!");

    // Check that the operand has a name and that it's unique.
    if (ArgName.empty())
      PrintFatalError("In instruction '" + R->getName() + "', operand #" +
                      Twine(i) + " has no name!");
    if (!OperandNames.insert(ArgName).second)
      PrintFatalError("In instruction '" + R->getName() + "', operand #" +
                      Twine(i) + " has the same name as a previous operand!");

    OperandList.emplace_back(Rec, ArgName, PrintMethod, EncoderMethod,
                             OperandNamespace + "::" + OperandType, MIOperandNo,
                             NumOps, MIOpInfo);
    MIOperandNo += NumOps;
  }


  // Make sure the constraints list for each operand is large enough to hold
  // constraint info, even if none is present.
  for (OperandInfo &OpInfo : OperandList)
    OpInfo.Constraints.resize(OpInfo.MINumOperands);
}


/// getOperandNamed - Return the index of the operand with the specified
/// non-empty name.  If the instruction does not have an operand with the
/// specified name, abort.
///
unsigned CGIOperandList::getOperandNamed(StringRef Name) const {
  unsigned OpIdx;
  if (hasOperandNamed(Name, OpIdx)) return OpIdx;
  PrintFatalError("'" + TheDef->getName() +
                  "' does not have an operand named '$" + Name + "'!");
}

/// hasOperandNamed - Query whether the instruction has an operand of the
/// given name. If so, return true and set OpIdx to the index of the
/// operand. Otherwise, return false.
bool CGIOperandList::hasOperandNamed(StringRef Name, unsigned &OpIdx) const {
  assert(!Name.empty() && "Cannot search for operand with no name!");
  for (unsigned i = 0, e = OperandList.size(); i != e; ++i)
    if (OperandList[i].Name == Name) {
      OpIdx = i;
      return true;
    }
  return false;
}

std::pair<unsigned,unsigned>
CGIOperandList::ParseOperandName(const std::string &Op, bool AllowWholeOp) {
  if (Op.empty() || Op[0] != '$')
    PrintFatalError(TheDef->getName() + ": Illegal operand name: '" + Op + "'");

  std::string OpName = Op.substr(1);
  std::string SubOpName;

  // Check to see if this is $foo.bar.
  std::string::size_type DotIdx = OpName.find_first_of('.');
  if (DotIdx != std::string::npos) {
    SubOpName = OpName.substr(DotIdx+1);
    if (SubOpName.empty())
      PrintFatalError(TheDef->getName() + ": illegal empty suboperand name in '" +Op +"'");
    OpName = OpName.substr(0, DotIdx);
  }

  unsigned OpIdx = getOperandNamed(OpName);

  if (SubOpName.empty()) {  // If no suboperand name was specified:
    // If one was needed, throw.
    if (OperandList[OpIdx].MINumOperands > 1 && !AllowWholeOp &&
        SubOpName.empty())
      PrintFatalError(TheDef->getName() + ": Illegal to refer to"
        " whole operand part of complex operand '" + Op + "'");

    // Otherwise, return the operand.
    return std::make_pair(OpIdx, 0U);
  }

  // Find the suboperand number involved.
  DagInit *MIOpInfo = OperandList[OpIdx].MIOperandInfo;
  if (!MIOpInfo)
    PrintFatalError(TheDef->getName() + ": unknown suboperand name in '" + Op + "'");

  // Find the operand with the right name.
  for (unsigned i = 0, e = MIOpInfo->getNumArgs(); i != e; ++i)
    if (MIOpInfo->getArgNameStr(i) == SubOpName)
      return std::make_pair(OpIdx, i);

  // Otherwise, didn't find it!
  PrintFatalError(TheDef->getName() + ": unknown suboperand name in '" + Op + "'");
  return std::make_pair(0U, 0U);
}

static void ParseConstraint(const std::string &CStr, CGIOperandList &Ops) {
  // EARLY_CLOBBER: @early $reg
  std::string::size_type wpos = CStr.find_first_of(" \t");
  std::string::size_type start = CStr.find_first_not_of(" \t");
  std::string Tok = CStr.substr(start, wpos - start);
  if (Tok == "@earlyclobber") {
    std::string Name = CStr.substr(wpos+1);
    wpos = Name.find_first_not_of(" \t");
    if (wpos == std::string::npos)
      PrintFatalError("Illegal format for @earlyclobber constraint: '" + CStr + "'");
    Name = Name.substr(wpos);
    std::pair<unsigned,unsigned> Op = Ops.ParseOperandName(Name, false);

    // Build the string for the operand
    if (!Ops[Op.first].Constraints[Op.second].isNone())
      PrintFatalError("Operand '" + Name + "' cannot have multiple constraints!");
    Ops[Op.first].Constraints[Op.second] =
    CGIOperandList::ConstraintInfo::getEarlyClobber();
    return;
  }

  // Only other constraint is "TIED_TO" for now.
  std::string::size_type pos = CStr.find_first_of('=');
  assert(pos != std::string::npos && "Unrecognized constraint");
  start = CStr.find_first_not_of(" \t");
  std::string Name = CStr.substr(start, pos - start);

  // TIED_TO: $src1 = $dst
  wpos = Name.find_first_of(" \t");
  if (wpos == std::string::npos)
    PrintFatalError("Illegal format for tied-to constraint: '" + CStr + "'");
  std::string DestOpName = Name.substr(0, wpos);
  std::pair<unsigned,unsigned> DestOp = Ops.ParseOperandName(DestOpName, false);

  Name = CStr.substr(pos+1);
  wpos = Name.find_first_not_of(" \t");
  if (wpos == std::string::npos)
    PrintFatalError("Illegal format for tied-to constraint: '" + CStr + "'");

  std::string SrcOpName = Name.substr(wpos);
  std::pair<unsigned,unsigned> SrcOp = Ops.ParseOperandName(SrcOpName, false);
  if (SrcOp > DestOp) {
    std::swap(SrcOp, DestOp);
    std::swap(SrcOpName, DestOpName);
  }

  unsigned FlatOpNo = Ops.getFlattenedOperandNumber(SrcOp);

  if (!Ops[DestOp.first].Constraints[DestOp.second].isNone())
    PrintFatalError("Operand '" + DestOpName +
      "' cannot have multiple constraints!");
  Ops[DestOp.first].Constraints[DestOp.second] =
    CGIOperandList::ConstraintInfo::getTied(FlatOpNo);
}

static void ParseConstraints(const std::string &CStr, CGIOperandList &Ops) {
  if (CStr.empty()) return;

  const std::string delims(",");
  std::string::size_type bidx, eidx;

  bidx = CStr.find_first_not_of(delims);
  while (bidx != std::string::npos) {
    eidx = CStr.find_first_of(delims, bidx);
    if (eidx == std::string::npos)
      eidx = CStr.length();

    ParseConstraint(CStr.substr(bidx, eidx - bidx), Ops);
    bidx = CStr.find_first_not_of(delims, eidx);
  }
}

void CGIOperandList::ProcessDisableEncoding(std::string DisableEncoding) {
  while (1) {
    std::pair<StringRef, StringRef> P = getToken(DisableEncoding, " ,\t");
    std::string OpName = P.first;
    DisableEncoding = P.second;
    if (OpName.empty()) break;

    // Figure out which operand this is.
    std::pair<unsigned,unsigned> Op = ParseOperandName(OpName, false);

    // Mark the operand as not-to-be encoded.
    if (Op.second >= OperandList[Op.first].DoNotEncode.size())
      OperandList[Op.first].DoNotEncode.resize(Op.second+1);
    OperandList[Op.first].DoNotEncode[Op.second] = true;
  }

}

//===----------------------------------------------------------------------===//
// CodeGenInstruction Implementation
//===----------------------------------------------------------------------===//

CodeGenInstruction::CodeGenInstruction(Record *R)
  : TheDef(R), Operands(R), InferredFrom(nullptr) {
  Namespace = R->getValueAsString("Namespace");
  AsmString = R->getValueAsString("AsmString");

  isReturn     = R->getValueAsBit("isReturn");
  isBranch     = R->getValueAsBit("isBranch");
  isIndirectBranch = R->getValueAsBit("isIndirectBranch");
  isCompare    = R->getValueAsBit("isCompare");
  isMoveImm    = R->getValueAsBit("isMoveImm");
  isBitcast    = R->getValueAsBit("isBitcast");
  isSelect     = R->getValueAsBit("isSelect");
  isBarrier    = R->getValueAsBit("isBarrier");
  isCall       = R->getValueAsBit("isCall");
  isAdd        = R->getValueAsBit("isAdd");
  canFoldAsLoad = R->getValueAsBit("canFoldAsLoad");
  isPredicable = Operands.isPredicable || R->getValueAsBit("isPredicable");
  isConvertibleToThreeAddress = R->getValueAsBit("isConvertibleToThreeAddress");
  isCommutable = R->getValueAsBit("isCommutable");
  isTerminator = R->getValueAsBit("isTerminator");
  isReMaterializable = R->getValueAsBit("isReMaterializable");
  hasDelaySlot = R->getValueAsBit("hasDelaySlot");
  usesCustomInserter = R->getValueAsBit("usesCustomInserter");
  hasPostISelHook = R->getValueAsBit("hasPostISelHook");
  hasCtrlDep   = R->getValueAsBit("hasCtrlDep");
  isNotDuplicable = R->getValueAsBit("isNotDuplicable");
  isRegSequence = R->getValueAsBit("isRegSequence");
  isExtractSubreg = R->getValueAsBit("isExtractSubreg");
  isInsertSubreg = R->getValueAsBit("isInsertSubreg");
  isConvergent = R->getValueAsBit("isConvergent");
  hasNoSchedulingInfo = R->getValueAsBit("hasNoSchedulingInfo");

  bool Unset;
  mayLoad      = R->getValueAsBitOrUnset("mayLoad", Unset);
  mayLoad_Unset = Unset;
  mayStore     = R->getValueAsBitOrUnset("mayStore", Unset);
  mayStore_Unset = Unset;
  hasSideEffects = R->getValueAsBitOrUnset("hasSideEffects", Unset);
  hasSideEffects_Unset = Unset;

  isAsCheapAsAMove = R->getValueAsBit("isAsCheapAsAMove");
  hasExtraSrcRegAllocReq = R->getValueAsBit("hasExtraSrcRegAllocReq");
  hasExtraDefRegAllocReq = R->getValueAsBit("hasExtraDefRegAllocReq");
  isCodeGenOnly = R->getValueAsBit("isCodeGenOnly");
  isPseudo = R->getValueAsBit("isPseudo");
  ImplicitDefs = R->getValueAsListOfDefs("Defs");
  ImplicitUses = R->getValueAsListOfDefs("Uses");

  // Parse Constraints.
  ParseConstraints(R->getValueAsString("Constraints"), Operands);

  // Parse the DisableEncoding field.
  Operands.ProcessDisableEncoding(R->getValueAsString("DisableEncoding"));

  // First check for a ComplexDeprecationPredicate.
  if (R->getValue("ComplexDeprecationPredicate")) {
    HasComplexDeprecationPredicate = true;
    DeprecatedReason = R->getValueAsString("ComplexDeprecationPredicate");
  } else if (RecordVal *Dep = R->getValue("DeprecatedFeatureMask")) {
    // Check if we have a Subtarget feature mask.
    HasComplexDeprecationPredicate = false;
    DeprecatedReason = Dep->getValue()->getAsString();
  } else {
    // This instruction isn't deprecated.
    HasComplexDeprecationPredicate = false;
    DeprecatedReason = "";
  }
}

/// HasOneImplicitDefWithKnownVT - If the instruction has at least one
/// implicit def and it has a known VT, return the VT, otherwise return
/// MVT::Other.
MVT::SimpleValueType CodeGenInstruction::
HasOneImplicitDefWithKnownVT(const CodeGenTarget &TargetInfo) const {
  if (ImplicitDefs.empty()) return MVT::Other;

  // Check to see if the first implicit def has a resolvable type.
  Record *FirstImplicitDef = ImplicitDefs[0];
  assert(FirstImplicitDef->isSubClassOf("Register"));
  const std::vector<ValueTypeByHwMode> &RegVTs =
    TargetInfo.getRegisterVTs(FirstImplicitDef);
  if (RegVTs.size() == 1 && RegVTs[0].isSimple())
    return RegVTs[0].getSimple().SimpleTy;
  return MVT::Other;
}


/// FlattenAsmStringVariants - Flatten the specified AsmString to only
/// include text from the specified variant, returning the new string.
std::string CodeGenInstruction::
FlattenAsmStringVariants(StringRef Cur, unsigned Variant) {
  std::string Res = "";

  for (;;) {
    // Find the start of the next variant string.
    size_t VariantsStart = 0;
    for (size_t e = Cur.size(); VariantsStart != e; ++VariantsStart)
      if (Cur[VariantsStart] == '{' &&
          (VariantsStart == 0 || (Cur[VariantsStart-1] != '$' &&
                                  Cur[VariantsStart-1] != '\\')))
        break;

    // Add the prefix to the result.
    Res += Cur.slice(0, VariantsStart);
    if (VariantsStart == Cur.size())
      break;

    ++VariantsStart; // Skip the '{'.

    // Scan to the end of the variants string.
    size_t VariantsEnd = VariantsStart;
    unsigned NestedBraces = 1;
    for (size_t e = Cur.size(); VariantsEnd != e; ++VariantsEnd) {
      if (Cur[VariantsEnd] == '}' && Cur[VariantsEnd-1] != '\\') {
        if (--NestedBraces == 0)
          break;
      } else if (Cur[VariantsEnd] == '{')
        ++NestedBraces;
    }

    // Select the Nth variant (or empty).
    StringRef Selection = Cur.slice(VariantsStart, VariantsEnd);
    for (unsigned i = 0; i != Variant; ++i)
      Selection = Selection.split('|').second;
    Res += Selection.split('|').first;

    assert(VariantsEnd != Cur.size() &&
           "Unterminated variants in assembly string!");
    Cur = Cur.substr(VariantsEnd + 1);
  }

  return Res;
}


//===----------------------------------------------------------------------===//
/// CodeGenInstAlias Implementation
//===----------------------------------------------------------------------===//

/// tryAliasOpMatch - This is a helper function for the CodeGenInstAlias
/// constructor.  It checks if an argument in an InstAlias pattern matches
/// the corresponding operand of the instruction.  It returns true on a
/// successful match, with ResOp set to the result operand to be used.
bool CodeGenInstAlias::tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo,
                                       Record *InstOpRec, bool hasSubOps,
                                       ArrayRef<SMLoc> Loc, CodeGenTarget &T,
                                       ResultOperand &ResOp) {
  Init *Arg = Result->getArg(AliasOpNo);
  DefInit *ADI = dyn_cast<DefInit>(Arg);
  Record *ResultRecord = ADI ? ADI->getDef() : nullptr;

  if (ADI && ADI->getDef() == InstOpRec) {
    // If the operand is a record, it must have a name, and the record type
    // must match up with the instruction's argument type.
    if (!Result->getArgName(AliasOpNo))
      PrintFatalError(Loc, "result argument #" + Twine(AliasOpNo) +
                           " must have a name!");
    ResOp = ResultOperand(Result->getArgNameStr(AliasOpNo), ResultRecord);
    return true;
  }

  // For register operands, the source register class can be a subclass
  // of the instruction register class, not just an exact match.
  if (InstOpRec->isSubClassOf("RegisterOperand"))
    InstOpRec = InstOpRec->getValueAsDef("RegClass");

  if (ADI && ADI->getDef()->isSubClassOf("RegisterOperand"))
    ADI = ADI->getDef()->getValueAsDef("RegClass")->getDefInit();

  if (ADI && ADI->getDef()->isSubClassOf("RegisterClass")) {
    if (!InstOpRec->isSubClassOf("RegisterClass"))
      return false;
    if (!T.getRegisterClass(InstOpRec)
              .hasSubClass(&T.getRegisterClass(ADI->getDef())))
      return false;
    ResOp = ResultOperand(Result->getArgNameStr(AliasOpNo), ResultRecord);
    return true;
  }

  // Handle explicit registers.
  if (ADI && ADI->getDef()->isSubClassOf("Register")) {
    if (InstOpRec->isSubClassOf("OptionalDefOperand")) {
      DagInit *DI = InstOpRec->getValueAsDag("MIOperandInfo");
      // The operand info should only have a single (register) entry. We
      // want the register class of it.
      InstOpRec = cast<DefInit>(DI->getArg(0))->getDef();
    }

    if (!InstOpRec->isSubClassOf("RegisterClass"))
      return false;

    if (!T.getRegisterClass(InstOpRec)
        .contains(T.getRegBank().getReg(ADI->getDef())))
      PrintFatalError(Loc, "fixed register " + ADI->getDef()->getName() +
                      " is not a member of the " + InstOpRec->getName() +
                      " register class!");

    if (Result->getArgName(AliasOpNo))
      PrintFatalError(Loc, "result fixed register argument must "
                      "not have a name!");

    ResOp = ResultOperand(ResultRecord);
    return true;
  }

  // Handle "zero_reg" for optional def operands.
  if (ADI && ADI->getDef()->getName() == "zero_reg") {

    // Check if this is an optional def.
    // Tied operands where the source is a sub-operand of a complex operand
    // need to represent both operands in the alias destination instruction.
    // Allow zero_reg for the tied portion. This can and should go away once
    // the MC representation of things doesn't use tied operands at all.
    //if (!InstOpRec->isSubClassOf("OptionalDefOperand"))
    //  throw TGError(Loc, "reg0 used for result that is not an "
    //                "OptionalDefOperand!");

    ResOp = ResultOperand(static_cast<Record*>(nullptr));
    return true;
  }

  // Literal integers.
  if (IntInit *II = dyn_cast<IntInit>(Arg)) {
    if (hasSubOps || !InstOpRec->isSubClassOf("Operand"))
      return false;
    // Integer arguments can't have names.
    if (Result->getArgName(AliasOpNo))
      PrintFatalError(Loc, "result argument #" + Twine(AliasOpNo) +
                      " must not have a name!");
    ResOp = ResultOperand(II->getValue());
    return true;
  }

  // Bits<n> (also used for 0bxx literals)
  if (BitsInit *BI = dyn_cast<BitsInit>(Arg)) {
    if (hasSubOps || !InstOpRec->isSubClassOf("Operand"))
      return false;
    if (!BI->isComplete())
      return false;
    // Convert the bits init to an integer and use that for the result.
    IntInit *II =
      dyn_cast_or_null<IntInit>(BI->convertInitializerTo(IntRecTy::get()));
    if (!II)
      return false;
    ResOp = ResultOperand(II->getValue());
    return true;
  }

  // If both are Operands with the same MVT, allow the conversion. It's
  // up to the user to make sure the values are appropriate, just like
  // for isel Pat's.
  if (InstOpRec->isSubClassOf("Operand") && ADI &&
      ADI->getDef()->isSubClassOf("Operand")) {
    // FIXME: What other attributes should we check here? Identical
    // MIOperandInfo perhaps?
    if (InstOpRec->getValueInit("Type") != ADI->getDef()->getValueInit("Type"))
      return false;
    ResOp = ResultOperand(Result->getArgNameStr(AliasOpNo), ADI->getDef());
    return true;
  }

  return false;
}

unsigned CodeGenInstAlias::ResultOperand::getMINumOperands() const {
  if (!isRecord())
    return 1;

  Record *Rec = getRecord();
  if (!Rec->isSubClassOf("Operand"))
    return 1;

  DagInit *MIOpInfo = Rec->getValueAsDag("MIOperandInfo");
  if (MIOpInfo->getNumArgs() == 0) {
    // Unspecified, so it defaults to 1
    return 1;
  }

  return MIOpInfo->getNumArgs();
}

CodeGenInstAlias::CodeGenInstAlias(Record *R, unsigned Variant,
                                   CodeGenTarget &T)
    : TheDef(R) {
  Result = R->getValueAsDag("ResultInst");
  AsmString = R->getValueAsString("AsmString");
  AsmString = CodeGenInstruction::FlattenAsmStringVariants(AsmString, Variant);


  // Verify that the root of the result is an instruction.
  DefInit *DI = dyn_cast<DefInit>(Result->getOperator());
  if (!DI || !DI->getDef()->isSubClassOf("Instruction"))
    PrintFatalError(R->getLoc(),
                    "result of inst alias should be an instruction");

  ResultInst = &T.getInstruction(DI->getDef());

  // NameClass - If argument names are repeated, we need to verify they have
  // the same class.
  StringMap<Record*> NameClass;
  for (unsigned i = 0, e = Result->getNumArgs(); i != e; ++i) {
    DefInit *ADI = dyn_cast<DefInit>(Result->getArg(i));
    if (!ADI || !Result->getArgName(i))
      continue;
    // Verify we don't have something like: (someinst GR16:$foo, GR32:$foo)
    // $foo can exist multiple times in the result list, but it must have the
    // same type.
    Record *&Entry = NameClass[Result->getArgNameStr(i)];
    if (Entry && Entry != ADI->getDef())
      PrintFatalError(R->getLoc(), "result value $" + Result->getArgNameStr(i) +
                      " is both " + Entry->getName() + " and " +
                      ADI->getDef()->getName() + "!");
    Entry = ADI->getDef();
  }

  // Decode and validate the arguments of the result.
  unsigned AliasOpNo = 0;
  for (unsigned i = 0, e = ResultInst->Operands.size(); i != e; ++i) {

    // Tied registers don't have an entry in the result dag unless they're part
    // of a complex operand, in which case we include them anyways, as we
    // don't have any other way to specify the whole operand.
    if (ResultInst->Operands[i].MINumOperands == 1 &&
        ResultInst->Operands[i].getTiedRegister() != -1)
      continue;

    if (AliasOpNo >= Result->getNumArgs())
      PrintFatalError(R->getLoc(), "not enough arguments for instruction!");

    Record *InstOpRec = ResultInst->Operands[i].Rec;
    unsigned NumSubOps = ResultInst->Operands[i].MINumOperands;
    ResultOperand ResOp(static_cast<int64_t>(0));
    if (tryAliasOpMatch(Result, AliasOpNo, InstOpRec, (NumSubOps > 1),
                        R->getLoc(), T, ResOp)) {
      // If this is a simple operand, or a complex operand with a custom match
      // class, then we can match is verbatim.
      if (NumSubOps == 1 ||
          (InstOpRec->getValue("ParserMatchClass") &&
           InstOpRec->getValueAsDef("ParserMatchClass")
             ->getValueAsString("Name") != "Imm")) {
        ResultOperands.push_back(ResOp);
        ResultInstOperandIndex.push_back(std::make_pair(i, -1));
        ++AliasOpNo;

      // Otherwise, we need to match each of the suboperands individually.
      } else {
         DagInit *MIOI = ResultInst->Operands[i].MIOperandInfo;
         for (unsigned SubOp = 0; SubOp != NumSubOps; ++SubOp) {
          Record *SubRec = cast<DefInit>(MIOI->getArg(SubOp))->getDef();

          // Take care to instantiate each of the suboperands with the correct
          // nomenclature: $foo.bar
          ResultOperands.emplace_back(
            Result->getArgName(AliasOpNo)->getAsUnquotedString() + "." +
            MIOI->getArgName(SubOp)->getAsUnquotedString(), SubRec);
          ResultInstOperandIndex.push_back(std::make_pair(i, SubOp));
         }
         ++AliasOpNo;
      }
      continue;
    }

    // If the argument did not match the instruction operand, and the operand
    // is composed of multiple suboperands, try matching the suboperands.
    if (NumSubOps > 1) {
      DagInit *MIOI = ResultInst->Operands[i].MIOperandInfo;
      for (unsigned SubOp = 0; SubOp != NumSubOps; ++SubOp) {
        if (AliasOpNo >= Result->getNumArgs())
          PrintFatalError(R->getLoc(), "not enough arguments for instruction!");
        Record *SubRec = cast<DefInit>(MIOI->getArg(SubOp))->getDef();
        if (tryAliasOpMatch(Result, AliasOpNo, SubRec, false,
                            R->getLoc(), T, ResOp)) {
          ResultOperands.push_back(ResOp);
          ResultInstOperandIndex.push_back(std::make_pair(i, SubOp));
          ++AliasOpNo;
        } else {
          PrintFatalError(R->getLoc(), "result argument #" + Twine(AliasOpNo) +
                        " does not match instruction operand class " +
                        (SubOp == 0 ? InstOpRec->getName() :SubRec->getName()));
        }
      }
      continue;
    }
    PrintFatalError(R->getLoc(), "result argument #" + Twine(AliasOpNo) +
                    " does not match instruction operand class " +
                    InstOpRec->getName());
  }

  if (AliasOpNo != Result->getNumArgs())
    PrintFatalError(R->getLoc(), "too many operands for instruction!");
}
