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