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 | |
21 | using 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. |
27 | bool 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 | |
150 | unsigned 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 | |
167 | CodeGenInstAlias::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 | |