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