]>
Commit | Line | Data |
---|---|---|
223e47cc LB |
1 | //===- AsmMatcherEmitter.cpp - Generate an assembly matcher ---------------===// |
2 | // | |
3 | // The LLVM Compiler Infrastructure | |
4 | // | |
5 | // This file is distributed under the University of Illinois Open Source | |
6 | // License. See LICENSE.TXT for details. | |
7 | // | |
8 | //===----------------------------------------------------------------------===// | |
9 | // | |
10 | // This tablegen backend emits a target specifier matcher for converting parsed | |
11 | // assembly operands in the MCInst structures. It also emits a matcher for | |
12 | // custom operand parsing. | |
13 | // | |
14 | // Converting assembly operands into MCInst structures | |
15 | // --------------------------------------------------- | |
16 | // | |
17 | // The input to the target specific matcher is a list of literal tokens and | |
18 | // operands. The target specific parser should generally eliminate any syntax | |
19 | // which is not relevant for matching; for example, comma tokens should have | |
20 | // already been consumed and eliminated by the parser. Most instructions will | |
21 | // end up with a single literal token (the instruction name) and some number of | |
22 | // operands. | |
23 | // | |
24 | // Some example inputs, for X86: | |
25 | // 'addl' (immediate ...) (register ...) | |
26 | // 'add' (immediate ...) (memory ...) | |
27 | // 'call' '*' %epc | |
28 | // | |
29 | // The assembly matcher is responsible for converting this input into a precise | |
30 | // machine instruction (i.e., an instruction with a well defined encoding). This | |
31 | // mapping has several properties which complicate matching: | |
32 | // | |
33 | // - It may be ambiguous; many architectures can legally encode particular | |
34 | // variants of an instruction in different ways (for example, using a smaller | |
35 | // encoding for small immediates). Such ambiguities should never be | |
36 | // arbitrarily resolved by the assembler, the assembler is always responsible | |
37 | // for choosing the "best" available instruction. | |
38 | // | |
39 | // - It may depend on the subtarget or the assembler context. Instructions | |
40 | // which are invalid for the current mode, but otherwise unambiguous (e.g., | |
41 | // an SSE instruction in a file being assembled for i486) should be accepted | |
42 | // and rejected by the assembler front end. However, if the proper encoding | |
43 | // for an instruction is dependent on the assembler context then the matcher | |
44 | // is responsible for selecting the correct machine instruction for the | |
45 | // current mode. | |
46 | // | |
47 | // The core matching algorithm attempts to exploit the regularity in most | |
48 | // instruction sets to quickly determine the set of possibly matching | |
49 | // instructions, and the simplify the generated code. Additionally, this helps | |
50 | // to ensure that the ambiguities are intentionally resolved by the user. | |
51 | // | |
52 | // The matching is divided into two distinct phases: | |
53 | // | |
54 | // 1. Classification: Each operand is mapped to the unique set which (a) | |
55 | // contains it, and (b) is the largest such subset for which a single | |
56 | // instruction could match all members. | |
57 | // | |
58 | // For register classes, we can generate these subgroups automatically. For | |
59 | // arbitrary operands, we expect the user to define the classes and their | |
60 | // relations to one another (for example, 8-bit signed immediates as a | |
61 | // subset of 32-bit immediates). | |
62 | // | |
63 | // By partitioning the operands in this way, we guarantee that for any | |
64 | // tuple of classes, any single instruction must match either all or none | |
65 | // of the sets of operands which could classify to that tuple. | |
66 | // | |
67 | // In addition, the subset relation amongst classes induces a partial order | |
68 | // on such tuples, which we use to resolve ambiguities. | |
69 | // | |
70 | // 2. The input can now be treated as a tuple of classes (static tokens are | |
71 | // simple singleton sets). Each such tuple should generally map to a single | |
72 | // instruction (we currently ignore cases where this isn't true, whee!!!), | |
73 | // which we can emit a simple matcher for. | |
74 | // | |
75 | // Custom Operand Parsing | |
76 | // ---------------------- | |
77 | // | |
78 | // Some targets need a custom way to parse operands, some specific instructions | |
79 | // can contain arguments that can represent processor flags and other kinds of | |
80 | // identifiers that need to be mapped to specific values in the final encoded | |
81 | // instructions. The target specific custom operand parsing works in the | |
82 | // following way: | |
83 | // | |
84 | // 1. A operand match table is built, each entry contains a mnemonic, an | |
85 | // operand class, a mask for all operand positions for that same | |
86 | // class/mnemonic and target features to be checked while trying to match. | |
87 | // | |
88 | // 2. The operand matcher will try every possible entry with the same | |
89 | // mnemonic and will check if the target feature for this mnemonic also | |
90 | // matches. After that, if the operand to be matched has its index | |
91 | // present in the mask, a successful match occurs. Otherwise, fallback | |
92 | // to the regular operand parsing. | |
93 | // | |
94 | // 3. For a match success, each operand class that has a 'ParserMethod' | |
95 | // becomes part of a switch from where the custom method is called. | |
96 | // | |
97 | //===----------------------------------------------------------------------===// | |
98 | ||
99 | #include "CodeGenTarget.h" | |
223e47cc | 100 | #include "llvm/ADT/PointerUnion.h" |
970d7e83 | 101 | #include "llvm/ADT/STLExtras.h" |
223e47cc LB |
102 | #include "llvm/ADT/SmallPtrSet.h" |
103 | #include "llvm/ADT/SmallVector.h" | |
223e47cc LB |
104 | #include "llvm/ADT/StringExtras.h" |
105 | #include "llvm/Support/CommandLine.h" | |
106 | #include "llvm/Support/Debug.h" | |
107 | #include "llvm/Support/ErrorHandling.h" | |
108 | #include "llvm/TableGen/Error.h" | |
109 | #include "llvm/TableGen/Record.h" | |
110 | #include "llvm/TableGen/StringMatcher.h" | |
1a4d82fc | 111 | #include "llvm/TableGen/StringToOffsetTable.h" |
223e47cc LB |
112 | #include "llvm/TableGen/TableGenBackend.h" |
113 | #include <cassert> | |
1a4d82fc | 114 | #include <cctype> |
223e47cc LB |
115 | #include <map> |
116 | #include <set> | |
1a4d82fc | 117 | #include <sstream> |
85aaf69f | 118 | #include <forward_list> |
223e47cc LB |
119 | using namespace llvm; |
120 | ||
1a4d82fc JJ |
121 | #define DEBUG_TYPE "asm-matcher-emitter" |
122 | ||
223e47cc LB |
123 | static cl::opt<std::string> |
124 | MatchPrefix("match-prefix", cl::init(""), | |
125 | cl::desc("Only match instructions with the given prefix")); | |
126 | ||
127 | namespace { | |
128 | class AsmMatcherInfo; | |
129 | struct SubtargetFeatureInfo; | |
130 | ||
1a4d82fc JJ |
131 | // Register sets are used as keys in some second-order sets TableGen creates |
132 | // when generating its data structures. This means that the order of two | |
133 | // RegisterSets can be seen in the outputted AsmMatcher tables occasionally, and | |
134 | // can even affect compiler output (at least seen in diagnostics produced when | |
135 | // all matches fail). So we use a type that sorts them consistently. | |
136 | typedef std::set<Record*, LessRecordByID> RegisterSet; | |
137 | ||
223e47cc LB |
138 | class AsmMatcherEmitter { |
139 | RecordKeeper &Records; | |
140 | public: | |
141 | AsmMatcherEmitter(RecordKeeper &R) : Records(R) {} | |
142 | ||
143 | void run(raw_ostream &o); | |
144 | }; | |
145 | ||
146 | /// ClassInfo - Helper class for storing the information about a particular | |
147 | /// class of operands which can be matched. | |
148 | struct ClassInfo { | |
149 | enum ClassInfoKind { | |
150 | /// Invalid kind, for use as a sentinel value. | |
151 | Invalid = 0, | |
152 | ||
153 | /// The class for a particular token. | |
154 | Token, | |
155 | ||
156 | /// The (first) register class, subsequent register classes are | |
157 | /// RegisterClass0+1, and so on. | |
158 | RegisterClass0, | |
159 | ||
160 | /// The (first) user defined class, subsequent user defined classes are | |
161 | /// UserClass0+1, and so on. | |
162 | UserClass0 = 1<<16 | |
163 | }; | |
164 | ||
165 | /// Kind - The class kind, which is either a predefined kind, or (UserClass0 + | |
166 | /// N) for the Nth user defined class. | |
167 | unsigned Kind; | |
168 | ||
169 | /// SuperClasses - The super classes of this class. Note that for simplicities | |
170 | /// sake user operands only record their immediate super class, while register | |
171 | /// operands include all superclasses. | |
172 | std::vector<ClassInfo*> SuperClasses; | |
173 | ||
174 | /// Name - The full class name, suitable for use in an enum. | |
175 | std::string Name; | |
176 | ||
177 | /// ClassName - The unadorned generic name for this class (e.g., Token). | |
178 | std::string ClassName; | |
179 | ||
180 | /// ValueName - The name of the value this class represents; for a token this | |
181 | /// is the literal token string, for an operand it is the TableGen class (or | |
182 | /// empty if this is a derived class). | |
183 | std::string ValueName; | |
184 | ||
185 | /// PredicateMethod - The name of the operand method to test whether the | |
186 | /// operand matches this class; this is not valid for Token or register kinds. | |
187 | std::string PredicateMethod; | |
188 | ||
189 | /// RenderMethod - The name of the operand method to add this operand to an | |
190 | /// MCInst; this is not valid for Token or register kinds. | |
191 | std::string RenderMethod; | |
192 | ||
193 | /// ParserMethod - The name of the operand method to do a target specific | |
194 | /// parsing on the operand. | |
195 | std::string ParserMethod; | |
196 | ||
1a4d82fc JJ |
197 | /// For register classes: the records for all the registers in this class. |
198 | RegisterSet Registers; | |
223e47cc | 199 | |
1a4d82fc | 200 | /// For custom match classes: the diagnostic kind for when the predicate fails. |
223e47cc LB |
201 | std::string DiagnosticType; |
202 | public: | |
203 | /// isRegisterClass() - Check if this is a register class. | |
204 | bool isRegisterClass() const { | |
205 | return Kind >= RegisterClass0 && Kind < UserClass0; | |
206 | } | |
207 | ||
208 | /// isUserClass() - Check if this is a user defined class. | |
209 | bool isUserClass() const { | |
210 | return Kind >= UserClass0; | |
211 | } | |
212 | ||
213 | /// isRelatedTo - Check whether this class is "related" to \p RHS. Classes | |
214 | /// are related if they are in the same class hierarchy. | |
215 | bool isRelatedTo(const ClassInfo &RHS) const { | |
216 | // Tokens are only related to tokens. | |
217 | if (Kind == Token || RHS.Kind == Token) | |
218 | return Kind == Token && RHS.Kind == Token; | |
219 | ||
220 | // Registers classes are only related to registers classes, and only if | |
221 | // their intersection is non-empty. | |
222 | if (isRegisterClass() || RHS.isRegisterClass()) { | |
223 | if (!isRegisterClass() || !RHS.isRegisterClass()) | |
224 | return false; | |
225 | ||
1a4d82fc JJ |
226 | RegisterSet Tmp; |
227 | std::insert_iterator<RegisterSet> II(Tmp, Tmp.begin()); | |
223e47cc LB |
228 | std::set_intersection(Registers.begin(), Registers.end(), |
229 | RHS.Registers.begin(), RHS.Registers.end(), | |
1a4d82fc | 230 | II, LessRecordByID()); |
223e47cc LB |
231 | |
232 | return !Tmp.empty(); | |
233 | } | |
234 | ||
235 | // Otherwise we have two users operands; they are related if they are in the | |
236 | // same class hierarchy. | |
237 | // | |
238 | // FIXME: This is an oversimplification, they should only be related if they | |
239 | // intersect, however we don't have that information. | |
240 | assert(isUserClass() && RHS.isUserClass() && "Unexpected class!"); | |
241 | const ClassInfo *Root = this; | |
242 | while (!Root->SuperClasses.empty()) | |
243 | Root = Root->SuperClasses.front(); | |
244 | ||
245 | const ClassInfo *RHSRoot = &RHS; | |
246 | while (!RHSRoot->SuperClasses.empty()) | |
247 | RHSRoot = RHSRoot->SuperClasses.front(); | |
248 | ||
249 | return Root == RHSRoot; | |
250 | } | |
251 | ||
252 | /// isSubsetOf - Test whether this class is a subset of \p RHS. | |
253 | bool isSubsetOf(const ClassInfo &RHS) const { | |
254 | // This is a subset of RHS if it is the same class... | |
255 | if (this == &RHS) | |
256 | return true; | |
257 | ||
258 | // ... or if any of its super classes are a subset of RHS. | |
85aaf69f SL |
259 | for (const ClassInfo *CI : SuperClasses) |
260 | if (CI->isSubsetOf(RHS)) | |
223e47cc LB |
261 | return true; |
262 | ||
263 | return false; | |
264 | } | |
265 | ||
266 | /// operator< - Compare two classes. | |
267 | bool operator<(const ClassInfo &RHS) const { | |
268 | if (this == &RHS) | |
269 | return false; | |
270 | ||
271 | // Unrelated classes can be ordered by kind. | |
272 | if (!isRelatedTo(RHS)) | |
273 | return Kind < RHS.Kind; | |
274 | ||
275 | switch (Kind) { | |
276 | case Invalid: | |
277 | llvm_unreachable("Invalid kind!"); | |
278 | ||
279 | default: | |
280 | // This class precedes the RHS if it is a proper subset of the RHS. | |
281 | if (isSubsetOf(RHS)) | |
282 | return true; | |
283 | if (RHS.isSubsetOf(*this)) | |
284 | return false; | |
285 | ||
286 | // Otherwise, order by name to ensure we have a total ordering. | |
287 | return ValueName < RHS.ValueName; | |
288 | } | |
289 | } | |
290 | }; | |
291 | ||
223e47cc LB |
292 | /// MatchableInfo - Helper class for storing the necessary information for an |
293 | /// instruction or alias which is capable of being matched. | |
294 | struct MatchableInfo { | |
295 | struct AsmOperand { | |
296 | /// Token - This is the token that the operand came from. | |
297 | StringRef Token; | |
298 | ||
299 | /// The unique class instance this operand should match. | |
300 | ClassInfo *Class; | |
301 | ||
302 | /// The operand name this is, if anything. | |
303 | StringRef SrcOpName; | |
304 | ||
305 | /// The suboperand index within SrcOpName, or -1 for the entire operand. | |
306 | int SubOpIdx; | |
307 | ||
308 | /// Register record if this token is singleton register. | |
309 | Record *SingletonReg; | |
310 | ||
1a4d82fc JJ |
311 | explicit AsmOperand(StringRef T) : Token(T), Class(nullptr), SubOpIdx(-1), |
312 | SingletonReg(nullptr) {} | |
223e47cc LB |
313 | }; |
314 | ||
315 | /// ResOperand - This represents a single operand in the result instruction | |
316 | /// generated by the match. In cases (like addressing modes) where a single | |
317 | /// assembler operand expands to multiple MCOperands, this represents the | |
318 | /// single assembler operand, not the MCOperand. | |
319 | struct ResOperand { | |
320 | enum { | |
321 | /// RenderAsmOperand - This represents an operand result that is | |
322 | /// generated by calling the render method on the assembly operand. The | |
323 | /// corresponding AsmOperand is specified by AsmOperandNum. | |
324 | RenderAsmOperand, | |
325 | ||
326 | /// TiedOperand - This represents a result operand that is a duplicate of | |
327 | /// a previous result operand. | |
328 | TiedOperand, | |
329 | ||
330 | /// ImmOperand - This represents an immediate value that is dumped into | |
331 | /// the operand. | |
332 | ImmOperand, | |
333 | ||
334 | /// RegOperand - This represents a fixed register that is dumped in. | |
335 | RegOperand | |
336 | } Kind; | |
337 | ||
338 | union { | |
339 | /// This is the operand # in the AsmOperands list that this should be | |
340 | /// copied from. | |
341 | unsigned AsmOperandNum; | |
342 | ||
343 | /// TiedOperandNum - This is the (earlier) result operand that should be | |
344 | /// copied from. | |
345 | unsigned TiedOperandNum; | |
346 | ||
347 | /// ImmVal - This is the immediate value added to the instruction. | |
348 | int64_t ImmVal; | |
349 | ||
350 | /// Register - This is the register record. | |
351 | Record *Register; | |
352 | }; | |
353 | ||
354 | /// MINumOperands - The number of MCInst operands populated by this | |
355 | /// operand. | |
356 | unsigned MINumOperands; | |
357 | ||
358 | static ResOperand getRenderedOp(unsigned AsmOpNum, unsigned NumOperands) { | |
359 | ResOperand X; | |
360 | X.Kind = RenderAsmOperand; | |
361 | X.AsmOperandNum = AsmOpNum; | |
362 | X.MINumOperands = NumOperands; | |
363 | return X; | |
364 | } | |
365 | ||
366 | static ResOperand getTiedOp(unsigned TiedOperandNum) { | |
367 | ResOperand X; | |
368 | X.Kind = TiedOperand; | |
369 | X.TiedOperandNum = TiedOperandNum; | |
370 | X.MINumOperands = 1; | |
371 | return X; | |
372 | } | |
373 | ||
374 | static ResOperand getImmOp(int64_t Val) { | |
375 | ResOperand X; | |
376 | X.Kind = ImmOperand; | |
377 | X.ImmVal = Val; | |
378 | X.MINumOperands = 1; | |
379 | return X; | |
380 | } | |
381 | ||
382 | static ResOperand getRegOp(Record *Reg) { | |
383 | ResOperand X; | |
384 | X.Kind = RegOperand; | |
385 | X.Register = Reg; | |
386 | X.MINumOperands = 1; | |
387 | return X; | |
388 | } | |
389 | }; | |
390 | ||
391 | /// AsmVariantID - Target's assembly syntax variant no. | |
392 | int AsmVariantID; | |
393 | ||
85aaf69f SL |
394 | /// AsmString - The assembly string for this instruction (with variants |
395 | /// removed), e.g. "movsx $src, $dst". | |
396 | std::string AsmString; | |
397 | ||
223e47cc LB |
398 | /// TheDef - This is the definition of the instruction or InstAlias that this |
399 | /// matchable came from. | |
400 | Record *const TheDef; | |
401 | ||
402 | /// DefRec - This is the definition that it came from. | |
403 | PointerUnion<const CodeGenInstruction*, const CodeGenInstAlias*> DefRec; | |
404 | ||
405 | const CodeGenInstruction *getResultInst() const { | |
406 | if (DefRec.is<const CodeGenInstruction*>()) | |
407 | return DefRec.get<const CodeGenInstruction*>(); | |
408 | return DefRec.get<const CodeGenInstAlias*>()->ResultInst; | |
409 | } | |
410 | ||
411 | /// ResOperands - This is the operand list that should be built for the result | |
412 | /// MCInst. | |
413 | SmallVector<ResOperand, 8> ResOperands; | |
414 | ||
223e47cc LB |
415 | /// Mnemonic - This is the first token of the matched instruction, its |
416 | /// mnemonic. | |
417 | StringRef Mnemonic; | |
418 | ||
419 | /// AsmOperands - The textual operands that this instruction matches, | |
420 | /// annotated with a class and where in the OperandList they were defined. | |
421 | /// This directly corresponds to the tokenized AsmString after the mnemonic is | |
422 | /// removed. | |
423 | SmallVector<AsmOperand, 8> AsmOperands; | |
424 | ||
425 | /// Predicates - The required subtarget features to match this instruction. | |
85aaf69f | 426 | SmallVector<const SubtargetFeatureInfo *, 4> RequiredFeatures; |
223e47cc LB |
427 | |
428 | /// ConversionFnKind - The enum value which is passed to the generated | |
429 | /// convertToMCInst to convert parsed operands into an MCInst for this | |
430 | /// function. | |
431 | std::string ConversionFnKind; | |
432 | ||
1a4d82fc JJ |
433 | /// If this instruction is deprecated in some form. |
434 | bool HasDeprecation; | |
435 | ||
223e47cc | 436 | MatchableInfo(const CodeGenInstruction &CGI) |
85aaf69f | 437 | : AsmVariantID(0), AsmString(CGI.AsmString), TheDef(CGI.TheDef), DefRec(&CGI) { |
223e47cc LB |
438 | } |
439 | ||
85aaf69f SL |
440 | MatchableInfo(std::unique_ptr<const CodeGenInstAlias> Alias) |
441 | : AsmVariantID(0), AsmString(Alias->AsmString), TheDef(Alias->TheDef), DefRec(Alias.release()) { | |
442 | } | |
443 | ||
444 | ~MatchableInfo() { | |
445 | delete DefRec.dyn_cast<const CodeGenInstAlias*>(); | |
223e47cc LB |
446 | } |
447 | ||
448 | // Two-operand aliases clone from the main matchable, but mark the second | |
449 | // operand as a tied operand of the first for purposes of the assembler. | |
450 | void formTwoOperandAlias(StringRef Constraint); | |
451 | ||
452 | void initialize(const AsmMatcherInfo &Info, | |
1a4d82fc | 453 | SmallPtrSetImpl<Record*> &SingletonRegisters, |
223e47cc LB |
454 | int AsmVariantNo, std::string &RegisterPrefix); |
455 | ||
456 | /// validate - Return true if this matchable is a valid thing to match against | |
457 | /// and perform a bunch of validity checking. | |
458 | bool validate(StringRef CommentDelimiter, bool Hack) const; | |
459 | ||
460 | /// extractSingletonRegisterForAsmOperand - Extract singleton register, | |
461 | /// if present, from specified token. | |
462 | void | |
463 | extractSingletonRegisterForAsmOperand(unsigned i, const AsmMatcherInfo &Info, | |
464 | std::string &RegisterPrefix); | |
465 | ||
466 | /// findAsmOperand - Find the AsmOperand with the specified name and | |
467 | /// suboperand index. | |
468 | int findAsmOperand(StringRef N, int SubOpIdx) const { | |
469 | for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) | |
470 | if (N == AsmOperands[i].SrcOpName && | |
471 | SubOpIdx == AsmOperands[i].SubOpIdx) | |
472 | return i; | |
473 | return -1; | |
474 | } | |
475 | ||
476 | /// findAsmOperandNamed - Find the first AsmOperand with the specified name. | |
477 | /// This does not check the suboperand index. | |
478 | int findAsmOperandNamed(StringRef N) const { | |
479 | for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) | |
480 | if (N == AsmOperands[i].SrcOpName) | |
481 | return i; | |
482 | return -1; | |
483 | } | |
484 | ||
485 | void buildInstructionResultOperands(); | |
486 | void buildAliasResultOperands(); | |
487 | ||
488 | /// operator< - Compare two matchables. | |
489 | bool operator<(const MatchableInfo &RHS) const { | |
490 | // The primary comparator is the instruction mnemonic. | |
491 | if (Mnemonic != RHS.Mnemonic) | |
492 | return Mnemonic < RHS.Mnemonic; | |
493 | ||
494 | if (AsmOperands.size() != RHS.AsmOperands.size()) | |
495 | return AsmOperands.size() < RHS.AsmOperands.size(); | |
496 | ||
497 | // Compare lexicographically by operand. The matcher validates that other | |
498 | // orderings wouldn't be ambiguous using \see couldMatchAmbiguouslyWith(). | |
499 | for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) { | |
500 | if (*AsmOperands[i].Class < *RHS.AsmOperands[i].Class) | |
501 | return true; | |
502 | if (*RHS.AsmOperands[i].Class < *AsmOperands[i].Class) | |
503 | return false; | |
504 | } | |
505 | ||
506 | // Give matches that require more features higher precedence. This is useful | |
507 | // because we cannot define AssemblerPredicates with the negation of | |
508 | // processor features. For example, ARM v6 "nop" may be either a HINT or | |
509 | // MOV. With v6, we want to match HINT. The assembler has no way to | |
510 | // predicate MOV under "NoV6", but HINT will always match first because it | |
511 | // requires V6 while MOV does not. | |
512 | if (RequiredFeatures.size() != RHS.RequiredFeatures.size()) | |
513 | return RequiredFeatures.size() > RHS.RequiredFeatures.size(); | |
514 | ||
515 | return false; | |
516 | } | |
517 | ||
518 | /// couldMatchAmbiguouslyWith - Check whether this matchable could | |
519 | /// ambiguously match the same set of operands as \p RHS (without being a | |
520 | /// strictly superior match). | |
85aaf69f | 521 | bool couldMatchAmbiguouslyWith(const MatchableInfo &RHS) const { |
223e47cc LB |
522 | // The primary comparator is the instruction mnemonic. |
523 | if (Mnemonic != RHS.Mnemonic) | |
524 | return false; | |
525 | ||
526 | // The number of operands is unambiguous. | |
527 | if (AsmOperands.size() != RHS.AsmOperands.size()) | |
528 | return false; | |
529 | ||
530 | // Otherwise, make sure the ordering of the two instructions is unambiguous | |
531 | // by checking that either (a) a token or operand kind discriminates them, | |
532 | // or (b) the ordering among equivalent kinds is consistent. | |
533 | ||
534 | // Tokens and operand kinds are unambiguous (assuming a correct target | |
535 | // specific parser). | |
536 | for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) | |
537 | if (AsmOperands[i].Class->Kind != RHS.AsmOperands[i].Class->Kind || | |
538 | AsmOperands[i].Class->Kind == ClassInfo::Token) | |
539 | if (*AsmOperands[i].Class < *RHS.AsmOperands[i].Class || | |
540 | *RHS.AsmOperands[i].Class < *AsmOperands[i].Class) | |
541 | return false; | |
542 | ||
543 | // Otherwise, this operand could commute if all operands are equivalent, or | |
544 | // there is a pair of operands that compare less than and a pair that | |
545 | // compare greater than. | |
546 | bool HasLT = false, HasGT = false; | |
547 | for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) { | |
548 | if (*AsmOperands[i].Class < *RHS.AsmOperands[i].Class) | |
549 | HasLT = true; | |
550 | if (*RHS.AsmOperands[i].Class < *AsmOperands[i].Class) | |
551 | HasGT = true; | |
552 | } | |
553 | ||
554 | return !(HasLT ^ HasGT); | |
555 | } | |
556 | ||
85aaf69f | 557 | void dump() const; |
223e47cc LB |
558 | |
559 | private: | |
560 | void tokenizeAsmString(const AsmMatcherInfo &Info); | |
561 | }; | |
562 | ||
563 | /// SubtargetFeatureInfo - Helper class for storing information on a subtarget | |
564 | /// feature which participates in instruction matching. | |
565 | struct SubtargetFeatureInfo { | |
566 | /// \brief The predicate record for this feature. | |
567 | Record *TheDef; | |
568 | ||
569 | /// \brief An unique index assigned to represent this feature. | |
1a4d82fc | 570 | uint64_t Index; |
223e47cc | 571 | |
1a4d82fc | 572 | SubtargetFeatureInfo(Record *D, uint64_t Idx) : TheDef(D), Index(Idx) {} |
223e47cc LB |
573 | |
574 | /// \brief The name of the enumerated constant identifying this feature. | |
575 | std::string getEnumName() const { | |
576 | return "Feature_" + TheDef->getName(); | |
577 | } | |
1a4d82fc | 578 | |
85aaf69f | 579 | void dump() const { |
1a4d82fc JJ |
580 | errs() << getEnumName() << " " << Index << "\n"; |
581 | TheDef->dump(); | |
582 | } | |
223e47cc LB |
583 | }; |
584 | ||
585 | struct OperandMatchEntry { | |
586 | unsigned OperandMask; | |
85aaf69f | 587 | const MatchableInfo* MI; |
223e47cc LB |
588 | ClassInfo *CI; |
589 | ||
85aaf69f | 590 | static OperandMatchEntry create(const MatchableInfo *mi, ClassInfo *ci, |
223e47cc LB |
591 | unsigned opMask) { |
592 | OperandMatchEntry X; | |
593 | X.OperandMask = opMask; | |
594 | X.CI = ci; | |
595 | X.MI = mi; | |
596 | return X; | |
597 | } | |
598 | }; | |
599 | ||
600 | ||
601 | class AsmMatcherInfo { | |
602 | public: | |
603 | /// Tracked Records | |
604 | RecordKeeper &Records; | |
605 | ||
606 | /// The tablegen AsmParser record. | |
607 | Record *AsmParser; | |
608 | ||
609 | /// Target - The target information. | |
610 | CodeGenTarget &Target; | |
611 | ||
612 | /// The classes which are needed for matching. | |
85aaf69f | 613 | std::forward_list<ClassInfo> Classes; |
223e47cc LB |
614 | |
615 | /// The information on the matchables to match. | |
85aaf69f | 616 | std::vector<std::unique_ptr<MatchableInfo>> Matchables; |
223e47cc LB |
617 | |
618 | /// Info for custom matching operands by user defined methods. | |
619 | std::vector<OperandMatchEntry> OperandMatchInfo; | |
620 | ||
621 | /// Map of Register records to their class information. | |
622 | typedef std::map<Record*, ClassInfo*, LessRecordByID> RegisterClassesTy; | |
623 | RegisterClassesTy RegisterClasses; | |
624 | ||
625 | /// Map of Predicate records to their subtarget information. | |
85aaf69f | 626 | std::map<Record *, SubtargetFeatureInfo, LessRecordByID> SubtargetFeatures; |
223e47cc LB |
627 | |
628 | /// Map of AsmOperandClass records to their class information. | |
629 | std::map<Record*, ClassInfo*> AsmOperandClasses; | |
630 | ||
631 | private: | |
632 | /// Map of token to class information which has already been constructed. | |
633 | std::map<std::string, ClassInfo*> TokenClasses; | |
634 | ||
635 | /// Map of RegisterClass records to their class information. | |
636 | std::map<Record*, ClassInfo*> RegisterClassClasses; | |
637 | ||
638 | private: | |
639 | /// getTokenClass - Lookup or create the class for the given token. | |
640 | ClassInfo *getTokenClass(StringRef Token); | |
641 | ||
642 | /// getOperandClass - Lookup or create the class for the given operand. | |
643 | ClassInfo *getOperandClass(const CGIOperandList::OperandInfo &OI, | |
644 | int SubOpIdx); | |
645 | ClassInfo *getOperandClass(Record *Rec, int SubOpIdx); | |
646 | ||
647 | /// buildRegisterClasses - Build the ClassInfo* instances for register | |
648 | /// classes. | |
1a4d82fc | 649 | void buildRegisterClasses(SmallPtrSetImpl<Record*> &SingletonRegisters); |
223e47cc LB |
650 | |
651 | /// buildOperandClasses - Build the ClassInfo* instances for user defined | |
652 | /// operand classes. | |
653 | void buildOperandClasses(); | |
654 | ||
655 | void buildInstructionOperandReference(MatchableInfo *II, StringRef OpName, | |
656 | unsigned AsmOpIdx); | |
657 | void buildAliasOperandReference(MatchableInfo *II, StringRef OpName, | |
658 | MatchableInfo::AsmOperand &Op); | |
659 | ||
660 | public: | |
661 | AsmMatcherInfo(Record *AsmParser, | |
662 | CodeGenTarget &Target, | |
663 | RecordKeeper &Records); | |
664 | ||
665 | /// buildInfo - Construct the various tables used during matching. | |
666 | void buildInfo(); | |
667 | ||
668 | /// buildOperandMatchInfo - Build the necessary information to handle user | |
669 | /// defined operand parsing methods. | |
670 | void buildOperandMatchInfo(); | |
671 | ||
672 | /// getSubtargetFeature - Lookup or create the subtarget feature info for the | |
673 | /// given operand. | |
85aaf69f | 674 | const SubtargetFeatureInfo *getSubtargetFeature(Record *Def) const { |
223e47cc | 675 | assert(Def->isSubClassOf("Predicate") && "Invalid predicate type!"); |
85aaf69f SL |
676 | const auto &I = SubtargetFeatures.find(Def); |
677 | return I == SubtargetFeatures.end() ? nullptr : &I->second; | |
223e47cc LB |
678 | } |
679 | ||
680 | RecordKeeper &getRecords() const { | |
681 | return Records; | |
682 | } | |
683 | }; | |
684 | ||
685 | } // End anonymous namespace | |
686 | ||
85aaf69f | 687 | void MatchableInfo::dump() const { |
223e47cc LB |
688 | errs() << TheDef->getName() << " -- " << "flattened:\"" << AsmString <<"\"\n"; |
689 | ||
690 | for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) { | |
85aaf69f | 691 | const AsmOperand &Op = AsmOperands[i]; |
223e47cc LB |
692 | errs() << " op[" << i << "] = " << Op.Class->ClassName << " - "; |
693 | errs() << '\"' << Op.Token << "\"\n"; | |
694 | } | |
695 | } | |
696 | ||
697 | static std::pair<StringRef, StringRef> | |
698 | parseTwoOperandConstraint(StringRef S, ArrayRef<SMLoc> Loc) { | |
699 | // Split via the '='. | |
700 | std::pair<StringRef, StringRef> Ops = S.split('='); | |
701 | if (Ops.second == "") | |
970d7e83 | 702 | PrintFatalError(Loc, "missing '=' in two-operand alias constraint"); |
223e47cc LB |
703 | // Trim whitespace and the leading '$' on the operand names. |
704 | size_t start = Ops.first.find_first_of('$'); | |
705 | if (start == std::string::npos) | |
970d7e83 | 706 | PrintFatalError(Loc, "expected '$' prefix on asm operand name"); |
223e47cc LB |
707 | Ops.first = Ops.first.slice(start + 1, std::string::npos); |
708 | size_t end = Ops.first.find_last_of(" \t"); | |
709 | Ops.first = Ops.first.slice(0, end); | |
710 | // Now the second operand. | |
711 | start = Ops.second.find_first_of('$'); | |
712 | if (start == std::string::npos) | |
970d7e83 | 713 | PrintFatalError(Loc, "expected '$' prefix on asm operand name"); |
223e47cc LB |
714 | Ops.second = Ops.second.slice(start + 1, std::string::npos); |
715 | end = Ops.second.find_last_of(" \t"); | |
716 | Ops.first = Ops.first.slice(0, end); | |
717 | return Ops; | |
718 | } | |
719 | ||
720 | void MatchableInfo::formTwoOperandAlias(StringRef Constraint) { | |
721 | // Figure out which operands are aliased and mark them as tied. | |
722 | std::pair<StringRef, StringRef> Ops = | |
723 | parseTwoOperandConstraint(Constraint, TheDef->getLoc()); | |
724 | ||
725 | // Find the AsmOperands that refer to the operands we're aliasing. | |
726 | int SrcAsmOperand = findAsmOperandNamed(Ops.first); | |
727 | int DstAsmOperand = findAsmOperandNamed(Ops.second); | |
728 | if (SrcAsmOperand == -1) | |
970d7e83 | 729 | PrintFatalError(TheDef->getLoc(), |
1a4d82fc JJ |
730 | "unknown source two-operand alias operand '" + Ops.first + |
731 | "'."); | |
223e47cc | 732 | if (DstAsmOperand == -1) |
970d7e83 | 733 | PrintFatalError(TheDef->getLoc(), |
1a4d82fc JJ |
734 | "unknown destination two-operand alias operand '" + |
735 | Ops.second + "'."); | |
223e47cc LB |
736 | |
737 | // Find the ResOperand that refers to the operand we're aliasing away | |
738 | // and update it to refer to the combined operand instead. | |
739 | for (unsigned i = 0, e = ResOperands.size(); i != e; ++i) { | |
740 | ResOperand &Op = ResOperands[i]; | |
741 | if (Op.Kind == ResOperand::RenderAsmOperand && | |
742 | Op.AsmOperandNum == (unsigned)SrcAsmOperand) { | |
743 | Op.AsmOperandNum = DstAsmOperand; | |
744 | break; | |
745 | } | |
746 | } | |
747 | // Remove the AsmOperand for the alias operand. | |
748 | AsmOperands.erase(AsmOperands.begin() + SrcAsmOperand); | |
749 | // Adjust the ResOperand references to any AsmOperands that followed | |
750 | // the one we just deleted. | |
751 | for (unsigned i = 0, e = ResOperands.size(); i != e; ++i) { | |
752 | ResOperand &Op = ResOperands[i]; | |
753 | switch(Op.Kind) { | |
754 | default: | |
755 | // Nothing to do for operands that don't reference AsmOperands. | |
756 | break; | |
757 | case ResOperand::RenderAsmOperand: | |
758 | if (Op.AsmOperandNum > (unsigned)SrcAsmOperand) | |
759 | --Op.AsmOperandNum; | |
760 | break; | |
761 | case ResOperand::TiedOperand: | |
762 | if (Op.TiedOperandNum > (unsigned)SrcAsmOperand) | |
763 | --Op.TiedOperandNum; | |
764 | break; | |
765 | } | |
766 | } | |
767 | } | |
768 | ||
769 | void MatchableInfo::initialize(const AsmMatcherInfo &Info, | |
1a4d82fc | 770 | SmallPtrSetImpl<Record*> &SingletonRegisters, |
223e47cc LB |
771 | int AsmVariantNo, std::string &RegisterPrefix) { |
772 | AsmVariantID = AsmVariantNo; | |
773 | AsmString = | |
774 | CodeGenInstruction::FlattenAsmStringVariants(AsmString, AsmVariantNo); | |
775 | ||
776 | tokenizeAsmString(Info); | |
777 | ||
778 | // Compute the require features. | |
779 | std::vector<Record*> Predicates =TheDef->getValueAsListOfDefs("Predicates"); | |
780 | for (unsigned i = 0, e = Predicates.size(); i != e; ++i) | |
85aaf69f SL |
781 | if (const SubtargetFeatureInfo *Feature = |
782 | Info.getSubtargetFeature(Predicates[i])) | |
223e47cc LB |
783 | RequiredFeatures.push_back(Feature); |
784 | ||
785 | // Collect singleton registers, if used. | |
786 | for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) { | |
787 | extractSingletonRegisterForAsmOperand(i, Info, RegisterPrefix); | |
788 | if (Record *Reg = AsmOperands[i].SingletonReg) | |
789 | SingletonRegisters.insert(Reg); | |
790 | } | |
1a4d82fc JJ |
791 | |
792 | const RecordVal *DepMask = TheDef->getValue("DeprecatedFeatureMask"); | |
793 | if (!DepMask) | |
794 | DepMask = TheDef->getValue("ComplexDeprecationPredicate"); | |
795 | ||
796 | HasDeprecation = | |
797 | DepMask ? !DepMask->getValue()->getAsUnquotedString().empty() : false; | |
223e47cc LB |
798 | } |
799 | ||
800 | /// tokenizeAsmString - Tokenize a simplified assembly string. | |
801 | void MatchableInfo::tokenizeAsmString(const AsmMatcherInfo &Info) { | |
802 | StringRef String = AsmString; | |
803 | unsigned Prev = 0; | |
804 | bool InTok = true; | |
805 | for (unsigned i = 0, e = String.size(); i != e; ++i) { | |
806 | switch (String[i]) { | |
807 | case '[': | |
808 | case ']': | |
809 | case '*': | |
810 | case '!': | |
811 | case ' ': | |
812 | case '\t': | |
813 | case ',': | |
814 | if (InTok) { | |
815 | AsmOperands.push_back(AsmOperand(String.slice(Prev, i))); | |
816 | InTok = false; | |
817 | } | |
818 | if (!isspace(String[i]) && String[i] != ',') | |
819 | AsmOperands.push_back(AsmOperand(String.substr(i, 1))); | |
820 | Prev = i + 1; | |
821 | break; | |
822 | ||
823 | case '\\': | |
824 | if (InTok) { | |
825 | AsmOperands.push_back(AsmOperand(String.slice(Prev, i))); | |
826 | InTok = false; | |
827 | } | |
828 | ++i; | |
829 | assert(i != String.size() && "Invalid quoted character"); | |
830 | AsmOperands.push_back(AsmOperand(String.substr(i, 1))); | |
831 | Prev = i + 1; | |
832 | break; | |
833 | ||
834 | case '$': { | |
835 | if (InTok) { | |
836 | AsmOperands.push_back(AsmOperand(String.slice(Prev, i))); | |
837 | InTok = false; | |
838 | } | |
839 | ||
840 | // If this isn't "${", treat like a normal token. | |
841 | if (i + 1 == String.size() || String[i + 1] != '{') { | |
842 | Prev = i; | |
843 | break; | |
844 | } | |
845 | ||
846 | StringRef::iterator End = std::find(String.begin() + i, String.end(),'}'); | |
847 | assert(End != String.end() && "Missing brace in operand reference!"); | |
848 | size_t EndPos = End - String.begin(); | |
849 | AsmOperands.push_back(AsmOperand(String.slice(i, EndPos+1))); | |
850 | Prev = EndPos + 1; | |
851 | i = EndPos; | |
852 | break; | |
853 | } | |
854 | ||
855 | case '.': | |
1a4d82fc JJ |
856 | if (!Info.AsmParser->getValueAsBit("MnemonicContainsDot")) { |
857 | if (InTok) | |
858 | AsmOperands.push_back(AsmOperand(String.slice(Prev, i))); | |
859 | Prev = i; | |
860 | } | |
223e47cc LB |
861 | InTok = true; |
862 | break; | |
863 | ||
864 | default: | |
865 | InTok = true; | |
866 | } | |
867 | } | |
868 | if (InTok && Prev != String.size()) | |
869 | AsmOperands.push_back(AsmOperand(String.substr(Prev))); | |
870 | ||
871 | // The first token of the instruction is the mnemonic, which must be a | |
872 | // simple string, not a $foo variable or a singleton register. | |
873 | if (AsmOperands.empty()) | |
970d7e83 | 874 | PrintFatalError(TheDef->getLoc(), |
223e47cc LB |
875 | "Instruction '" + TheDef->getName() + "' has no tokens"); |
876 | Mnemonic = AsmOperands[0].Token; | |
877 | if (Mnemonic.empty()) | |
970d7e83 | 878 | PrintFatalError(TheDef->getLoc(), |
223e47cc LB |
879 | "Missing instruction mnemonic"); |
880 | // FIXME : Check and raise an error if it is a register. | |
881 | if (Mnemonic[0] == '$') | |
970d7e83 | 882 | PrintFatalError(TheDef->getLoc(), |
1a4d82fc | 883 | "Invalid instruction mnemonic '" + Mnemonic + "'!"); |
223e47cc LB |
884 | |
885 | // Remove the first operand, it is tracked in the mnemonic field. | |
886 | AsmOperands.erase(AsmOperands.begin()); | |
887 | } | |
888 | ||
889 | bool MatchableInfo::validate(StringRef CommentDelimiter, bool Hack) const { | |
890 | // Reject matchables with no .s string. | |
891 | if (AsmString.empty()) | |
970d7e83 | 892 | PrintFatalError(TheDef->getLoc(), "instruction with empty asm string"); |
223e47cc LB |
893 | |
894 | // Reject any matchables with a newline in them, they should be marked | |
895 | // isCodeGenOnly if they are pseudo instructions. | |
896 | if (AsmString.find('\n') != std::string::npos) | |
970d7e83 | 897 | PrintFatalError(TheDef->getLoc(), |
223e47cc LB |
898 | "multiline instruction is not valid for the asmparser, " |
899 | "mark it isCodeGenOnly"); | |
900 | ||
901 | // Remove comments from the asm string. We know that the asmstring only | |
902 | // has one line. | |
903 | if (!CommentDelimiter.empty() && | |
904 | StringRef(AsmString).find(CommentDelimiter) != StringRef::npos) | |
970d7e83 | 905 | PrintFatalError(TheDef->getLoc(), |
223e47cc LB |
906 | "asmstring for instruction has comment character in it, " |
907 | "mark it isCodeGenOnly"); | |
908 | ||
909 | // Reject matchables with operand modifiers, these aren't something we can | |
910 | // handle, the target should be refactored to use operands instead of | |
911 | // modifiers. | |
912 | // | |
913 | // Also, check for instructions which reference the operand multiple times; | |
914 | // this implies a constraint we would not honor. | |
915 | std::set<std::string> OperandNames; | |
916 | for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) { | |
917 | StringRef Tok = AsmOperands[i].Token; | |
918 | if (Tok[0] == '$' && Tok.find(':') != StringRef::npos) | |
970d7e83 | 919 | PrintFatalError(TheDef->getLoc(), |
1a4d82fc JJ |
920 | "matchable with operand modifier '" + Tok + |
921 | "' not supported by asm matcher. Mark isCodeGenOnly!"); | |
223e47cc LB |
922 | |
923 | // Verify that any operand is only mentioned once. | |
924 | // We reject aliases and ignore instructions for now. | |
925 | if (Tok[0] == '$' && !OperandNames.insert(Tok).second) { | |
926 | if (!Hack) | |
970d7e83 | 927 | PrintFatalError(TheDef->getLoc(), |
1a4d82fc JJ |
928 | "ERROR: matchable with tied operand '" + Tok + |
929 | "' can never be matched!"); | |
223e47cc LB |
930 | // FIXME: Should reject these. The ARM backend hits this with $lane in a |
931 | // bunch of instructions. It is unclear what the right answer is. | |
932 | DEBUG({ | |
933 | errs() << "warning: '" << TheDef->getName() << "': " | |
934 | << "ignoring instruction with tied operand '" | |
1a4d82fc | 935 | << Tok << "'\n"; |
223e47cc LB |
936 | }); |
937 | return false; | |
938 | } | |
939 | } | |
940 | ||
941 | return true; | |
942 | } | |
943 | ||
944 | /// extractSingletonRegisterForAsmOperand - Extract singleton register, | |
945 | /// if present, from specified token. | |
946 | void MatchableInfo:: | |
947 | extractSingletonRegisterForAsmOperand(unsigned OperandNo, | |
948 | const AsmMatcherInfo &Info, | |
949 | std::string &RegisterPrefix) { | |
950 | StringRef Tok = AsmOperands[OperandNo].Token; | |
951 | if (RegisterPrefix.empty()) { | |
952 | std::string LoweredTok = Tok.lower(); | |
953 | if (const CodeGenRegister *Reg = Info.Target.getRegisterByName(LoweredTok)) | |
954 | AsmOperands[OperandNo].SingletonReg = Reg->TheDef; | |
955 | return; | |
956 | } | |
957 | ||
958 | if (!Tok.startswith(RegisterPrefix)) | |
959 | return; | |
960 | ||
961 | StringRef RegName = Tok.substr(RegisterPrefix.size()); | |
962 | if (const CodeGenRegister *Reg = Info.Target.getRegisterByName(RegName)) | |
963 | AsmOperands[OperandNo].SingletonReg = Reg->TheDef; | |
964 | ||
965 | // If there is no register prefix (i.e. "%" in "%eax"), then this may | |
966 | // be some random non-register token, just ignore it. | |
967 | return; | |
968 | } | |
969 | ||
970 | static std::string getEnumNameForToken(StringRef Str) { | |
971 | std::string Res; | |
972 | ||
973 | for (StringRef::iterator it = Str.begin(), ie = Str.end(); it != ie; ++it) { | |
974 | switch (*it) { | |
975 | case '*': Res += "_STAR_"; break; | |
976 | case '%': Res += "_PCT_"; break; | |
977 | case ':': Res += "_COLON_"; break; | |
978 | case '!': Res += "_EXCLAIM_"; break; | |
979 | case '.': Res += "_DOT_"; break; | |
970d7e83 LB |
980 | case '<': Res += "_LT_"; break; |
981 | case '>': Res += "_GT_"; break; | |
223e47cc | 982 | default: |
970d7e83 LB |
983 | if ((*it >= 'A' && *it <= 'Z') || |
984 | (*it >= 'a' && *it <= 'z') || | |
985 | (*it >= '0' && *it <= '9')) | |
223e47cc LB |
986 | Res += *it; |
987 | else | |
988 | Res += "_" + utostr((unsigned) *it) + "_"; | |
989 | } | |
990 | } | |
991 | ||
992 | return Res; | |
993 | } | |
994 | ||
995 | ClassInfo *AsmMatcherInfo::getTokenClass(StringRef Token) { | |
996 | ClassInfo *&Entry = TokenClasses[Token]; | |
997 | ||
998 | if (!Entry) { | |
85aaf69f SL |
999 | Classes.emplace_front(); |
1000 | Entry = &Classes.front(); | |
223e47cc LB |
1001 | Entry->Kind = ClassInfo::Token; |
1002 | Entry->ClassName = "Token"; | |
1003 | Entry->Name = "MCK_" + getEnumNameForToken(Token); | |
1004 | Entry->ValueName = Token; | |
1005 | Entry->PredicateMethod = "<invalid>"; | |
1006 | Entry->RenderMethod = "<invalid>"; | |
1007 | Entry->ParserMethod = ""; | |
1008 | Entry->DiagnosticType = ""; | |
223e47cc LB |
1009 | } |
1010 | ||
1011 | return Entry; | |
1012 | } | |
1013 | ||
1014 | ClassInfo * | |
1015 | AsmMatcherInfo::getOperandClass(const CGIOperandList::OperandInfo &OI, | |
1016 | int SubOpIdx) { | |
1017 | Record *Rec = OI.Rec; | |
1018 | if (SubOpIdx != -1) | |
970d7e83 | 1019 | Rec = cast<DefInit>(OI.MIOperandInfo->getArg(SubOpIdx))->getDef(); |
223e47cc LB |
1020 | return getOperandClass(Rec, SubOpIdx); |
1021 | } | |
1022 | ||
1023 | ClassInfo * | |
1024 | AsmMatcherInfo::getOperandClass(Record *Rec, int SubOpIdx) { | |
1025 | if (Rec->isSubClassOf("RegisterOperand")) { | |
1026 | // RegisterOperand may have an associated ParserMatchClass. If it does, | |
1027 | // use it, else just fall back to the underlying register class. | |
1028 | const RecordVal *R = Rec->getValue("ParserMatchClass"); | |
1a4d82fc | 1029 | if (!R || !R->getValue()) |
970d7e83 LB |
1030 | PrintFatalError("Record `" + Rec->getName() + |
1031 | "' does not have a ParserMatchClass!\n"); | |
223e47cc | 1032 | |
970d7e83 | 1033 | if (DefInit *DI= dyn_cast<DefInit>(R->getValue())) { |
223e47cc LB |
1034 | Record *MatchClass = DI->getDef(); |
1035 | if (ClassInfo *CI = AsmOperandClasses[MatchClass]) | |
1036 | return CI; | |
1037 | } | |
1038 | ||
1039 | // No custom match class. Just use the register class. | |
1040 | Record *ClassRec = Rec->getValueAsDef("RegClass"); | |
1041 | if (!ClassRec) | |
970d7e83 | 1042 | PrintFatalError(Rec->getLoc(), "RegisterOperand `" + Rec->getName() + |
223e47cc LB |
1043 | "' has no associated register class!\n"); |
1044 | if (ClassInfo *CI = RegisterClassClasses[ClassRec]) | |
1045 | return CI; | |
970d7e83 | 1046 | PrintFatalError(Rec->getLoc(), "register class has no class info!"); |
223e47cc LB |
1047 | } |
1048 | ||
1049 | ||
1050 | if (Rec->isSubClassOf("RegisterClass")) { | |
1051 | if (ClassInfo *CI = RegisterClassClasses[Rec]) | |
1052 | return CI; | |
970d7e83 | 1053 | PrintFatalError(Rec->getLoc(), "register class has no class info!"); |
223e47cc LB |
1054 | } |
1055 | ||
1056 | if (!Rec->isSubClassOf("Operand")) | |
970d7e83 | 1057 | PrintFatalError(Rec->getLoc(), "Operand `" + Rec->getName() + |
223e47cc LB |
1058 | "' does not derive from class Operand!\n"); |
1059 | Record *MatchClass = Rec->getValueAsDef("ParserMatchClass"); | |
1060 | if (ClassInfo *CI = AsmOperandClasses[MatchClass]) | |
1061 | return CI; | |
1062 | ||
970d7e83 | 1063 | PrintFatalError(Rec->getLoc(), "operand has no match class!"); |
223e47cc LB |
1064 | } |
1065 | ||
1a4d82fc JJ |
1066 | struct LessRegisterSet { |
1067 | bool operator() (const RegisterSet &LHS, const RegisterSet & RHS) const { | |
1068 | // std::set<T> defines its own compariso "operator<", but it | |
1069 | // performs a lexicographical comparison by T's innate comparison | |
1070 | // for some reason. We don't want non-deterministic pointer | |
1071 | // comparisons so use this instead. | |
1072 | return std::lexicographical_compare(LHS.begin(), LHS.end(), | |
1073 | RHS.begin(), RHS.end(), | |
1074 | LessRecordByID()); | |
1075 | } | |
1076 | }; | |
1077 | ||
223e47cc | 1078 | void AsmMatcherInfo:: |
1a4d82fc | 1079 | buildRegisterClasses(SmallPtrSetImpl<Record*> &SingletonRegisters) { |
85aaf69f SL |
1080 | const auto &Registers = Target.getRegBank().getRegisters(); |
1081 | auto &RegClassList = Target.getRegBank().getRegClasses(); | |
223e47cc | 1082 | |
1a4d82fc JJ |
1083 | typedef std::set<RegisterSet, LessRegisterSet> RegisterSetSet; |
1084 | ||
223e47cc | 1085 | // The register sets used for matching. |
1a4d82fc | 1086 | RegisterSetSet RegisterSets; |
223e47cc LB |
1087 | |
1088 | // Gather the defined sets. | |
85aaf69f SL |
1089 | for (const CodeGenRegisterClass &RC : RegClassList) |
1090 | RegisterSets.insert( | |
1091 | RegisterSet(RC.getOrder().begin(), RC.getOrder().end())); | |
223e47cc LB |
1092 | |
1093 | // Add any required singleton sets. | |
85aaf69f | 1094 | for (Record *Rec : SingletonRegisters) { |
1a4d82fc | 1095 | RegisterSets.insert(RegisterSet(&Rec, &Rec + 1)); |
223e47cc LB |
1096 | } |
1097 | ||
1098 | // Introduce derived sets where necessary (when a register does not determine | |
1099 | // a unique register set class), and build the mapping of registers to the set | |
1100 | // they should classify to. | |
1a4d82fc | 1101 | std::map<Record*, RegisterSet> RegisterMap; |
85aaf69f | 1102 | for (const CodeGenRegister &CGR : Registers) { |
223e47cc | 1103 | // Compute the intersection of all sets containing this register. |
1a4d82fc | 1104 | RegisterSet ContainingSet; |
223e47cc | 1105 | |
85aaf69f SL |
1106 | for (const RegisterSet &RS : RegisterSets) { |
1107 | if (!RS.count(CGR.TheDef)) | |
223e47cc LB |
1108 | continue; |
1109 | ||
1110 | if (ContainingSet.empty()) { | |
85aaf69f | 1111 | ContainingSet = RS; |
223e47cc LB |
1112 | continue; |
1113 | } | |
1114 | ||
1a4d82fc | 1115 | RegisterSet Tmp; |
223e47cc | 1116 | std::swap(Tmp, ContainingSet); |
1a4d82fc JJ |
1117 | std::insert_iterator<RegisterSet> II(ContainingSet, |
1118 | ContainingSet.begin()); | |
85aaf69f | 1119 | std::set_intersection(Tmp.begin(), Tmp.end(), RS.begin(), RS.end(), II, |
1a4d82fc | 1120 | LessRecordByID()); |
223e47cc LB |
1121 | } |
1122 | ||
1123 | if (!ContainingSet.empty()) { | |
1124 | RegisterSets.insert(ContainingSet); | |
1125 | RegisterMap.insert(std::make_pair(CGR.TheDef, ContainingSet)); | |
1126 | } | |
1127 | } | |
1128 | ||
1129 | // Construct the register classes. | |
1a4d82fc | 1130 | std::map<RegisterSet, ClassInfo*, LessRegisterSet> RegisterSetClasses; |
223e47cc | 1131 | unsigned Index = 0; |
85aaf69f SL |
1132 | for (const RegisterSet &RS : RegisterSets) { |
1133 | Classes.emplace_front(); | |
1134 | ClassInfo *CI = &Classes.front(); | |
223e47cc LB |
1135 | CI->Kind = ClassInfo::RegisterClass0 + Index; |
1136 | CI->ClassName = "Reg" + utostr(Index); | |
1137 | CI->Name = "MCK_Reg" + utostr(Index); | |
1138 | CI->ValueName = ""; | |
1139 | CI->PredicateMethod = ""; // unused | |
1140 | CI->RenderMethod = "addRegOperands"; | |
85aaf69f | 1141 | CI->Registers = RS; |
223e47cc LB |
1142 | // FIXME: diagnostic type. |
1143 | CI->DiagnosticType = ""; | |
85aaf69f SL |
1144 | RegisterSetClasses.insert(std::make_pair(RS, CI)); |
1145 | ++Index; | |
223e47cc LB |
1146 | } |
1147 | ||
1148 | // Find the superclasses; we could compute only the subgroup lattice edges, | |
1149 | // but there isn't really a point. | |
85aaf69f SL |
1150 | for (const RegisterSet &RS : RegisterSets) { |
1151 | ClassInfo *CI = RegisterSetClasses[RS]; | |
1152 | for (const RegisterSet &RS2 : RegisterSets) | |
1153 | if (RS != RS2 && | |
1154 | std::includes(RS2.begin(), RS2.end(), RS.begin(), RS.end(), | |
1a4d82fc | 1155 | LessRecordByID())) |
85aaf69f | 1156 | CI->SuperClasses.push_back(RegisterSetClasses[RS2]); |
223e47cc LB |
1157 | } |
1158 | ||
1159 | // Name the register classes which correspond to a user defined RegisterClass. | |
85aaf69f | 1160 | for (const CodeGenRegisterClass &RC : RegClassList) { |
223e47cc LB |
1161 | // Def will be NULL for non-user defined register classes. |
1162 | Record *Def = RC.getDef(); | |
1163 | if (!Def) | |
1164 | continue; | |
1a4d82fc JJ |
1165 | ClassInfo *CI = RegisterSetClasses[RegisterSet(RC.getOrder().begin(), |
1166 | RC.getOrder().end())]; | |
223e47cc LB |
1167 | if (CI->ValueName.empty()) { |
1168 | CI->ClassName = RC.getName(); | |
1169 | CI->Name = "MCK_" + RC.getName(); | |
1170 | CI->ValueName = RC.getName(); | |
1171 | } else | |
1172 | CI->ValueName = CI->ValueName + "," + RC.getName(); | |
1173 | ||
1174 | RegisterClassClasses.insert(std::make_pair(Def, CI)); | |
1175 | } | |
1176 | ||
1177 | // Populate the map for individual registers. | |
1a4d82fc | 1178 | for (std::map<Record*, RegisterSet>::iterator it = RegisterMap.begin(), |
223e47cc LB |
1179 | ie = RegisterMap.end(); it != ie; ++it) |
1180 | RegisterClasses[it->first] = RegisterSetClasses[it->second]; | |
1181 | ||
1182 | // Name the register classes which correspond to singleton registers. | |
85aaf69f | 1183 | for (Record *Rec : SingletonRegisters) { |
223e47cc LB |
1184 | ClassInfo *CI = RegisterClasses[Rec]; |
1185 | assert(CI && "Missing singleton register class info!"); | |
1186 | ||
1187 | if (CI->ValueName.empty()) { | |
1188 | CI->ClassName = Rec->getName(); | |
1189 | CI->Name = "MCK_" + Rec->getName(); | |
1190 | CI->ValueName = Rec->getName(); | |
1191 | } else | |
1192 | CI->ValueName = CI->ValueName + "," + Rec->getName(); | |
1193 | } | |
1194 | } | |
1195 | ||
1196 | void AsmMatcherInfo::buildOperandClasses() { | |
1197 | std::vector<Record*> AsmOperands = | |
1198 | Records.getAllDerivedDefinitions("AsmOperandClass"); | |
1199 | ||
1200 | // Pre-populate AsmOperandClasses map. | |
85aaf69f SL |
1201 | for (Record *Rec : AsmOperands) { |
1202 | Classes.emplace_front(); | |
1203 | AsmOperandClasses[Rec] = &Classes.front(); | |
1204 | } | |
223e47cc LB |
1205 | |
1206 | unsigned Index = 0; | |
85aaf69f SL |
1207 | for (Record *Rec : AsmOperands) { |
1208 | ClassInfo *CI = AsmOperandClasses[Rec]; | |
223e47cc LB |
1209 | CI->Kind = ClassInfo::UserClass0 + Index; |
1210 | ||
85aaf69f | 1211 | ListInit *Supers = Rec->getValueAsListInit("SuperClasses"); |
223e47cc | 1212 | for (unsigned i = 0, e = Supers->getSize(); i != e; ++i) { |
970d7e83 | 1213 | DefInit *DI = dyn_cast<DefInit>(Supers->getElement(i)); |
223e47cc | 1214 | if (!DI) { |
85aaf69f | 1215 | PrintError(Rec->getLoc(), "Invalid super class reference!"); |
223e47cc LB |
1216 | continue; |
1217 | } | |
1218 | ||
1219 | ClassInfo *SC = AsmOperandClasses[DI->getDef()]; | |
1220 | if (!SC) | |
85aaf69f | 1221 | PrintError(Rec->getLoc(), "Invalid super class reference!"); |
223e47cc LB |
1222 | else |
1223 | CI->SuperClasses.push_back(SC); | |
1224 | } | |
85aaf69f | 1225 | CI->ClassName = Rec->getValueAsString("Name"); |
223e47cc | 1226 | CI->Name = "MCK_" + CI->ClassName; |
85aaf69f | 1227 | CI->ValueName = Rec->getName(); |
223e47cc LB |
1228 | |
1229 | // Get or construct the predicate method name. | |
85aaf69f | 1230 | Init *PMName = Rec->getValueInit("PredicateMethod"); |
970d7e83 | 1231 | if (StringInit *SI = dyn_cast<StringInit>(PMName)) { |
223e47cc LB |
1232 | CI->PredicateMethod = SI->getValue(); |
1233 | } else { | |
970d7e83 | 1234 | assert(isa<UnsetInit>(PMName) && "Unexpected PredicateMethod field!"); |
223e47cc LB |
1235 | CI->PredicateMethod = "is" + CI->ClassName; |
1236 | } | |
1237 | ||
1238 | // Get or construct the render method name. | |
85aaf69f | 1239 | Init *RMName = Rec->getValueInit("RenderMethod"); |
970d7e83 | 1240 | if (StringInit *SI = dyn_cast<StringInit>(RMName)) { |
223e47cc LB |
1241 | CI->RenderMethod = SI->getValue(); |
1242 | } else { | |
970d7e83 | 1243 | assert(isa<UnsetInit>(RMName) && "Unexpected RenderMethod field!"); |
223e47cc LB |
1244 | CI->RenderMethod = "add" + CI->ClassName + "Operands"; |
1245 | } | |
1246 | ||
1247 | // Get the parse method name or leave it as empty. | |
85aaf69f | 1248 | Init *PRMName = Rec->getValueInit("ParserMethod"); |
970d7e83 | 1249 | if (StringInit *SI = dyn_cast<StringInit>(PRMName)) |
223e47cc LB |
1250 | CI->ParserMethod = SI->getValue(); |
1251 | ||
1252 | // Get the diagnostic type or leave it as empty. | |
1253 | // Get the parse method name or leave it as empty. | |
85aaf69f | 1254 | Init *DiagnosticType = Rec->getValueInit("DiagnosticType"); |
970d7e83 | 1255 | if (StringInit *SI = dyn_cast<StringInit>(DiagnosticType)) |
223e47cc LB |
1256 | CI->DiagnosticType = SI->getValue(); |
1257 | ||
85aaf69f | 1258 | ++Index; |
223e47cc LB |
1259 | } |
1260 | } | |
1261 | ||
1262 | AsmMatcherInfo::AsmMatcherInfo(Record *asmParser, | |
1263 | CodeGenTarget &target, | |
1264 | RecordKeeper &records) | |
1265 | : Records(records), AsmParser(asmParser), Target(target) { | |
1266 | } | |
1267 | ||
1268 | /// buildOperandMatchInfo - Build the necessary information to handle user | |
1269 | /// defined operand parsing methods. | |
1270 | void AsmMatcherInfo::buildOperandMatchInfo() { | |
1271 | ||
1272 | /// Map containing a mask with all operands indices that can be found for | |
1273 | /// that class inside a instruction. | |
1a4d82fc | 1274 | typedef std::map<ClassInfo *, unsigned, less_ptr<ClassInfo>> OpClassMaskTy; |
223e47cc LB |
1275 | OpClassMaskTy OpClassMask; |
1276 | ||
85aaf69f | 1277 | for (const auto &MI : Matchables) { |
223e47cc LB |
1278 | OpClassMask.clear(); |
1279 | ||
1280 | // Keep track of all operands of this instructions which belong to the | |
1281 | // same class. | |
85aaf69f SL |
1282 | for (unsigned i = 0, e = MI->AsmOperands.size(); i != e; ++i) { |
1283 | const MatchableInfo::AsmOperand &Op = MI->AsmOperands[i]; | |
223e47cc LB |
1284 | if (Op.Class->ParserMethod.empty()) |
1285 | continue; | |
1286 | unsigned &OperandMask = OpClassMask[Op.Class]; | |
1287 | OperandMask |= (1 << i); | |
1288 | } | |
1289 | ||
1290 | // Generate operand match info for each mnemonic/operand class pair. | |
85aaf69f SL |
1291 | for (const auto &OCM : OpClassMask) { |
1292 | unsigned OpMask = OCM.second; | |
1293 | ClassInfo *CI = OCM.first; | |
1294 | OperandMatchInfo.push_back(OperandMatchEntry::create(MI.get(), CI, | |
1295 | OpMask)); | |
223e47cc LB |
1296 | } |
1297 | } | |
1298 | } | |
1299 | ||
1300 | void AsmMatcherInfo::buildInfo() { | |
1301 | // Build information about all of the AssemblerPredicates. | |
1302 | std::vector<Record*> AllPredicates = | |
1303 | Records.getAllDerivedDefinitions("Predicate"); | |
1304 | for (unsigned i = 0, e = AllPredicates.size(); i != e; ++i) { | |
1305 | Record *Pred = AllPredicates[i]; | |
1306 | // Ignore predicates that are not intended for the assembler. | |
1307 | if (!Pred->getValueAsBit("AssemblerMatcherPredicate")) | |
1308 | continue; | |
1309 | ||
1310 | if (Pred->getName().empty()) | |
970d7e83 | 1311 | PrintFatalError(Pred->getLoc(), "Predicate has no name!"); |
223e47cc | 1312 | |
85aaf69f SL |
1313 | SubtargetFeatures.insert(std::make_pair( |
1314 | Pred, SubtargetFeatureInfo(Pred, SubtargetFeatures.size()))); | |
1315 | DEBUG(SubtargetFeatures.find(Pred)->second.dump()); | |
1316 | assert(SubtargetFeatures.size() <= 64 && "Too many subtarget features!"); | |
223e47cc LB |
1317 | } |
1318 | ||
1319 | // Parse the instructions; we need to do this first so that we can gather the | |
1320 | // singleton register classes. | |
1321 | SmallPtrSet<Record*, 16> SingletonRegisters; | |
1322 | unsigned VariantCount = Target.getAsmParserVariantCount(); | |
1323 | for (unsigned VC = 0; VC != VariantCount; ++VC) { | |
1324 | Record *AsmVariant = Target.getAsmParserVariant(VC); | |
1325 | std::string CommentDelimiter = | |
1326 | AsmVariant->getValueAsString("CommentDelimiter"); | |
1327 | std::string RegisterPrefix = AsmVariant->getValueAsString("RegisterPrefix"); | |
1328 | int AsmVariantNo = AsmVariant->getValueAsInt("Variant"); | |
1329 | ||
85aaf69f | 1330 | for (const CodeGenInstruction *CGI : Target.instructions()) { |
223e47cc LB |
1331 | |
1332 | // If the tblgen -match-prefix option is specified (for tblgen hackers), | |
1333 | // filter the set of instructions we consider. | |
85aaf69f | 1334 | if (!StringRef(CGI->TheDef->getName()).startswith(MatchPrefix)) |
223e47cc LB |
1335 | continue; |
1336 | ||
1337 | // Ignore "codegen only" instructions. | |
85aaf69f | 1338 | if (CGI->TheDef->getValueAsBit("isCodeGenOnly")) |
223e47cc LB |
1339 | continue; |
1340 | ||
85aaf69f | 1341 | std::unique_ptr<MatchableInfo> II(new MatchableInfo(*CGI)); |
223e47cc LB |
1342 | |
1343 | II->initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix); | |
1344 | ||
1345 | // Ignore instructions which shouldn't be matched and diagnose invalid | |
1346 | // instruction definitions with an error. | |
1347 | if (!II->validate(CommentDelimiter, true)) | |
1348 | continue; | |
1349 | ||
85aaf69f | 1350 | Matchables.push_back(std::move(II)); |
223e47cc LB |
1351 | } |
1352 | ||
1353 | // Parse all of the InstAlias definitions and stick them in the list of | |
1354 | // matchables. | |
1355 | std::vector<Record*> AllInstAliases = | |
1356 | Records.getAllDerivedDefinitions("InstAlias"); | |
1357 | for (unsigned i = 0, e = AllInstAliases.size(); i != e; ++i) { | |
85aaf69f SL |
1358 | auto Alias = llvm::make_unique<CodeGenInstAlias>(AllInstAliases[i], |
1359 | AsmVariantNo, Target); | |
223e47cc LB |
1360 | |
1361 | // If the tblgen -match-prefix option is specified (for tblgen hackers), | |
1362 | // filter the set of instruction aliases we consider, based on the target | |
1363 | // instruction. | |
1364 | if (!StringRef(Alias->ResultInst->TheDef->getName()) | |
1365 | .startswith( MatchPrefix)) | |
1366 | continue; | |
1367 | ||
85aaf69f | 1368 | std::unique_ptr<MatchableInfo> II(new MatchableInfo(std::move(Alias))); |
223e47cc LB |
1369 | |
1370 | II->initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix); | |
1371 | ||
1372 | // Validate the alias definitions. | |
1373 | II->validate(CommentDelimiter, false); | |
1374 | ||
85aaf69f | 1375 | Matchables.push_back(std::move(II)); |
223e47cc LB |
1376 | } |
1377 | } | |
1378 | ||
1379 | // Build info for the register classes. | |
1380 | buildRegisterClasses(SingletonRegisters); | |
1381 | ||
1382 | // Build info for the user defined assembly operand classes. | |
1383 | buildOperandClasses(); | |
1384 | ||
1385 | // Build the information about matchables, now that we have fully formed | |
1386 | // classes. | |
85aaf69f SL |
1387 | std::vector<std::unique_ptr<MatchableInfo>> NewMatchables; |
1388 | for (auto &II : Matchables) { | |
223e47cc LB |
1389 | // Parse the tokens after the mnemonic. |
1390 | // Note: buildInstructionOperandReference may insert new AsmOperands, so | |
1391 | // don't precompute the loop bound. | |
1392 | for (unsigned i = 0; i != II->AsmOperands.size(); ++i) { | |
1393 | MatchableInfo::AsmOperand &Op = II->AsmOperands[i]; | |
1394 | StringRef Token = Op.Token; | |
1395 | ||
1396 | // Check for singleton registers. | |
1397 | if (Record *RegRecord = II->AsmOperands[i].SingletonReg) { | |
1398 | Op.Class = RegisterClasses[RegRecord]; | |
1399 | assert(Op.Class && Op.Class->Registers.size() == 1 && | |
1400 | "Unexpected class for singleton register"); | |
1401 | continue; | |
1402 | } | |
1403 | ||
1404 | // Check for simple tokens. | |
1405 | if (Token[0] != '$') { | |
1406 | Op.Class = getTokenClass(Token); | |
1407 | continue; | |
1408 | } | |
1409 | ||
1410 | if (Token.size() > 1 && isdigit(Token[1])) { | |
1411 | Op.Class = getTokenClass(Token); | |
1412 | continue; | |
1413 | } | |
1414 | ||
1415 | // Otherwise this is an operand reference. | |
1416 | StringRef OperandName; | |
1417 | if (Token[1] == '{') | |
1418 | OperandName = Token.substr(2, Token.size() - 3); | |
1419 | else | |
1420 | OperandName = Token.substr(1); | |
1421 | ||
1422 | if (II->DefRec.is<const CodeGenInstruction*>()) | |
85aaf69f | 1423 | buildInstructionOperandReference(II.get(), OperandName, i); |
223e47cc | 1424 | else |
85aaf69f | 1425 | buildAliasOperandReference(II.get(), OperandName, Op); |
223e47cc LB |
1426 | } |
1427 | ||
1428 | if (II->DefRec.is<const CodeGenInstruction*>()) { | |
1429 | II->buildInstructionResultOperands(); | |
1430 | // If the instruction has a two-operand alias, build up the | |
1431 | // matchable here. We'll add them in bulk at the end to avoid | |
1432 | // confusing this loop. | |
1433 | std::string Constraint = | |
1434 | II->TheDef->getValueAsString("TwoOperandAliasConstraint"); | |
1435 | if (Constraint != "") { | |
1436 | // Start by making a copy of the original matchable. | |
1a4d82fc | 1437 | std::unique_ptr<MatchableInfo> AliasII(new MatchableInfo(*II)); |
223e47cc LB |
1438 | |
1439 | // Adjust it to be a two-operand alias. | |
1440 | AliasII->formTwoOperandAlias(Constraint); | |
1441 | ||
1442 | // Add the alias to the matchables list. | |
85aaf69f | 1443 | NewMatchables.push_back(std::move(AliasII)); |
223e47cc LB |
1444 | } |
1445 | } else | |
1446 | II->buildAliasResultOperands(); | |
1447 | } | |
1448 | if (!NewMatchables.empty()) | |
85aaf69f SL |
1449 | std::move(NewMatchables.begin(), NewMatchables.end(), |
1450 | std::back_inserter(Matchables)); | |
223e47cc LB |
1451 | |
1452 | // Process token alias definitions and set up the associated superclass | |
1453 | // information. | |
1454 | std::vector<Record*> AllTokenAliases = | |
1455 | Records.getAllDerivedDefinitions("TokenAlias"); | |
1456 | for (unsigned i = 0, e = AllTokenAliases.size(); i != e; ++i) { | |
1457 | Record *Rec = AllTokenAliases[i]; | |
1458 | ClassInfo *FromClass = getTokenClass(Rec->getValueAsString("FromToken")); | |
1459 | ClassInfo *ToClass = getTokenClass(Rec->getValueAsString("ToToken")); | |
1460 | if (FromClass == ToClass) | |
970d7e83 | 1461 | PrintFatalError(Rec->getLoc(), |
223e47cc LB |
1462 | "error: Destination value identical to source value."); |
1463 | FromClass->SuperClasses.push_back(ToClass); | |
1464 | } | |
1465 | ||
1466 | // Reorder classes so that classes precede super classes. | |
85aaf69f | 1467 | Classes.sort(); |
223e47cc LB |
1468 | } |
1469 | ||
1470 | /// buildInstructionOperandReference - The specified operand is a reference to a | |
1471 | /// named operand such as $src. Resolve the Class and OperandInfo pointers. | |
1472 | void AsmMatcherInfo:: | |
1473 | buildInstructionOperandReference(MatchableInfo *II, | |
1474 | StringRef OperandName, | |
1475 | unsigned AsmOpIdx) { | |
1476 | const CodeGenInstruction &CGI = *II->DefRec.get<const CodeGenInstruction*>(); | |
1477 | const CGIOperandList &Operands = CGI.Operands; | |
1478 | MatchableInfo::AsmOperand *Op = &II->AsmOperands[AsmOpIdx]; | |
1479 | ||
1480 | // Map this token to an operand. | |
1481 | unsigned Idx; | |
1482 | if (!Operands.hasOperandNamed(OperandName, Idx)) | |
1a4d82fc JJ |
1483 | PrintFatalError(II->TheDef->getLoc(), |
1484 | "error: unable to find operand: '" + OperandName + "'"); | |
223e47cc LB |
1485 | |
1486 | // If the instruction operand has multiple suboperands, but the parser | |
1487 | // match class for the asm operand is still the default "ImmAsmOperand", | |
1488 | // then handle each suboperand separately. | |
1489 | if (Op->SubOpIdx == -1 && Operands[Idx].MINumOperands > 1) { | |
1490 | Record *Rec = Operands[Idx].Rec; | |
1491 | assert(Rec->isSubClassOf("Operand") && "Unexpected operand!"); | |
1492 | Record *MatchClass = Rec->getValueAsDef("ParserMatchClass"); | |
1493 | if (MatchClass && MatchClass->getValueAsString("Name") == "Imm") { | |
1494 | // Insert remaining suboperands after AsmOpIdx in II->AsmOperands. | |
1495 | StringRef Token = Op->Token; // save this in case Op gets moved | |
1496 | for (unsigned SI = 1, SE = Operands[Idx].MINumOperands; SI != SE; ++SI) { | |
1497 | MatchableInfo::AsmOperand NewAsmOp(Token); | |
1498 | NewAsmOp.SubOpIdx = SI; | |
1499 | II->AsmOperands.insert(II->AsmOperands.begin()+AsmOpIdx+SI, NewAsmOp); | |
1500 | } | |
1501 | // Replace Op with first suboperand. | |
1502 | Op = &II->AsmOperands[AsmOpIdx]; // update the pointer in case it moved | |
1503 | Op->SubOpIdx = 0; | |
1504 | } | |
1505 | } | |
1506 | ||
1507 | // Set up the operand class. | |
1508 | Op->Class = getOperandClass(Operands[Idx], Op->SubOpIdx); | |
1509 | ||
1510 | // If the named operand is tied, canonicalize it to the untied operand. | |
1511 | // For example, something like: | |
1512 | // (outs GPR:$dst), (ins GPR:$src) | |
1513 | // with an asmstring of | |
1514 | // "inc $src" | |
1515 | // we want to canonicalize to: | |
1516 | // "inc $dst" | |
1517 | // so that we know how to provide the $dst operand when filling in the result. | |
1a4d82fc JJ |
1518 | int OITied = -1; |
1519 | if (Operands[Idx].MINumOperands == 1) | |
1520 | OITied = Operands[Idx].getTiedRegister(); | |
223e47cc LB |
1521 | if (OITied != -1) { |
1522 | // The tied operand index is an MIOperand index, find the operand that | |
1523 | // contains it. | |
1524 | std::pair<unsigned, unsigned> Idx = Operands.getSubOperandNumber(OITied); | |
1525 | OperandName = Operands[Idx.first].Name; | |
1526 | Op->SubOpIdx = Idx.second; | |
1527 | } | |
1528 | ||
1529 | Op->SrcOpName = OperandName; | |
1530 | } | |
1531 | ||
1532 | /// buildAliasOperandReference - When parsing an operand reference out of the | |
1533 | /// matching string (e.g. "movsx $src, $dst"), determine what the class of the | |
1534 | /// operand reference is by looking it up in the result pattern definition. | |
1535 | void AsmMatcherInfo::buildAliasOperandReference(MatchableInfo *II, | |
1536 | StringRef OperandName, | |
1537 | MatchableInfo::AsmOperand &Op) { | |
1538 | const CodeGenInstAlias &CGA = *II->DefRec.get<const CodeGenInstAlias*>(); | |
1539 | ||
1540 | // Set up the operand class. | |
1541 | for (unsigned i = 0, e = CGA.ResultOperands.size(); i != e; ++i) | |
1542 | if (CGA.ResultOperands[i].isRecord() && | |
1543 | CGA.ResultOperands[i].getName() == OperandName) { | |
1544 | // It's safe to go with the first one we find, because CodeGenInstAlias | |
1545 | // validates that all operands with the same name have the same record. | |
1546 | Op.SubOpIdx = CGA.ResultInstOperandIndex[i].second; | |
1547 | // Use the match class from the Alias definition, not the | |
1548 | // destination instruction, as we may have an immediate that's | |
1549 | // being munged by the match class. | |
1550 | Op.Class = getOperandClass(CGA.ResultOperands[i].getRecord(), | |
1551 | Op.SubOpIdx); | |
1552 | Op.SrcOpName = OperandName; | |
1553 | return; | |
1554 | } | |
1555 | ||
1a4d82fc JJ |
1556 | PrintFatalError(II->TheDef->getLoc(), |
1557 | "error: unable to find operand: '" + OperandName + "'"); | |
223e47cc LB |
1558 | } |
1559 | ||
1560 | void MatchableInfo::buildInstructionResultOperands() { | |
1561 | const CodeGenInstruction *ResultInst = getResultInst(); | |
1562 | ||
1563 | // Loop over all operands of the result instruction, determining how to | |
1564 | // populate them. | |
1565 | for (unsigned i = 0, e = ResultInst->Operands.size(); i != e; ++i) { | |
1566 | const CGIOperandList::OperandInfo &OpInfo = ResultInst->Operands[i]; | |
1567 | ||
1568 | // If this is a tied operand, just copy from the previously handled operand. | |
1a4d82fc JJ |
1569 | int TiedOp = -1; |
1570 | if (OpInfo.MINumOperands == 1) | |
1571 | TiedOp = OpInfo.getTiedRegister(); | |
223e47cc LB |
1572 | if (TiedOp != -1) { |
1573 | ResOperands.push_back(ResOperand::getTiedOp(TiedOp)); | |
1574 | continue; | |
1575 | } | |
1576 | ||
1577 | // Find out what operand from the asmparser this MCInst operand comes from. | |
1578 | int SrcOperand = findAsmOperandNamed(OpInfo.Name); | |
1a4d82fc JJ |
1579 | if (OpInfo.Name.empty() || SrcOperand == -1) { |
1580 | // This may happen for operands that are tied to a suboperand of a | |
1581 | // complex operand. Simply use a dummy value here; nobody should | |
1582 | // use this operand slot. | |
1583 | // FIXME: The long term goal is for the MCOperand list to not contain | |
1584 | // tied operands at all. | |
1585 | ResOperands.push_back(ResOperand::getImmOp(0)); | |
1586 | continue; | |
1587 | } | |
223e47cc LB |
1588 | |
1589 | // Check if the one AsmOperand populates the entire operand. | |
1590 | unsigned NumOperands = OpInfo.MINumOperands; | |
1591 | if (AsmOperands[SrcOperand].SubOpIdx == -1) { | |
1592 | ResOperands.push_back(ResOperand::getRenderedOp(SrcOperand, NumOperands)); | |
1593 | continue; | |
1594 | } | |
1595 | ||
1596 | // Add a separate ResOperand for each suboperand. | |
1597 | for (unsigned AI = 0; AI < NumOperands; ++AI) { | |
1598 | assert(AsmOperands[SrcOperand+AI].SubOpIdx == (int)AI && | |
1599 | AsmOperands[SrcOperand+AI].SrcOpName == OpInfo.Name && | |
1600 | "unexpected AsmOperands for suboperands"); | |
1601 | ResOperands.push_back(ResOperand::getRenderedOp(SrcOperand + AI, 1)); | |
1602 | } | |
1603 | } | |
1604 | } | |
1605 | ||
1606 | void MatchableInfo::buildAliasResultOperands() { | |
1607 | const CodeGenInstAlias &CGA = *DefRec.get<const CodeGenInstAlias*>(); | |
1608 | const CodeGenInstruction *ResultInst = getResultInst(); | |
1609 | ||
1610 | // Loop over all operands of the result instruction, determining how to | |
1611 | // populate them. | |
1612 | unsigned AliasOpNo = 0; | |
1613 | unsigned LastOpNo = CGA.ResultInstOperandIndex.size(); | |
1614 | for (unsigned i = 0, e = ResultInst->Operands.size(); i != e; ++i) { | |
1615 | const CGIOperandList::OperandInfo *OpInfo = &ResultInst->Operands[i]; | |
1616 | ||
1617 | // If this is a tied operand, just copy from the previously handled operand. | |
1a4d82fc JJ |
1618 | int TiedOp = -1; |
1619 | if (OpInfo->MINumOperands == 1) | |
1620 | TiedOp = OpInfo->getTiedRegister(); | |
223e47cc LB |
1621 | if (TiedOp != -1) { |
1622 | ResOperands.push_back(ResOperand::getTiedOp(TiedOp)); | |
1623 | continue; | |
1624 | } | |
1625 | ||
1626 | // Handle all the suboperands for this operand. | |
1627 | const std::string &OpName = OpInfo->Name; | |
1628 | for ( ; AliasOpNo < LastOpNo && | |
1629 | CGA.ResultInstOperandIndex[AliasOpNo].first == i; ++AliasOpNo) { | |
1630 | int SubIdx = CGA.ResultInstOperandIndex[AliasOpNo].second; | |
1631 | ||
1632 | // Find out what operand from the asmparser that this MCInst operand | |
1633 | // comes from. | |
1634 | switch (CGA.ResultOperands[AliasOpNo].Kind) { | |
1635 | case CodeGenInstAlias::ResultOperand::K_Record: { | |
1636 | StringRef Name = CGA.ResultOperands[AliasOpNo].getName(); | |
1637 | int SrcOperand = findAsmOperand(Name, SubIdx); | |
1638 | if (SrcOperand == -1) | |
970d7e83 | 1639 | PrintFatalError(TheDef->getLoc(), "Instruction '" + |
223e47cc LB |
1640 | TheDef->getName() + "' has operand '" + OpName + |
1641 | "' that doesn't appear in asm string!"); | |
1642 | unsigned NumOperands = (SubIdx == -1 ? OpInfo->MINumOperands : 1); | |
1643 | ResOperands.push_back(ResOperand::getRenderedOp(SrcOperand, | |
1644 | NumOperands)); | |
1645 | break; | |
1646 | } | |
1647 | case CodeGenInstAlias::ResultOperand::K_Imm: { | |
1648 | int64_t ImmVal = CGA.ResultOperands[AliasOpNo].getImm(); | |
1649 | ResOperands.push_back(ResOperand::getImmOp(ImmVal)); | |
1650 | break; | |
1651 | } | |
1652 | case CodeGenInstAlias::ResultOperand::K_Reg: { | |
1653 | Record *Reg = CGA.ResultOperands[AliasOpNo].getRegister(); | |
1654 | ResOperands.push_back(ResOperand::getRegOp(Reg)); | |
1655 | break; | |
1656 | } | |
1657 | } | |
1658 | } | |
1659 | } | |
1660 | } | |
1661 | ||
1662 | static unsigned getConverterOperandID(const std::string &Name, | |
1663 | SetVector<std::string> &Table, | |
1664 | bool &IsNew) { | |
1665 | IsNew = Table.insert(Name); | |
1666 | ||
1667 | unsigned ID = IsNew ? Table.size() - 1 : | |
1668 | std::find(Table.begin(), Table.end(), Name) - Table.begin(); | |
1669 | ||
1670 | assert(ID < Table.size()); | |
1671 | ||
1672 | return ID; | |
1673 | } | |
1674 | ||
1675 | ||
970d7e83 | 1676 | static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName, |
85aaf69f | 1677 | std::vector<std::unique_ptr<MatchableInfo>> &Infos, |
970d7e83 | 1678 | raw_ostream &OS) { |
223e47cc LB |
1679 | SetVector<std::string> OperandConversionKinds; |
1680 | SetVector<std::string> InstructionConversionKinds; | |
1681 | std::vector<std::vector<uint8_t> > ConversionTable; | |
1682 | size_t MaxRowLength = 2; // minimum is custom converter plus terminator. | |
1683 | ||
1684 | // TargetOperandClass - This is the target's operand class, like X86Operand. | |
1685 | std::string TargetOperandClass = Target.getName() + "Operand"; | |
1686 | ||
1687 | // Write the convert function to a separate stream, so we can drop it after | |
1688 | // the enum. We'll build up the conversion handlers for the individual | |
1689 | // operand types opportunistically as we encounter them. | |
1690 | std::string ConvertFnBody; | |
1691 | raw_string_ostream CvtOS(ConvertFnBody); | |
1692 | // Start the unified conversion function. | |
1693 | CvtOS << "void " << Target.getName() << ClassName << "::\n" | |
1694 | << "convertToMCInst(unsigned Kind, MCInst &Inst, " | |
1695 | << "unsigned Opcode,\n" | |
1a4d82fc JJ |
1696 | << " const OperandVector" |
1697 | << " &Operands) {\n" | |
223e47cc LB |
1698 | << " assert(Kind < CVT_NUM_SIGNATURES && \"Invalid signature!\");\n" |
1699 | << " const uint8_t *Converter = ConversionTable[Kind];\n" | |
1700 | << " Inst.setOpcode(Opcode);\n" | |
1701 | << " for (const uint8_t *p = Converter; *p; p+= 2) {\n" | |
1702 | << " switch (*p) {\n" | |
1703 | << " default: llvm_unreachable(\"invalid conversion entry!\");\n" | |
1704 | << " case CVT_Reg:\n" | |
1705 | << " static_cast<" << TargetOperandClass | |
1a4d82fc | 1706 | << "&>(*Operands[*(p + 1)]).addRegOperands(Inst, 1);\n" |
223e47cc LB |
1707 | << " break;\n" |
1708 | << " case CVT_Tied:\n" | |
1709 | << " Inst.addOperand(Inst.getOperand(*(p + 1)));\n" | |
1710 | << " break;\n"; | |
1711 | ||
1712 | std::string OperandFnBody; | |
1713 | raw_string_ostream OpOS(OperandFnBody); | |
1714 | // Start the operand number lookup function. | |
970d7e83 LB |
1715 | OpOS << "void " << Target.getName() << ClassName << "::\n" |
1716 | << "convertToMapAndConstraints(unsigned Kind,\n"; | |
1717 | OpOS.indent(27); | |
1a4d82fc | 1718 | OpOS << "const OperandVector &Operands) {\n" |
223e47cc | 1719 | << " assert(Kind < CVT_NUM_SIGNATURES && \"Invalid signature!\");\n" |
970d7e83 | 1720 | << " unsigned NumMCOperands = 0;\n" |
223e47cc LB |
1721 | << " const uint8_t *Converter = ConversionTable[Kind];\n" |
1722 | << " for (const uint8_t *p = Converter; *p; p+= 2) {\n" | |
223e47cc LB |
1723 | << " switch (*p) {\n" |
1724 | << " default: llvm_unreachable(\"invalid conversion entry!\");\n" | |
1725 | << " case CVT_Reg:\n" | |
970d7e83 LB |
1726 | << " Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);\n" |
1727 | << " Operands[*(p + 1)]->setConstraint(\"r\");\n" | |
1728 | << " ++NumMCOperands;\n" | |
223e47cc LB |
1729 | << " break;\n" |
1730 | << " case CVT_Tied:\n" | |
970d7e83 | 1731 | << " ++NumMCOperands;\n" |
223e47cc LB |
1732 | << " break;\n"; |
1733 | ||
1734 | // Pre-populate the operand conversion kinds with the standard always | |
1735 | // available entries. | |
1736 | OperandConversionKinds.insert("CVT_Done"); | |
1737 | OperandConversionKinds.insert("CVT_Reg"); | |
1738 | OperandConversionKinds.insert("CVT_Tied"); | |
1739 | enum { CVT_Done, CVT_Reg, CVT_Tied }; | |
1740 | ||
85aaf69f | 1741 | for (auto &II : Infos) { |
223e47cc LB |
1742 | // Check if we have a custom match function. |
1743 | std::string AsmMatchConverter = | |
85aaf69f | 1744 | II->getResultInst()->TheDef->getValueAsString("AsmMatchConverter"); |
223e47cc LB |
1745 | if (!AsmMatchConverter.empty()) { |
1746 | std::string Signature = "ConvertCustom_" + AsmMatchConverter; | |
85aaf69f | 1747 | II->ConversionFnKind = Signature; |
223e47cc LB |
1748 | |
1749 | // Check if we have already generated this signature. | |
1750 | if (!InstructionConversionKinds.insert(Signature)) | |
1751 | continue; | |
1752 | ||
1753 | // Remember this converter for the kind enum. | |
1754 | unsigned KindID = OperandConversionKinds.size(); | |
970d7e83 LB |
1755 | OperandConversionKinds.insert("CVT_" + |
1756 | getEnumNameForToken(AsmMatchConverter)); | |
223e47cc LB |
1757 | |
1758 | // Add the converter row for this instruction. | |
1759 | ConversionTable.push_back(std::vector<uint8_t>()); | |
1760 | ConversionTable.back().push_back(KindID); | |
1761 | ConversionTable.back().push_back(CVT_Done); | |
1762 | ||
1763 | // Add the handler to the conversion driver function. | |
970d7e83 LB |
1764 | CvtOS << " case CVT_" |
1765 | << getEnumNameForToken(AsmMatchConverter) << ":\n" | |
223e47cc LB |
1766 | << " " << AsmMatchConverter << "(Inst, Operands);\n" |
1767 | << " break;\n"; | |
1768 | ||
1769 | // FIXME: Handle the operand number lookup for custom match functions. | |
1770 | continue; | |
1771 | } | |
1772 | ||
1773 | // Build the conversion function signature. | |
1774 | std::string Signature = "Convert"; | |
1775 | ||
1776 | std::vector<uint8_t> ConversionRow; | |
1777 | ||
1778 | // Compute the convert enum and the case body. | |
85aaf69f | 1779 | MaxRowLength = std::max(MaxRowLength, II->ResOperands.size()*2 + 1 ); |
223e47cc | 1780 | |
85aaf69f SL |
1781 | for (unsigned i = 0, e = II->ResOperands.size(); i != e; ++i) { |
1782 | const MatchableInfo::ResOperand &OpInfo = II->ResOperands[i]; | |
223e47cc LB |
1783 | |
1784 | // Generate code to populate each result operand. | |
1785 | switch (OpInfo.Kind) { | |
1786 | case MatchableInfo::ResOperand::RenderAsmOperand: { | |
1787 | // This comes from something we parsed. | |
85aaf69f SL |
1788 | const MatchableInfo::AsmOperand &Op = |
1789 | II->AsmOperands[OpInfo.AsmOperandNum]; | |
223e47cc LB |
1790 | |
1791 | // Registers are always converted the same, don't duplicate the | |
1792 | // conversion function based on them. | |
1793 | Signature += "__"; | |
1794 | std::string Class; | |
1795 | Class = Op.Class->isRegisterClass() ? "Reg" : Op.Class->ClassName; | |
1796 | Signature += Class; | |
1797 | Signature += utostr(OpInfo.MINumOperands); | |
1798 | Signature += "_" + itostr(OpInfo.AsmOperandNum); | |
1799 | ||
1800 | // Add the conversion kind, if necessary, and get the associated ID | |
1801 | // the index of its entry in the vector). | |
1802 | std::string Name = "CVT_" + (Op.Class->isRegisterClass() ? "Reg" : | |
1803 | Op.Class->RenderMethod); | |
970d7e83 | 1804 | Name = getEnumNameForToken(Name); |
223e47cc LB |
1805 | |
1806 | bool IsNewConverter = false; | |
1807 | unsigned ID = getConverterOperandID(Name, OperandConversionKinds, | |
1808 | IsNewConverter); | |
1809 | ||
1810 | // Add the operand entry to the instruction kind conversion row. | |
1811 | ConversionRow.push_back(ID); | |
1812 | ConversionRow.push_back(OpInfo.AsmOperandNum + 1); | |
1813 | ||
1814 | if (!IsNewConverter) | |
1815 | break; | |
1816 | ||
1817 | // This is a new operand kind. Add a handler for it to the | |
1818 | // converter driver. | |
1819 | CvtOS << " case " << Name << ":\n" | |
1820 | << " static_cast<" << TargetOperandClass | |
1a4d82fc JJ |
1821 | << "&>(*Operands[*(p + 1)])." << Op.Class->RenderMethod |
1822 | << "(Inst, " << OpInfo.MINumOperands << ");\n" | |
223e47cc LB |
1823 | << " break;\n"; |
1824 | ||
1825 | // Add a handler for the operand number lookup. | |
1826 | OpOS << " case " << Name << ":\n" | |
970d7e83 LB |
1827 | << " Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);\n"; |
1828 | ||
1829 | if (Op.Class->isRegisterClass()) | |
1830 | OpOS << " Operands[*(p + 1)]->setConstraint(\"r\");\n"; | |
1831 | else | |
1832 | OpOS << " Operands[*(p + 1)]->setConstraint(\"m\");\n"; | |
1833 | OpOS << " NumMCOperands += " << OpInfo.MINumOperands << ";\n" | |
223e47cc LB |
1834 | << " break;\n"; |
1835 | break; | |
1836 | } | |
1837 | case MatchableInfo::ResOperand::TiedOperand: { | |
1838 | // If this operand is tied to a previous one, just copy the MCInst | |
1839 | // operand from the earlier one.We can only tie single MCOperand values. | |
1a4d82fc | 1840 | assert(OpInfo.MINumOperands == 1 && "Not a singular MCOperand"); |
223e47cc LB |
1841 | unsigned TiedOp = OpInfo.TiedOperandNum; |
1842 | assert(i > TiedOp && "Tied operand precedes its target!"); | |
1843 | Signature += "__Tie" + utostr(TiedOp); | |
1844 | ConversionRow.push_back(CVT_Tied); | |
1845 | ConversionRow.push_back(TiedOp); | |
223e47cc LB |
1846 | break; |
1847 | } | |
1848 | case MatchableInfo::ResOperand::ImmOperand: { | |
1849 | int64_t Val = OpInfo.ImmVal; | |
1850 | std::string Ty = "imm_" + itostr(Val); | |
1851 | Signature += "__" + Ty; | |
1852 | ||
1853 | std::string Name = "CVT_" + Ty; | |
1854 | bool IsNewConverter = false; | |
1855 | unsigned ID = getConverterOperandID(Name, OperandConversionKinds, | |
1856 | IsNewConverter); | |
1857 | // Add the operand entry to the instruction kind conversion row. | |
1858 | ConversionRow.push_back(ID); | |
1859 | ConversionRow.push_back(0); | |
1860 | ||
1861 | if (!IsNewConverter) | |
1862 | break; | |
1863 | ||
1864 | CvtOS << " case " << Name << ":\n" | |
1865 | << " Inst.addOperand(MCOperand::CreateImm(" << Val << "));\n" | |
1866 | << " break;\n"; | |
1867 | ||
1868 | OpOS << " case " << Name << ":\n" | |
970d7e83 LB |
1869 | << " Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);\n" |
1870 | << " Operands[*(p + 1)]->setConstraint(\"\");\n" | |
1871 | << " ++NumMCOperands;\n" | |
223e47cc LB |
1872 | << " break;\n"; |
1873 | break; | |
1874 | } | |
1875 | case MatchableInfo::ResOperand::RegOperand: { | |
1876 | std::string Reg, Name; | |
1a4d82fc | 1877 | if (!OpInfo.Register) { |
223e47cc LB |
1878 | Name = "reg0"; |
1879 | Reg = "0"; | |
1880 | } else { | |
1881 | Reg = getQualifiedName(OpInfo.Register); | |
1882 | Name = "reg" + OpInfo.Register->getName(); | |
1883 | } | |
1884 | Signature += "__" + Name; | |
1885 | Name = "CVT_" + Name; | |
1886 | bool IsNewConverter = false; | |
1887 | unsigned ID = getConverterOperandID(Name, OperandConversionKinds, | |
1888 | IsNewConverter); | |
1889 | // Add the operand entry to the instruction kind conversion row. | |
1890 | ConversionRow.push_back(ID); | |
1891 | ConversionRow.push_back(0); | |
1892 | ||
1893 | if (!IsNewConverter) | |
1894 | break; | |
1895 | CvtOS << " case " << Name << ":\n" | |
1896 | << " Inst.addOperand(MCOperand::CreateReg(" << Reg << "));\n" | |
1897 | << " break;\n"; | |
1898 | ||
1899 | OpOS << " case " << Name << ":\n" | |
970d7e83 LB |
1900 | << " Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);\n" |
1901 | << " Operands[*(p + 1)]->setConstraint(\"m\");\n" | |
1902 | << " ++NumMCOperands;\n" | |
223e47cc LB |
1903 | << " break;\n"; |
1904 | } | |
1905 | } | |
1906 | } | |
1907 | ||
1908 | // If there were no operands, add to the signature to that effect | |
1909 | if (Signature == "Convert") | |
1910 | Signature += "_NoOperands"; | |
1911 | ||
85aaf69f | 1912 | II->ConversionFnKind = Signature; |
223e47cc LB |
1913 | |
1914 | // Save the signature. If we already have it, don't add a new row | |
1915 | // to the table. | |
1916 | if (!InstructionConversionKinds.insert(Signature)) | |
1917 | continue; | |
1918 | ||
1919 | // Add the row to the table. | |
1920 | ConversionTable.push_back(ConversionRow); | |
1921 | } | |
1922 | ||
1923 | // Finish up the converter driver function. | |
1924 | CvtOS << " }\n }\n}\n\n"; | |
1925 | ||
1926 | // Finish up the operand number lookup function. | |
970d7e83 | 1927 | OpOS << " }\n }\n}\n\n"; |
223e47cc LB |
1928 | |
1929 | OS << "namespace {\n"; | |
1930 | ||
1931 | // Output the operand conversion kind enum. | |
1932 | OS << "enum OperatorConversionKind {\n"; | |
1933 | for (unsigned i = 0, e = OperandConversionKinds.size(); i != e; ++i) | |
1934 | OS << " " << OperandConversionKinds[i] << ",\n"; | |
1935 | OS << " CVT_NUM_CONVERTERS\n"; | |
1936 | OS << "};\n\n"; | |
1937 | ||
1938 | // Output the instruction conversion kind enum. | |
1939 | OS << "enum InstructionConversionKind {\n"; | |
1940 | for (SetVector<std::string>::const_iterator | |
1941 | i = InstructionConversionKinds.begin(), | |
1942 | e = InstructionConversionKinds.end(); i != e; ++i) | |
1943 | OS << " " << *i << ",\n"; | |
1944 | OS << " CVT_NUM_SIGNATURES\n"; | |
1945 | OS << "};\n\n"; | |
1946 | ||
1947 | ||
1948 | OS << "} // end anonymous namespace\n\n"; | |
1949 | ||
1950 | // Output the conversion table. | |
1951 | OS << "static const uint8_t ConversionTable[CVT_NUM_SIGNATURES][" | |
1952 | << MaxRowLength << "] = {\n"; | |
1953 | ||
1954 | for (unsigned Row = 0, ERow = ConversionTable.size(); Row != ERow; ++Row) { | |
1955 | assert(ConversionTable[Row].size() % 2 == 0 && "bad conversion row!"); | |
1956 | OS << " // " << InstructionConversionKinds[Row] << "\n"; | |
1957 | OS << " { "; | |
1958 | for (unsigned i = 0, e = ConversionTable[Row].size(); i != e; i += 2) | |
1959 | OS << OperandConversionKinds[ConversionTable[Row][i]] << ", " | |
1960 | << (unsigned)(ConversionTable[Row][i + 1]) << ", "; | |
1961 | OS << "CVT_Done },\n"; | |
1962 | } | |
1963 | ||
1964 | OS << "};\n\n"; | |
1965 | ||
1966 | // Spit out the conversion driver function. | |
1967 | OS << CvtOS.str(); | |
1968 | ||
1969 | // Spit out the operand number lookup function. | |
1970 | OS << OpOS.str(); | |
1971 | } | |
1972 | ||
1973 | /// emitMatchClassEnumeration - Emit the enumeration for match class kinds. | |
1974 | static void emitMatchClassEnumeration(CodeGenTarget &Target, | |
85aaf69f | 1975 | std::forward_list<ClassInfo> &Infos, |
223e47cc LB |
1976 | raw_ostream &OS) { |
1977 | OS << "namespace {\n\n"; | |
1978 | ||
1979 | OS << "/// MatchClassKind - The kinds of classes which participate in\n" | |
1980 | << "/// instruction matching.\n"; | |
1981 | OS << "enum MatchClassKind {\n"; | |
1982 | OS << " InvalidMatchClass = 0,\n"; | |
85aaf69f | 1983 | for (const auto &CI : Infos) { |
223e47cc LB |
1984 | OS << " " << CI.Name << ", // "; |
1985 | if (CI.Kind == ClassInfo::Token) { | |
1986 | OS << "'" << CI.ValueName << "'\n"; | |
1987 | } else if (CI.isRegisterClass()) { | |
1988 | if (!CI.ValueName.empty()) | |
1989 | OS << "register class '" << CI.ValueName << "'\n"; | |
1990 | else | |
1991 | OS << "derived register class\n"; | |
1992 | } else { | |
1993 | OS << "user defined class '" << CI.ValueName << "'\n"; | |
1994 | } | |
1995 | } | |
1996 | OS << " NumMatchClassKinds\n"; | |
1997 | OS << "};\n\n"; | |
1998 | ||
1999 | OS << "}\n\n"; | |
2000 | } | |
2001 | ||
2002 | /// emitValidateOperandClass - Emit the function to validate an operand class. | |
2003 | static void emitValidateOperandClass(AsmMatcherInfo &Info, | |
2004 | raw_ostream &OS) { | |
1a4d82fc | 2005 | OS << "static unsigned validateOperandClass(MCParsedAsmOperand &GOp, " |
223e47cc | 2006 | << "MatchClassKind Kind) {\n"; |
1a4d82fc JJ |
2007 | OS << " " << Info.Target.getName() << "Operand &Operand = (" |
2008 | << Info.Target.getName() << "Operand&)GOp;\n"; | |
223e47cc LB |
2009 | |
2010 | // The InvalidMatchClass is not to match any operand. | |
2011 | OS << " if (Kind == InvalidMatchClass)\n"; | |
2012 | OS << " return MCTargetAsmParser::Match_InvalidOperand;\n\n"; | |
2013 | ||
2014 | // Check for Token operands first. | |
2015 | // FIXME: Use a more specific diagnostic type. | |
2016 | OS << " if (Operand.isToken())\n"; | |
2017 | OS << " return isSubclass(matchTokenString(Operand.getToken()), Kind) ?\n" | |
2018 | << " MCTargetAsmParser::Match_Success :\n" | |
2019 | << " MCTargetAsmParser::Match_InvalidOperand;\n\n"; | |
2020 | ||
2021 | // Check the user classes. We don't care what order since we're only | |
2022 | // actually matching against one of them. | |
85aaf69f | 2023 | for (const auto &CI : Info.Classes) { |
223e47cc LB |
2024 | if (!CI.isUserClass()) |
2025 | continue; | |
2026 | ||
2027 | OS << " // '" << CI.ClassName << "' class\n"; | |
2028 | OS << " if (Kind == " << CI.Name << ") {\n"; | |
2029 | OS << " if (Operand." << CI.PredicateMethod << "())\n"; | |
2030 | OS << " return MCTargetAsmParser::Match_Success;\n"; | |
2031 | if (!CI.DiagnosticType.empty()) | |
2032 | OS << " return " << Info.Target.getName() << "AsmParser::Match_" | |
2033 | << CI.DiagnosticType << ";\n"; | |
2034 | OS << " }\n\n"; | |
2035 | } | |
2036 | ||
2037 | // Check for register operands, including sub-classes. | |
2038 | OS << " if (Operand.isReg()) {\n"; | |
2039 | OS << " MatchClassKind OpKind;\n"; | |
2040 | OS << " switch (Operand.getReg()) {\n"; | |
2041 | OS << " default: OpKind = InvalidMatchClass; break;\n"; | |
85aaf69f | 2042 | for (const auto &RC : Info.RegisterClasses) |
223e47cc | 2043 | OS << " case " << Info.Target.getName() << "::" |
85aaf69f | 2044 | << RC.first->getName() << ": OpKind = " << RC.second->Name |
223e47cc LB |
2045 | << "; break;\n"; |
2046 | OS << " }\n"; | |
2047 | OS << " return isSubclass(OpKind, Kind) ? " | |
2048 | << "MCTargetAsmParser::Match_Success :\n " | |
2049 | << " MCTargetAsmParser::Match_InvalidOperand;\n }\n\n"; | |
2050 | ||
2051 | // Generic fallthrough match failure case for operands that don't have | |
2052 | // specialized diagnostic types. | |
2053 | OS << " return MCTargetAsmParser::Match_InvalidOperand;\n"; | |
2054 | OS << "}\n\n"; | |
2055 | } | |
2056 | ||
2057 | /// emitIsSubclass - Emit the subclass predicate function. | |
2058 | static void emitIsSubclass(CodeGenTarget &Target, | |
85aaf69f | 2059 | std::forward_list<ClassInfo> &Infos, |
223e47cc LB |
2060 | raw_ostream &OS) { |
2061 | OS << "/// isSubclass - Compute whether \\p A is a subclass of \\p B.\n"; | |
2062 | OS << "static bool isSubclass(MatchClassKind A, MatchClassKind B) {\n"; | |
2063 | OS << " if (A == B)\n"; | |
2064 | OS << " return true;\n\n"; | |
2065 | ||
1a4d82fc JJ |
2066 | std::string OStr; |
2067 | raw_string_ostream SS(OStr); | |
2068 | unsigned Count = 0; | |
2069 | SS << " switch (A) {\n"; | |
2070 | SS << " default:\n"; | |
2071 | SS << " return false;\n"; | |
85aaf69f | 2072 | for (const auto &A : Infos) { |
223e47cc | 2073 | std::vector<StringRef> SuperClasses; |
85aaf69f | 2074 | for (const auto &B : Infos) { |
223e47cc LB |
2075 | if (&A != &B && A.isSubsetOf(B)) |
2076 | SuperClasses.push_back(B.Name); | |
2077 | } | |
2078 | ||
2079 | if (SuperClasses.empty()) | |
2080 | continue; | |
1a4d82fc | 2081 | ++Count; |
223e47cc | 2082 | |
1a4d82fc | 2083 | SS << "\n case " << A.Name << ":\n"; |
223e47cc LB |
2084 | |
2085 | if (SuperClasses.size() == 1) { | |
1a4d82fc | 2086 | SS << " return B == " << SuperClasses.back().str() << ";\n"; |
223e47cc LB |
2087 | continue; |
2088 | } | |
2089 | ||
1a4d82fc JJ |
2090 | if (!SuperClasses.empty()) { |
2091 | SS << " switch (B) {\n"; | |
2092 | SS << " default: return false;\n"; | |
2093 | for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i) | |
2094 | SS << " case " << SuperClasses[i].str() << ": return true;\n"; | |
2095 | SS << " }\n"; | |
2096 | } else { | |
2097 | // No case statement to emit | |
2098 | SS << " return false;\n"; | |
2099 | } | |
223e47cc | 2100 | } |
1a4d82fc JJ |
2101 | SS << " }\n"; |
2102 | ||
2103 | // If there were case statements emitted into the string stream, write them | |
2104 | // to the output stream, otherwise write the default. | |
2105 | if (Count) | |
2106 | OS << SS.str(); | |
2107 | else | |
2108 | OS << " return false;\n"; | |
2109 | ||
223e47cc LB |
2110 | OS << "}\n\n"; |
2111 | } | |
2112 | ||
2113 | /// emitMatchTokenString - Emit the function to match a token string to the | |
2114 | /// appropriate match class value. | |
2115 | static void emitMatchTokenString(CodeGenTarget &Target, | |
85aaf69f | 2116 | std::forward_list<ClassInfo> &Infos, |
223e47cc LB |
2117 | raw_ostream &OS) { |
2118 | // Construct the match list. | |
2119 | std::vector<StringMatcher::StringPair> Matches; | |
85aaf69f | 2120 | for (const auto &CI : Infos) { |
223e47cc | 2121 | if (CI.Kind == ClassInfo::Token) |
85aaf69f SL |
2122 | Matches.push_back( |
2123 | StringMatcher::StringPair(CI.ValueName, "return " + CI.Name + ";")); | |
223e47cc LB |
2124 | } |
2125 | ||
2126 | OS << "static MatchClassKind matchTokenString(StringRef Name) {\n"; | |
2127 | ||
2128 | StringMatcher("Name", Matches, OS).Emit(); | |
2129 | ||
2130 | OS << " return InvalidMatchClass;\n"; | |
2131 | OS << "}\n\n"; | |
2132 | } | |
2133 | ||
2134 | /// emitMatchRegisterName - Emit the function to match a string to the target | |
2135 | /// specific register enum. | |
2136 | static void emitMatchRegisterName(CodeGenTarget &Target, Record *AsmParser, | |
2137 | raw_ostream &OS) { | |
2138 | // Construct the match list. | |
2139 | std::vector<StringMatcher::StringPair> Matches; | |
85aaf69f SL |
2140 | const auto &Regs = Target.getRegBank().getRegisters(); |
2141 | for (const CodeGenRegister &Reg : Regs) { | |
2142 | if (Reg.TheDef->getValueAsString("AsmName").empty()) | |
223e47cc LB |
2143 | continue; |
2144 | ||
85aaf69f SL |
2145 | Matches.push_back( |
2146 | StringMatcher::StringPair(Reg.TheDef->getValueAsString("AsmName"), | |
2147 | "return " + utostr(Reg.EnumValue) + ";")); | |
223e47cc LB |
2148 | } |
2149 | ||
2150 | OS << "static unsigned MatchRegisterName(StringRef Name) {\n"; | |
2151 | ||
2152 | StringMatcher("Name", Matches, OS).Emit(); | |
2153 | ||
2154 | OS << " return 0;\n"; | |
2155 | OS << "}\n\n"; | |
2156 | } | |
2157 | ||
1a4d82fc JJ |
2158 | static const char *getMinimalTypeForRange(uint64_t Range) { |
2159 | assert(Range <= 0xFFFFFFFFFFFFFFFFULL && "Enum too large"); | |
2160 | if (Range > 0xFFFFFFFFULL) | |
2161 | return "uint64_t"; | |
2162 | if (Range > 0xFFFF) | |
2163 | return "uint32_t"; | |
2164 | if (Range > 0xFF) | |
2165 | return "uint16_t"; | |
2166 | return "uint8_t"; | |
2167 | } | |
2168 | ||
2169 | static const char *getMinimalRequiredFeaturesType(const AsmMatcherInfo &Info) { | |
2170 | uint64_t MaxIndex = Info.SubtargetFeatures.size(); | |
2171 | if (MaxIndex > 0) | |
2172 | MaxIndex--; | |
2173 | return getMinimalTypeForRange(1ULL << MaxIndex); | |
2174 | } | |
2175 | ||
223e47cc LB |
2176 | /// emitSubtargetFeatureFlagEnumeration - Emit the subtarget feature flag |
2177 | /// definitions. | |
2178 | static void emitSubtargetFeatureFlagEnumeration(AsmMatcherInfo &Info, | |
2179 | raw_ostream &OS) { | |
2180 | OS << "// Flags for subtarget features that participate in " | |
2181 | << "instruction matching.\n"; | |
1a4d82fc JJ |
2182 | OS << "enum SubtargetFeatureFlag : " << getMinimalRequiredFeaturesType(Info) |
2183 | << " {\n"; | |
85aaf69f SL |
2184 | for (const auto &SF : Info.SubtargetFeatures) { |
2185 | const SubtargetFeatureInfo &SFI = SF.second; | |
1a4d82fc | 2186 | OS << " " << SFI.getEnumName() << " = (1ULL << " << SFI.Index << "),\n"; |
223e47cc LB |
2187 | } |
2188 | OS << " Feature_None = 0\n"; | |
2189 | OS << "};\n\n"; | |
2190 | } | |
2191 | ||
2192 | /// emitOperandDiagnosticTypes - Emit the operand matching diagnostic types. | |
2193 | static void emitOperandDiagnosticTypes(AsmMatcherInfo &Info, raw_ostream &OS) { | |
2194 | // Get the set of diagnostic types from all of the operand classes. | |
2195 | std::set<StringRef> Types; | |
2196 | for (std::map<Record*, ClassInfo*>::const_iterator | |
2197 | I = Info.AsmOperandClasses.begin(), | |
2198 | E = Info.AsmOperandClasses.end(); I != E; ++I) { | |
2199 | if (!I->second->DiagnosticType.empty()) | |
2200 | Types.insert(I->second->DiagnosticType); | |
2201 | } | |
2202 | ||
2203 | if (Types.empty()) return; | |
2204 | ||
2205 | // Now emit the enum entries. | |
2206 | for (std::set<StringRef>::const_iterator I = Types.begin(), E = Types.end(); | |
2207 | I != E; ++I) | |
2208 | OS << " Match_" << *I << ",\n"; | |
2209 | OS << " END_OPERAND_DIAGNOSTIC_TYPES\n"; | |
2210 | } | |
2211 | ||
2212 | /// emitGetSubtargetFeatureName - Emit the helper function to get the | |
2213 | /// user-level name for a subtarget feature. | |
2214 | static void emitGetSubtargetFeatureName(AsmMatcherInfo &Info, raw_ostream &OS) { | |
2215 | OS << "// User-level names for subtarget features that participate in\n" | |
2216 | << "// instruction matching.\n" | |
1a4d82fc JJ |
2217 | << "static const char *getSubtargetFeatureName(uint64_t Val) {\n"; |
2218 | if (!Info.SubtargetFeatures.empty()) { | |
2219 | OS << " switch(Val) {\n"; | |
85aaf69f SL |
2220 | for (const auto &SF : Info.SubtargetFeatures) { |
2221 | const SubtargetFeatureInfo &SFI = SF.second; | |
1a4d82fc JJ |
2222 | // FIXME: Totally just a placeholder name to get the algorithm working. |
2223 | OS << " case " << SFI.getEnumName() << ": return \"" | |
2224 | << SFI.TheDef->getValueAsString("PredicateName") << "\";\n"; | |
2225 | } | |
2226 | OS << " default: return \"(unknown)\";\n"; | |
2227 | OS << " }\n"; | |
2228 | } else { | |
2229 | // Nothing to emit, so skip the switch | |
2230 | OS << " return \"(unknown)\";\n"; | |
223e47cc | 2231 | } |
1a4d82fc | 2232 | OS << "}\n\n"; |
223e47cc LB |
2233 | } |
2234 | ||
2235 | /// emitComputeAvailableFeatures - Emit the function to compute the list of | |
2236 | /// available features given a subtarget. | |
2237 | static void emitComputeAvailableFeatures(AsmMatcherInfo &Info, | |
2238 | raw_ostream &OS) { | |
2239 | std::string ClassName = | |
2240 | Info.AsmParser->getValueAsString("AsmParserClassName"); | |
2241 | ||
1a4d82fc | 2242 | OS << "uint64_t " << Info.Target.getName() << ClassName << "::\n" |
223e47cc | 2243 | << "ComputeAvailableFeatures(uint64_t FB) const {\n"; |
1a4d82fc | 2244 | OS << " uint64_t Features = 0;\n"; |
85aaf69f SL |
2245 | for (const auto &SF : Info.SubtargetFeatures) { |
2246 | const SubtargetFeatureInfo &SFI = SF.second; | |
223e47cc LB |
2247 | |
2248 | OS << " if ("; | |
2249 | std::string CondStorage = | |
2250 | SFI.TheDef->getValueAsString("AssemblerCondString"); | |
2251 | StringRef Conds = CondStorage; | |
2252 | std::pair<StringRef,StringRef> Comma = Conds.split(','); | |
2253 | bool First = true; | |
2254 | do { | |
2255 | if (!First) | |
2256 | OS << " && "; | |
2257 | ||
2258 | bool Neg = false; | |
2259 | StringRef Cond = Comma.first; | |
2260 | if (Cond[0] == '!') { | |
2261 | Neg = true; | |
2262 | Cond = Cond.substr(1); | |
2263 | } | |
2264 | ||
2265 | OS << "((FB & " << Info.Target.getName() << "::" << Cond << ")"; | |
2266 | if (Neg) | |
2267 | OS << " == 0"; | |
2268 | else | |
2269 | OS << " != 0"; | |
2270 | OS << ")"; | |
2271 | ||
2272 | if (Comma.second.empty()) | |
2273 | break; | |
2274 | ||
2275 | First = false; | |
2276 | Comma = Comma.second.split(','); | |
2277 | } while (true); | |
2278 | ||
2279 | OS << ")\n"; | |
2280 | OS << " Features |= " << SFI.getEnumName() << ";\n"; | |
2281 | } | |
2282 | OS << " return Features;\n"; | |
2283 | OS << "}\n\n"; | |
2284 | } | |
2285 | ||
2286 | static std::string GetAliasRequiredFeatures(Record *R, | |
2287 | const AsmMatcherInfo &Info) { | |
2288 | std::vector<Record*> ReqFeatures = R->getValueAsListOfDefs("Predicates"); | |
2289 | std::string Result; | |
2290 | unsigned NumFeatures = 0; | |
2291 | for (unsigned i = 0, e = ReqFeatures.size(); i != e; ++i) { | |
85aaf69f | 2292 | const SubtargetFeatureInfo *F = Info.getSubtargetFeature(ReqFeatures[i]); |
223e47cc | 2293 | |
1a4d82fc | 2294 | if (!F) |
970d7e83 | 2295 | PrintFatalError(R->getLoc(), "Predicate '" + ReqFeatures[i]->getName() + |
223e47cc LB |
2296 | "' is not marked as an AssemblerPredicate!"); |
2297 | ||
2298 | if (NumFeatures) | |
2299 | Result += '|'; | |
2300 | ||
2301 | Result += F->getEnumName(); | |
2302 | ++NumFeatures; | |
2303 | } | |
2304 | ||
2305 | if (NumFeatures > 1) | |
2306 | Result = '(' + Result + ')'; | |
2307 | return Result; | |
2308 | } | |
2309 | ||
1a4d82fc JJ |
2310 | static void emitMnemonicAliasVariant(raw_ostream &OS,const AsmMatcherInfo &Info, |
2311 | std::vector<Record*> &Aliases, | |
2312 | unsigned Indent = 0, | |
2313 | StringRef AsmParserVariantName = StringRef()){ | |
223e47cc LB |
2314 | // Keep track of all the aliases from a mnemonic. Use an std::map so that the |
2315 | // iteration order of the map is stable. | |
2316 | std::map<std::string, std::vector<Record*> > AliasesFromMnemonic; | |
2317 | ||
2318 | for (unsigned i = 0, e = Aliases.size(); i != e; ++i) { | |
2319 | Record *R = Aliases[i]; | |
1a4d82fc JJ |
2320 | // FIXME: Allow AssemblerVariantName to be a comma separated list. |
2321 | std::string AsmVariantName = R->getValueAsString("AsmVariantName"); | |
2322 | if (AsmVariantName != AsmParserVariantName) | |
2323 | continue; | |
223e47cc LB |
2324 | AliasesFromMnemonic[R->getValueAsString("FromMnemonic")].push_back(R); |
2325 | } | |
1a4d82fc JJ |
2326 | if (AliasesFromMnemonic.empty()) |
2327 | return; | |
223e47cc LB |
2328 | |
2329 | // Process each alias a "from" mnemonic at a time, building the code executed | |
2330 | // by the string remapper. | |
2331 | std::vector<StringMatcher::StringPair> Cases; | |
2332 | for (std::map<std::string, std::vector<Record*> >::iterator | |
2333 | I = AliasesFromMnemonic.begin(), E = AliasesFromMnemonic.end(); | |
2334 | I != E; ++I) { | |
2335 | const std::vector<Record*> &ToVec = I->second; | |
2336 | ||
2337 | // Loop through each alias and emit code that handles each case. If there | |
2338 | // are two instructions without predicates, emit an error. If there is one, | |
2339 | // emit it last. | |
2340 | std::string MatchCode; | |
2341 | int AliasWithNoPredicate = -1; | |
2342 | ||
2343 | for (unsigned i = 0, e = ToVec.size(); i != e; ++i) { | |
2344 | Record *R = ToVec[i]; | |
2345 | std::string FeatureMask = GetAliasRequiredFeatures(R, Info); | |
2346 | ||
2347 | // If this unconditionally matches, remember it for later and diagnose | |
2348 | // duplicates. | |
2349 | if (FeatureMask.empty()) { | |
2350 | if (AliasWithNoPredicate != -1) { | |
2351 | // We can't have two aliases from the same mnemonic with no predicate. | |
2352 | PrintError(ToVec[AliasWithNoPredicate]->getLoc(), | |
2353 | "two MnemonicAliases with the same 'from' mnemonic!"); | |
970d7e83 | 2354 | PrintFatalError(R->getLoc(), "this is the other MnemonicAlias."); |
223e47cc LB |
2355 | } |
2356 | ||
2357 | AliasWithNoPredicate = i; | |
2358 | continue; | |
2359 | } | |
2360 | if (R->getValueAsString("ToMnemonic") == I->first) | |
970d7e83 | 2361 | PrintFatalError(R->getLoc(), "MnemonicAlias to the same string"); |
223e47cc LB |
2362 | |
2363 | if (!MatchCode.empty()) | |
2364 | MatchCode += "else "; | |
2365 | MatchCode += "if ((Features & " + FeatureMask + ") == "+FeatureMask+")\n"; | |
2366 | MatchCode += " Mnemonic = \"" +R->getValueAsString("ToMnemonic")+"\";\n"; | |
2367 | } | |
2368 | ||
2369 | if (AliasWithNoPredicate != -1) { | |
2370 | Record *R = ToVec[AliasWithNoPredicate]; | |
2371 | if (!MatchCode.empty()) | |
2372 | MatchCode += "else\n "; | |
2373 | MatchCode += "Mnemonic = \"" + R->getValueAsString("ToMnemonic")+"\";\n"; | |
2374 | } | |
2375 | ||
2376 | MatchCode += "return;"; | |
2377 | ||
2378 | Cases.push_back(std::make_pair(I->first, MatchCode)); | |
2379 | } | |
1a4d82fc JJ |
2380 | StringMatcher("Mnemonic", Cases, OS).Emit(Indent); |
2381 | } | |
2382 | ||
2383 | /// emitMnemonicAliases - If the target has any MnemonicAlias<> definitions, | |
2384 | /// emit a function for them and return true, otherwise return false. | |
2385 | static bool emitMnemonicAliases(raw_ostream &OS, const AsmMatcherInfo &Info, | |
2386 | CodeGenTarget &Target) { | |
2387 | // Ignore aliases when match-prefix is set. | |
2388 | if (!MatchPrefix.empty()) | |
2389 | return false; | |
2390 | ||
2391 | std::vector<Record*> Aliases = | |
2392 | Info.getRecords().getAllDerivedDefinitions("MnemonicAlias"); | |
2393 | if (Aliases.empty()) return false; | |
2394 | ||
2395 | OS << "static void applyMnemonicAliases(StringRef &Mnemonic, " | |
2396 | "uint64_t Features, unsigned VariantID) {\n"; | |
2397 | OS << " switch (VariantID) {\n"; | |
2398 | unsigned VariantCount = Target.getAsmParserVariantCount(); | |
2399 | for (unsigned VC = 0; VC != VariantCount; ++VC) { | |
2400 | Record *AsmVariant = Target.getAsmParserVariant(VC); | |
2401 | int AsmParserVariantNo = AsmVariant->getValueAsInt("Variant"); | |
2402 | std::string AsmParserVariantName = AsmVariant->getValueAsString("Name"); | |
2403 | OS << " case " << AsmParserVariantNo << ":\n"; | |
2404 | emitMnemonicAliasVariant(OS, Info, Aliases, /*Indent=*/2, | |
2405 | AsmParserVariantName); | |
2406 | OS << " break;\n"; | |
2407 | } | |
2408 | OS << " }\n"; | |
2409 | ||
2410 | // Emit aliases that apply to all variants. | |
2411 | emitMnemonicAliasVariant(OS, Info, Aliases); | |
223e47cc | 2412 | |
223e47cc LB |
2413 | OS << "}\n\n"; |
2414 | ||
2415 | return true; | |
2416 | } | |
2417 | ||
223e47cc LB |
2418 | static void emitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target, |
2419 | const AsmMatcherInfo &Info, StringRef ClassName, | |
2420 | StringToOffsetTable &StringTable, | |
2421 | unsigned MaxMnemonicIndex) { | |
2422 | unsigned MaxMask = 0; | |
2423 | for (std::vector<OperandMatchEntry>::const_iterator it = | |
2424 | Info.OperandMatchInfo.begin(), ie = Info.OperandMatchInfo.end(); | |
2425 | it != ie; ++it) { | |
2426 | MaxMask |= it->OperandMask; | |
2427 | } | |
2428 | ||
2429 | // Emit the static custom operand parsing table; | |
2430 | OS << "namespace {\n"; | |
2431 | OS << " struct OperandMatchEntry {\n"; | |
1a4d82fc | 2432 | OS << " " << getMinimalRequiredFeaturesType(Info) |
223e47cc LB |
2433 | << " RequiredFeatures;\n"; |
2434 | OS << " " << getMinimalTypeForRange(MaxMnemonicIndex) | |
2435 | << " Mnemonic;\n"; | |
85aaf69f SL |
2436 | OS << " " << getMinimalTypeForRange(std::distance( |
2437 | Info.Classes.begin(), Info.Classes.end())) << " Class;\n"; | |
223e47cc LB |
2438 | OS << " " << getMinimalTypeForRange(MaxMask) |
2439 | << " OperandMask;\n\n"; | |
2440 | OS << " StringRef getMnemonic() const {\n"; | |
2441 | OS << " return StringRef(MnemonicTable + Mnemonic + 1,\n"; | |
2442 | OS << " MnemonicTable[Mnemonic]);\n"; | |
2443 | OS << " }\n"; | |
2444 | OS << " };\n\n"; | |
2445 | ||
2446 | OS << " // Predicate for searching for an opcode.\n"; | |
2447 | OS << " struct LessOpcodeOperand {\n"; | |
2448 | OS << " bool operator()(const OperandMatchEntry &LHS, StringRef RHS) {\n"; | |
2449 | OS << " return LHS.getMnemonic() < RHS;\n"; | |
2450 | OS << " }\n"; | |
2451 | OS << " bool operator()(StringRef LHS, const OperandMatchEntry &RHS) {\n"; | |
2452 | OS << " return LHS < RHS.getMnemonic();\n"; | |
2453 | OS << " }\n"; | |
2454 | OS << " bool operator()(const OperandMatchEntry &LHS,"; | |
2455 | OS << " const OperandMatchEntry &RHS) {\n"; | |
2456 | OS << " return LHS.getMnemonic() < RHS.getMnemonic();\n"; | |
2457 | OS << " }\n"; | |
2458 | OS << " };\n"; | |
2459 | ||
2460 | OS << "} // end anonymous namespace.\n\n"; | |
2461 | ||
2462 | OS << "static const OperandMatchEntry OperandMatchTable[" | |
2463 | << Info.OperandMatchInfo.size() << "] = {\n"; | |
2464 | ||
2465 | OS << " /* Operand List Mask, Mnemonic, Operand Class, Features */\n"; | |
2466 | for (std::vector<OperandMatchEntry>::const_iterator it = | |
2467 | Info.OperandMatchInfo.begin(), ie = Info.OperandMatchInfo.end(); | |
2468 | it != ie; ++it) { | |
2469 | const OperandMatchEntry &OMI = *it; | |
2470 | const MatchableInfo &II = *OMI.MI; | |
2471 | ||
2472 | OS << " { "; | |
2473 | ||
2474 | // Write the required features mask. | |
2475 | if (!II.RequiredFeatures.empty()) { | |
2476 | for (unsigned i = 0, e = II.RequiredFeatures.size(); i != e; ++i) { | |
2477 | if (i) OS << "|"; | |
2478 | OS << II.RequiredFeatures[i]->getEnumName(); | |
2479 | } | |
2480 | } else | |
2481 | OS << "0"; | |
2482 | ||
2483 | // Store a pascal-style length byte in the mnemonic. | |
2484 | std::string LenMnemonic = char(II.Mnemonic.size()) + II.Mnemonic.str(); | |
2485 | OS << ", " << StringTable.GetOrAddStringOffset(LenMnemonic, false) | |
2486 | << " /* " << II.Mnemonic << " */, "; | |
2487 | ||
2488 | OS << OMI.CI->Name; | |
2489 | ||
2490 | OS << ", " << OMI.OperandMask; | |
2491 | OS << " /* "; | |
2492 | bool printComma = false; | |
2493 | for (int i = 0, e = 31; i !=e; ++i) | |
2494 | if (OMI.OperandMask & (1 << i)) { | |
2495 | if (printComma) | |
2496 | OS << ", "; | |
2497 | OS << i; | |
2498 | printComma = true; | |
2499 | } | |
2500 | OS << " */"; | |
2501 | ||
2502 | OS << " },\n"; | |
2503 | } | |
2504 | OS << "};\n\n"; | |
2505 | ||
2506 | // Emit the operand class switch to call the correct custom parser for | |
2507 | // the found operand class. | |
2508 | OS << Target.getName() << ClassName << "::OperandMatchResultTy " | |
2509 | << Target.getName() << ClassName << "::\n" | |
1a4d82fc | 2510 | << "tryCustomParseOperand(OperandVector" |
223e47cc LB |
2511 | << " &Operands,\n unsigned MCK) {\n\n" |
2512 | << " switch(MCK) {\n"; | |
2513 | ||
85aaf69f SL |
2514 | for (const auto &CI : Info.Classes) { |
2515 | if (CI.ParserMethod.empty()) | |
223e47cc | 2516 | continue; |
85aaf69f SL |
2517 | OS << " case " << CI.Name << ":\n" |
2518 | << " return " << CI.ParserMethod << "(Operands);\n"; | |
223e47cc LB |
2519 | } |
2520 | ||
2521 | OS << " default:\n"; | |
2522 | OS << " return MatchOperand_NoMatch;\n"; | |
2523 | OS << " }\n"; | |
2524 | OS << " return MatchOperand_NoMatch;\n"; | |
2525 | OS << "}\n\n"; | |
2526 | ||
2527 | // Emit the static custom operand parser. This code is very similar with | |
2528 | // the other matcher. Also use MatchResultTy here just in case we go for | |
2529 | // a better error handling. | |
2530 | OS << Target.getName() << ClassName << "::OperandMatchResultTy " | |
2531 | << Target.getName() << ClassName << "::\n" | |
1a4d82fc | 2532 | << "MatchOperandParserImpl(OperandVector" |
223e47cc LB |
2533 | << " &Operands,\n StringRef Mnemonic) {\n"; |
2534 | ||
2535 | // Emit code to get the available features. | |
2536 | OS << " // Get the current feature set.\n"; | |
1a4d82fc | 2537 | OS << " uint64_t AvailableFeatures = getAvailableFeatures();\n\n"; |
223e47cc LB |
2538 | |
2539 | OS << " // Get the next operand index.\n"; | |
2540 | OS << " unsigned NextOpNum = Operands.size()-1;\n"; | |
2541 | ||
2542 | // Emit code to search the table. | |
2543 | OS << " // Search the table.\n"; | |
2544 | OS << " std::pair<const OperandMatchEntry*, const OperandMatchEntry*>"; | |
2545 | OS << " MnemonicRange =\n"; | |
2546 | OS << " std::equal_range(OperandMatchTable, OperandMatchTable+" | |
2547 | << Info.OperandMatchInfo.size() << ", Mnemonic,\n" | |
2548 | << " LessOpcodeOperand());\n\n"; | |
2549 | ||
2550 | OS << " if (MnemonicRange.first == MnemonicRange.second)\n"; | |
2551 | OS << " return MatchOperand_NoMatch;\n\n"; | |
2552 | ||
2553 | OS << " for (const OperandMatchEntry *it = MnemonicRange.first,\n" | |
2554 | << " *ie = MnemonicRange.second; it != ie; ++it) {\n"; | |
2555 | ||
2556 | OS << " // equal_range guarantees that instruction mnemonic matches.\n"; | |
2557 | OS << " assert(Mnemonic == it->getMnemonic());\n\n"; | |
2558 | ||
2559 | // Emit check that the required features are available. | |
2560 | OS << " // check if the available features match\n"; | |
2561 | OS << " if ((AvailableFeatures & it->RequiredFeatures) " | |
2562 | << "!= it->RequiredFeatures) {\n"; | |
2563 | OS << " continue;\n"; | |
2564 | OS << " }\n\n"; | |
2565 | ||
2566 | // Emit check to ensure the operand number matches. | |
2567 | OS << " // check if the operand in question has a custom parser.\n"; | |
2568 | OS << " if (!(it->OperandMask & (1 << NextOpNum)))\n"; | |
2569 | OS << " continue;\n\n"; | |
2570 | ||
2571 | // Emit call to the custom parser method | |
2572 | OS << " // call custom parse method to handle the operand\n"; | |
2573 | OS << " OperandMatchResultTy Result = "; | |
2574 | OS << "tryCustomParseOperand(Operands, it->Class);\n"; | |
2575 | OS << " if (Result != MatchOperand_NoMatch)\n"; | |
2576 | OS << " return Result;\n"; | |
2577 | OS << " }\n\n"; | |
2578 | ||
2579 | OS << " // Okay, we had no match.\n"; | |
2580 | OS << " return MatchOperand_NoMatch;\n"; | |
2581 | OS << "}\n\n"; | |
2582 | } | |
2583 | ||
2584 | void AsmMatcherEmitter::run(raw_ostream &OS) { | |
2585 | CodeGenTarget Target(Records); | |
2586 | Record *AsmParser = Target.getAsmParser(); | |
2587 | std::string ClassName = AsmParser->getValueAsString("AsmParserClassName"); | |
2588 | ||
2589 | // Compute the information on the instructions to match. | |
2590 | AsmMatcherInfo Info(AsmParser, Target, Records); | |
2591 | Info.buildInfo(); | |
2592 | ||
2593 | // Sort the instruction table using the partial order on classes. We use | |
2594 | // stable_sort to ensure that ambiguous instructions are still | |
2595 | // deterministically ordered. | |
2596 | std::stable_sort(Info.Matchables.begin(), Info.Matchables.end(), | |
85aaf69f SL |
2597 | [](const std::unique_ptr<MatchableInfo> &a, |
2598 | const std::unique_ptr<MatchableInfo> &b){ | |
2599 | return *a < *b;}); | |
223e47cc LB |
2600 | |
2601 | DEBUG_WITH_TYPE("instruction_info", { | |
85aaf69f SL |
2602 | for (const auto &MI : Info.Matchables) |
2603 | MI->dump(); | |
223e47cc LB |
2604 | }); |
2605 | ||
2606 | // Check for ambiguous matchables. | |
2607 | DEBUG_WITH_TYPE("ambiguous_instrs", { | |
2608 | unsigned NumAmbiguous = 0; | |
85aaf69f SL |
2609 | for (auto I = Info.Matchables.begin(), E = Info.Matchables.end(); I != E; |
2610 | ++I) { | |
2611 | for (auto J = std::next(I); J != E; ++J) { | |
2612 | const MatchableInfo &A = **I; | |
2613 | const MatchableInfo &B = **J; | |
223e47cc LB |
2614 | |
2615 | if (A.couldMatchAmbiguouslyWith(B)) { | |
2616 | errs() << "warning: ambiguous matchables:\n"; | |
2617 | A.dump(); | |
2618 | errs() << "\nis incomparable with:\n"; | |
2619 | B.dump(); | |
2620 | errs() << "\n\n"; | |
2621 | ++NumAmbiguous; | |
2622 | } | |
2623 | } | |
2624 | } | |
2625 | if (NumAmbiguous) | |
2626 | errs() << "warning: " << NumAmbiguous | |
2627 | << " ambiguous matchables!\n"; | |
2628 | }); | |
2629 | ||
2630 | // Compute the information on the custom operand parsing. | |
2631 | Info.buildOperandMatchInfo(); | |
2632 | ||
2633 | // Write the output. | |
2634 | ||
2635 | // Information for the class declaration. | |
2636 | OS << "\n#ifdef GET_ASSEMBLER_HEADER\n"; | |
2637 | OS << "#undef GET_ASSEMBLER_HEADER\n"; | |
2638 | OS << " // This should be included into the middle of the declaration of\n"; | |
2639 | OS << " // your subclasses implementation of MCTargetAsmParser.\n"; | |
1a4d82fc | 2640 | OS << " uint64_t ComputeAvailableFeatures(uint64_t FeatureBits) const;\n"; |
223e47cc LB |
2641 | OS << " void convertToMCInst(unsigned Kind, MCInst &Inst, " |
2642 | << "unsigned Opcode,\n" | |
1a4d82fc | 2643 | << " const OperandVector " |
223e47cc | 2644 | << "&Operands);\n"; |
970d7e83 | 2645 | OS << " void convertToMapAndConstraints(unsigned Kind,\n "; |
1a4d82fc JJ |
2646 | OS << " const OperandVector &Operands) override;\n"; |
2647 | OS << " bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) override;\n"; | |
85aaf69f | 2648 | OS << " unsigned MatchInstructionImpl(const OperandVector &Operands,\n" |
970d7e83 | 2649 | << " MCInst &Inst,\n" |
1a4d82fc | 2650 | << " uint64_t &ErrorInfo," |
970d7e83 LB |
2651 | << " bool matchingInlineAsm,\n" |
2652 | << " unsigned VariantID = 0);\n"; | |
223e47cc LB |
2653 | |
2654 | if (Info.OperandMatchInfo.size()) { | |
2655 | OS << "\n enum OperandMatchResultTy {\n"; | |
2656 | OS << " MatchOperand_Success, // operand matched successfully\n"; | |
2657 | OS << " MatchOperand_NoMatch, // operand did not match\n"; | |
2658 | OS << " MatchOperand_ParseFail // operand matched but had errors\n"; | |
2659 | OS << " };\n"; | |
2660 | OS << " OperandMatchResultTy MatchOperandParserImpl(\n"; | |
1a4d82fc | 2661 | OS << " OperandVector &Operands,\n"; |
223e47cc LB |
2662 | OS << " StringRef Mnemonic);\n"; |
2663 | ||
2664 | OS << " OperandMatchResultTy tryCustomParseOperand(\n"; | |
1a4d82fc | 2665 | OS << " OperandVector &Operands,\n"; |
223e47cc LB |
2666 | OS << " unsigned MCK);\n\n"; |
2667 | } | |
2668 | ||
2669 | OS << "#endif // GET_ASSEMBLER_HEADER_INFO\n\n"; | |
2670 | ||
2671 | // Emit the operand match diagnostic enum names. | |
2672 | OS << "\n#ifdef GET_OPERAND_DIAGNOSTIC_TYPES\n"; | |
2673 | OS << "#undef GET_OPERAND_DIAGNOSTIC_TYPES\n\n"; | |
2674 | emitOperandDiagnosticTypes(Info, OS); | |
2675 | OS << "#endif // GET_OPERAND_DIAGNOSTIC_TYPES\n\n"; | |
2676 | ||
2677 | ||
2678 | OS << "\n#ifdef GET_REGISTER_MATCHER\n"; | |
2679 | OS << "#undef GET_REGISTER_MATCHER\n\n"; | |
2680 | ||
2681 | // Emit the subtarget feature enumeration. | |
2682 | emitSubtargetFeatureFlagEnumeration(Info, OS); | |
2683 | ||
2684 | // Emit the function to match a register name to number. | |
2685 | // This should be omitted for Mips target | |
2686 | if (AsmParser->getValueAsBit("ShouldEmitMatchRegisterName")) | |
2687 | emitMatchRegisterName(Target, AsmParser, OS); | |
2688 | ||
2689 | OS << "#endif // GET_REGISTER_MATCHER\n\n"; | |
2690 | ||
2691 | OS << "\n#ifdef GET_SUBTARGET_FEATURE_NAME\n"; | |
2692 | OS << "#undef GET_SUBTARGET_FEATURE_NAME\n\n"; | |
2693 | ||
2694 | // Generate the helper function to get the names for subtarget features. | |
2695 | emitGetSubtargetFeatureName(Info, OS); | |
2696 | ||
2697 | OS << "#endif // GET_SUBTARGET_FEATURE_NAME\n\n"; | |
2698 | ||
2699 | OS << "\n#ifdef GET_MATCHER_IMPLEMENTATION\n"; | |
2700 | OS << "#undef GET_MATCHER_IMPLEMENTATION\n\n"; | |
2701 | ||
2702 | // Generate the function that remaps for mnemonic aliases. | |
1a4d82fc | 2703 | bool HasMnemonicAliases = emitMnemonicAliases(OS, Info, Target); |
223e47cc | 2704 | |
970d7e83 LB |
2705 | // Generate the convertToMCInst function to convert operands into an MCInst. |
2706 | // Also, generate the convertToMapAndConstraints function for MS-style inline | |
2707 | // assembly. The latter doesn't actually generate a MCInst. | |
2708 | emitConvertFuncs(Target, ClassName, Info.Matchables, OS); | |
223e47cc LB |
2709 | |
2710 | // Emit the enumeration for classes which participate in matching. | |
2711 | emitMatchClassEnumeration(Target, Info.Classes, OS); | |
2712 | ||
2713 | // Emit the routine to match token strings to their match class. | |
2714 | emitMatchTokenString(Target, Info.Classes, OS); | |
2715 | ||
2716 | // Emit the subclass predicate routine. | |
2717 | emitIsSubclass(Target, Info.Classes, OS); | |
2718 | ||
2719 | // Emit the routine to validate an operand against a match class. | |
2720 | emitValidateOperandClass(Info, OS); | |
2721 | ||
2722 | // Emit the available features compute function. | |
2723 | emitComputeAvailableFeatures(Info, OS); | |
2724 | ||
2725 | ||
2726 | StringToOffsetTable StringTable; | |
2727 | ||
2728 | size_t MaxNumOperands = 0; | |
2729 | unsigned MaxMnemonicIndex = 0; | |
1a4d82fc | 2730 | bool HasDeprecation = false; |
85aaf69f SL |
2731 | for (const auto &MI : Info.Matchables) { |
2732 | MaxNumOperands = std::max(MaxNumOperands, MI->AsmOperands.size()); | |
2733 | HasDeprecation |= MI->HasDeprecation; | |
223e47cc LB |
2734 | |
2735 | // Store a pascal-style length byte in the mnemonic. | |
85aaf69f | 2736 | std::string LenMnemonic = char(MI->Mnemonic.size()) + MI->Mnemonic.str(); |
223e47cc LB |
2737 | MaxMnemonicIndex = std::max(MaxMnemonicIndex, |
2738 | StringTable.GetOrAddStringOffset(LenMnemonic, false)); | |
2739 | } | |
2740 | ||
2741 | OS << "static const char *const MnemonicTable =\n"; | |
2742 | StringTable.EmitString(OS); | |
2743 | OS << ";\n\n"; | |
2744 | ||
2745 | // Emit the static match table; unused classes get initalized to 0 which is | |
2746 | // guaranteed to be InvalidMatchClass. | |
2747 | // | |
2748 | // FIXME: We can reduce the size of this table very easily. First, we change | |
2749 | // it so that store the kinds in separate bit-fields for each index, which | |
2750 | // only needs to be the max width used for classes at that index (we also need | |
2751 | // to reject based on this during classification). If we then make sure to | |
2752 | // order the match kinds appropriately (putting mnemonics last), then we | |
2753 | // should only end up using a few bits for each class, especially the ones | |
2754 | // following the mnemonic. | |
2755 | OS << "namespace {\n"; | |
2756 | OS << " struct MatchEntry {\n"; | |
2757 | OS << " " << getMinimalTypeForRange(MaxMnemonicIndex) | |
2758 | << " Mnemonic;\n"; | |
2759 | OS << " uint16_t Opcode;\n"; | |
2760 | OS << " " << getMinimalTypeForRange(Info.Matchables.size()) | |
2761 | << " ConvertFn;\n"; | |
1a4d82fc | 2762 | OS << " " << getMinimalRequiredFeaturesType(Info) |
223e47cc | 2763 | << " RequiredFeatures;\n"; |
85aaf69f SL |
2764 | OS << " " << getMinimalTypeForRange( |
2765 | std::distance(Info.Classes.begin(), Info.Classes.end())) | |
2766 | << " Classes[" << MaxNumOperands << "];\n"; | |
223e47cc LB |
2767 | OS << " StringRef getMnemonic() const {\n"; |
2768 | OS << " return StringRef(MnemonicTable + Mnemonic + 1,\n"; | |
2769 | OS << " MnemonicTable[Mnemonic]);\n"; | |
2770 | OS << " }\n"; | |
2771 | OS << " };\n\n"; | |
2772 | ||
2773 | OS << " // Predicate for searching for an opcode.\n"; | |
2774 | OS << " struct LessOpcode {\n"; | |
2775 | OS << " bool operator()(const MatchEntry &LHS, StringRef RHS) {\n"; | |
2776 | OS << " return LHS.getMnemonic() < RHS;\n"; | |
2777 | OS << " }\n"; | |
2778 | OS << " bool operator()(StringRef LHS, const MatchEntry &RHS) {\n"; | |
2779 | OS << " return LHS < RHS.getMnemonic();\n"; | |
2780 | OS << " }\n"; | |
2781 | OS << " bool operator()(const MatchEntry &LHS, const MatchEntry &RHS) {\n"; | |
2782 | OS << " return LHS.getMnemonic() < RHS.getMnemonic();\n"; | |
2783 | OS << " }\n"; | |
2784 | OS << " };\n"; | |
2785 | ||
2786 | OS << "} // end anonymous namespace.\n\n"; | |
2787 | ||
1a4d82fc JJ |
2788 | unsigned VariantCount = Target.getAsmParserVariantCount(); |
2789 | for (unsigned VC = 0; VC != VariantCount; ++VC) { | |
2790 | Record *AsmVariant = Target.getAsmParserVariant(VC); | |
2791 | int AsmVariantNo = AsmVariant->getValueAsInt("Variant"); | |
223e47cc | 2792 | |
1a4d82fc | 2793 | OS << "static const MatchEntry MatchTable" << VC << "[] = {\n"; |
223e47cc | 2794 | |
85aaf69f SL |
2795 | for (const auto &MI : Info.Matchables) { |
2796 | if (MI->AsmVariantID != AsmVariantNo) | |
1a4d82fc | 2797 | continue; |
223e47cc | 2798 | |
1a4d82fc | 2799 | // Store a pascal-style length byte in the mnemonic. |
85aaf69f | 2800 | std::string LenMnemonic = char(MI->Mnemonic.size()) + MI->Mnemonic.str(); |
1a4d82fc | 2801 | OS << " { " << StringTable.GetOrAddStringOffset(LenMnemonic, false) |
85aaf69f | 2802 | << " /* " << MI->Mnemonic << " */, " |
1a4d82fc | 2803 | << Target.getName() << "::" |
85aaf69f SL |
2804 | << MI->getResultInst()->TheDef->getName() << ", " |
2805 | << MI->ConversionFnKind << ", "; | |
1a4d82fc JJ |
2806 | |
2807 | // Write the required features mask. | |
85aaf69f SL |
2808 | if (!MI->RequiredFeatures.empty()) { |
2809 | for (unsigned i = 0, e = MI->RequiredFeatures.size(); i != e; ++i) { | |
1a4d82fc | 2810 | if (i) OS << "|"; |
85aaf69f | 2811 | OS << MI->RequiredFeatures[i]->getEnumName(); |
1a4d82fc JJ |
2812 | } |
2813 | } else | |
2814 | OS << "0"; | |
223e47cc | 2815 | |
1a4d82fc | 2816 | OS << ", { "; |
85aaf69f SL |
2817 | for (unsigned i = 0, e = MI->AsmOperands.size(); i != e; ++i) { |
2818 | const MatchableInfo::AsmOperand &Op = MI->AsmOperands[i]; | |
223e47cc | 2819 | |
1a4d82fc JJ |
2820 | if (i) OS << ", "; |
2821 | OS << Op.Class->Name; | |
2822 | } | |
2823 | OS << " }, },\n"; | |
223e47cc | 2824 | } |
223e47cc | 2825 | |
1a4d82fc JJ |
2826 | OS << "};\n\n"; |
2827 | } | |
223e47cc LB |
2828 | |
2829 | // A method to determine if a mnemonic is in the list. | |
2830 | OS << "bool " << Target.getName() << ClassName << "::\n" | |
1a4d82fc JJ |
2831 | << "mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) {\n"; |
2832 | OS << " // Find the appropriate table for this asm variant.\n"; | |
2833 | OS << " const MatchEntry *Start, *End;\n"; | |
2834 | OS << " switch (VariantID) {\n"; | |
85aaf69f | 2835 | OS << " default: llvm_unreachable(\"invalid variant!\");\n"; |
1a4d82fc JJ |
2836 | for (unsigned VC = 0; VC != VariantCount; ++VC) { |
2837 | Record *AsmVariant = Target.getAsmParserVariant(VC); | |
2838 | int AsmVariantNo = AsmVariant->getValueAsInt("Variant"); | |
2839 | OS << " case " << AsmVariantNo << ": Start = std::begin(MatchTable" << VC | |
2840 | << "); End = std::end(MatchTable" << VC << "); break;\n"; | |
2841 | } | |
2842 | OS << " }\n"; | |
223e47cc LB |
2843 | OS << " // Search the table.\n"; |
2844 | OS << " std::pair<const MatchEntry*, const MatchEntry*> MnemonicRange =\n"; | |
1a4d82fc | 2845 | OS << " std::equal_range(Start, End, Mnemonic, LessOpcode());\n"; |
223e47cc LB |
2846 | OS << " return MnemonicRange.first != MnemonicRange.second;\n"; |
2847 | OS << "}\n\n"; | |
2848 | ||
2849 | // Finally, build the match function. | |
1a4d82fc | 2850 | OS << "unsigned " << Target.getName() << ClassName << "::\n" |
85aaf69f SL |
2851 | << "MatchInstructionImpl(const OperandVector &Operands,\n"; |
2852 | OS << " MCInst &Inst, uint64_t &ErrorInfo,\n" | |
2853 | << " bool matchingInlineAsm, unsigned VariantID) {\n"; | |
223e47cc LB |
2854 | |
2855 | OS << " // Eliminate obvious mismatches.\n"; | |
2856 | OS << " if (Operands.size() > " << (MaxNumOperands+1) << ") {\n"; | |
2857 | OS << " ErrorInfo = " << (MaxNumOperands+1) << ";\n"; | |
2858 | OS << " return Match_InvalidOperand;\n"; | |
2859 | OS << " }\n\n"; | |
2860 | ||
2861 | // Emit code to get the available features. | |
2862 | OS << " // Get the current feature set.\n"; | |
1a4d82fc | 2863 | OS << " uint64_t AvailableFeatures = getAvailableFeatures();\n\n"; |
223e47cc LB |
2864 | |
2865 | OS << " // Get the instruction mnemonic, which is the first token.\n"; | |
2866 | OS << " StringRef Mnemonic = ((" << Target.getName() | |
1a4d82fc | 2867 | << "Operand&)*Operands[0]).getToken();\n\n"; |
223e47cc LB |
2868 | |
2869 | if (HasMnemonicAliases) { | |
2870 | OS << " // Process all MnemonicAliases to remap the mnemonic.\n"; | |
1a4d82fc | 2871 | OS << " applyMnemonicAliases(Mnemonic, AvailableFeatures, VariantID);\n\n"; |
223e47cc LB |
2872 | } |
2873 | ||
2874 | // Emit code to compute the class list for this operand vector. | |
2875 | OS << " // Some state to try to produce better error messages.\n"; | |
2876 | OS << " bool HadMatchOtherThanFeatures = false;\n"; | |
2877 | OS << " bool HadMatchOtherThanPredicate = false;\n"; | |
2878 | OS << " unsigned RetCode = Match_InvalidOperand;\n"; | |
1a4d82fc | 2879 | OS << " uint64_t MissingFeatures = ~0ULL;\n"; |
223e47cc LB |
2880 | OS << " // Set ErrorInfo to the operand that mismatches if it is\n"; |
2881 | OS << " // wrong for all instances of the instruction.\n"; | |
2882 | OS << " ErrorInfo = ~0U;\n"; | |
2883 | ||
2884 | // Emit code to search the table. | |
1a4d82fc JJ |
2885 | OS << " // Find the appropriate table for this asm variant.\n"; |
2886 | OS << " const MatchEntry *Start, *End;\n"; | |
2887 | OS << " switch (VariantID) {\n"; | |
85aaf69f | 2888 | OS << " default: llvm_unreachable(\"invalid variant!\");\n"; |
1a4d82fc JJ |
2889 | for (unsigned VC = 0; VC != VariantCount; ++VC) { |
2890 | Record *AsmVariant = Target.getAsmParserVariant(VC); | |
2891 | int AsmVariantNo = AsmVariant->getValueAsInt("Variant"); | |
2892 | OS << " case " << AsmVariantNo << ": Start = std::begin(MatchTable" << VC | |
2893 | << "); End = std::end(MatchTable" << VC << "); break;\n"; | |
2894 | } | |
2895 | OS << " }\n"; | |
223e47cc LB |
2896 | OS << " // Search the table.\n"; |
2897 | OS << " std::pair<const MatchEntry*, const MatchEntry*> MnemonicRange =\n"; | |
1a4d82fc | 2898 | OS << " std::equal_range(Start, End, Mnemonic, LessOpcode());\n\n"; |
223e47cc LB |
2899 | |
2900 | OS << " // Return a more specific error code if no mnemonics match.\n"; | |
2901 | OS << " if (MnemonicRange.first == MnemonicRange.second)\n"; | |
2902 | OS << " return Match_MnemonicFail;\n\n"; | |
2903 | ||
2904 | OS << " for (const MatchEntry *it = MnemonicRange.first, " | |
2905 | << "*ie = MnemonicRange.second;\n"; | |
2906 | OS << " it != ie; ++it) {\n"; | |
2907 | ||
2908 | OS << " // equal_range guarantees that instruction mnemonic matches.\n"; | |
2909 | OS << " assert(Mnemonic == it->getMnemonic());\n"; | |
2910 | ||
2911 | // Emit check that the subclasses match. | |
223e47cc LB |
2912 | OS << " bool OperandsValid = true;\n"; |
2913 | OS << " for (unsigned i = 0; i != " << MaxNumOperands << "; ++i) {\n"; | |
2914 | OS << " if (i + 1 >= Operands.size()) {\n"; | |
2915 | OS << " OperandsValid = (it->Classes[i] == " <<"InvalidMatchClass);\n"; | |
2916 | OS << " if (!OperandsValid) ErrorInfo = i + 1;\n"; | |
2917 | OS << " break;\n"; | |
2918 | OS << " }\n"; | |
1a4d82fc | 2919 | OS << " unsigned Diag = validateOperandClass(*Operands[i+1],\n"; |
223e47cc LB |
2920 | OS.indent(43); |
2921 | OS << "(MatchClassKind)it->Classes[i]);\n"; | |
2922 | OS << " if (Diag == Match_Success)\n"; | |
2923 | OS << " continue;\n"; | |
970d7e83 LB |
2924 | OS << " // If the generic handler indicates an invalid operand\n"; |
2925 | OS << " // failure, check for a special case.\n"; | |
2926 | OS << " if (Diag == Match_InvalidOperand) {\n"; | |
1a4d82fc | 2927 | OS << " Diag = validateTargetOperandClass(*Operands[i+1],\n"; |
970d7e83 LB |
2928 | OS.indent(43); |
2929 | OS << "(MatchClassKind)it->Classes[i]);\n"; | |
2930 | OS << " if (Diag == Match_Success)\n"; | |
2931 | OS << " continue;\n"; | |
2932 | OS << " }\n"; | |
223e47cc LB |
2933 | OS << " // If this operand is broken for all of the instances of this\n"; |
2934 | OS << " // mnemonic, keep track of it so we can report loc info.\n"; | |
2935 | OS << " // If we already had a match that only failed due to a\n"; | |
2936 | OS << " // target predicate, that diagnostic is preferred.\n"; | |
2937 | OS << " if (!HadMatchOtherThanPredicate &&\n"; | |
2938 | OS << " (it == MnemonicRange.first || ErrorInfo <= i+1)) {\n"; | |
2939 | OS << " ErrorInfo = i+1;\n"; | |
2940 | OS << " // InvalidOperand is the default. Prefer specificity.\n"; | |
2941 | OS << " if (Diag != Match_InvalidOperand)\n"; | |
2942 | OS << " RetCode = Diag;\n"; | |
2943 | OS << " }\n"; | |
2944 | OS << " // Otherwise, just reject this instance of the mnemonic.\n"; | |
2945 | OS << " OperandsValid = false;\n"; | |
2946 | OS << " break;\n"; | |
2947 | OS << " }\n\n"; | |
2948 | ||
2949 | OS << " if (!OperandsValid) continue;\n"; | |
2950 | ||
2951 | // Emit check that the required features are available. | |
2952 | OS << " if ((AvailableFeatures & it->RequiredFeatures) " | |
2953 | << "!= it->RequiredFeatures) {\n"; | |
2954 | OS << " HadMatchOtherThanFeatures = true;\n"; | |
1a4d82fc | 2955 | OS << " uint64_t NewMissingFeatures = it->RequiredFeatures & " |
223e47cc | 2956 | "~AvailableFeatures;\n"; |
1a4d82fc JJ |
2957 | OS << " if (CountPopulation_64(NewMissingFeatures) <=\n" |
2958 | " CountPopulation_64(MissingFeatures))\n"; | |
223e47cc LB |
2959 | OS << " MissingFeatures = NewMissingFeatures;\n"; |
2960 | OS << " continue;\n"; | |
2961 | OS << " }\n"; | |
2962 | OS << "\n"; | |
85aaf69f | 2963 | OS << " Inst.clear();\n\n"; |
970d7e83 LB |
2964 | OS << " if (matchingInlineAsm) {\n"; |
2965 | OS << " Inst.setOpcode(it->Opcode);\n"; | |
2966 | OS << " convertToMapAndConstraints(it->ConvertFn, Operands);\n"; | |
2967 | OS << " return Match_Success;\n"; | |
2968 | OS << " }\n\n"; | |
223e47cc LB |
2969 | OS << " // We have selected a definite instruction, convert the parsed\n" |
2970 | << " // operands into the appropriate MCInst.\n"; | |
2971 | OS << " convertToMCInst(it->ConvertFn, Inst, it->Opcode, Operands);\n"; | |
2972 | OS << "\n"; | |
2973 | ||
2974 | // Verify the instruction with the target-specific match predicate function. | |
2975 | OS << " // We have a potential match. Check the target predicate to\n" | |
2976 | << " // handle any context sensitive constraints.\n" | |
2977 | << " unsigned MatchResult;\n" | |
2978 | << " if ((MatchResult = checkTargetMatchPredicate(Inst)) !=" | |
2979 | << " Match_Success) {\n" | |
2980 | << " Inst.clear();\n" | |
2981 | << " RetCode = MatchResult;\n" | |
2982 | << " HadMatchOtherThanPredicate = true;\n" | |
2983 | << " continue;\n" | |
2984 | << " }\n\n"; | |
2985 | ||
2986 | // Call the post-processing function, if used. | |
2987 | std::string InsnCleanupFn = | |
2988 | AsmParser->getValueAsString("AsmParserInstCleanup"); | |
2989 | if (!InsnCleanupFn.empty()) | |
2990 | OS << " " << InsnCleanupFn << "(Inst);\n"; | |
2991 | ||
1a4d82fc JJ |
2992 | if (HasDeprecation) { |
2993 | OS << " std::string Info;\n"; | |
2994 | OS << " if (MII.get(Inst.getOpcode()).getDeprecatedInfo(Inst, STI, Info)) {\n"; | |
2995 | OS << " SMLoc Loc = ((" << Target.getName() | |
2996 | << "Operand&)*Operands[0]).getStartLoc();\n"; | |
85aaf69f | 2997 | OS << " getParser().Warning(Loc, Info, None);\n"; |
1a4d82fc JJ |
2998 | OS << " }\n"; |
2999 | } | |
3000 | ||
223e47cc LB |
3001 | OS << " return Match_Success;\n"; |
3002 | OS << " }\n\n"; | |
3003 | ||
3004 | OS << " // Okay, we had no match. Try to return a useful error code.\n"; | |
3005 | OS << " if (HadMatchOtherThanPredicate || !HadMatchOtherThanFeatures)\n"; | |
3006 | OS << " return RetCode;\n\n"; | |
3007 | OS << " // Missing feature matches return which features were missing\n"; | |
3008 | OS << " ErrorInfo = MissingFeatures;\n"; | |
3009 | OS << " return Match_MissingFeature;\n"; | |
3010 | OS << "}\n\n"; | |
3011 | ||
3012 | if (Info.OperandMatchInfo.size()) | |
3013 | emitCustomOperandParsing(OS, Target, Info, ClassName, StringTable, | |
3014 | MaxMnemonicIndex); | |
3015 | ||
3016 | OS << "#endif // GET_MATCHER_IMPLEMENTATION\n\n"; | |
3017 | } | |
3018 | ||
3019 | namespace llvm { | |
3020 | ||
3021 | void EmitAsmMatcher(RecordKeeper &RK, raw_ostream &OS) { | |
3022 | emitSourceFileHeader("Assembly Matcher Source Fragment", OS); | |
3023 | AsmMatcherEmitter(RK).run(OS); | |
3024 | } | |
3025 | ||
3026 | } // End llvm namespace |