xref: /freebsd-src/contrib/llvm-project/llvm/utils/TableGen/Common/CodeGenInstAlias.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1*0fca6ea1SDimitry Andric //===- CodeGenInstAlias.cpp - CodeGen InstAlias Class Wrapper -------------===//
2*0fca6ea1SDimitry Andric //
3*0fca6ea1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0fca6ea1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0fca6ea1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0fca6ea1SDimitry Andric //
7*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===//
8*0fca6ea1SDimitry Andric //
9*0fca6ea1SDimitry Andric // This file implements the CodeGenInstAlias class.
10*0fca6ea1SDimitry Andric //
11*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===//
12*0fca6ea1SDimitry Andric 
13*0fca6ea1SDimitry Andric #include "CodeGenInstAlias.h"
14*0fca6ea1SDimitry Andric #include "CodeGenInstruction.h"
15*0fca6ea1SDimitry Andric #include "CodeGenRegisters.h"
16*0fca6ea1SDimitry Andric #include "CodeGenTarget.h"
17*0fca6ea1SDimitry Andric #include "llvm/ADT/StringMap.h"
18*0fca6ea1SDimitry Andric #include "llvm/TableGen/Error.h"
19*0fca6ea1SDimitry Andric #include "llvm/TableGen/Record.h"
20*0fca6ea1SDimitry Andric 
21*0fca6ea1SDimitry Andric using namespace llvm;
22*0fca6ea1SDimitry Andric 
23*0fca6ea1SDimitry Andric /// tryAliasOpMatch - This is a helper function for the CodeGenInstAlias
24*0fca6ea1SDimitry Andric /// constructor.  It checks if an argument in an InstAlias pattern matches
25*0fca6ea1SDimitry Andric /// the corresponding operand of the instruction.  It returns true on a
26*0fca6ea1SDimitry Andric /// successful match, with ResOp set to the result operand to be used.
27*0fca6ea1SDimitry Andric bool CodeGenInstAlias::tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo,
28*0fca6ea1SDimitry Andric                                        Record *InstOpRec, bool hasSubOps,
29*0fca6ea1SDimitry Andric                                        ArrayRef<SMLoc> Loc, CodeGenTarget &T,
30*0fca6ea1SDimitry Andric                                        ResultOperand &ResOp) {
31*0fca6ea1SDimitry Andric   Init *Arg = Result->getArg(AliasOpNo);
32*0fca6ea1SDimitry Andric   DefInit *ADI = dyn_cast<DefInit>(Arg);
33*0fca6ea1SDimitry Andric   Record *ResultRecord = ADI ? ADI->getDef() : nullptr;
34*0fca6ea1SDimitry Andric 
35*0fca6ea1SDimitry Andric   if (ADI && ADI->getDef() == InstOpRec) {
36*0fca6ea1SDimitry Andric     // If the operand is a record, it must have a name, and the record type
37*0fca6ea1SDimitry Andric     // must match up with the instruction's argument type.
38*0fca6ea1SDimitry Andric     if (!Result->getArgName(AliasOpNo))
39*0fca6ea1SDimitry Andric       PrintFatalError(Loc, "result argument #" + Twine(AliasOpNo) +
40*0fca6ea1SDimitry Andric                                " must have a name!");
41*0fca6ea1SDimitry Andric     ResOp = ResultOperand(std::string(Result->getArgNameStr(AliasOpNo)),
42*0fca6ea1SDimitry Andric                           ResultRecord);
43*0fca6ea1SDimitry Andric     return true;
44*0fca6ea1SDimitry Andric   }
45*0fca6ea1SDimitry Andric 
46*0fca6ea1SDimitry Andric   // For register operands, the source register class can be a subclass
47*0fca6ea1SDimitry Andric   // of the instruction register class, not just an exact match.
48*0fca6ea1SDimitry Andric   if (InstOpRec->isSubClassOf("RegisterOperand"))
49*0fca6ea1SDimitry Andric     InstOpRec = InstOpRec->getValueAsDef("RegClass");
50*0fca6ea1SDimitry Andric 
51*0fca6ea1SDimitry Andric   if (ADI && ADI->getDef()->isSubClassOf("RegisterOperand"))
52*0fca6ea1SDimitry Andric     ADI = ADI->getDef()->getValueAsDef("RegClass")->getDefInit();
53*0fca6ea1SDimitry Andric 
54*0fca6ea1SDimitry Andric   if (ADI && ADI->getDef()->isSubClassOf("RegisterClass")) {
55*0fca6ea1SDimitry Andric     if (!InstOpRec->isSubClassOf("RegisterClass"))
56*0fca6ea1SDimitry Andric       return false;
57*0fca6ea1SDimitry Andric     if (!T.getRegisterClass(InstOpRec).hasSubClass(
58*0fca6ea1SDimitry Andric             &T.getRegisterClass(ADI->getDef())))
59*0fca6ea1SDimitry Andric       return false;
60*0fca6ea1SDimitry Andric     ResOp = ResultOperand(std::string(Result->getArgNameStr(AliasOpNo)),
61*0fca6ea1SDimitry Andric                           ResultRecord);
62*0fca6ea1SDimitry Andric     return true;
63*0fca6ea1SDimitry Andric   }
64*0fca6ea1SDimitry Andric 
65*0fca6ea1SDimitry Andric   // Handle explicit registers.
66*0fca6ea1SDimitry Andric   if (ADI && ADI->getDef()->isSubClassOf("Register")) {
67*0fca6ea1SDimitry Andric     if (InstOpRec->isSubClassOf("OptionalDefOperand")) {
68*0fca6ea1SDimitry Andric       DagInit *DI = InstOpRec->getValueAsDag("MIOperandInfo");
69*0fca6ea1SDimitry Andric       // The operand info should only have a single (register) entry. We
70*0fca6ea1SDimitry Andric       // want the register class of it.
71*0fca6ea1SDimitry Andric       InstOpRec = cast<DefInit>(DI->getArg(0))->getDef();
72*0fca6ea1SDimitry Andric     }
73*0fca6ea1SDimitry Andric 
74*0fca6ea1SDimitry Andric     if (!InstOpRec->isSubClassOf("RegisterClass"))
75*0fca6ea1SDimitry Andric       return false;
76*0fca6ea1SDimitry Andric 
77*0fca6ea1SDimitry Andric     if (!T.getRegisterClass(InstOpRec).contains(
78*0fca6ea1SDimitry Andric             T.getRegBank().getReg(ADI->getDef())))
79*0fca6ea1SDimitry Andric       PrintFatalError(Loc, "fixed register " + ADI->getDef()->getName() +
80*0fca6ea1SDimitry Andric                                " is not a member of the " +
81*0fca6ea1SDimitry Andric                                InstOpRec->getName() + " register class!");
82*0fca6ea1SDimitry Andric 
83*0fca6ea1SDimitry Andric     if (Result->getArgName(AliasOpNo))
84*0fca6ea1SDimitry Andric       PrintFatalError(Loc, "result fixed register argument must "
85*0fca6ea1SDimitry Andric                            "not have a name!");
86*0fca6ea1SDimitry Andric 
87*0fca6ea1SDimitry Andric     ResOp = ResultOperand(ResultRecord);
88*0fca6ea1SDimitry Andric     return true;
89*0fca6ea1SDimitry Andric   }
90*0fca6ea1SDimitry Andric 
91*0fca6ea1SDimitry Andric   // Handle "zero_reg" for optional def operands.
92*0fca6ea1SDimitry Andric   if (ADI && ADI->getDef()->getName() == "zero_reg") {
93*0fca6ea1SDimitry Andric 
94*0fca6ea1SDimitry Andric     // Check if this is an optional def.
95*0fca6ea1SDimitry Andric     // Tied operands where the source is a sub-operand of a complex operand
96*0fca6ea1SDimitry Andric     // need to represent both operands in the alias destination instruction.
97*0fca6ea1SDimitry Andric     // Allow zero_reg for the tied portion. This can and should go away once
98*0fca6ea1SDimitry Andric     // the MC representation of things doesn't use tied operands at all.
99*0fca6ea1SDimitry Andric     // if (!InstOpRec->isSubClassOf("OptionalDefOperand"))
100*0fca6ea1SDimitry Andric     //  throw TGError(Loc, "reg0 used for result that is not an "
101*0fca6ea1SDimitry Andric     //                "OptionalDefOperand!");
102*0fca6ea1SDimitry Andric 
103*0fca6ea1SDimitry Andric     ResOp = ResultOperand(static_cast<Record *>(nullptr));
104*0fca6ea1SDimitry Andric     return true;
105*0fca6ea1SDimitry Andric   }
106*0fca6ea1SDimitry Andric 
107*0fca6ea1SDimitry Andric   // Literal integers.
108*0fca6ea1SDimitry Andric   if (IntInit *II = dyn_cast<IntInit>(Arg)) {
109*0fca6ea1SDimitry Andric     if (hasSubOps || !InstOpRec->isSubClassOf("Operand"))
110*0fca6ea1SDimitry Andric       return false;
111*0fca6ea1SDimitry Andric     // Integer arguments can't have names.
112*0fca6ea1SDimitry Andric     if (Result->getArgName(AliasOpNo))
113*0fca6ea1SDimitry Andric       PrintFatalError(Loc, "result argument #" + Twine(AliasOpNo) +
114*0fca6ea1SDimitry Andric                                " must not have a name!");
115*0fca6ea1SDimitry Andric     ResOp = ResultOperand(II->getValue());
116*0fca6ea1SDimitry Andric     return true;
117*0fca6ea1SDimitry Andric   }
118*0fca6ea1SDimitry Andric 
119*0fca6ea1SDimitry Andric   // Bits<n> (also used for 0bxx literals)
120*0fca6ea1SDimitry Andric   if (BitsInit *BI = dyn_cast<BitsInit>(Arg)) {
121*0fca6ea1SDimitry Andric     if (hasSubOps || !InstOpRec->isSubClassOf("Operand"))
122*0fca6ea1SDimitry Andric       return false;
123*0fca6ea1SDimitry Andric     if (!BI->isComplete())
124*0fca6ea1SDimitry Andric       return false;
125*0fca6ea1SDimitry Andric     // Convert the bits init to an integer and use that for the result.
126*0fca6ea1SDimitry Andric     IntInit *II = dyn_cast_or_null<IntInit>(
127*0fca6ea1SDimitry Andric         BI->convertInitializerTo(IntRecTy::get(BI->getRecordKeeper())));
128*0fca6ea1SDimitry Andric     if (!II)
129*0fca6ea1SDimitry Andric       return false;
130*0fca6ea1SDimitry Andric     ResOp = ResultOperand(II->getValue());
131*0fca6ea1SDimitry Andric     return true;
132*0fca6ea1SDimitry Andric   }
133*0fca6ea1SDimitry Andric 
134*0fca6ea1SDimitry Andric   // If both are Operands with the same MVT, allow the conversion. It's
135*0fca6ea1SDimitry Andric   // up to the user to make sure the values are appropriate, just like
136*0fca6ea1SDimitry Andric   // for isel Pat's.
137*0fca6ea1SDimitry Andric   if (InstOpRec->isSubClassOf("Operand") && ADI &&
138*0fca6ea1SDimitry Andric       ADI->getDef()->isSubClassOf("Operand")) {
139*0fca6ea1SDimitry Andric     // FIXME: What other attributes should we check here? Identical
140*0fca6ea1SDimitry Andric     // MIOperandInfo perhaps?
141*0fca6ea1SDimitry Andric     if (InstOpRec->getValueInit("Type") != ADI->getDef()->getValueInit("Type"))
142*0fca6ea1SDimitry Andric       return false;
143*0fca6ea1SDimitry Andric     ResOp = ResultOperand(std::string(Result->getArgNameStr(AliasOpNo)),
144*0fca6ea1SDimitry Andric                           ADI->getDef());
145*0fca6ea1SDimitry Andric     return true;
146*0fca6ea1SDimitry Andric   }
147*0fca6ea1SDimitry Andric 
148*0fca6ea1SDimitry Andric   return false;
149*0fca6ea1SDimitry Andric }
150*0fca6ea1SDimitry Andric 
151*0fca6ea1SDimitry Andric unsigned CodeGenInstAlias::ResultOperand::getMINumOperands() const {
152*0fca6ea1SDimitry Andric   if (!isRecord())
153*0fca6ea1SDimitry Andric     return 1;
154*0fca6ea1SDimitry Andric 
155*0fca6ea1SDimitry Andric   Record *Rec = getRecord();
156*0fca6ea1SDimitry Andric   if (!Rec->isSubClassOf("Operand"))
157*0fca6ea1SDimitry Andric     return 1;
158*0fca6ea1SDimitry Andric 
159*0fca6ea1SDimitry Andric   DagInit *MIOpInfo = Rec->getValueAsDag("MIOperandInfo");
160*0fca6ea1SDimitry Andric   if (MIOpInfo->getNumArgs() == 0) {
161*0fca6ea1SDimitry Andric     // Unspecified, so it defaults to 1
162*0fca6ea1SDimitry Andric     return 1;
163*0fca6ea1SDimitry Andric   }
164*0fca6ea1SDimitry Andric 
165*0fca6ea1SDimitry Andric   return MIOpInfo->getNumArgs();
166*0fca6ea1SDimitry Andric }
167*0fca6ea1SDimitry Andric 
168*0fca6ea1SDimitry Andric CodeGenInstAlias::CodeGenInstAlias(Record *R, CodeGenTarget &T) : TheDef(R) {
169*0fca6ea1SDimitry Andric   Result = R->getValueAsDag("ResultInst");
170*0fca6ea1SDimitry Andric   AsmString = std::string(R->getValueAsString("AsmString"));
171*0fca6ea1SDimitry Andric 
172*0fca6ea1SDimitry Andric   // Verify that the root of the result is an instruction.
173*0fca6ea1SDimitry Andric   DefInit *DI = dyn_cast<DefInit>(Result->getOperator());
174*0fca6ea1SDimitry Andric   if (!DI || !DI->getDef()->isSubClassOf("Instruction"))
175*0fca6ea1SDimitry Andric     PrintFatalError(R->getLoc(),
176*0fca6ea1SDimitry Andric                     "result of inst alias should be an instruction");
177*0fca6ea1SDimitry Andric 
178*0fca6ea1SDimitry Andric   ResultInst = &T.getInstruction(DI->getDef());
179*0fca6ea1SDimitry Andric 
180*0fca6ea1SDimitry Andric   // NameClass - If argument names are repeated, we need to verify they have
181*0fca6ea1SDimitry Andric   // the same class.
182*0fca6ea1SDimitry Andric   StringMap<Record *> NameClass;
183*0fca6ea1SDimitry Andric   for (unsigned i = 0, e = Result->getNumArgs(); i != e; ++i) {
184*0fca6ea1SDimitry Andric     DefInit *ADI = dyn_cast<DefInit>(Result->getArg(i));
185*0fca6ea1SDimitry Andric     if (!ADI || !Result->getArgName(i))
186*0fca6ea1SDimitry Andric       continue;
187*0fca6ea1SDimitry Andric     // Verify we don't have something like: (someinst GR16:$foo, GR32:$foo)
188*0fca6ea1SDimitry Andric     // $foo can exist multiple times in the result list, but it must have the
189*0fca6ea1SDimitry Andric     // same type.
190*0fca6ea1SDimitry Andric     Record *&Entry = NameClass[Result->getArgNameStr(i)];
191*0fca6ea1SDimitry Andric     if (Entry && Entry != ADI->getDef())
192*0fca6ea1SDimitry Andric       PrintFatalError(R->getLoc(), "result value $" + Result->getArgNameStr(i) +
193*0fca6ea1SDimitry Andric                                        " is both " + Entry->getName() +
194*0fca6ea1SDimitry Andric                                        " and " + ADI->getDef()->getName() +
195*0fca6ea1SDimitry Andric                                        "!");
196*0fca6ea1SDimitry Andric     Entry = ADI->getDef();
197*0fca6ea1SDimitry Andric   }
198*0fca6ea1SDimitry Andric 
199*0fca6ea1SDimitry Andric   // Decode and validate the arguments of the result.
200*0fca6ea1SDimitry Andric   unsigned AliasOpNo = 0;
201*0fca6ea1SDimitry Andric   for (unsigned i = 0, e = ResultInst->Operands.size(); i != e; ++i) {
202*0fca6ea1SDimitry Andric 
203*0fca6ea1SDimitry Andric     // Tied registers don't have an entry in the result dag unless they're part
204*0fca6ea1SDimitry Andric     // of a complex operand, in which case we include them anyways, as we
205*0fca6ea1SDimitry Andric     // don't have any other way to specify the whole operand.
206*0fca6ea1SDimitry Andric     if (ResultInst->Operands[i].MINumOperands == 1 &&
207*0fca6ea1SDimitry Andric         ResultInst->Operands[i].getTiedRegister() != -1) {
208*0fca6ea1SDimitry Andric       // Tied operands of different RegisterClass should be explicit within an
209*0fca6ea1SDimitry Andric       // instruction's syntax and so cannot be skipped.
210*0fca6ea1SDimitry Andric       int TiedOpNum = ResultInst->Operands[i].getTiedRegister();
211*0fca6ea1SDimitry Andric       if (ResultInst->Operands[i].Rec->getName() ==
212*0fca6ea1SDimitry Andric           ResultInst->Operands[TiedOpNum].Rec->getName())
213*0fca6ea1SDimitry Andric         continue;
214*0fca6ea1SDimitry Andric     }
215*0fca6ea1SDimitry Andric 
216*0fca6ea1SDimitry Andric     if (AliasOpNo >= Result->getNumArgs())
217*0fca6ea1SDimitry Andric       PrintFatalError(R->getLoc(), "not enough arguments for instruction!");
218*0fca6ea1SDimitry Andric 
219*0fca6ea1SDimitry Andric     Record *InstOpRec = ResultInst->Operands[i].Rec;
220*0fca6ea1SDimitry Andric     unsigned NumSubOps = ResultInst->Operands[i].MINumOperands;
221*0fca6ea1SDimitry Andric     ResultOperand ResOp(static_cast<int64_t>(0));
222*0fca6ea1SDimitry Andric     if (tryAliasOpMatch(Result, AliasOpNo, InstOpRec, (NumSubOps > 1),
223*0fca6ea1SDimitry Andric                         R->getLoc(), T, ResOp)) {
224*0fca6ea1SDimitry Andric       // If this is a simple operand, or a complex operand with a custom match
225*0fca6ea1SDimitry Andric       // class, then we can match is verbatim.
226*0fca6ea1SDimitry Andric       if (NumSubOps == 1 || (InstOpRec->getValue("ParserMatchClass") &&
227*0fca6ea1SDimitry Andric                              InstOpRec->getValueAsDef("ParserMatchClass")
228*0fca6ea1SDimitry Andric                                      ->getValueAsString("Name") != "Imm")) {
229*0fca6ea1SDimitry Andric         ResultOperands.push_back(ResOp);
230*0fca6ea1SDimitry Andric         ResultInstOperandIndex.push_back(std::pair(i, -1));
231*0fca6ea1SDimitry Andric         ++AliasOpNo;
232*0fca6ea1SDimitry Andric 
233*0fca6ea1SDimitry Andric         // Otherwise, we need to match each of the suboperands individually.
234*0fca6ea1SDimitry Andric       } else {
235*0fca6ea1SDimitry Andric         DagInit *MIOI = ResultInst->Operands[i].MIOperandInfo;
236*0fca6ea1SDimitry Andric         for (unsigned SubOp = 0; SubOp != NumSubOps; ++SubOp) {
237*0fca6ea1SDimitry Andric           Record *SubRec = cast<DefInit>(MIOI->getArg(SubOp))->getDef();
238*0fca6ea1SDimitry Andric 
239*0fca6ea1SDimitry Andric           // Take care to instantiate each of the suboperands with the correct
240*0fca6ea1SDimitry Andric           // nomenclature: $foo.bar
241*0fca6ea1SDimitry Andric           ResultOperands.emplace_back(
242*0fca6ea1SDimitry Andric               Result->getArgName(AliasOpNo)->getAsUnquotedString() + "." +
243*0fca6ea1SDimitry Andric                   MIOI->getArgName(SubOp)->getAsUnquotedString(),
244*0fca6ea1SDimitry Andric               SubRec);
245*0fca6ea1SDimitry Andric           ResultInstOperandIndex.push_back(std::pair(i, SubOp));
246*0fca6ea1SDimitry Andric         }
247*0fca6ea1SDimitry Andric         ++AliasOpNo;
248*0fca6ea1SDimitry Andric       }
249*0fca6ea1SDimitry Andric       continue;
250*0fca6ea1SDimitry Andric     }
251*0fca6ea1SDimitry Andric 
252*0fca6ea1SDimitry Andric     // If the argument did not match the instruction operand, and the operand
253*0fca6ea1SDimitry Andric     // is composed of multiple suboperands, try matching the suboperands.
254*0fca6ea1SDimitry Andric     if (NumSubOps > 1) {
255*0fca6ea1SDimitry Andric       DagInit *MIOI = ResultInst->Operands[i].MIOperandInfo;
256*0fca6ea1SDimitry Andric       for (unsigned SubOp = 0; SubOp != NumSubOps; ++SubOp) {
257*0fca6ea1SDimitry Andric         if (AliasOpNo >= Result->getNumArgs())
258*0fca6ea1SDimitry Andric           PrintFatalError(R->getLoc(), "not enough arguments for instruction!");
259*0fca6ea1SDimitry Andric         Record *SubRec = cast<DefInit>(MIOI->getArg(SubOp))->getDef();
260*0fca6ea1SDimitry Andric         if (tryAliasOpMatch(Result, AliasOpNo, SubRec, false, R->getLoc(), T,
261*0fca6ea1SDimitry Andric                             ResOp)) {
262*0fca6ea1SDimitry Andric           ResultOperands.push_back(ResOp);
263*0fca6ea1SDimitry Andric           ResultInstOperandIndex.push_back(std::pair(i, SubOp));
264*0fca6ea1SDimitry Andric           ++AliasOpNo;
265*0fca6ea1SDimitry Andric         } else {
266*0fca6ea1SDimitry Andric           PrintFatalError(
267*0fca6ea1SDimitry Andric               R->getLoc(),
268*0fca6ea1SDimitry Andric               "result argument #" + Twine(AliasOpNo) +
269*0fca6ea1SDimitry Andric                   " does not match instruction operand class " +
270*0fca6ea1SDimitry Andric                   (SubOp == 0 ? InstOpRec->getName() : SubRec->getName()));
271*0fca6ea1SDimitry Andric         }
272*0fca6ea1SDimitry Andric       }
273*0fca6ea1SDimitry Andric       continue;
274*0fca6ea1SDimitry Andric     }
275*0fca6ea1SDimitry Andric     PrintFatalError(R->getLoc(),
276*0fca6ea1SDimitry Andric                     "result argument #" + Twine(AliasOpNo) +
277*0fca6ea1SDimitry Andric                         " does not match instruction operand class " +
278*0fca6ea1SDimitry Andric                         InstOpRec->getName());
279*0fca6ea1SDimitry Andric   }
280*0fca6ea1SDimitry Andric 
281*0fca6ea1SDimitry Andric   if (AliasOpNo != Result->getNumArgs())
282*0fca6ea1SDimitry Andric     PrintFatalError(R->getLoc(), "too many operands for instruction!");
283*0fca6ea1SDimitry Andric }
284