xref: /minix3/external/bsd/llvm/dist/llvm/utils/TableGen/CodeGenInstruction.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc //===- CodeGenInstruction.cpp - CodeGen Instruction Class Wrapper ---------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc // This file implements the CodeGenInstruction class.
11f4a2713aSLionel Sambuc //
12f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
13f4a2713aSLionel Sambuc 
14f4a2713aSLionel Sambuc #include "CodeGenInstruction.h"
15f4a2713aSLionel Sambuc #include "CodeGenTarget.h"
16f4a2713aSLionel Sambuc #include "llvm/ADT/STLExtras.h"
17f4a2713aSLionel Sambuc #include "llvm/ADT/StringExtras.h"
18f4a2713aSLionel Sambuc #include "llvm/ADT/StringMap.h"
19f4a2713aSLionel Sambuc #include "llvm/TableGen/Error.h"
20f4a2713aSLionel Sambuc #include "llvm/TableGen/Record.h"
21f4a2713aSLionel Sambuc #include <set>
22f4a2713aSLionel Sambuc using namespace llvm;
23f4a2713aSLionel Sambuc 
24f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
25f4a2713aSLionel Sambuc // CGIOperandList Implementation
26f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
27f4a2713aSLionel Sambuc 
CGIOperandList(Record * R)28f4a2713aSLionel Sambuc CGIOperandList::CGIOperandList(Record *R) : TheDef(R) {
29f4a2713aSLionel Sambuc   isPredicable = false;
30f4a2713aSLionel Sambuc   hasOptionalDef = false;
31f4a2713aSLionel Sambuc   isVariadic = false;
32f4a2713aSLionel Sambuc 
33f4a2713aSLionel Sambuc   DagInit *OutDI = R->getValueAsDag("OutOperandList");
34f4a2713aSLionel Sambuc 
35f4a2713aSLionel Sambuc   if (DefInit *Init = dyn_cast<DefInit>(OutDI->getOperator())) {
36f4a2713aSLionel Sambuc     if (Init->getDef()->getName() != "outs")
37f4a2713aSLionel Sambuc       PrintFatalError(R->getName() + ": invalid def name for output list: use 'outs'");
38f4a2713aSLionel Sambuc   } else
39f4a2713aSLionel Sambuc     PrintFatalError(R->getName() + ": invalid output list: use 'outs'");
40f4a2713aSLionel Sambuc 
41f4a2713aSLionel Sambuc   NumDefs = OutDI->getNumArgs();
42f4a2713aSLionel Sambuc 
43f4a2713aSLionel Sambuc   DagInit *InDI = R->getValueAsDag("InOperandList");
44f4a2713aSLionel Sambuc   if (DefInit *Init = dyn_cast<DefInit>(InDI->getOperator())) {
45f4a2713aSLionel Sambuc     if (Init->getDef()->getName() != "ins")
46f4a2713aSLionel Sambuc       PrintFatalError(R->getName() + ": invalid def name for input list: use 'ins'");
47f4a2713aSLionel Sambuc   } else
48f4a2713aSLionel Sambuc     PrintFatalError(R->getName() + ": invalid input list: use 'ins'");
49f4a2713aSLionel Sambuc 
50f4a2713aSLionel Sambuc   unsigned MIOperandNo = 0;
51f4a2713aSLionel Sambuc   std::set<std::string> OperandNames;
52f4a2713aSLionel Sambuc   for (unsigned i = 0, e = InDI->getNumArgs()+OutDI->getNumArgs(); i != e; ++i){
53f4a2713aSLionel Sambuc     Init *ArgInit;
54f4a2713aSLionel Sambuc     std::string ArgName;
55f4a2713aSLionel Sambuc     if (i < NumDefs) {
56f4a2713aSLionel Sambuc       ArgInit = OutDI->getArg(i);
57f4a2713aSLionel Sambuc       ArgName = OutDI->getArgName(i);
58f4a2713aSLionel Sambuc     } else {
59f4a2713aSLionel Sambuc       ArgInit = InDI->getArg(i-NumDefs);
60f4a2713aSLionel Sambuc       ArgName = InDI->getArgName(i-NumDefs);
61f4a2713aSLionel Sambuc     }
62f4a2713aSLionel Sambuc 
63f4a2713aSLionel Sambuc     DefInit *Arg = dyn_cast<DefInit>(ArgInit);
64f4a2713aSLionel Sambuc     if (!Arg)
65f4a2713aSLionel Sambuc       PrintFatalError("Illegal operand for the '" + R->getName() + "' instruction!");
66f4a2713aSLionel Sambuc 
67f4a2713aSLionel Sambuc     Record *Rec = Arg->getDef();
68f4a2713aSLionel Sambuc     std::string PrintMethod = "printOperand";
69f4a2713aSLionel Sambuc     std::string EncoderMethod;
70f4a2713aSLionel Sambuc     std::string OperandType = "OPERAND_UNKNOWN";
71*0a6a1f1dSLionel Sambuc     std::string OperandNamespace = "MCOI";
72f4a2713aSLionel Sambuc     unsigned NumOps = 1;
73*0a6a1f1dSLionel Sambuc     DagInit *MIOpInfo = nullptr;
74f4a2713aSLionel Sambuc     if (Rec->isSubClassOf("RegisterOperand")) {
75f4a2713aSLionel Sambuc       PrintMethod = Rec->getValueAsString("PrintMethod");
76*0a6a1f1dSLionel Sambuc       OperandType = Rec->getValueAsString("OperandType");
77*0a6a1f1dSLionel Sambuc       OperandNamespace = Rec->getValueAsString("OperandNamespace");
78f4a2713aSLionel Sambuc     } else if (Rec->isSubClassOf("Operand")) {
79f4a2713aSLionel Sambuc       PrintMethod = Rec->getValueAsString("PrintMethod");
80f4a2713aSLionel Sambuc       OperandType = Rec->getValueAsString("OperandType");
81f4a2713aSLionel Sambuc       // If there is an explicit encoder method, use it.
82f4a2713aSLionel Sambuc       EncoderMethod = Rec->getValueAsString("EncoderMethod");
83f4a2713aSLionel Sambuc       MIOpInfo = Rec->getValueAsDag("MIOperandInfo");
84f4a2713aSLionel Sambuc 
85f4a2713aSLionel Sambuc       // Verify that MIOpInfo has an 'ops' root value.
86f4a2713aSLionel Sambuc       if (!isa<DefInit>(MIOpInfo->getOperator()) ||
87f4a2713aSLionel Sambuc           cast<DefInit>(MIOpInfo->getOperator())->getDef()->getName() != "ops")
88f4a2713aSLionel Sambuc         PrintFatalError("Bad value for MIOperandInfo in operand '" + Rec->getName() +
89f4a2713aSLionel Sambuc           "'\n");
90f4a2713aSLionel Sambuc 
91f4a2713aSLionel Sambuc       // If we have MIOpInfo, then we have #operands equal to number of entries
92f4a2713aSLionel Sambuc       // in MIOperandInfo.
93f4a2713aSLionel Sambuc       if (unsigned NumArgs = MIOpInfo->getNumArgs())
94f4a2713aSLionel Sambuc         NumOps = NumArgs;
95f4a2713aSLionel Sambuc 
96f4a2713aSLionel Sambuc       if (Rec->isSubClassOf("PredicateOp"))
97f4a2713aSLionel Sambuc         isPredicable = true;
98f4a2713aSLionel Sambuc       else if (Rec->isSubClassOf("OptionalDefOperand"))
99f4a2713aSLionel Sambuc         hasOptionalDef = true;
100f4a2713aSLionel Sambuc     } else if (Rec->getName() == "variable_ops") {
101f4a2713aSLionel Sambuc       isVariadic = true;
102f4a2713aSLionel Sambuc       continue;
103f4a2713aSLionel Sambuc     } else if (Rec->isSubClassOf("RegisterClass")) {
104f4a2713aSLionel Sambuc       OperandType = "OPERAND_REGISTER";
105f4a2713aSLionel Sambuc     } else if (!Rec->isSubClassOf("PointerLikeRegClass") &&
106f4a2713aSLionel Sambuc                !Rec->isSubClassOf("unknown_class"))
107f4a2713aSLionel Sambuc       PrintFatalError("Unknown operand class '" + Rec->getName() +
108f4a2713aSLionel Sambuc         "' in '" + R->getName() + "' instruction!");
109f4a2713aSLionel Sambuc 
110f4a2713aSLionel Sambuc     // Check that the operand has a name and that it's unique.
111f4a2713aSLionel Sambuc     if (ArgName.empty())
112*0a6a1f1dSLionel Sambuc       PrintFatalError("In instruction '" + R->getName() + "', operand #" +
113*0a6a1f1dSLionel Sambuc                       Twine(i) + " has no name!");
114f4a2713aSLionel Sambuc     if (!OperandNames.insert(ArgName).second)
115*0a6a1f1dSLionel Sambuc       PrintFatalError("In instruction '" + R->getName() + "', operand #" +
116*0a6a1f1dSLionel Sambuc                       Twine(i) + " has the same name as a previous operand!");
117f4a2713aSLionel Sambuc 
118f4a2713aSLionel Sambuc     OperandList.push_back(OperandInfo(Rec, ArgName, PrintMethod, EncoderMethod,
119*0a6a1f1dSLionel Sambuc                                       OperandNamespace + "::" + OperandType,
120*0a6a1f1dSLionel Sambuc 				      MIOperandNo, NumOps, MIOpInfo));
121f4a2713aSLionel Sambuc     MIOperandNo += NumOps;
122f4a2713aSLionel Sambuc   }
123f4a2713aSLionel Sambuc 
124f4a2713aSLionel Sambuc 
125f4a2713aSLionel Sambuc   // Make sure the constraints list for each operand is large enough to hold
126f4a2713aSLionel Sambuc   // constraint info, even if none is present.
127f4a2713aSLionel Sambuc   for (unsigned i = 0, e = OperandList.size(); i != e; ++i)
128f4a2713aSLionel Sambuc     OperandList[i].Constraints.resize(OperandList[i].MINumOperands);
129f4a2713aSLionel Sambuc }
130f4a2713aSLionel Sambuc 
131f4a2713aSLionel Sambuc 
132f4a2713aSLionel Sambuc /// getOperandNamed - Return the index of the operand with the specified
133f4a2713aSLionel Sambuc /// non-empty name.  If the instruction does not have an operand with the
134f4a2713aSLionel Sambuc /// specified name, abort.
135f4a2713aSLionel Sambuc ///
getOperandNamed(StringRef Name) const136f4a2713aSLionel Sambuc unsigned CGIOperandList::getOperandNamed(StringRef Name) const {
137f4a2713aSLionel Sambuc   unsigned OpIdx;
138f4a2713aSLionel Sambuc   if (hasOperandNamed(Name, OpIdx)) return OpIdx;
139*0a6a1f1dSLionel Sambuc   PrintFatalError("'" + TheDef->getName() +
140*0a6a1f1dSLionel Sambuc                   "' does not have an operand named '$" + Name + "'!");
141f4a2713aSLionel Sambuc }
142f4a2713aSLionel Sambuc 
143f4a2713aSLionel Sambuc /// hasOperandNamed - Query whether the instruction has an operand of the
144f4a2713aSLionel Sambuc /// given name. If so, return true and set OpIdx to the index of the
145f4a2713aSLionel Sambuc /// operand. Otherwise, return false.
hasOperandNamed(StringRef Name,unsigned & OpIdx) const146f4a2713aSLionel Sambuc bool CGIOperandList::hasOperandNamed(StringRef Name, unsigned &OpIdx) const {
147f4a2713aSLionel Sambuc   assert(!Name.empty() && "Cannot search for operand with no name!");
148f4a2713aSLionel Sambuc   for (unsigned i = 0, e = OperandList.size(); i != e; ++i)
149f4a2713aSLionel Sambuc     if (OperandList[i].Name == Name) {
150f4a2713aSLionel Sambuc       OpIdx = i;
151f4a2713aSLionel Sambuc       return true;
152f4a2713aSLionel Sambuc     }
153f4a2713aSLionel Sambuc   return false;
154f4a2713aSLionel Sambuc }
155f4a2713aSLionel Sambuc 
156f4a2713aSLionel Sambuc std::pair<unsigned,unsigned>
ParseOperandName(const std::string & Op,bool AllowWholeOp)157f4a2713aSLionel Sambuc CGIOperandList::ParseOperandName(const std::string &Op, bool AllowWholeOp) {
158f4a2713aSLionel Sambuc   if (Op.empty() || Op[0] != '$')
159f4a2713aSLionel Sambuc     PrintFatalError(TheDef->getName() + ": Illegal operand name: '" + Op + "'");
160f4a2713aSLionel Sambuc 
161f4a2713aSLionel Sambuc   std::string OpName = Op.substr(1);
162f4a2713aSLionel Sambuc   std::string SubOpName;
163f4a2713aSLionel Sambuc 
164f4a2713aSLionel Sambuc   // Check to see if this is $foo.bar.
165f4a2713aSLionel Sambuc   std::string::size_type DotIdx = OpName.find_first_of(".");
166f4a2713aSLionel Sambuc   if (DotIdx != std::string::npos) {
167f4a2713aSLionel Sambuc     SubOpName = OpName.substr(DotIdx+1);
168f4a2713aSLionel Sambuc     if (SubOpName.empty())
169f4a2713aSLionel Sambuc       PrintFatalError(TheDef->getName() + ": illegal empty suboperand name in '" +Op +"'");
170f4a2713aSLionel Sambuc     OpName = OpName.substr(0, DotIdx);
171f4a2713aSLionel Sambuc   }
172f4a2713aSLionel Sambuc 
173f4a2713aSLionel Sambuc   unsigned OpIdx = getOperandNamed(OpName);
174f4a2713aSLionel Sambuc 
175f4a2713aSLionel Sambuc   if (SubOpName.empty()) {  // If no suboperand name was specified:
176f4a2713aSLionel Sambuc     // If one was needed, throw.
177f4a2713aSLionel Sambuc     if (OperandList[OpIdx].MINumOperands > 1 && !AllowWholeOp &&
178f4a2713aSLionel Sambuc         SubOpName.empty())
179f4a2713aSLionel Sambuc       PrintFatalError(TheDef->getName() + ": Illegal to refer to"
180f4a2713aSLionel Sambuc         " whole operand part of complex operand '" + Op + "'");
181f4a2713aSLionel Sambuc 
182f4a2713aSLionel Sambuc     // Otherwise, return the operand.
183f4a2713aSLionel Sambuc     return std::make_pair(OpIdx, 0U);
184f4a2713aSLionel Sambuc   }
185f4a2713aSLionel Sambuc 
186f4a2713aSLionel Sambuc   // Find the suboperand number involved.
187f4a2713aSLionel Sambuc   DagInit *MIOpInfo = OperandList[OpIdx].MIOperandInfo;
188*0a6a1f1dSLionel Sambuc   if (!MIOpInfo)
189f4a2713aSLionel Sambuc     PrintFatalError(TheDef->getName() + ": unknown suboperand name in '" + Op + "'");
190f4a2713aSLionel Sambuc 
191f4a2713aSLionel Sambuc   // Find the operand with the right name.
192f4a2713aSLionel Sambuc   for (unsigned i = 0, e = MIOpInfo->getNumArgs(); i != e; ++i)
193f4a2713aSLionel Sambuc     if (MIOpInfo->getArgName(i) == SubOpName)
194f4a2713aSLionel Sambuc       return std::make_pair(OpIdx, i);
195f4a2713aSLionel Sambuc 
196f4a2713aSLionel Sambuc   // Otherwise, didn't find it!
197f4a2713aSLionel Sambuc   PrintFatalError(TheDef->getName() + ": unknown suboperand name in '" + Op + "'");
198f4a2713aSLionel Sambuc   return std::make_pair(0U, 0U);
199f4a2713aSLionel Sambuc }
200f4a2713aSLionel Sambuc 
ParseConstraint(const std::string & CStr,CGIOperandList & Ops)201f4a2713aSLionel Sambuc static void ParseConstraint(const std::string &CStr, CGIOperandList &Ops) {
202f4a2713aSLionel Sambuc   // EARLY_CLOBBER: @early $reg
203f4a2713aSLionel Sambuc   std::string::size_type wpos = CStr.find_first_of(" \t");
204f4a2713aSLionel Sambuc   std::string::size_type start = CStr.find_first_not_of(" \t");
205f4a2713aSLionel Sambuc   std::string Tok = CStr.substr(start, wpos - start);
206f4a2713aSLionel Sambuc   if (Tok == "@earlyclobber") {
207f4a2713aSLionel Sambuc     std::string Name = CStr.substr(wpos+1);
208f4a2713aSLionel Sambuc     wpos = Name.find_first_not_of(" \t");
209f4a2713aSLionel Sambuc     if (wpos == std::string::npos)
210f4a2713aSLionel Sambuc       PrintFatalError("Illegal format for @earlyclobber constraint: '" + CStr + "'");
211f4a2713aSLionel Sambuc     Name = Name.substr(wpos);
212f4a2713aSLionel Sambuc     std::pair<unsigned,unsigned> Op = Ops.ParseOperandName(Name, false);
213f4a2713aSLionel Sambuc 
214f4a2713aSLionel Sambuc     // Build the string for the operand
215f4a2713aSLionel Sambuc     if (!Ops[Op.first].Constraints[Op.second].isNone())
216f4a2713aSLionel Sambuc       PrintFatalError("Operand '" + Name + "' cannot have multiple constraints!");
217f4a2713aSLionel Sambuc     Ops[Op.first].Constraints[Op.second] =
218f4a2713aSLionel Sambuc     CGIOperandList::ConstraintInfo::getEarlyClobber();
219f4a2713aSLionel Sambuc     return;
220f4a2713aSLionel Sambuc   }
221f4a2713aSLionel Sambuc 
222f4a2713aSLionel Sambuc   // Only other constraint is "TIED_TO" for now.
223f4a2713aSLionel Sambuc   std::string::size_type pos = CStr.find_first_of('=');
224f4a2713aSLionel Sambuc   assert(pos != std::string::npos && "Unrecognized constraint");
225f4a2713aSLionel Sambuc   start = CStr.find_first_not_of(" \t");
226f4a2713aSLionel Sambuc   std::string Name = CStr.substr(start, pos - start);
227f4a2713aSLionel Sambuc 
228f4a2713aSLionel Sambuc   // TIED_TO: $src1 = $dst
229f4a2713aSLionel Sambuc   wpos = Name.find_first_of(" \t");
230f4a2713aSLionel Sambuc   if (wpos == std::string::npos)
231f4a2713aSLionel Sambuc     PrintFatalError("Illegal format for tied-to constraint: '" + CStr + "'");
232f4a2713aSLionel Sambuc   std::string DestOpName = Name.substr(0, wpos);
233f4a2713aSLionel Sambuc   std::pair<unsigned,unsigned> DestOp = Ops.ParseOperandName(DestOpName, false);
234f4a2713aSLionel Sambuc 
235f4a2713aSLionel Sambuc   Name = CStr.substr(pos+1);
236f4a2713aSLionel Sambuc   wpos = Name.find_first_not_of(" \t");
237f4a2713aSLionel Sambuc   if (wpos == std::string::npos)
238f4a2713aSLionel Sambuc     PrintFatalError("Illegal format for tied-to constraint: '" + CStr + "'");
239f4a2713aSLionel Sambuc 
240f4a2713aSLionel Sambuc   std::string SrcOpName = Name.substr(wpos);
241f4a2713aSLionel Sambuc   std::pair<unsigned,unsigned> SrcOp = Ops.ParseOperandName(SrcOpName, false);
242f4a2713aSLionel Sambuc   if (SrcOp > DestOp) {
243f4a2713aSLionel Sambuc     std::swap(SrcOp, DestOp);
244f4a2713aSLionel Sambuc     std::swap(SrcOpName, DestOpName);
245f4a2713aSLionel Sambuc   }
246f4a2713aSLionel Sambuc 
247f4a2713aSLionel Sambuc   unsigned FlatOpNo = Ops.getFlattenedOperandNumber(SrcOp);
248f4a2713aSLionel Sambuc 
249f4a2713aSLionel Sambuc   if (!Ops[DestOp.first].Constraints[DestOp.second].isNone())
250f4a2713aSLionel Sambuc     PrintFatalError("Operand '" + DestOpName +
251f4a2713aSLionel Sambuc       "' cannot have multiple constraints!");
252f4a2713aSLionel Sambuc   Ops[DestOp.first].Constraints[DestOp.second] =
253f4a2713aSLionel Sambuc     CGIOperandList::ConstraintInfo::getTied(FlatOpNo);
254f4a2713aSLionel Sambuc }
255f4a2713aSLionel Sambuc 
ParseConstraints(const std::string & CStr,CGIOperandList & Ops)256f4a2713aSLionel Sambuc static void ParseConstraints(const std::string &CStr, CGIOperandList &Ops) {
257f4a2713aSLionel Sambuc   if (CStr.empty()) return;
258f4a2713aSLionel Sambuc 
259f4a2713aSLionel Sambuc   const std::string delims(",");
260f4a2713aSLionel Sambuc   std::string::size_type bidx, eidx;
261f4a2713aSLionel Sambuc 
262f4a2713aSLionel Sambuc   bidx = CStr.find_first_not_of(delims);
263f4a2713aSLionel Sambuc   while (bidx != std::string::npos) {
264f4a2713aSLionel Sambuc     eidx = CStr.find_first_of(delims, bidx);
265f4a2713aSLionel Sambuc     if (eidx == std::string::npos)
266f4a2713aSLionel Sambuc       eidx = CStr.length();
267f4a2713aSLionel Sambuc 
268f4a2713aSLionel Sambuc     ParseConstraint(CStr.substr(bidx, eidx - bidx), Ops);
269f4a2713aSLionel Sambuc     bidx = CStr.find_first_not_of(delims, eidx);
270f4a2713aSLionel Sambuc   }
271f4a2713aSLionel Sambuc }
272f4a2713aSLionel Sambuc 
ProcessDisableEncoding(std::string DisableEncoding)273f4a2713aSLionel Sambuc void CGIOperandList::ProcessDisableEncoding(std::string DisableEncoding) {
274f4a2713aSLionel Sambuc   while (1) {
275f4a2713aSLionel Sambuc     std::pair<StringRef, StringRef> P = getToken(DisableEncoding, " ,\t");
276f4a2713aSLionel Sambuc     std::string OpName = P.first;
277f4a2713aSLionel Sambuc     DisableEncoding = P.second;
278f4a2713aSLionel Sambuc     if (OpName.empty()) break;
279f4a2713aSLionel Sambuc 
280f4a2713aSLionel Sambuc     // Figure out which operand this is.
281f4a2713aSLionel Sambuc     std::pair<unsigned,unsigned> Op = ParseOperandName(OpName, false);
282f4a2713aSLionel Sambuc 
283f4a2713aSLionel Sambuc     // Mark the operand as not-to-be encoded.
284f4a2713aSLionel Sambuc     if (Op.second >= OperandList[Op.first].DoNotEncode.size())
285f4a2713aSLionel Sambuc       OperandList[Op.first].DoNotEncode.resize(Op.second+1);
286f4a2713aSLionel Sambuc     OperandList[Op.first].DoNotEncode[Op.second] = true;
287f4a2713aSLionel Sambuc   }
288f4a2713aSLionel Sambuc 
289f4a2713aSLionel Sambuc }
290f4a2713aSLionel Sambuc 
291f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
292f4a2713aSLionel Sambuc // CodeGenInstruction Implementation
293f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
294f4a2713aSLionel Sambuc 
CodeGenInstruction(Record * R)295f4a2713aSLionel Sambuc CodeGenInstruction::CodeGenInstruction(Record *R)
296*0a6a1f1dSLionel Sambuc   : TheDef(R), Operands(R), InferredFrom(nullptr) {
297f4a2713aSLionel Sambuc   Namespace = R->getValueAsString("Namespace");
298f4a2713aSLionel Sambuc   AsmString = R->getValueAsString("AsmString");
299f4a2713aSLionel Sambuc 
300f4a2713aSLionel Sambuc   isReturn     = R->getValueAsBit("isReturn");
301f4a2713aSLionel Sambuc   isBranch     = R->getValueAsBit("isBranch");
302f4a2713aSLionel Sambuc   isIndirectBranch = R->getValueAsBit("isIndirectBranch");
303f4a2713aSLionel Sambuc   isCompare    = R->getValueAsBit("isCompare");
304f4a2713aSLionel Sambuc   isMoveImm    = R->getValueAsBit("isMoveImm");
305f4a2713aSLionel Sambuc   isBitcast    = R->getValueAsBit("isBitcast");
306f4a2713aSLionel Sambuc   isSelect     = R->getValueAsBit("isSelect");
307f4a2713aSLionel Sambuc   isBarrier    = R->getValueAsBit("isBarrier");
308f4a2713aSLionel Sambuc   isCall       = R->getValueAsBit("isCall");
309f4a2713aSLionel Sambuc   canFoldAsLoad = R->getValueAsBit("canFoldAsLoad");
310f4a2713aSLionel Sambuc   isPredicable = Operands.isPredicable || R->getValueAsBit("isPredicable");
311f4a2713aSLionel Sambuc   isConvertibleToThreeAddress = R->getValueAsBit("isConvertibleToThreeAddress");
312f4a2713aSLionel Sambuc   isCommutable = R->getValueAsBit("isCommutable");
313f4a2713aSLionel Sambuc   isTerminator = R->getValueAsBit("isTerminator");
314f4a2713aSLionel Sambuc   isReMaterializable = R->getValueAsBit("isReMaterializable");
315f4a2713aSLionel Sambuc   hasDelaySlot = R->getValueAsBit("hasDelaySlot");
316f4a2713aSLionel Sambuc   usesCustomInserter = R->getValueAsBit("usesCustomInserter");
317f4a2713aSLionel Sambuc   hasPostISelHook = R->getValueAsBit("hasPostISelHook");
318f4a2713aSLionel Sambuc   hasCtrlDep   = R->getValueAsBit("hasCtrlDep");
319f4a2713aSLionel Sambuc   isNotDuplicable = R->getValueAsBit("isNotDuplicable");
320*0a6a1f1dSLionel Sambuc   isRegSequence = R->getValueAsBit("isRegSequence");
321*0a6a1f1dSLionel Sambuc   isExtractSubreg = R->getValueAsBit("isExtractSubreg");
322*0a6a1f1dSLionel Sambuc   isInsertSubreg = R->getValueAsBit("isInsertSubreg");
323f4a2713aSLionel Sambuc 
324*0a6a1f1dSLionel Sambuc   bool Unset;
325*0a6a1f1dSLionel Sambuc   mayLoad      = R->getValueAsBitOrUnset("mayLoad", Unset);
326*0a6a1f1dSLionel Sambuc   mayLoad_Unset = Unset;
327*0a6a1f1dSLionel Sambuc   mayStore     = R->getValueAsBitOrUnset("mayStore", Unset);
328*0a6a1f1dSLionel Sambuc   mayStore_Unset = Unset;
329*0a6a1f1dSLionel Sambuc   hasSideEffects = R->getValueAsBitOrUnset("hasSideEffects", Unset);
330*0a6a1f1dSLionel Sambuc   hasSideEffects_Unset = Unset;
331f4a2713aSLionel Sambuc 
332f4a2713aSLionel Sambuc   isAsCheapAsAMove = R->getValueAsBit("isAsCheapAsAMove");
333f4a2713aSLionel Sambuc   hasExtraSrcRegAllocReq = R->getValueAsBit("hasExtraSrcRegAllocReq");
334f4a2713aSLionel Sambuc   hasExtraDefRegAllocReq = R->getValueAsBit("hasExtraDefRegAllocReq");
335f4a2713aSLionel Sambuc   isCodeGenOnly = R->getValueAsBit("isCodeGenOnly");
336f4a2713aSLionel Sambuc   isPseudo = R->getValueAsBit("isPseudo");
337f4a2713aSLionel Sambuc   ImplicitDefs = R->getValueAsListOfDefs("Defs");
338f4a2713aSLionel Sambuc   ImplicitUses = R->getValueAsListOfDefs("Uses");
339f4a2713aSLionel Sambuc 
340f4a2713aSLionel Sambuc   // Parse Constraints.
341f4a2713aSLionel Sambuc   ParseConstraints(R->getValueAsString("Constraints"), Operands);
342f4a2713aSLionel Sambuc 
343f4a2713aSLionel Sambuc   // Parse the DisableEncoding field.
344f4a2713aSLionel Sambuc   Operands.ProcessDisableEncoding(R->getValueAsString("DisableEncoding"));
345f4a2713aSLionel Sambuc 
346f4a2713aSLionel Sambuc   // First check for a ComplexDeprecationPredicate.
347f4a2713aSLionel Sambuc   if (R->getValue("ComplexDeprecationPredicate")) {
348f4a2713aSLionel Sambuc     HasComplexDeprecationPredicate = true;
349f4a2713aSLionel Sambuc     DeprecatedReason = R->getValueAsString("ComplexDeprecationPredicate");
350f4a2713aSLionel Sambuc   } else if (RecordVal *Dep = R->getValue("DeprecatedFeatureMask")) {
351f4a2713aSLionel Sambuc     // Check if we have a Subtarget feature mask.
352f4a2713aSLionel Sambuc     HasComplexDeprecationPredicate = false;
353f4a2713aSLionel Sambuc     DeprecatedReason = Dep->getValue()->getAsString();
354f4a2713aSLionel Sambuc   } else {
355f4a2713aSLionel Sambuc     // This instruction isn't deprecated.
356f4a2713aSLionel Sambuc     HasComplexDeprecationPredicate = false;
357f4a2713aSLionel Sambuc     DeprecatedReason = "";
358f4a2713aSLionel Sambuc   }
359f4a2713aSLionel Sambuc }
360f4a2713aSLionel Sambuc 
361f4a2713aSLionel Sambuc /// HasOneImplicitDefWithKnownVT - If the instruction has at least one
362f4a2713aSLionel Sambuc /// implicit def and it has a known VT, return the VT, otherwise return
363f4a2713aSLionel Sambuc /// MVT::Other.
364f4a2713aSLionel Sambuc MVT::SimpleValueType CodeGenInstruction::
HasOneImplicitDefWithKnownVT(const CodeGenTarget & TargetInfo) const365f4a2713aSLionel Sambuc HasOneImplicitDefWithKnownVT(const CodeGenTarget &TargetInfo) const {
366f4a2713aSLionel Sambuc   if (ImplicitDefs.empty()) return MVT::Other;
367f4a2713aSLionel Sambuc 
368f4a2713aSLionel Sambuc   // Check to see if the first implicit def has a resolvable type.
369f4a2713aSLionel Sambuc   Record *FirstImplicitDef = ImplicitDefs[0];
370f4a2713aSLionel Sambuc   assert(FirstImplicitDef->isSubClassOf("Register"));
371f4a2713aSLionel Sambuc   const std::vector<MVT::SimpleValueType> &RegVTs =
372f4a2713aSLionel Sambuc     TargetInfo.getRegisterVTs(FirstImplicitDef);
373f4a2713aSLionel Sambuc   if (RegVTs.size() == 1)
374f4a2713aSLionel Sambuc     return RegVTs[0];
375f4a2713aSLionel Sambuc   return MVT::Other;
376f4a2713aSLionel Sambuc }
377f4a2713aSLionel Sambuc 
378f4a2713aSLionel Sambuc 
379f4a2713aSLionel Sambuc /// FlattenAsmStringVariants - Flatten the specified AsmString to only
380f4a2713aSLionel Sambuc /// include text from the specified variant, returning the new string.
381f4a2713aSLionel Sambuc std::string CodeGenInstruction::
FlattenAsmStringVariants(StringRef Cur,unsigned Variant)382f4a2713aSLionel Sambuc FlattenAsmStringVariants(StringRef Cur, unsigned Variant) {
383f4a2713aSLionel Sambuc   std::string Res = "";
384f4a2713aSLionel Sambuc 
385f4a2713aSLionel Sambuc   for (;;) {
386f4a2713aSLionel Sambuc     // Find the start of the next variant string.
387f4a2713aSLionel Sambuc     size_t VariantsStart = 0;
388f4a2713aSLionel Sambuc     for (size_t e = Cur.size(); VariantsStart != e; ++VariantsStart)
389f4a2713aSLionel Sambuc       if (Cur[VariantsStart] == '{' &&
390f4a2713aSLionel Sambuc           (VariantsStart == 0 || (Cur[VariantsStart-1] != '$' &&
391f4a2713aSLionel Sambuc                                   Cur[VariantsStart-1] != '\\')))
392f4a2713aSLionel Sambuc         break;
393f4a2713aSLionel Sambuc 
394f4a2713aSLionel Sambuc     // Add the prefix to the result.
395f4a2713aSLionel Sambuc     Res += Cur.slice(0, VariantsStart);
396f4a2713aSLionel Sambuc     if (VariantsStart == Cur.size())
397f4a2713aSLionel Sambuc       break;
398f4a2713aSLionel Sambuc 
399f4a2713aSLionel Sambuc     ++VariantsStart; // Skip the '{'.
400f4a2713aSLionel Sambuc 
401f4a2713aSLionel Sambuc     // Scan to the end of the variants string.
402f4a2713aSLionel Sambuc     size_t VariantsEnd = VariantsStart;
403f4a2713aSLionel Sambuc     unsigned NestedBraces = 1;
404f4a2713aSLionel Sambuc     for (size_t e = Cur.size(); VariantsEnd != e; ++VariantsEnd) {
405f4a2713aSLionel Sambuc       if (Cur[VariantsEnd] == '}' && Cur[VariantsEnd-1] != '\\') {
406f4a2713aSLionel Sambuc         if (--NestedBraces == 0)
407f4a2713aSLionel Sambuc           break;
408f4a2713aSLionel Sambuc       } else if (Cur[VariantsEnd] == '{')
409f4a2713aSLionel Sambuc         ++NestedBraces;
410f4a2713aSLionel Sambuc     }
411f4a2713aSLionel Sambuc 
412f4a2713aSLionel Sambuc     // Select the Nth variant (or empty).
413f4a2713aSLionel Sambuc     StringRef Selection = Cur.slice(VariantsStart, VariantsEnd);
414f4a2713aSLionel Sambuc     for (unsigned i = 0; i != Variant; ++i)
415f4a2713aSLionel Sambuc       Selection = Selection.split('|').second;
416f4a2713aSLionel Sambuc     Res += Selection.split('|').first;
417f4a2713aSLionel Sambuc 
418f4a2713aSLionel Sambuc     assert(VariantsEnd != Cur.size() &&
419f4a2713aSLionel Sambuc            "Unterminated variants in assembly string!");
420f4a2713aSLionel Sambuc     Cur = Cur.substr(VariantsEnd + 1);
421f4a2713aSLionel Sambuc   }
422f4a2713aSLionel Sambuc 
423f4a2713aSLionel Sambuc   return Res;
424f4a2713aSLionel Sambuc }
425f4a2713aSLionel Sambuc 
426f4a2713aSLionel Sambuc 
427f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
428f4a2713aSLionel Sambuc /// CodeGenInstAlias Implementation
429f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
430f4a2713aSLionel Sambuc 
431f4a2713aSLionel Sambuc /// tryAliasOpMatch - This is a helper function for the CodeGenInstAlias
432f4a2713aSLionel Sambuc /// constructor.  It checks if an argument in an InstAlias pattern matches
433f4a2713aSLionel Sambuc /// the corresponding operand of the instruction.  It returns true on a
434f4a2713aSLionel Sambuc /// successful match, with ResOp set to the result operand to be used.
tryAliasOpMatch(DagInit * Result,unsigned AliasOpNo,Record * InstOpRec,bool hasSubOps,ArrayRef<SMLoc> Loc,CodeGenTarget & T,ResultOperand & ResOp)435f4a2713aSLionel Sambuc bool CodeGenInstAlias::tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo,
436f4a2713aSLionel Sambuc                                        Record *InstOpRec, bool hasSubOps,
437f4a2713aSLionel Sambuc                                        ArrayRef<SMLoc> Loc, CodeGenTarget &T,
438f4a2713aSLionel Sambuc                                        ResultOperand &ResOp) {
439f4a2713aSLionel Sambuc   Init *Arg = Result->getArg(AliasOpNo);
440f4a2713aSLionel Sambuc   DefInit *ADI = dyn_cast<DefInit>(Arg);
441*0a6a1f1dSLionel Sambuc   Record *ResultRecord = ADI ? ADI->getDef() : nullptr;
442f4a2713aSLionel Sambuc 
443f4a2713aSLionel Sambuc   if (ADI && ADI->getDef() == InstOpRec) {
444f4a2713aSLionel Sambuc     // If the operand is a record, it must have a name, and the record type
445f4a2713aSLionel Sambuc     // must match up with the instruction's argument type.
446f4a2713aSLionel Sambuc     if (Result->getArgName(AliasOpNo).empty())
447*0a6a1f1dSLionel Sambuc       PrintFatalError(Loc, "result argument #" + Twine(AliasOpNo) +
448f4a2713aSLionel Sambuc                            " must have a name!");
449*0a6a1f1dSLionel Sambuc     ResOp = ResultOperand(Result->getArgName(AliasOpNo), ResultRecord);
450f4a2713aSLionel Sambuc     return true;
451f4a2713aSLionel Sambuc   }
452f4a2713aSLionel Sambuc 
453f4a2713aSLionel Sambuc   // For register operands, the source register class can be a subclass
454f4a2713aSLionel Sambuc   // of the instruction register class, not just an exact match.
455*0a6a1f1dSLionel Sambuc   if (InstOpRec->isSubClassOf("RegisterOperand"))
456*0a6a1f1dSLionel Sambuc     InstOpRec = InstOpRec->getValueAsDef("RegClass");
457*0a6a1f1dSLionel Sambuc 
458*0a6a1f1dSLionel Sambuc   if (ADI && ADI->getDef()->isSubClassOf("RegisterOperand"))
459*0a6a1f1dSLionel Sambuc     ADI = ADI->getDef()->getValueAsDef("RegClass")->getDefInit();
460*0a6a1f1dSLionel Sambuc 
461f4a2713aSLionel Sambuc   if (ADI && ADI->getDef()->isSubClassOf("RegisterClass")) {
462f4a2713aSLionel Sambuc     if (!InstOpRec->isSubClassOf("RegisterClass"))
463f4a2713aSLionel Sambuc       return false;
464f4a2713aSLionel Sambuc     if (!T.getRegisterClass(InstOpRec)
465f4a2713aSLionel Sambuc               .hasSubClass(&T.getRegisterClass(ADI->getDef())))
466f4a2713aSLionel Sambuc       return false;
467*0a6a1f1dSLionel Sambuc     ResOp = ResultOperand(Result->getArgName(AliasOpNo), ResultRecord);
468f4a2713aSLionel Sambuc     return true;
469f4a2713aSLionel Sambuc   }
470f4a2713aSLionel Sambuc 
471f4a2713aSLionel Sambuc   // Handle explicit registers.
472f4a2713aSLionel Sambuc   if (ADI && ADI->getDef()->isSubClassOf("Register")) {
473f4a2713aSLionel Sambuc     if (InstOpRec->isSubClassOf("OptionalDefOperand")) {
474f4a2713aSLionel Sambuc       DagInit *DI = InstOpRec->getValueAsDag("MIOperandInfo");
475f4a2713aSLionel Sambuc       // The operand info should only have a single (register) entry. We
476f4a2713aSLionel Sambuc       // want the register class of it.
477f4a2713aSLionel Sambuc       InstOpRec = cast<DefInit>(DI->getArg(0))->getDef();
478f4a2713aSLionel Sambuc     }
479f4a2713aSLionel Sambuc 
480f4a2713aSLionel Sambuc     if (!InstOpRec->isSubClassOf("RegisterClass"))
481f4a2713aSLionel Sambuc       return false;
482f4a2713aSLionel Sambuc 
483f4a2713aSLionel Sambuc     if (!T.getRegisterClass(InstOpRec)
484f4a2713aSLionel Sambuc         .contains(T.getRegBank().getReg(ADI->getDef())))
485f4a2713aSLionel Sambuc       PrintFatalError(Loc, "fixed register " + ADI->getDef()->getName() +
486f4a2713aSLionel Sambuc                       " is not a member of the " + InstOpRec->getName() +
487f4a2713aSLionel Sambuc                       " register class!");
488f4a2713aSLionel Sambuc 
489f4a2713aSLionel Sambuc     if (!Result->getArgName(AliasOpNo).empty())
490f4a2713aSLionel Sambuc       PrintFatalError(Loc, "result fixed register argument must "
491f4a2713aSLionel Sambuc                       "not have a name!");
492f4a2713aSLionel Sambuc 
493*0a6a1f1dSLionel Sambuc     ResOp = ResultOperand(ResultRecord);
494f4a2713aSLionel Sambuc     return true;
495f4a2713aSLionel Sambuc   }
496f4a2713aSLionel Sambuc 
497f4a2713aSLionel Sambuc   // Handle "zero_reg" for optional def operands.
498f4a2713aSLionel Sambuc   if (ADI && ADI->getDef()->getName() == "zero_reg") {
499f4a2713aSLionel Sambuc 
500f4a2713aSLionel Sambuc     // Check if this is an optional def.
501f4a2713aSLionel Sambuc     // Tied operands where the source is a sub-operand of a complex operand
502f4a2713aSLionel Sambuc     // need to represent both operands in the alias destination instruction.
503f4a2713aSLionel Sambuc     // Allow zero_reg for the tied portion. This can and should go away once
504f4a2713aSLionel Sambuc     // the MC representation of things doesn't use tied operands at all.
505f4a2713aSLionel Sambuc     //if (!InstOpRec->isSubClassOf("OptionalDefOperand"))
506f4a2713aSLionel Sambuc     //  throw TGError(Loc, "reg0 used for result that is not an "
507f4a2713aSLionel Sambuc     //                "OptionalDefOperand!");
508f4a2713aSLionel Sambuc 
509*0a6a1f1dSLionel Sambuc     ResOp = ResultOperand(static_cast<Record*>(nullptr));
510f4a2713aSLionel Sambuc     return true;
511f4a2713aSLionel Sambuc   }
512f4a2713aSLionel Sambuc 
513f4a2713aSLionel Sambuc   // Literal integers.
514f4a2713aSLionel Sambuc   if (IntInit *II = dyn_cast<IntInit>(Arg)) {
515f4a2713aSLionel Sambuc     if (hasSubOps || !InstOpRec->isSubClassOf("Operand"))
516f4a2713aSLionel Sambuc       return false;
517f4a2713aSLionel Sambuc     // Integer arguments can't have names.
518f4a2713aSLionel Sambuc     if (!Result->getArgName(AliasOpNo).empty())
519*0a6a1f1dSLionel Sambuc       PrintFatalError(Loc, "result argument #" + Twine(AliasOpNo) +
520f4a2713aSLionel Sambuc                       " must not have a name!");
521f4a2713aSLionel Sambuc     ResOp = ResultOperand(II->getValue());
522f4a2713aSLionel Sambuc     return true;
523f4a2713aSLionel Sambuc   }
524f4a2713aSLionel Sambuc 
525*0a6a1f1dSLionel Sambuc   // Bits<n> (also used for 0bxx literals)
526*0a6a1f1dSLionel Sambuc   if (BitsInit *BI = dyn_cast<BitsInit>(Arg)) {
527*0a6a1f1dSLionel Sambuc     if (hasSubOps || !InstOpRec->isSubClassOf("Operand"))
528*0a6a1f1dSLionel Sambuc       return false;
529*0a6a1f1dSLionel Sambuc     if (!BI->isComplete())
530*0a6a1f1dSLionel Sambuc       return false;
531*0a6a1f1dSLionel Sambuc     // Convert the bits init to an integer and use that for the result.
532*0a6a1f1dSLionel Sambuc     IntInit *II =
533*0a6a1f1dSLionel Sambuc       dyn_cast_or_null<IntInit>(BI->convertInitializerTo(IntRecTy::get()));
534*0a6a1f1dSLionel Sambuc     if (!II)
535*0a6a1f1dSLionel Sambuc       return false;
536*0a6a1f1dSLionel Sambuc     ResOp = ResultOperand(II->getValue());
537*0a6a1f1dSLionel Sambuc     return true;
538*0a6a1f1dSLionel Sambuc   }
539*0a6a1f1dSLionel Sambuc 
540f4a2713aSLionel Sambuc   // If both are Operands with the same MVT, allow the conversion. It's
541f4a2713aSLionel Sambuc   // up to the user to make sure the values are appropriate, just like
542f4a2713aSLionel Sambuc   // for isel Pat's.
543*0a6a1f1dSLionel Sambuc   if (InstOpRec->isSubClassOf("Operand") && ADI &&
544f4a2713aSLionel Sambuc       ADI->getDef()->isSubClassOf("Operand")) {
545f4a2713aSLionel Sambuc     // FIXME: What other attributes should we check here? Identical
546f4a2713aSLionel Sambuc     // MIOperandInfo perhaps?
547f4a2713aSLionel Sambuc     if (InstOpRec->getValueInit("Type") != ADI->getDef()->getValueInit("Type"))
548f4a2713aSLionel Sambuc       return false;
549f4a2713aSLionel Sambuc     ResOp = ResultOperand(Result->getArgName(AliasOpNo), ADI->getDef());
550f4a2713aSLionel Sambuc     return true;
551f4a2713aSLionel Sambuc   }
552f4a2713aSLionel Sambuc 
553f4a2713aSLionel Sambuc   return false;
554f4a2713aSLionel Sambuc }
555f4a2713aSLionel Sambuc 
getMINumOperands() const556*0a6a1f1dSLionel Sambuc unsigned CodeGenInstAlias::ResultOperand::getMINumOperands() const {
557*0a6a1f1dSLionel Sambuc   if (!isRecord())
558*0a6a1f1dSLionel Sambuc     return 1;
559*0a6a1f1dSLionel Sambuc 
560*0a6a1f1dSLionel Sambuc   Record *Rec = getRecord();
561*0a6a1f1dSLionel Sambuc   if (!Rec->isSubClassOf("Operand"))
562*0a6a1f1dSLionel Sambuc     return 1;
563*0a6a1f1dSLionel Sambuc 
564*0a6a1f1dSLionel Sambuc   DagInit *MIOpInfo = Rec->getValueAsDag("MIOperandInfo");
565*0a6a1f1dSLionel Sambuc   if (MIOpInfo->getNumArgs() == 0) {
566*0a6a1f1dSLionel Sambuc     // Unspecified, so it defaults to 1
567*0a6a1f1dSLionel Sambuc     return 1;
568*0a6a1f1dSLionel Sambuc   }
569*0a6a1f1dSLionel Sambuc 
570*0a6a1f1dSLionel Sambuc   return MIOpInfo->getNumArgs();
571*0a6a1f1dSLionel Sambuc }
572*0a6a1f1dSLionel Sambuc 
CodeGenInstAlias(Record * R,unsigned Variant,CodeGenTarget & T)573*0a6a1f1dSLionel Sambuc CodeGenInstAlias::CodeGenInstAlias(Record *R, unsigned Variant,
574*0a6a1f1dSLionel Sambuc                                    CodeGenTarget &T)
575*0a6a1f1dSLionel Sambuc     : TheDef(R) {
576f4a2713aSLionel Sambuc   Result = R->getValueAsDag("ResultInst");
577*0a6a1f1dSLionel Sambuc   AsmString = R->getValueAsString("AsmString");
578*0a6a1f1dSLionel Sambuc   AsmString = CodeGenInstruction::FlattenAsmStringVariants(AsmString, Variant);
579*0a6a1f1dSLionel Sambuc 
580f4a2713aSLionel Sambuc 
581f4a2713aSLionel Sambuc   // Verify that the root of the result is an instruction.
582f4a2713aSLionel Sambuc   DefInit *DI = dyn_cast<DefInit>(Result->getOperator());
583*0a6a1f1dSLionel Sambuc   if (!DI || !DI->getDef()->isSubClassOf("Instruction"))
584f4a2713aSLionel Sambuc     PrintFatalError(R->getLoc(),
585f4a2713aSLionel Sambuc                     "result of inst alias should be an instruction");
586f4a2713aSLionel Sambuc 
587f4a2713aSLionel Sambuc   ResultInst = &T.getInstruction(DI->getDef());
588f4a2713aSLionel Sambuc 
589f4a2713aSLionel Sambuc   // NameClass - If argument names are repeated, we need to verify they have
590f4a2713aSLionel Sambuc   // the same class.
591f4a2713aSLionel Sambuc   StringMap<Record*> NameClass;
592f4a2713aSLionel Sambuc   for (unsigned i = 0, e = Result->getNumArgs(); i != e; ++i) {
593f4a2713aSLionel Sambuc     DefInit *ADI = dyn_cast<DefInit>(Result->getArg(i));
594f4a2713aSLionel Sambuc     if (!ADI || Result->getArgName(i).empty())
595f4a2713aSLionel Sambuc       continue;
596f4a2713aSLionel Sambuc     // Verify we don't have something like: (someinst GR16:$foo, GR32:$foo)
597f4a2713aSLionel Sambuc     // $foo can exist multiple times in the result list, but it must have the
598f4a2713aSLionel Sambuc     // same type.
599f4a2713aSLionel Sambuc     Record *&Entry = NameClass[Result->getArgName(i)];
600f4a2713aSLionel Sambuc     if (Entry && Entry != ADI->getDef())
601f4a2713aSLionel Sambuc       PrintFatalError(R->getLoc(), "result value $" + Result->getArgName(i) +
602f4a2713aSLionel Sambuc                       " is both " + Entry->getName() + " and " +
603f4a2713aSLionel Sambuc                       ADI->getDef()->getName() + "!");
604f4a2713aSLionel Sambuc     Entry = ADI->getDef();
605f4a2713aSLionel Sambuc   }
606f4a2713aSLionel Sambuc 
607f4a2713aSLionel Sambuc   // Decode and validate the arguments of the result.
608f4a2713aSLionel Sambuc   unsigned AliasOpNo = 0;
609f4a2713aSLionel Sambuc   for (unsigned i = 0, e = ResultInst->Operands.size(); i != e; ++i) {
610f4a2713aSLionel Sambuc 
611f4a2713aSLionel Sambuc     // Tied registers don't have an entry in the result dag unless they're part
612f4a2713aSLionel Sambuc     // of a complex operand, in which case we include them anyways, as we
613f4a2713aSLionel Sambuc     // don't have any other way to specify the whole operand.
614f4a2713aSLionel Sambuc     if (ResultInst->Operands[i].MINumOperands == 1 &&
615f4a2713aSLionel Sambuc         ResultInst->Operands[i].getTiedRegister() != -1)
616f4a2713aSLionel Sambuc       continue;
617f4a2713aSLionel Sambuc 
618f4a2713aSLionel Sambuc     if (AliasOpNo >= Result->getNumArgs())
619f4a2713aSLionel Sambuc       PrintFatalError(R->getLoc(), "not enough arguments for instruction!");
620f4a2713aSLionel Sambuc 
621f4a2713aSLionel Sambuc     Record *InstOpRec = ResultInst->Operands[i].Rec;
622f4a2713aSLionel Sambuc     unsigned NumSubOps = ResultInst->Operands[i].MINumOperands;
623f4a2713aSLionel Sambuc     ResultOperand ResOp(static_cast<int64_t>(0));
624f4a2713aSLionel Sambuc     if (tryAliasOpMatch(Result, AliasOpNo, InstOpRec, (NumSubOps > 1),
625f4a2713aSLionel Sambuc                         R->getLoc(), T, ResOp)) {
626f4a2713aSLionel Sambuc       // If this is a simple operand, or a complex operand with a custom match
627f4a2713aSLionel Sambuc       // class, then we can match is verbatim.
628f4a2713aSLionel Sambuc       if (NumSubOps == 1 ||
629f4a2713aSLionel Sambuc           (InstOpRec->getValue("ParserMatchClass") &&
630f4a2713aSLionel Sambuc            InstOpRec->getValueAsDef("ParserMatchClass")
631f4a2713aSLionel Sambuc              ->getValueAsString("Name") != "Imm")) {
632f4a2713aSLionel Sambuc         ResultOperands.push_back(ResOp);
633f4a2713aSLionel Sambuc         ResultInstOperandIndex.push_back(std::make_pair(i, -1));
634f4a2713aSLionel Sambuc         ++AliasOpNo;
635f4a2713aSLionel Sambuc 
636f4a2713aSLionel Sambuc       // Otherwise, we need to match each of the suboperands individually.
637f4a2713aSLionel Sambuc       } else {
638f4a2713aSLionel Sambuc          DagInit *MIOI = ResultInst->Operands[i].MIOperandInfo;
639f4a2713aSLionel Sambuc          for (unsigned SubOp = 0; SubOp != NumSubOps; ++SubOp) {
640f4a2713aSLionel Sambuc           Record *SubRec = cast<DefInit>(MIOI->getArg(SubOp))->getDef();
641f4a2713aSLionel Sambuc 
642f4a2713aSLionel Sambuc           // Take care to instantiate each of the suboperands with the correct
643f4a2713aSLionel Sambuc           // nomenclature: $foo.bar
644f4a2713aSLionel Sambuc           ResultOperands.push_back(
645f4a2713aSLionel Sambuc               ResultOperand(Result->getArgName(AliasOpNo) + "." +
646f4a2713aSLionel Sambuc                             MIOI->getArgName(SubOp), SubRec));
647f4a2713aSLionel Sambuc           ResultInstOperandIndex.push_back(std::make_pair(i, SubOp));
648f4a2713aSLionel Sambuc          }
649f4a2713aSLionel Sambuc          ++AliasOpNo;
650f4a2713aSLionel Sambuc       }
651f4a2713aSLionel Sambuc       continue;
652f4a2713aSLionel Sambuc     }
653f4a2713aSLionel Sambuc 
654f4a2713aSLionel Sambuc     // If the argument did not match the instruction operand, and the operand
655f4a2713aSLionel Sambuc     // is composed of multiple suboperands, try matching the suboperands.
656f4a2713aSLionel Sambuc     if (NumSubOps > 1) {
657f4a2713aSLionel Sambuc       DagInit *MIOI = ResultInst->Operands[i].MIOperandInfo;
658f4a2713aSLionel Sambuc       for (unsigned SubOp = 0; SubOp != NumSubOps; ++SubOp) {
659f4a2713aSLionel Sambuc         if (AliasOpNo >= Result->getNumArgs())
660f4a2713aSLionel Sambuc           PrintFatalError(R->getLoc(), "not enough arguments for instruction!");
661f4a2713aSLionel Sambuc         Record *SubRec = cast<DefInit>(MIOI->getArg(SubOp))->getDef();
662f4a2713aSLionel Sambuc         if (tryAliasOpMatch(Result, AliasOpNo, SubRec, false,
663f4a2713aSLionel Sambuc                             R->getLoc(), T, ResOp)) {
664f4a2713aSLionel Sambuc           ResultOperands.push_back(ResOp);
665f4a2713aSLionel Sambuc           ResultInstOperandIndex.push_back(std::make_pair(i, SubOp));
666f4a2713aSLionel Sambuc           ++AliasOpNo;
667f4a2713aSLionel Sambuc         } else {
668*0a6a1f1dSLionel Sambuc           PrintFatalError(R->getLoc(), "result argument #" + Twine(AliasOpNo) +
669f4a2713aSLionel Sambuc                         " does not match instruction operand class " +
670f4a2713aSLionel Sambuc                         (SubOp == 0 ? InstOpRec->getName() :SubRec->getName()));
671f4a2713aSLionel Sambuc         }
672f4a2713aSLionel Sambuc       }
673f4a2713aSLionel Sambuc       continue;
674f4a2713aSLionel Sambuc     }
675*0a6a1f1dSLionel Sambuc     PrintFatalError(R->getLoc(), "result argument #" + Twine(AliasOpNo) +
676f4a2713aSLionel Sambuc                     " does not match instruction operand class " +
677f4a2713aSLionel Sambuc                     InstOpRec->getName());
678f4a2713aSLionel Sambuc   }
679f4a2713aSLionel Sambuc 
680f4a2713aSLionel Sambuc   if (AliasOpNo != Result->getNumArgs())
681f4a2713aSLionel Sambuc     PrintFatalError(R->getLoc(), "too many operands for instruction!");
682f4a2713aSLionel Sambuc }
683