CodeGenInstruction.cpp revision f523e476c2e199220306b367b7bd834978fb93d6
1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//===- CodeGenInstruction.cpp - CodeGen Instruction Class Wrapper ---------===//
2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//
3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//                     The LLVM Compiler Infrastructure
4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//
5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// This file is distributed under the University of Illinois Open Source
6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// License. See LICENSE.TXT for details.
7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//
8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//===----------------------------------------------------------------------===//
9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//
10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// This file implements the CodeGenInstruction class.
11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//
12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//===----------------------------------------------------------------------===//
13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "CodeGenInstruction.h"
15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "CodeGenTarget.h"
16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "Record.h"
17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "llvm/ADT/StringExtras.h"
18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "llvm/ADT/STLExtras.h"
19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <set>
20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownusing namespace llvm;
21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void ParseConstraint(const std::string &CStr, CodeGenInstruction *I) {
23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  // EARLY_CLOBBER: @early $reg
24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  std::string::size_type wpos = CStr.find_first_of(" \t");
25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  std::string::size_type start = CStr.find_first_not_of(" \t");
26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  std::string Tok = CStr.substr(start, wpos - start);
27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (Tok == "@earlyclobber") {
28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    std::string Name = CStr.substr(wpos+1);
29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    wpos = Name.find_first_not_of(" \t");
30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    if (wpos == std::string::npos)
31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      throw "Illegal format for @earlyclobber constraint: '" + CStr + "'";
32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    Name = Name.substr(wpos);
33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    std::pair<unsigned,unsigned> Op =
34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      I->ParseOperandName(Name, false);
35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    // Build the string for the operand
37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    if (!I->OperandList[Op.first].Constraints[Op.second].isNone())
38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      throw "Operand '" + Name + "' cannot have multiple constraints!";
39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    I->OperandList[Op.first].Constraints[Op.second] =
40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CodeGenInstruction::ConstraintInfo::getEarlyClobber();
41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return;
42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  }
43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  // Only other constraint is "TIED_TO" for now.
45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  std::string::size_type pos = CStr.find_first_of('=');
46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  assert(pos != std::string::npos && "Unrecognized constraint");
47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  start = CStr.find_first_not_of(" \t");
48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  std::string Name = CStr.substr(start, pos - start);
49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  // TIED_TO: $src1 = $dst
51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  wpos = Name.find_first_of(" \t");
52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (wpos == std::string::npos)
53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    throw "Illegal format for tied-to constraint: '" + CStr + "'";
54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  std::string DestOpName = Name.substr(0, wpos);
55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  std::pair<unsigned,unsigned> DestOp = I->ParseOperandName(DestOpName, false);
56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Name = CStr.substr(pos+1);
58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  wpos = Name.find_first_not_of(" \t");
59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (wpos == std::string::npos)
60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    throw "Illegal format for tied-to constraint: '" + CStr + "'";
61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  std::pair<unsigned,unsigned> SrcOp =
63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  I->ParseOperandName(Name.substr(wpos), false);
64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (SrcOp > DestOp)
65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    throw "Illegal tied-to operand constraint '" + CStr + "'";
66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  unsigned FlatOpNo = I->getFlattenedOperandNumber(SrcOp);
69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (!I->OperandList[DestOp.first].Constraints[DestOp.second].isNone())
71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    throw "Operand '" + DestOpName + "' cannot have multiple constraints!";
72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  I->OperandList[DestOp.first].Constraints[DestOp.second] =
73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    CodeGenInstruction::ConstraintInfo::getTied(FlatOpNo);
74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void ParseConstraints(const std::string &CStr, CodeGenInstruction *I) {
77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  // Make sure the constraints list for each operand is large enough to hold
78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  // constraint info, even if none is present.
79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  for (unsigned i = 0, e = I->OperandList.size(); i != e; ++i)
80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    I->OperandList[i].Constraints.resize(I->OperandList[i].MINumOperands);
81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (CStr.empty()) return;
83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  const std::string delims(",");
85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  std::string::size_type bidx, eidx;
86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  bidx = CStr.find_first_not_of(delims);
88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  while (bidx != std::string::npos) {
89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    eidx = CStr.find_first_of(delims, bidx);
90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    if (eidx == std::string::npos)
91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      eidx = CStr.length();
92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    ParseConstraint(CStr.substr(bidx, eidx - bidx), I);
94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    bidx = CStr.find_first_not_of(delims, eidx);
95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  }
96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr)
99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  : TheDef(R), AsmString(AsmStr) {
100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Namespace = R->getValueAsString("Namespace");
101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  isReturn     = R->getValueAsBit("isReturn");
103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  isBranch     = R->getValueAsBit("isBranch");
104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  isIndirectBranch = R->getValueAsBit("isIndirectBranch");
105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  isCompare    = R->getValueAsBit("isCompare");
106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  isBarrier    = R->getValueAsBit("isBarrier");
107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  isCall       = R->getValueAsBit("isCall");
108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  canFoldAsLoad = R->getValueAsBit("canFoldAsLoad");
109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  mayLoad      = R->getValueAsBit("mayLoad");
110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  mayStore     = R->getValueAsBit("mayStore");
111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  isPredicable = R->getValueAsBit("isPredicable");
112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  isConvertibleToThreeAddress = R->getValueAsBit("isConvertibleToThreeAddress");
113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  isCommutable = R->getValueAsBit("isCommutable");
114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  isTerminator = R->getValueAsBit("isTerminator");
115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  isReMaterializable = R->getValueAsBit("isReMaterializable");
116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  hasDelaySlot = R->getValueAsBit("hasDelaySlot");
117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  usesCustomInserter = R->getValueAsBit("usesCustomInserter");
118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  hasCtrlDep   = R->getValueAsBit("hasCtrlDep");
119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  isNotDuplicable = R->getValueAsBit("isNotDuplicable");
120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  hasSideEffects = R->getValueAsBit("hasSideEffects");
121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  neverHasSideEffects = R->getValueAsBit("neverHasSideEffects");
122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  isAsCheapAsAMove = R->getValueAsBit("isAsCheapAsAMove");
123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  hasExtraSrcRegAllocReq = R->getValueAsBit("hasExtraSrcRegAllocReq");
124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  hasExtraDefRegAllocReq = R->getValueAsBit("hasExtraDefRegAllocReq");
125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  hasOptionalDef = false;
126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  isVariadic = false;
127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  ImplicitDefs = R->getValueAsListOfDefs("Defs");
128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  ImplicitUses = R->getValueAsListOfDefs("Uses");
129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (neverHasSideEffects + hasSideEffects > 1)
131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    throw R->getName() + ": multiple conflicting side-effect flags set!";
132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  DagInit *OutDI = R->getValueAsDag("OutOperandList");
134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (DefInit *Init = dynamic_cast<DefInit*>(OutDI->getOperator())) {
136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    if (Init->getDef()->getName() != "outs")
137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      throw R->getName() + ": invalid def name for output list: use 'outs'";
138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  } else
139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    throw R->getName() + ": invalid output list: use 'outs'";
140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  NumDefs = OutDI->getNumArgs();
142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  DagInit *InDI = R->getValueAsDag("InOperandList");
144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (DefInit *Init = dynamic_cast<DefInit*>(InDI->getOperator())) {
145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    if (Init->getDef()->getName() != "ins")
146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      throw R->getName() + ": invalid def name for input list: use 'ins'";
147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  } else
148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    throw R->getName() + ": invalid input list: use 'ins'";
149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  unsigned MIOperandNo = 0;
151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  std::set<std::string> OperandNames;
152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  for (unsigned i = 0, e = InDI->getNumArgs()+OutDI->getNumArgs(); i != e; ++i){
153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    Init *ArgInit;
154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    std::string ArgName;
155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    if (i < NumDefs) {
156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ArgInit = OutDI->getArg(i);
157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ArgName = OutDI->getArgName(i);
158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    } else {
159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ArgInit = InDI->getArg(i-NumDefs);
160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ArgName = InDI->getArgName(i-NumDefs);
161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    DefInit *Arg = dynamic_cast<DefInit*>(ArgInit);
164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    if (!Arg)
165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      throw "Illegal operand for the '" + R->getName() + "' instruction!";
166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    Record *Rec = Arg->getDef();
168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    std::string PrintMethod = "printOperand";
169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    unsigned NumOps = 1;
170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    DagInit *MIOpInfo = 0;
171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    if (Rec->isSubClassOf("Operand")) {
172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PrintMethod = Rec->getValueAsString("PrintMethod");
173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      MIOpInfo = Rec->getValueAsDag("MIOperandInfo");
174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // Verify that MIOpInfo has an 'ops' root value.
176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (!dynamic_cast<DefInit*>(MIOpInfo->getOperator()) ||
177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          dynamic_cast<DefInit*>(MIOpInfo->getOperator())
178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               ->getDef()->getName() != "ops")
179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        throw "Bad value for MIOperandInfo in operand '" + Rec->getName() +
180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              "'\n";
181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // If we have MIOpInfo, then we have #operands equal to number of entries
183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // in MIOperandInfo.
184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (unsigned NumArgs = MIOpInfo->getNumArgs())
185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        NumOps = NumArgs;
186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (Rec->isSubClassOf("PredicateOperand"))
188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        isPredicable = true;
189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else if (Rec->isSubClassOf("OptionalDefOperand"))
190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        hasOptionalDef = true;
191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    } else if (Rec->getName() == "variable_ops") {
192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      isVariadic = true;
193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      continue;
194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    } else if (!Rec->isSubClassOf("RegisterClass") &&
195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               Rec->getName() != "ptr_rc" && Rec->getName() != "unknown")
196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      throw "Unknown operand class '" + Rec->getName() +
197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            "' in '" + R->getName() + "' instruction!";
198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    // Check that the operand has a name and that it's unique.
200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    if (ArgName.empty())
201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      throw "In instruction '" + R->getName() + "', operand #" + utostr(i) +
202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        " has no name!";
203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    if (!OperandNames.insert(ArgName).second)
204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      throw "In instruction '" + R->getName() + "', operand #" + utostr(i) +
205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        " has the same name as a previous operand!";
206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    OperandList.push_back(OperandInfo(Rec, ArgName, PrintMethod,
208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                      MIOperandNo, NumOps, MIOpInfo));
209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    MIOperandNo += NumOps;
210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  }
211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  // Parse Constraints.
213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  ParseConstraints(R->getValueAsString("Constraints"), this);
214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  // Parse the DisableEncoding field.
216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  std::string DisableEncoding = R->getValueAsString("DisableEncoding");
217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  while (1) {
218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    std::string OpName;
219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    tie(OpName, DisableEncoding) = getToken(DisableEncoding, " ,\t");
220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    if (OpName.empty()) break;
221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    // Figure out which operand this is.
223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    std::pair<unsigned,unsigned> Op = ParseOperandName(OpName, false);
224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    // Mark the operand as not-to-be encoded.
226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    if (Op.second >= OperandList[Op.first].DoNotEncode.size())
227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      OperandList[Op.first].DoNotEncode.resize(Op.second+1);
228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    OperandList[Op.first].DoNotEncode[Op.second] = true;
229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  }
230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/// getOperandNamed - Return the index of the operand with the specified
233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/// non-empty name.  If the instruction does not have an operand with the
234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/// specified name, throw an exception.
235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown///
236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownunsigned CodeGenInstruction::getOperandNamed(const std::string &Name) const {
237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  assert(!Name.empty() && "Cannot search for operand with no name!");
238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  for (unsigned i = 0, e = OperandList.size(); i != e; ++i)
239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    if (OperandList[i].Name == Name) return i;
240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  throw "Instruction '" + TheDef->getName() +
241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        "' does not have an operand named '$" + Name + "'!";
242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstd::pair<unsigned,unsigned>
245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCodeGenInstruction::ParseOperandName(const std::string &Op,
246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                     bool AllowWholeOp) {
247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (Op.empty() || Op[0] != '$')
248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    throw TheDef->getName() + ": Illegal operand name: '" + Op + "'";
249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  std::string OpName = Op.substr(1);
251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  std::string SubOpName;
252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  // Check to see if this is $foo.bar.
254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  std::string::size_type DotIdx = OpName.find_first_of(".");
255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (DotIdx != std::string::npos) {
256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    SubOpName = OpName.substr(DotIdx+1);
257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    if (SubOpName.empty())
258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      throw TheDef->getName() + ": illegal empty suboperand name in '" +Op +"'";
259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    OpName = OpName.substr(0, DotIdx);
260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  }
261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  unsigned OpIdx = getOperandNamed(OpName);
263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (SubOpName.empty()) {  // If no suboperand name was specified:
265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    // If one was needed, throw.
266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    if (OperandList[OpIdx].MINumOperands > 1 && !AllowWholeOp &&
267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        SubOpName.empty())
268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      throw TheDef->getName() + ": Illegal to refer to"
269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            " whole operand part of complex operand '" + Op + "'";
270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    // Otherwise, return the operand.
272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return std::make_pair(OpIdx, 0U);
273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  }
274
275  // Find the suboperand number involved.
276  DagInit *MIOpInfo = OperandList[OpIdx].MIOperandInfo;
277  if (MIOpInfo == 0)
278    throw TheDef->getName() + ": unknown suboperand name in '" + Op + "'";
279
280  // Find the operand with the right name.
281  for (unsigned i = 0, e = MIOpInfo->getNumArgs(); i != e; ++i)
282    if (MIOpInfo->getArgName(i) == SubOpName)
283      return std::make_pair(OpIdx, i);
284
285  // Otherwise, didn't find it!
286  throw TheDef->getName() + ": unknown suboperand name in '" + Op + "'";
287}
288
289
290/// HasOneImplicitDefWithKnownVT - If the instruction has at least one
291/// implicit def and it has a known VT, return the VT, otherwise return
292/// MVT::Other.
293MVT::SimpleValueType CodeGenInstruction::
294HasOneImplicitDefWithKnownVT(const CodeGenTarget &TargetInfo) const {
295  if (ImplicitDefs.empty()) return MVT::Other;
296
297  // Check to see if the first implicit def has a resolvable type.
298  Record *FirstImplicitDef = ImplicitDefs[0];
299  assert(FirstImplicitDef->isSubClassOf("Register"));
300  const std::vector<MVT::SimpleValueType> &RegVTs =
301    TargetInfo.getRegisterVTs(FirstImplicitDef);
302  if (RegVTs.size() == 1)
303    return RegVTs[0];
304  return MVT::Other;
305}
306
307