1//===- AsmMatcherEmitter.cpp - Generate an assembly matcher ---------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This tablegen backend emits a target specifier matcher for converting parsed
10// assembly operands in the MCInst structures. It also emits a matcher for
11// custom operand parsing.
12//
13// Converting assembly operands into MCInst structures
14// ---------------------------------------------------
15//
16// The input to the target specific matcher is a list of literal tokens and
17// operands. The target specific parser should generally eliminate any syntax
18// which is not relevant for matching; for example, comma tokens should have
19// already been consumed and eliminated by the parser. Most instructions will
20// end up with a single literal token (the instruction name) and some number of
21// operands.
22//
23// Some example inputs, for X86:
24// 'addl' (immediate ...) (register ...)
25// 'add' (immediate ...) (memory ...)
26// 'call' '*' %epc
27//
28// The assembly matcher is responsible for converting this input into a precise
29// machine instruction (i.e., an instruction with a well defined encoding). This
30// mapping has several properties which complicate matching:
31//
32// - It may be ambiguous; many architectures can legally encode particular
33// variants of an instruction in different ways (for example, using a smaller
34// encoding for small immediates). Such ambiguities should never be
35// arbitrarily resolved by the assembler, the assembler is always responsible
36// for choosing the "best" available instruction.
37//
38// - It may depend on the subtarget or the assembler context. Instructions
39// which are invalid for the current mode, but otherwise unambiguous (e.g.,
40// an SSE instruction in a file being assembled for i486) should be accepted
41// and rejected by the assembler front end. However, if the proper encoding
42// for an instruction is dependent on the assembler context then the matcher
43// is responsible for selecting the correct machine instruction for the
44// current mode.
45//
46// The core matching algorithm attempts to exploit the regularity in most
47// instruction sets to quickly determine the set of possibly matching
48// instructions, and the simplify the generated code. Additionally, this helps
49// to ensure that the ambiguities are intentionally resolved by the user.
50//
51// The matching is divided into two distinct phases:
52//
53// 1. Classification: Each operand is mapped to the unique set which (a)
54// contains it, and (b) is the largest such subset for which a single
55// instruction could match all members.
56//
57// For register classes, we can generate these subgroups automatically. For
58// arbitrary operands, we expect the user to define the classes and their
59// relations to one another (for example, 8-bit signed immediates as a
60// subset of 32-bit immediates).
61//
62// By partitioning the operands in this way, we guarantee that for any
63// tuple of classes, any single instruction must match either all or none
64// of the sets of operands which could classify to that tuple.
65//
66// In addition, the subset relation amongst classes induces a partial order
67// on such tuples, which we use to resolve ambiguities.
68//
69// 2. The input can now be treated as a tuple of classes (static tokens are
70// simple singleton sets). Each such tuple should generally map to a single
71// instruction (we currently ignore cases where this isn't true, whee!!!),
72// which we can emit a simple matcher for.
73//
74// Custom Operand Parsing
75// ----------------------
76//
77// Some targets need a custom way to parse operands, some specific instructions
78// can contain arguments that can represent processor flags and other kinds of
79// identifiers that need to be mapped to specific values in the final encoded
80// instructions. The target specific custom operand parsing works in the
81// following way:
82//
83// 1. A operand match table is built, each entry contains a mnemonic, an
84// operand class, a mask for all operand positions for that same
85// class/mnemonic and target features to be checked while trying to match.
86//
87// 2. The operand matcher will try every possible entry with the same
88// mnemonic and will check if the target feature for this mnemonic also
89// matches. After that, if the operand to be matched has its index
90// present in the mask, a successful match occurs. Otherwise, fallback
91// to the regular operand parsing.
92//
93// 3. For a match success, each operand class that has a 'ParserMethod'
94// becomes part of a switch from where the custom method is called.
95//
96//===----------------------------------------------------------------------===//
97
98#include "Common/CodeGenInstAlias.h"
99#include "Common/CodeGenInstruction.h"
100#include "Common/CodeGenRegisters.h"
101#include "Common/CodeGenTarget.h"
102#include "Common/SubtargetFeatureInfo.h"
103#include "Common/Types.h"
104#include "llvm/ADT/CachedHashString.h"
105#include "llvm/ADT/PointerUnion.h"
106#include "llvm/ADT/STLExtras.h"
107#include "llvm/ADT/SmallPtrSet.h"
108#include "llvm/ADT/SmallVector.h"
109#include "llvm/ADT/StringExtras.h"
110#include "llvm/Support/CommandLine.h"
111#include "llvm/Support/Debug.h"
112#include "llvm/Support/ErrorHandling.h"
113#include "llvm/Support/FormatVariadic.h"
114#include "llvm/TableGen/Error.h"
115#include "llvm/TableGen/Record.h"
116#include "llvm/TableGen/StringMatcher.h"
117#include "llvm/TableGen/StringToOffsetTable.h"
118#include "llvm/TableGen/TableGenBackend.h"
119#include <cassert>
120#include <cctype>
121#include <forward_list>
122#include <map>
123#include <set>
124
125using namespace llvm;
126
127#define DEBUG_TYPE "asm-matcher-emitter"
128
129static cl::OptionCategory AsmMatcherEmitterCat("Options for -gen-asm-matcher");
130
131static cl::opt<std::string>
132 MatchPrefix("match-prefix", cl::init(Val: ""),
133 cl::desc("Only match instructions with the given prefix"),
134 cl::cat(AsmMatcherEmitterCat));
135
136namespace {
137class AsmMatcherInfo;
138
139// Register sets are used as keys in some second-order sets TableGen creates
140// when generating its data structures. This means that the order of two
141// RegisterSets can be seen in the outputted AsmMatcher tables occasionally, and
142// can even affect compiler output (at least seen in diagnostics produced when
143// all matches fail). So we use a type that sorts them consistently.
144typedef std::set<const Record *, LessRecordByID> RegisterSet;
145
146class AsmMatcherEmitter {
147 const RecordKeeper &Records;
148
149public:
150 AsmMatcherEmitter(const RecordKeeper &R) : Records(R) {}
151
152 void run(raw_ostream &o);
153};
154
155/// ClassInfo - Helper class for storing the information about a particular
156/// class of operands which can be matched.
157struct ClassInfo {
158 enum ClassInfoKind {
159 /// Invalid kind, for use as a sentinel value.
160 Invalid = 0,
161
162 /// The class for a particular token.
163 Token,
164
165 /// The (first) register class, subsequent register classes are
166 /// RegisterClass0+1, and so on.
167 RegisterClass0,
168
169 /// The (first) user defined class, subsequent user defined classes are
170 /// UserClass0+1, and so on.
171 UserClass0 = 1 << 16
172 };
173
174 /// Kind - The class kind, which is either a predefined kind, or (UserClass0 +
175 /// N) for the Nth user defined class.
176 unsigned Kind;
177
178 /// SuperClasses - The super classes of this class. Note that for simplicities
179 /// sake user operands only record their immediate super class, while register
180 /// operands include all superclasses.
181 std::vector<ClassInfo *> SuperClasses;
182
183 /// Name - The full class name, suitable for use in an enum.
184 std::string Name;
185
186 /// ClassName - The unadorned generic name for this class (e.g., Token).
187 std::string ClassName;
188
189 /// ValueName - The name of the value this class represents; for a token this
190 /// is the literal token string, for an operand it is the TableGen class (or
191 /// empty if this is a derived class).
192 std::string ValueName;
193
194 /// PredicateMethod - The name of the operand method to test whether the
195 /// operand matches this class; this is not valid for Token or register kinds.
196 std::string PredicateMethod;
197
198 /// RenderMethod - The name of the operand method to add this operand to an
199 /// MCInst; this is not valid for Token or register kinds.
200 std::string RenderMethod;
201
202 /// ParserMethod - The name of the operand method to do a target specific
203 /// parsing on the operand.
204 std::string ParserMethod;
205
206 /// For register classes: the records for all the registers in this class.
207 RegisterSet Registers;
208
209 /// For custom match classes: the diagnostic kind for when the predicate
210 /// fails.
211 std::string DiagnosticType;
212
213 /// For custom match classes: the diagnostic string for when the predicate
214 /// fails.
215 std::string DiagnosticString;
216
217 /// Is this operand optional and not always required.
218 bool IsOptional;
219
220 /// DefaultMethod - The name of the method that returns the default operand
221 /// for optional operand
222 std::string DefaultMethod;
223
224public:
225 /// isRegisterClass() - Check if this is a register class.
226 bool isRegisterClass() const {
227 return Kind >= RegisterClass0 && Kind < UserClass0;
228 }
229
230 /// isUserClass() - Check if this is a user defined class.
231 bool isUserClass() const { return Kind >= UserClass0; }
232
233 /// isRelatedTo - Check whether this class is "related" to \p RHS. Classes
234 /// are related if they are in the same class hierarchy.
235 bool isRelatedTo(const ClassInfo &RHS) const {
236 // Tokens are only related to tokens.
237 if (Kind == Token || RHS.Kind == Token)
238 return Kind == Token && RHS.Kind == Token;
239
240 // Registers classes are only related to registers classes, and only if
241 // their intersection is non-empty.
242 if (isRegisterClass() || RHS.isRegisterClass()) {
243 if (!isRegisterClass() || !RHS.isRegisterClass())
244 return false;
245
246 std::vector<const Record *> Tmp;
247 std::set_intersection(first1: Registers.begin(), last1: Registers.end(),
248 first2: RHS.Registers.begin(), last2: RHS.Registers.end(),
249 result: std::back_inserter(x&: Tmp), comp: LessRecordByID());
250
251 return !Tmp.empty();
252 }
253
254 // Otherwise we have two users operands; they are related if they are in the
255 // same class hierarchy.
256 //
257 // FIXME: This is an oversimplification, they should only be related if they
258 // intersect, however we don't have that information.
259 assert(isUserClass() && RHS.isUserClass() && "Unexpected class!");
260 const ClassInfo *Root = this;
261 while (!Root->SuperClasses.empty())
262 Root = Root->SuperClasses.front();
263
264 const ClassInfo *RHSRoot = &RHS;
265 while (!RHSRoot->SuperClasses.empty())
266 RHSRoot = RHSRoot->SuperClasses.front();
267
268 return Root == RHSRoot;
269 }
270
271 /// isSubsetOf - Test whether this class is a subset of \p RHS.
272 bool isSubsetOf(const ClassInfo &RHS) const {
273 // This is a subset of RHS if it is the same class...
274 if (this == &RHS)
275 return true;
276
277 // ... or if any of its super classes are a subset of RHS.
278 SmallVector<const ClassInfo *, 16> Worklist(SuperClasses.begin(),
279 SuperClasses.end());
280 SmallPtrSet<const ClassInfo *, 16> Visited;
281 while (!Worklist.empty()) {
282 auto *CI = Worklist.pop_back_val();
283 if (CI == &RHS)
284 return true;
285 for (auto *Super : CI->SuperClasses)
286 if (Visited.insert(Ptr: Super).second)
287 Worklist.push_back(Elt: Super);
288 }
289
290 return false;
291 }
292
293 int getTreeDepth() const {
294 int Depth = 0;
295 const ClassInfo *Root = this;
296 while (!Root->SuperClasses.empty()) {
297 Depth++;
298 Root = Root->SuperClasses.front();
299 }
300 return Depth;
301 }
302
303 const ClassInfo *findRoot() const {
304 const ClassInfo *Root = this;
305 while (!Root->SuperClasses.empty())
306 Root = Root->SuperClasses.front();
307 return Root;
308 }
309
310 /// Compare two classes. This does not produce a total ordering, but does
311 /// guarantee that subclasses are sorted before their parents, and that the
312 /// ordering is transitive.
313 bool operator<(const ClassInfo &RHS) const {
314 if (this == &RHS)
315 return false;
316
317 // First, enforce the ordering between the three different types of class.
318 // Tokens sort before registers, which sort before user classes.
319 if (Kind == Token) {
320 if (RHS.Kind != Token)
321 return true;
322 assert(RHS.Kind == Token);
323 } else if (isRegisterClass()) {
324 if (RHS.Kind == Token)
325 return false;
326 else if (RHS.isUserClass())
327 return true;
328 assert(RHS.isRegisterClass());
329 } else if (isUserClass()) {
330 if (!RHS.isUserClass())
331 return false;
332 assert(RHS.isUserClass());
333 } else {
334 llvm_unreachable("Unknown ClassInfoKind");
335 }
336
337 if (Kind == Token || isUserClass()) {
338 // Related tokens and user classes get sorted by depth in the inheritence
339 // tree (so that subclasses are before their parents).
340 if (isRelatedTo(RHS)) {
341 if (getTreeDepth() > RHS.getTreeDepth())
342 return true;
343 if (getTreeDepth() < RHS.getTreeDepth())
344 return false;
345 } else {
346 // Unrelated tokens and user classes are ordered by the name of their
347 // root nodes, so that there is a consistent ordering between
348 // unconnected trees.
349 return findRoot()->ValueName < RHS.findRoot()->ValueName;
350 }
351 } else if (isRegisterClass()) {
352 // For register sets, sort by number of registers. This guarantees that
353 // a set will always sort before all of it's strict supersets.
354 if (Registers.size() != RHS.Registers.size())
355 return Registers.size() < RHS.Registers.size();
356 } else {
357 llvm_unreachable("Unknown ClassInfoKind");
358 }
359
360 // FIXME: We should be able to just return false here, as we only need a
361 // partial order (we use stable sorts, so this is deterministic) and the
362 // name of a class shouldn't be significant. However, some of the backends
363 // accidentally rely on this behaviour, so it will have to stay like this
364 // until they are fixed.
365 return ValueName < RHS.ValueName;
366 }
367};
368
369class AsmVariantInfo {
370public:
371 StringRef RegisterPrefix;
372 StringRef TokenizingCharacters;
373 StringRef SeparatorCharacters;
374 StringRef BreakCharacters;
375 StringRef Name;
376 int AsmVariantNo;
377};
378
379bool getPreferSmallerInstructions(CodeGenTarget const &Target) {
380 return Target.getAsmParser()->getValueAsBit(FieldName: "PreferSmallerInstructions");
381}
382
383/// MatchableInfo - Helper class for storing the necessary information for an
384/// instruction or alias which is capable of being matched.
385struct MatchableInfo {
386 struct AsmOperand {
387 /// Token - This is the token that the operand came from.
388 StringRef Token;
389
390 /// The unique class instance this operand should match.
391 ClassInfo *Class = nullptr;
392
393 /// The operand name this is, if anything.
394 StringRef SrcOpName;
395
396 /// The operand name this is, before renaming for tied operands.
397 StringRef OrigSrcOpName;
398
399 /// The suboperand index within SrcOpName, or -1 for the entire operand.
400 int SubOpIdx = -1;
401
402 /// Whether the token is "isolated", i.e., it is preceded and followed
403 /// by separators.
404 bool IsIsolatedToken;
405
406 /// Register record if this token is singleton register.
407 const Record *SingletonReg = nullptr;
408
409 explicit AsmOperand(bool IsIsolatedToken, StringRef T)
410 : Token(T), IsIsolatedToken(IsIsolatedToken) {}
411 };
412
413 /// ResOperand - This represents a single operand in the result instruction
414 /// generated by the match. In cases (like addressing modes) where a single
415 /// assembler operand expands to multiple MCOperands, this represents the
416 /// single assembler operand, not the MCOperand.
417 struct ResOperand {
418 enum {
419 /// RenderAsmOperand - This represents an operand result that is
420 /// generated by calling the render method on the assembly operand. The
421 /// corresponding AsmOperand is specified by AsmOperandNum.
422 RenderAsmOperand,
423
424 /// TiedOperand - This represents a result operand that is a duplicate of
425 /// a previous result operand.
426 TiedOperand,
427
428 /// ImmOperand - This represents an immediate value that is dumped into
429 /// the operand.
430 ImmOperand,
431
432 /// RegOperand - This represents a fixed register that is dumped in.
433 RegOperand
434 } Kind;
435
436 /// Tuple containing the index of the (earlier) result operand that should
437 /// be copied from, as well as the indices of the corresponding (parsed)
438 /// operands in the asm string.
439 struct TiedOperandsTuple {
440 unsigned ResOpnd;
441 unsigned SrcOpnd1Idx;
442 unsigned SrcOpnd2Idx;
443 };
444
445 union {
446 /// This is the operand # in the AsmOperands list that this should be
447 /// copied from.
448 unsigned AsmOperandNum;
449
450 /// Description of tied operands.
451 TiedOperandsTuple TiedOperands;
452
453 /// ImmVal - This is the immediate value added to the instruction.
454 int64_t ImmVal;
455
456 /// Register - This is the register record.
457 const Record *Register;
458 };
459
460 /// MINumOperands - The number of MCInst operands populated by this
461 /// operand.
462 unsigned MINumOperands;
463
464 static ResOperand getRenderedOp(unsigned AsmOpNum, unsigned NumOperands) {
465 ResOperand X;
466 X.Kind = RenderAsmOperand;
467 X.AsmOperandNum = AsmOpNum;
468 X.MINumOperands = NumOperands;
469 return X;
470 }
471
472 static ResOperand getTiedOp(unsigned TiedOperandNum, unsigned SrcOperand1,
473 unsigned SrcOperand2) {
474 ResOperand X;
475 X.Kind = TiedOperand;
476 X.TiedOperands = {.ResOpnd: TiedOperandNum, .SrcOpnd1Idx: SrcOperand1, .SrcOpnd2Idx: SrcOperand2};
477 X.MINumOperands = 1;
478 return X;
479 }
480
481 static ResOperand getImmOp(int64_t Val) {
482 ResOperand X;
483 X.Kind = ImmOperand;
484 X.ImmVal = Val;
485 X.MINumOperands = 1;
486 return X;
487 }
488
489 static ResOperand getRegOp(const Record *Reg) {
490 ResOperand X;
491 X.Kind = RegOperand;
492 X.Register = Reg;
493 X.MINumOperands = 1;
494 return X;
495 }
496 };
497
498 /// AsmVariantID - Target's assembly syntax variant no.
499 int AsmVariantID;
500
501 /// AsmString - The assembly string for this instruction (with variants
502 /// removed), e.g. "movsx $src, $dst".
503 std::string AsmString;
504
505 /// TheDef - This is the definition of the instruction or InstAlias that this
506 /// matchable came from.
507 const Record *const TheDef;
508
509 // ResInstSize - The size of the resulting instruction for this matchable.
510 unsigned ResInstSize;
511
512 /// DefRec - This is the definition that it came from.
513 PointerUnion<const CodeGenInstruction *, const CodeGenInstAlias *> DefRec;
514
515 const CodeGenInstruction *getResultInst() const {
516 if (isa<const CodeGenInstruction *>(Val: DefRec))
517 return cast<const CodeGenInstruction *>(Val: DefRec);
518 return cast<const CodeGenInstAlias *>(Val: DefRec)->ResultInst;
519 }
520
521 /// ResOperands - This is the operand list that should be built for the result
522 /// MCInst.
523 SmallVector<ResOperand, 8> ResOperands;
524
525 /// Mnemonic - This is the first token of the matched instruction, its
526 /// mnemonic.
527 StringRef Mnemonic;
528
529 /// AsmOperands - The textual operands that this instruction matches,
530 /// annotated with a class and where in the OperandList they were defined.
531 /// This directly corresponds to the tokenized AsmString after the mnemonic is
532 /// removed.
533 SmallVector<AsmOperand, 8> AsmOperands;
534
535 /// Predicates - The required subtarget features to match this instruction.
536 SmallVector<const SubtargetFeatureInfo *, 4> RequiredFeatures;
537
538 /// ConversionFnKind - The enum value which is passed to the generated
539 /// convertToMCInst to convert parsed operands into an MCInst for this
540 /// function.
541 std::string ConversionFnKind;
542
543 /// If this instruction is deprecated in some form.
544 bool HasDeprecation = false;
545
546 /// If this is an alias, this is use to determine whether or not to using
547 /// the conversion function defined by the instruction's AsmMatchConverter
548 /// or to use the function generated by the alias.
549 bool UseInstAsmMatchConverter;
550
551 MatchableInfo(const CodeGenInstruction &CGI)
552 : AsmVariantID(0), AsmString(CGI.AsmString), TheDef(CGI.TheDef),
553 ResInstSize(TheDef->getValueAsInt(FieldName: "Size")), DefRec(&CGI),
554 UseInstAsmMatchConverter(true) {}
555
556 MatchableInfo(std::unique_ptr<const CodeGenInstAlias> Alias)
557 : AsmVariantID(0), AsmString(Alias->AsmString), TheDef(Alias->TheDef),
558 ResInstSize(Alias->ResultInst->TheDef->getValueAsInt(FieldName: "Size")),
559 DefRec(Alias.release()), UseInstAsmMatchConverter(TheDef->getValueAsBit(
560 FieldName: "UseInstAsmMatchConverter")) {}
561
562 // Could remove this and the dtor if PointerUnion supported unique_ptr
563 // elements with a dynamic failure/assertion (like the one below) in the case
564 // where it was copied while being in an owning state.
565 MatchableInfo(const MatchableInfo &RHS)
566 : AsmVariantID(RHS.AsmVariantID), AsmString(RHS.AsmString),
567 TheDef(RHS.TheDef), ResInstSize(RHS.ResInstSize), DefRec(RHS.DefRec),
568 ResOperands(RHS.ResOperands), Mnemonic(RHS.Mnemonic),
569 AsmOperands(RHS.AsmOperands), RequiredFeatures(RHS.RequiredFeatures),
570 ConversionFnKind(RHS.ConversionFnKind),
571 HasDeprecation(RHS.HasDeprecation),
572 UseInstAsmMatchConverter(RHS.UseInstAsmMatchConverter) {
573 assert(!isa<const CodeGenInstAlias *>(DefRec));
574 }
575
576 ~MatchableInfo() {
577 delete dyn_cast_if_present<const CodeGenInstAlias *>(Val&: DefRec);
578 }
579
580 // Two-operand aliases clone from the main matchable, but mark the second
581 // operand as a tied operand of the first for purposes of the assembler.
582 void formTwoOperandAlias(StringRef Constraint);
583
584 void initialize(const AsmMatcherInfo &Info,
585 SmallPtrSetImpl<const Record *> &SingletonRegisters,
586 AsmVariantInfo const &Variant, bool HasMnemonicFirst);
587
588 /// validate - Return true if this matchable is a valid thing to match against
589 /// and perform a bunch of validity checking.
590 bool validate(StringRef CommentDelimiter, bool IsAlias) const;
591
592 /// findAsmOperand - Find the AsmOperand with the specified name and
593 /// suboperand index.
594 int findAsmOperand(StringRef N, int SubOpIdx) const {
595 auto I = find_if(Range: AsmOperands, P: [&](const AsmOperand &Op) {
596 return Op.SrcOpName == N && Op.SubOpIdx == SubOpIdx;
597 });
598 return (I != AsmOperands.end()) ? I - AsmOperands.begin() : -1;
599 }
600
601 /// findAsmOperandNamed - Find the first AsmOperand with the specified name.
602 /// This does not check the suboperand index.
603 int findAsmOperandNamed(StringRef N, int LastIdx = -1) const {
604 auto I =
605 llvm::find_if(Range: llvm::drop_begin(RangeOrContainer: AsmOperands, N: LastIdx + 1),
606 P: [&](const AsmOperand &Op) { return Op.SrcOpName == N; });
607 return (I != AsmOperands.end()) ? I - AsmOperands.begin() : -1;
608 }
609
610 int findAsmOperandOriginallyNamed(StringRef N) const {
611 auto I = find_if(Range: AsmOperands, P: [&](const AsmOperand &Op) {
612 return Op.OrigSrcOpName == N;
613 });
614 return (I != AsmOperands.end()) ? I - AsmOperands.begin() : -1;
615 }
616
617 void buildInstructionResultOperands();
618 void buildAliasResultOperands(bool AliasConstraintsAreChecked);
619
620 /// shouldBeMatchedBefore - Compare two matchables for ordering.
621 bool shouldBeMatchedBefore(const MatchableInfo &RHS,
622 bool PreferSmallerInstructions) const {
623 // The primary comparator is the instruction mnemonic.
624 if (int Cmp = Mnemonic.compare_insensitive(RHS: RHS.Mnemonic))
625 return Cmp == -1;
626
627 // (Optionally) Order by the resultant instuctions size.
628 // eg. for ARM thumb instructions smaller encodings should be preferred.
629 if (PreferSmallerInstructions && ResInstSize != RHS.ResInstSize)
630 return ResInstSize < RHS.ResInstSize;
631
632 if (AsmOperands.size() != RHS.AsmOperands.size())
633 return AsmOperands.size() < RHS.AsmOperands.size();
634
635 // Compare lexicographically by operand. The matcher validates that other
636 // orderings wouldn't be ambiguous using \see couldMatchAmbiguouslyWith().
637 for (const auto &[LHSOp, RHSOp] : zip_equal(t: AsmOperands, u: RHS.AsmOperands)) {
638 if (*LHSOp.Class < *RHSOp.Class)
639 return true;
640 if (*RHSOp.Class < *LHSOp.Class)
641 return false;
642 }
643
644 // For X86 AVX/AVX512 instructions, we prefer vex encoding because the
645 // vex encoding size is smaller. Since X86InstrSSE.td is included ahead
646 // of X86InstrAVX512.td, the AVX instruction ID is less than AVX512 ID.
647 // We use the ID to sort AVX instruction before AVX512 instruction in
648 // matching table. As well as InstAlias.
649 if (getResultInst()->TheDef->isSubClassOf(Name: "Instruction") &&
650 getResultInst()->TheDef->getValueAsBit(FieldName: "HasPositionOrder") &&
651 RHS.getResultInst()->TheDef->isSubClassOf(Name: "Instruction") &&
652 RHS.getResultInst()->TheDef->getValueAsBit(FieldName: "HasPositionOrder"))
653 return getResultInst()->TheDef->getID() <
654 RHS.getResultInst()->TheDef->getID();
655
656 // Give matches that require more features higher precedence. This is useful
657 // because we cannot define AssemblerPredicates with the negation of
658 // processor features. For example, ARM v6 "nop" may be either a HINT or
659 // MOV. With v6, we want to match HINT. The assembler has no way to
660 // predicate MOV under "NoV6", but HINT will always match first because it
661 // requires V6 while MOV does not.
662 if (RequiredFeatures.size() != RHS.RequiredFeatures.size())
663 return RequiredFeatures.size() > RHS.RequiredFeatures.size();
664
665 return false;
666 }
667
668 /// couldMatchAmbiguouslyWith - Check whether this matchable could
669 /// ambiguously match the same set of operands as \p RHS (without being a
670 /// strictly superior match).
671 bool couldMatchAmbiguouslyWith(const MatchableInfo &RHS,
672 bool PreferSmallerInstructions) const {
673 // The primary comparator is the instruction mnemonic.
674 if (Mnemonic != RHS.Mnemonic)
675 return false;
676
677 // Different variants can't conflict.
678 if (AsmVariantID != RHS.AsmVariantID)
679 return false;
680
681 // The size of instruction is unambiguous.
682 if (PreferSmallerInstructions && ResInstSize != RHS.ResInstSize)
683 return false;
684
685 // The number of operands is unambiguous.
686 if (AsmOperands.size() != RHS.AsmOperands.size())
687 return false;
688
689 // Otherwise, make sure the ordering of the two instructions is unambiguous
690 // by checking that either (a) a token or operand kind discriminates them,
691 // or (b) the ordering among equivalent kinds is consistent.
692
693 // Tokens and operand kinds are unambiguous (assuming a correct target
694 // specific parser).
695 for (const auto &[LHSOp, RHSOp] : zip_equal(t: AsmOperands, u: RHS.AsmOperands)) {
696 if (LHSOp.Class->Kind != RHSOp.Class->Kind ||
697 LHSOp.Class->Kind == ClassInfo::Token)
698 if (*LHSOp.Class < *RHSOp.Class || *RHSOp.Class < *LHSOp.Class)
699 return false;
700 }
701
702 // Otherwise, this operand could commute if all operands are equivalent, or
703 // there is a pair of operands that compare less than and a pair that
704 // compare greater than.
705 bool HasLT = false, HasGT = false;
706 for (const auto &[LHSOp, RHSOp] : zip_equal(t: AsmOperands, u: RHS.AsmOperands)) {
707 if (*LHSOp.Class < *RHSOp.Class)
708 HasLT = true;
709 if (*RHSOp.Class < *LHSOp.Class)
710 HasGT = true;
711 }
712
713 return HasLT == HasGT;
714 }
715
716 void dump() const;
717
718private:
719 void tokenizeAsmString(AsmMatcherInfo const &Info,
720 AsmVariantInfo const &Variant);
721 void addAsmOperand(StringRef Token, bool IsIsolatedToken = false);
722};
723
724struct OperandMatchEntry {
725 unsigned OperandMask;
726 const MatchableInfo *MI;
727 ClassInfo *CI;
728
729 static OperandMatchEntry create(const MatchableInfo *mi, ClassInfo *ci,
730 unsigned opMask) {
731 OperandMatchEntry X;
732 X.OperandMask = opMask;
733 X.CI = ci;
734 X.MI = mi;
735 return X;
736 }
737};
738
739class AsmMatcherInfo {
740public:
741 /// Tracked Records
742 const RecordKeeper &Records;
743
744 /// The tablegen AsmParser record.
745 const Record *AsmParser;
746
747 /// Target - The target information.
748 const CodeGenTarget &Target;
749
750 /// The classes which are needed for matching.
751 std::forward_list<ClassInfo> Classes;
752
753 /// The information on the matchables to match.
754 std::vector<std::unique_ptr<MatchableInfo>> Matchables;
755
756 /// Info for custom matching operands by user defined methods.
757 std::vector<OperandMatchEntry> OperandMatchInfo;
758
759 /// Map of Register records to their class information.
760 typedef std::map<const Record *, ClassInfo *, LessRecordByID>
761 RegisterClassesTy;
762 RegisterClassesTy RegisterClasses;
763
764 /// Map of Predicate records to their subtarget information.
765 SubtargetFeatureInfoMap SubtargetFeatures;
766
767 /// Map of AsmOperandClass records to their class information.
768 std::map<const Record *, ClassInfo *> AsmOperandClasses;
769
770 /// Map of RegisterClass records to their class information.
771 std::map<const Record *, ClassInfo *> RegisterClassClasses;
772
773private:
774 /// Map of token to class information which has already been constructed.
775 std::map<std::string, ClassInfo *> TokenClasses;
776
777private:
778 /// getTokenClass - Lookup or create the class for the given token.
779 ClassInfo *getTokenClass(StringRef Token);
780
781 /// getOperandClass - Lookup or create the class for the given operand.
782 ClassInfo *getOperandClass(const CGIOperandList::OperandInfo &OI,
783 int SubOpIdx);
784 ClassInfo *getOperandClass(const Record *Rec, int SubOpIdx);
785
786 /// buildRegisterClasses - Build the ClassInfo* instances for register
787 /// classes.
788 void
789 buildRegisterClasses(SmallPtrSetImpl<const Record *> &SingletonRegisters);
790
791 /// buildOperandClasses - Build the ClassInfo* instances for user defined
792 /// operand classes.
793 void buildOperandClasses();
794
795 void buildInstructionOperandReference(MatchableInfo *II, StringRef OpName,
796 unsigned AsmOpIdx);
797 void buildAliasOperandReference(MatchableInfo *II, StringRef OpName,
798 MatchableInfo::AsmOperand &Op);
799
800public:
801 AsmMatcherInfo(const Record *AsmParser, const CodeGenTarget &Target,
802 const RecordKeeper &Records);
803
804 /// Construct the various tables used during matching.
805 void buildInfo();
806
807 /// buildOperandMatchInfo - Build the necessary information to handle user
808 /// defined operand parsing methods.
809 void buildOperandMatchInfo();
810
811 /// getSubtargetFeature - Lookup or create the subtarget feature info for the
812 /// given operand.
813 const SubtargetFeatureInfo *getSubtargetFeature(const Record *Def) const {
814 assert(Def->isSubClassOf("Predicate") && "Invalid predicate type!");
815 const auto &I = SubtargetFeatures.find(x: Def);
816 return I == SubtargetFeatures.end() ? nullptr : &I->second;
817 }
818
819 const RecordKeeper &getRecords() const { return Records; }
820
821 bool hasOptionalOperands() const {
822 return any_of(Range: Classes,
823 P: [](const ClassInfo &Class) { return Class.IsOptional; });
824 }
825};
826
827} // end anonymous namespace
828
829#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
830LLVM_DUMP_METHOD void MatchableInfo::dump() const {
831 errs() << TheDef->getName() << " -- "
832 << "flattened:\"" << AsmString << "\"\n";
833
834 errs() << " variant: " << AsmVariantID << "\n";
835
836 for (const auto &[Idx, Op] : enumerate(AsmOperands)) {
837 errs() << " op[" << Idx << "] = " << Op.Class->ClassName << " - ";
838 errs() << '\"' << Op.Token << "\"\n";
839 }
840}
841#endif
842
843static std::pair<StringRef, StringRef>
844parseTwoOperandConstraint(StringRef S, ArrayRef<SMLoc> Loc) {
845 // Split via the '='.
846 std::pair<StringRef, StringRef> Ops = S.split(Separator: '=');
847 if (Ops.second == "")
848 PrintFatalError(ErrorLoc: Loc, Msg: "missing '=' in two-operand alias constraint");
849 // Trim whitespace and the leading '$' on the operand names.
850 size_t start = Ops.first.find_first_of(C: '$');
851 if (start == std::string::npos)
852 PrintFatalError(ErrorLoc: Loc, Msg: "expected '$' prefix on asm operand name");
853 Ops.first = Ops.first.substr(Start: start + 1);
854 size_t end = Ops.first.find_last_of(Chars: " \t");
855 Ops.first = Ops.first.slice(Start: 0, End: end);
856 // Now the second operand.
857 start = Ops.second.find_first_of(C: '$');
858 if (start == std::string::npos)
859 PrintFatalError(ErrorLoc: Loc, Msg: "expected '$' prefix on asm operand name");
860 Ops.second = Ops.second.substr(Start: start + 1);
861 end = Ops.second.find_last_of(Chars: " \t");
862 Ops.first = Ops.first.slice(Start: 0, End: end);
863 return Ops;
864}
865
866void MatchableInfo::formTwoOperandAlias(StringRef Constraint) {
867 // Figure out which operands are aliased and mark them as tied.
868 std::pair<StringRef, StringRef> Ops =
869 parseTwoOperandConstraint(S: Constraint, Loc: TheDef->getLoc());
870
871 // Find the AsmOperands that refer to the operands we're aliasing.
872 int SrcAsmOperand = findAsmOperandNamed(N: Ops.first);
873 int DstAsmOperand = findAsmOperandNamed(N: Ops.second);
874 if (SrcAsmOperand == -1)
875 PrintFatalError(ErrorLoc: TheDef->getLoc(),
876 Msg: "unknown source two-operand alias operand '" + Ops.first +
877 "'.");
878 if (DstAsmOperand == -1)
879 PrintFatalError(ErrorLoc: TheDef->getLoc(),
880 Msg: "unknown destination two-operand alias operand '" +
881 Ops.second + "'.");
882
883 // Find the ResOperand that refers to the operand we're aliasing away
884 // and update it to refer to the combined operand instead.
885 for (ResOperand &Op : ResOperands) {
886 if (Op.Kind == ResOperand::RenderAsmOperand &&
887 Op.AsmOperandNum == (unsigned)SrcAsmOperand) {
888 Op.AsmOperandNum = DstAsmOperand;
889 break;
890 }
891 }
892 // Remove the AsmOperand for the alias operand.
893 AsmOperands.erase(CI: AsmOperands.begin() + SrcAsmOperand);
894 // Adjust the ResOperand references to any AsmOperands that followed
895 // the one we just deleted.
896 for (ResOperand &Op : ResOperands) {
897 switch (Op.Kind) {
898 default:
899 // Nothing to do for operands that don't reference AsmOperands.
900 break;
901 case ResOperand::RenderAsmOperand:
902 if (Op.AsmOperandNum > (unsigned)SrcAsmOperand)
903 --Op.AsmOperandNum;
904 break;
905 }
906 }
907}
908
909/// extractSingletonRegisterForAsmOperand - Extract singleton register,
910/// if present, from specified token.
911static void extractSingletonRegisterForAsmOperand(MatchableInfo::AsmOperand &Op,
912 const AsmMatcherInfo &Info,
913 StringRef RegisterPrefix) {
914 StringRef Tok = Op.Token;
915
916 // If this token is not an isolated token, i.e., it isn't separated from
917 // other tokens (e.g. with whitespace), don't interpret it as a register name.
918 if (!Op.IsIsolatedToken)
919 return;
920
921 if (RegisterPrefix.empty()) {
922 std::string LoweredTok = Tok.lower();
923 if (const CodeGenRegister *Reg = Info.Target.getRegisterByName(Name: LoweredTok))
924 Op.SingletonReg = Reg->TheDef;
925 return;
926 }
927
928 if (!Tok.starts_with(Prefix: RegisterPrefix))
929 return;
930
931 StringRef RegName = Tok.substr(Start: RegisterPrefix.size());
932 if (const CodeGenRegister *Reg = Info.Target.getRegisterByName(Name: RegName))
933 Op.SingletonReg = Reg->TheDef;
934
935 // If there is no register prefix (i.e. "%" in "%eax"), then this may
936 // be some random non-register token, just ignore it.
937}
938
939void MatchableInfo::initialize(
940 const AsmMatcherInfo &Info,
941 SmallPtrSetImpl<const Record *> &SingletonRegisters,
942 AsmVariantInfo const &Variant, bool HasMnemonicFirst) {
943 AsmVariantID = Variant.AsmVariantNo;
944 AsmString = CodeGenInstruction::FlattenAsmStringVariants(
945 AsmString, Variant: Variant.AsmVariantNo);
946
947 tokenizeAsmString(Info, Variant);
948
949 // The first token of the instruction is the mnemonic, which must be a
950 // simple string, not a $foo variable or a singleton register.
951 if (AsmOperands.empty())
952 PrintFatalError(ErrorLoc: TheDef->getLoc(),
953 Msg: "Instruction '" + TheDef->getName() + "' has no tokens");
954
955 assert(!AsmOperands[0].Token.empty());
956 if (HasMnemonicFirst) {
957 Mnemonic = AsmOperands[0].Token;
958 if (Mnemonic[0] == '$')
959 PrintFatalError(ErrorLoc: TheDef->getLoc(),
960 Msg: "Invalid instruction mnemonic '" + Mnemonic + "'!");
961
962 // Remove the first operand, it is tracked in the mnemonic field.
963 AsmOperands.erase(CI: AsmOperands.begin());
964 } else if (AsmOperands[0].Token[0] != '$')
965 Mnemonic = AsmOperands[0].Token;
966
967 // Compute the require features.
968 for (const Record *Predicate : TheDef->getValueAsListOfDefs(FieldName: "Predicates"))
969 if (const SubtargetFeatureInfo *Feature =
970 Info.getSubtargetFeature(Def: Predicate))
971 RequiredFeatures.push_back(Elt: Feature);
972
973 // Collect singleton registers, if used.
974 for (MatchableInfo::AsmOperand &Op : AsmOperands) {
975 extractSingletonRegisterForAsmOperand(Op, Info, RegisterPrefix: Variant.RegisterPrefix);
976 if (Op.SingletonReg)
977 SingletonRegisters.insert(Ptr: Op.SingletonReg);
978 }
979
980 const RecordVal *DepMask = TheDef->getValue(Name: "DeprecatedFeatureMask");
981 if (!DepMask)
982 DepMask = TheDef->getValue(Name: "ComplexDeprecationPredicate");
983
984 HasDeprecation =
985 DepMask ? !DepMask->getValue()->getAsUnquotedString().empty() : false;
986}
987
988/// Append an AsmOperand for the given substring of AsmString.
989void MatchableInfo::addAsmOperand(StringRef Token, bool IsIsolatedToken) {
990 AsmOperands.push_back(Elt: AsmOperand(IsIsolatedToken, Token));
991}
992
993/// tokenizeAsmString - Tokenize a simplified assembly string.
994void MatchableInfo::tokenizeAsmString(const AsmMatcherInfo &Info,
995 AsmVariantInfo const &Variant) {
996 StringRef String = AsmString;
997 size_t Prev = 0;
998 bool InTok = false;
999 bool IsIsolatedToken = true;
1000 for (size_t i = 0, e = String.size(); i != e; ++i) {
1001 char Char = String[i];
1002 if (Variant.BreakCharacters.contains(C: Char)) {
1003 if (InTok) {
1004 addAsmOperand(Token: String.substr(Start: Prev, N: i - Prev), IsIsolatedToken: false);
1005 Prev = i;
1006 IsIsolatedToken = false;
1007 }
1008 InTok = true;
1009 continue;
1010 }
1011 if (Variant.TokenizingCharacters.contains(C: Char)) {
1012 if (InTok) {
1013 addAsmOperand(Token: String.substr(Start: Prev, N: i - Prev), IsIsolatedToken);
1014 InTok = false;
1015 IsIsolatedToken = false;
1016 }
1017 addAsmOperand(Token: String.substr(Start: i, N: 1), IsIsolatedToken);
1018 Prev = i + 1;
1019 IsIsolatedToken = true;
1020 continue;
1021 }
1022 if (Variant.SeparatorCharacters.contains(C: Char)) {
1023 if (InTok) {
1024 addAsmOperand(Token: String.substr(Start: Prev, N: i - Prev), IsIsolatedToken);
1025 InTok = false;
1026 }
1027 Prev = i + 1;
1028 IsIsolatedToken = true;
1029 continue;
1030 }
1031
1032 switch (Char) {
1033 case '\\':
1034 if (InTok) {
1035 addAsmOperand(Token: String.substr(Start: Prev, N: i - Prev), IsIsolatedToken: false);
1036 InTok = false;
1037 IsIsolatedToken = false;
1038 }
1039 ++i;
1040 assert(i != String.size() && "Invalid quoted character");
1041 addAsmOperand(Token: String.substr(Start: i, N: 1), IsIsolatedToken);
1042 Prev = i + 1;
1043 IsIsolatedToken = false;
1044 break;
1045
1046 case '$': {
1047 if (InTok) {
1048 addAsmOperand(Token: String.substr(Start: Prev, N: i - Prev), IsIsolatedToken);
1049 InTok = false;
1050 IsIsolatedToken = false;
1051 }
1052
1053 // If this isn't "${", start new identifier looking like "$xxx"
1054 if (i + 1 == String.size() || String[i + 1] != '{') {
1055 Prev = i;
1056 break;
1057 }
1058
1059 size_t EndPos = String.find(C: '}', From: i);
1060 assert(EndPos != StringRef::npos &&
1061 "Missing brace in operand reference!");
1062 addAsmOperand(Token: String.substr(Start: i, N: EndPos + 1 - i), IsIsolatedToken);
1063 Prev = EndPos + 1;
1064 i = EndPos;
1065 IsIsolatedToken = false;
1066 break;
1067 }
1068
1069 default:
1070 InTok = true;
1071 break;
1072 }
1073 }
1074 if (InTok && Prev != String.size())
1075 addAsmOperand(Token: String.substr(Start: Prev), IsIsolatedToken);
1076}
1077
1078bool MatchableInfo::validate(StringRef CommentDelimiter, bool IsAlias) const {
1079 // Reject matchables with no .s string.
1080 if (AsmString.empty())
1081 PrintFatalError(ErrorLoc: TheDef->getLoc(), Msg: "instruction with empty asm string");
1082
1083 // Reject any matchables with a newline in them, they should be marked
1084 // isCodeGenOnly if they are pseudo instructions.
1085 if (AsmString.find(c: '\n') != std::string::npos)
1086 PrintFatalError(ErrorLoc: TheDef->getLoc(),
1087 Msg: "multiline instruction is not valid for the asmparser, "
1088 "mark it isCodeGenOnly");
1089
1090 // Remove comments from the asm string. We know that the asmstring only
1091 // has one line.
1092 if (!CommentDelimiter.empty() &&
1093 StringRef(AsmString).contains(Other: CommentDelimiter))
1094 PrintFatalError(ErrorLoc: TheDef->getLoc(),
1095 Msg: "asmstring for instruction has comment character in it, "
1096 "mark it isCodeGenOnly");
1097
1098 // Reject matchables with operand modifiers, these aren't something we can
1099 // handle, the target should be refactored to use operands instead of
1100 // modifiers.
1101 //
1102 // Also, check for instructions which reference the operand multiple times,
1103 // if they don't define a custom AsmMatcher: this implies a constraint that
1104 // the built-in matching code would not honor.
1105 std::set<std::string> OperandNames;
1106 for (const AsmOperand &Op : AsmOperands) {
1107 StringRef Tok = Op.Token;
1108 if (Tok[0] == '$' && Tok.contains(C: ':'))
1109 PrintFatalError(
1110 ErrorLoc: TheDef->getLoc(),
1111 Msg: "matchable with operand modifier '" + Tok +
1112 "' not supported by asm matcher. Mark isCodeGenOnly!");
1113 // Verify that any operand is only mentioned once.
1114 // We reject aliases and ignore instructions for now.
1115 if (!IsAlias && TheDef->getValueAsString(FieldName: "AsmMatchConverter").empty() &&
1116 Tok[0] == '$' && !OperandNames.insert(x: Tok.str()).second) {
1117 LLVM_DEBUG({
1118 errs() << "warning: '" << TheDef->getName() << "': "
1119 << "ignoring instruction with tied operand '" << Tok << "'\n";
1120 });
1121 return false;
1122 }
1123 }
1124
1125 return true;
1126}
1127
1128static std::string getEnumNameForToken(StringRef Str) {
1129 std::string Res;
1130
1131 for (char C : Str) {
1132 switch (C) {
1133 case '*':
1134 Res += "_STAR_";
1135 break;
1136 case '%':
1137 Res += "_PCT_";
1138 break;
1139 case ':':
1140 Res += "_COLON_";
1141 break;
1142 case '!':
1143 Res += "_EXCLAIM_";
1144 break;
1145 case '.':
1146 Res += "_DOT_";
1147 break;
1148 case '<':
1149 Res += "_LT_";
1150 break;
1151 case '>':
1152 Res += "_GT_";
1153 break;
1154 case '-':
1155 Res += "_MINUS_";
1156 break;
1157 case '#':
1158 Res += "_HASH_";
1159 break;
1160 default:
1161 if (isAlnum(C))
1162 Res += C;
1163 else
1164 Res += "_" + utostr(X: (unsigned)C) + "_";
1165 }
1166 }
1167
1168 return Res;
1169}
1170
1171ClassInfo *AsmMatcherInfo::getTokenClass(StringRef Token) {
1172 ClassInfo *&Entry = TokenClasses[Token.str()];
1173
1174 if (!Entry) {
1175 Classes.emplace_front();
1176 Entry = &Classes.front();
1177 Entry->Kind = ClassInfo::Token;
1178 Entry->ClassName = "Token";
1179 Entry->Name = "MCK_" + getEnumNameForToken(Str: Token);
1180 Entry->ValueName = Token.str();
1181 Entry->PredicateMethod = "<invalid>";
1182 Entry->RenderMethod = "<invalid>";
1183 Entry->ParserMethod = "";
1184 Entry->DiagnosticType = "";
1185 Entry->IsOptional = false;
1186 Entry->DefaultMethod = "<invalid>";
1187 }
1188
1189 return Entry;
1190}
1191
1192ClassInfo *
1193AsmMatcherInfo::getOperandClass(const CGIOperandList::OperandInfo &OI,
1194 int SubOpIdx) {
1195 const Record *Rec = OI.Rec;
1196 if (SubOpIdx != -1)
1197 Rec = cast<DefInit>(Val: OI.MIOperandInfo->getArg(Num: SubOpIdx))->getDef();
1198 return getOperandClass(Rec, SubOpIdx);
1199}
1200
1201ClassInfo *AsmMatcherInfo::getOperandClass(const Record *Rec, int SubOpIdx) {
1202 if (Rec->isSubClassOf(Name: "RegisterOperand")) {
1203 // RegisterOperand may have an associated ParserMatchClass. If it does,
1204 // use it, else just fall back to the underlying register class.
1205 const RecordVal *R = Rec->getValue(Name: "ParserMatchClass");
1206 if (!R || !R->getValue())
1207 PrintFatalError(ErrorLoc: Rec->getLoc(),
1208 Msg: "Record `" + Rec->getName() +
1209 "' does not have a ParserMatchClass!\n");
1210
1211 if (const DefInit *DI = dyn_cast<DefInit>(Val: R->getValue())) {
1212 const Record *MatchClass = DI->getDef();
1213 if (ClassInfo *CI = AsmOperandClasses[MatchClass])
1214 return CI;
1215 }
1216
1217 // No custom match class. Just use the register class.
1218 const Record *ClassRec = Rec->getValueAsDef(FieldName: "RegClass");
1219 if (!ClassRec)
1220 PrintFatalError(ErrorLoc: Rec->getLoc(),
1221 Msg: "RegisterOperand `" + Rec->getName() +
1222 "' has no associated register class!\n");
1223 if (ClassInfo *CI = RegisterClassClasses[ClassRec])
1224 return CI;
1225 PrintFatalError(ErrorLoc: Rec->getLoc(), Msg: "register class has no class info!");
1226 }
1227
1228 if (Rec->isSubClassOf(Name: "RegisterClass")) {
1229 if (ClassInfo *CI = RegisterClassClasses[Rec])
1230 return CI;
1231 PrintFatalError(ErrorLoc: Rec->getLoc(), Msg: "register class has no class info!");
1232 }
1233
1234 if (!Rec->isSubClassOf(Name: "Operand"))
1235 PrintFatalError(ErrorLoc: Rec->getLoc(),
1236 Msg: "Operand `" + Rec->getName() +
1237 "' does not derive from class Operand!\n");
1238 const Record *MatchClass = Rec->getValueAsDef(FieldName: "ParserMatchClass");
1239 if (ClassInfo *CI = AsmOperandClasses[MatchClass])
1240 return CI;
1241
1242 PrintFatalError(ErrorLoc: Rec->getLoc(), Msg: "operand has no match class!");
1243}
1244
1245struct LessRegisterSet {
1246 bool operator()(const RegisterSet &LHS, const RegisterSet &RHS) const {
1247 // std::set<T> defines its own compariso "operator<", but it
1248 // performs a lexicographical comparison by T's innate comparison
1249 // for some reason. We don't want non-deterministic pointer
1250 // comparisons so use this instead.
1251 return std::lexicographical_compare(first1: LHS.begin(), last1: LHS.end(), first2: RHS.begin(),
1252 last2: RHS.end(), comp: LessRecordByID());
1253 }
1254};
1255
1256void AsmMatcherInfo::buildRegisterClasses(
1257 SmallPtrSetImpl<const Record *> &SingletonRegisters) {
1258 const auto &Registers = Target.getRegBank().getRegisters();
1259 auto &RegClassList = Target.getRegBank().getRegClasses();
1260
1261 typedef std::set<RegisterSet, LessRegisterSet> RegisterSetSet;
1262
1263 // The register sets used for matching.
1264 RegisterSetSet RegisterSets;
1265
1266 // Gather the defined sets.
1267 for (const CodeGenRegisterClass &RC : RegClassList)
1268 RegisterSets.insert(
1269 x: RegisterSet(RC.getOrder().begin(), RC.getOrder().end()));
1270
1271 // Add any required singleton sets.
1272 for (const Record *Rec : SingletonRegisters) {
1273 RegisterSets.insert(x: RegisterSet(&Rec, &Rec + 1));
1274 }
1275
1276 // Introduce derived sets where necessary (when a register does not determine
1277 // a unique register set class), and build the mapping of registers to the set
1278 // they should classify to.
1279 std::map<const Record *, RegisterSet> RegisterMap;
1280 for (const CodeGenRegister &CGR : Registers) {
1281 // Compute the intersection of all sets containing this register.
1282 RegisterSet ContainingSet;
1283
1284 for (const RegisterSet &RS : RegisterSets) {
1285 if (!RS.count(x: CGR.TheDef))
1286 continue;
1287
1288 if (ContainingSet.empty()) {
1289 ContainingSet = RS;
1290 continue;
1291 }
1292
1293 RegisterSet Tmp;
1294 std::set_intersection(first1: ContainingSet.begin(), last1: ContainingSet.end(),
1295 first2: RS.begin(), last2: RS.end(),
1296 result: std::inserter(x&: Tmp, i: Tmp.begin()), comp: LessRecordByID());
1297 ContainingSet = std::move(Tmp);
1298 }
1299
1300 if (!ContainingSet.empty()) {
1301 RegisterSets.insert(x: ContainingSet);
1302 RegisterMap.try_emplace(k: CGR.TheDef, args&: ContainingSet);
1303 }
1304 }
1305
1306 // Construct the register classes.
1307 std::map<RegisterSet, ClassInfo *, LessRegisterSet> RegisterSetClasses;
1308 unsigned Index = 0;
1309 for (const RegisterSet &RS : RegisterSets) {
1310 Classes.emplace_front();
1311 ClassInfo *CI = &Classes.front();
1312 CI->Kind = ClassInfo::RegisterClass0 + Index;
1313 CI->ClassName = "Reg" + utostr(X: Index);
1314 CI->Name = "MCK_Reg" + utostr(X: Index);
1315 CI->ValueName = "";
1316 CI->PredicateMethod = ""; // unused
1317 CI->RenderMethod = "addRegOperands";
1318 CI->Registers = RS;
1319 // FIXME: diagnostic type.
1320 CI->DiagnosticType = "";
1321 CI->IsOptional = false;
1322 CI->DefaultMethod = ""; // unused
1323 RegisterSetClasses.try_emplace(k: RS, args&: CI);
1324 ++Index;
1325 }
1326
1327 // Find the superclasses; we could compute only the subgroup lattice edges,
1328 // but there isn't really a point.
1329 for (const RegisterSet &RS : RegisterSets) {
1330 ClassInfo *CI = RegisterSetClasses[RS];
1331 for (const RegisterSet &RS2 : RegisterSets)
1332 if (RS != RS2 && llvm::includes(Range1: RS2, Range2: RS, C: LessRecordByID()))
1333 CI->SuperClasses.push_back(x: RegisterSetClasses[RS2]);
1334 }
1335
1336 // Name the register classes which correspond to a user defined RegisterClass.
1337 for (const CodeGenRegisterClass &RC : RegClassList) {
1338 // Def will be NULL for non-user defined register classes.
1339 const Record *Def = RC.getDef();
1340 if (!Def)
1341 continue;
1342 ClassInfo *CI = RegisterSetClasses[RegisterSet(RC.getOrder().begin(),
1343 RC.getOrder().end())];
1344 if (CI->ValueName.empty()) {
1345 CI->ClassName = RC.getName();
1346 CI->Name = "MCK_" + RC.getName();
1347 CI->ValueName = RC.getName();
1348 } else {
1349 CI->ValueName = CI->ValueName + "," + RC.getName();
1350 }
1351
1352 const Init *DiagnosticType = Def->getValueInit(FieldName: "DiagnosticType");
1353 if (const StringInit *SI = dyn_cast<StringInit>(Val: DiagnosticType))
1354 CI->DiagnosticType = SI->getValue().str();
1355
1356 const Init *DiagnosticString = Def->getValueInit(FieldName: "DiagnosticString");
1357 if (const StringInit *SI = dyn_cast<StringInit>(Val: DiagnosticString))
1358 CI->DiagnosticString = SI->getValue().str();
1359
1360 // If we have a diagnostic string but the diagnostic type is not specified
1361 // explicitly, create an anonymous diagnostic type.
1362 if (!CI->DiagnosticString.empty() && CI->DiagnosticType.empty())
1363 CI->DiagnosticType = RC.getName();
1364
1365 RegisterClassClasses.try_emplace(k: Def, args&: CI);
1366 }
1367
1368 // Populate the map for individual registers.
1369 for (auto &It : RegisterMap)
1370 RegisterClasses[It.first] = RegisterSetClasses[It.second];
1371
1372 // Name the register classes which correspond to singleton registers.
1373 for (const Record *Rec : SingletonRegisters) {
1374 ClassInfo *CI = RegisterClasses[Rec];
1375 assert(CI && "Missing singleton register class info!");
1376
1377 if (CI->ValueName.empty()) {
1378 CI->ClassName = Rec->getName().str();
1379 CI->Name = "MCK_" + Rec->getName().str();
1380 CI->ValueName = Rec->getName().str();
1381 } else {
1382 CI->ValueName = CI->ValueName + "," + Rec->getName().str();
1383 }
1384 }
1385}
1386
1387void AsmMatcherInfo::buildOperandClasses() {
1388 ArrayRef<const Record *> AsmOperands =
1389 Records.getAllDerivedDefinitions(ClassName: "AsmOperandClass");
1390
1391 // Pre-populate AsmOperandClasses map.
1392 for (const Record *Rec : AsmOperands) {
1393 Classes.emplace_front();
1394 AsmOperandClasses[Rec] = &Classes.front();
1395 }
1396
1397 unsigned Index = 0;
1398 for (const Record *Rec : AsmOperands) {
1399 ClassInfo *CI = AsmOperandClasses[Rec];
1400 CI->Kind = ClassInfo::UserClass0 + Index;
1401
1402 const ListInit *Supers = Rec->getValueAsListInit(FieldName: "SuperClasses");
1403 for (const Init *I : Supers->getElements()) {
1404 const DefInit *DI = dyn_cast<DefInit>(Val: I);
1405 if (!DI) {
1406 PrintError(ErrorLoc: Rec->getLoc(), Msg: "Invalid super class reference!");
1407 continue;
1408 }
1409
1410 ClassInfo *SC = AsmOperandClasses[DI->getDef()];
1411 if (!SC)
1412 PrintError(ErrorLoc: Rec->getLoc(), Msg: "Invalid super class reference!");
1413 else
1414 CI->SuperClasses.push_back(x: SC);
1415 }
1416 CI->ClassName = Rec->getValueAsString(FieldName: "Name").str();
1417 CI->Name = "MCK_" + CI->ClassName;
1418 CI->ValueName = Rec->getName().str();
1419
1420 // Get or construct the predicate method name.
1421 const Init *PMName = Rec->getValueInit(FieldName: "PredicateMethod");
1422 if (const StringInit *SI = dyn_cast<StringInit>(Val: PMName)) {
1423 CI->PredicateMethod = SI->getValue().str();
1424 } else {
1425 assert(isa<UnsetInit>(PMName) && "Unexpected PredicateMethod field!");
1426 CI->PredicateMethod = "is" + CI->ClassName;
1427 }
1428
1429 // Get or construct the render method name.
1430 const Init *RMName = Rec->getValueInit(FieldName: "RenderMethod");
1431 if (const StringInit *SI = dyn_cast<StringInit>(Val: RMName)) {
1432 CI->RenderMethod = SI->getValue().str();
1433 } else {
1434 assert(isa<UnsetInit>(RMName) && "Unexpected RenderMethod field!");
1435 CI->RenderMethod = "add" + CI->ClassName + "Operands";
1436 }
1437
1438 // Get the parse method name or leave it as empty.
1439 const Init *PRMName = Rec->getValueInit(FieldName: "ParserMethod");
1440 if (const StringInit *SI = dyn_cast<StringInit>(Val: PRMName))
1441 CI->ParserMethod = SI->getValue().str();
1442
1443 // Get the diagnostic type and string or leave them as empty.
1444 const Init *DiagnosticType = Rec->getValueInit(FieldName: "DiagnosticType");
1445 if (const StringInit *SI = dyn_cast<StringInit>(Val: DiagnosticType))
1446 CI->DiagnosticType = SI->getValue().str();
1447 const Init *DiagnosticString = Rec->getValueInit(FieldName: "DiagnosticString");
1448 if (const StringInit *SI = dyn_cast<StringInit>(Val: DiagnosticString))
1449 CI->DiagnosticString = SI->getValue().str();
1450 // If we have a DiagnosticString, we need a DiagnosticType for use within
1451 // the matcher.
1452 if (!CI->DiagnosticString.empty() && CI->DiagnosticType.empty())
1453 CI->DiagnosticType = CI->ClassName;
1454
1455 const Init *IsOptional = Rec->getValueInit(FieldName: "IsOptional");
1456 if (const BitInit *BI = dyn_cast<BitInit>(Val: IsOptional))
1457 CI->IsOptional = BI->getValue();
1458
1459 // Get or construct the default method name.
1460 const Init *DMName = Rec->getValueInit(FieldName: "DefaultMethod");
1461 if (const StringInit *SI = dyn_cast<StringInit>(Val: DMName)) {
1462 CI->DefaultMethod = SI->getValue().str();
1463 } else {
1464 assert(isa<UnsetInit>(DMName) && "Unexpected DefaultMethod field!");
1465 CI->DefaultMethod = "default" + CI->ClassName + "Operands";
1466 }
1467
1468 ++Index;
1469 }
1470}
1471
1472AsmMatcherInfo::AsmMatcherInfo(const Record *asmParser,
1473 const CodeGenTarget &target,
1474 const RecordKeeper &records)
1475 : Records(records), AsmParser(asmParser), Target(target) {}
1476
1477/// buildOperandMatchInfo - Build the necessary information to handle user
1478/// defined operand parsing methods.
1479void AsmMatcherInfo::buildOperandMatchInfo() {
1480 /// Map containing a mask with all operands indices that can be found for
1481 /// that class inside a instruction.
1482 typedef std::map<ClassInfo *, unsigned, deref<std::less<>>> OpClassMaskTy;
1483 OpClassMaskTy OpClassMask;
1484
1485 bool CallCustomParserForAllOperands =
1486 AsmParser->getValueAsBit(FieldName: "CallCustomParserForAllOperands");
1487 for (const auto &MI : Matchables) {
1488 OpClassMask.clear();
1489
1490 // Keep track of all operands of this instructions which belong to the
1491 // same class.
1492 unsigned NumOptionalOps = 0;
1493 for (const auto &[Idx, Op] : enumerate(First&: MI->AsmOperands)) {
1494 if (CallCustomParserForAllOperands || !Op.Class->ParserMethod.empty()) {
1495 unsigned &OperandMask = OpClassMask[Op.Class];
1496 OperandMask |= maskTrailingOnes<unsigned>(N: NumOptionalOps + 1)
1497 << (Idx - NumOptionalOps);
1498 }
1499 if (Op.Class->IsOptional)
1500 ++NumOptionalOps;
1501 }
1502
1503 // Generate operand match info for each mnemonic/operand class pair.
1504 for (const auto [CI, OpMask] : OpClassMask) {
1505 OperandMatchInfo.push_back(
1506 x: OperandMatchEntry::create(mi: MI.get(), ci: CI, opMask: OpMask));
1507 }
1508 }
1509}
1510
1511void AsmMatcherInfo::buildInfo() {
1512 // Build information about all of the AssemblerPredicates.
1513 SubtargetFeaturesInfoVec SubtargetFeaturePairs =
1514 SubtargetFeatureInfo::getAll(Records);
1515 SubtargetFeatures.insert(first: SubtargetFeaturePairs.begin(),
1516 last: SubtargetFeaturePairs.end());
1517#ifndef NDEBUG
1518 for (const auto &Pair : SubtargetFeatures)
1519 LLVM_DEBUG(Pair.second.dump());
1520#endif // NDEBUG
1521
1522 bool HasMnemonicFirst = AsmParser->getValueAsBit(FieldName: "HasMnemonicFirst");
1523 bool ReportMultipleNearMisses =
1524 AsmParser->getValueAsBit(FieldName: "ReportMultipleNearMisses");
1525
1526 // Parse the instructions; we need to do this first so that we can gather the
1527 // singleton register classes.
1528 SmallPtrSet<const Record *, 16> SingletonRegisters;
1529 unsigned VariantCount = Target.getAsmParserVariantCount();
1530 for (unsigned VC = 0; VC != VariantCount; ++VC) {
1531 const Record *AsmVariant = Target.getAsmParserVariant(i: VC);
1532 StringRef CommentDelimiter =
1533 AsmVariant->getValueAsString(FieldName: "CommentDelimiter");
1534 AsmVariantInfo Variant;
1535 Variant.RegisterPrefix = AsmVariant->getValueAsString(FieldName: "RegisterPrefix");
1536 Variant.TokenizingCharacters =
1537 AsmVariant->getValueAsString(FieldName: "TokenizingCharacters");
1538 Variant.SeparatorCharacters =
1539 AsmVariant->getValueAsString(FieldName: "SeparatorCharacters");
1540 Variant.BreakCharacters = AsmVariant->getValueAsString(FieldName: "BreakCharacters");
1541 Variant.Name = AsmVariant->getValueAsString(FieldName: "Name");
1542 Variant.AsmVariantNo = AsmVariant->getValueAsInt(FieldName: "Variant");
1543
1544 for (const CodeGenInstruction *CGI : Target.getInstructionsByEnumValue()) {
1545
1546 // If the tblgen -match-prefix option is specified (for tblgen hackers),
1547 // filter the set of instructions we consider.
1548 if (!StringRef(CGI->TheDef->getName()).starts_with(Prefix: MatchPrefix))
1549 continue;
1550
1551 // Ignore "codegen only" instructions.
1552 if (CGI->TheDef->getValueAsBit(FieldName: "isCodeGenOnly"))
1553 continue;
1554
1555 // Ignore instructions for different instructions
1556 StringRef V = CGI->TheDef->getValueAsString(FieldName: "AsmVariantName");
1557 if (!V.empty() && V != Variant.Name)
1558 continue;
1559
1560 auto II = std::make_unique<MatchableInfo>(args: *CGI);
1561
1562 II->initialize(Info: *this, SingletonRegisters, Variant, HasMnemonicFirst);
1563
1564 // Ignore instructions which shouldn't be matched and diagnose invalid
1565 // instruction definitions with an error.
1566 if (!II->validate(CommentDelimiter, IsAlias: false))
1567 continue;
1568
1569 Matchables.push_back(x: std::move(II));
1570 }
1571
1572 // Parse all of the InstAlias definitions and stick them in the list of
1573 // matchables.
1574 for (const Record *InstAlias :
1575 Records.getAllDerivedDefinitions(ClassName: "InstAlias")) {
1576 auto Alias = std::make_unique<CodeGenInstAlias>(args&: InstAlias, args: Target);
1577
1578 // If the tblgen -match-prefix option is specified (for tblgen hackers),
1579 // filter the set of instruction aliases we consider, based on the target
1580 // instruction.
1581 if (!StringRef(Alias->ResultInst->TheDef->getName())
1582 .starts_with(Prefix: MatchPrefix))
1583 continue;
1584
1585 StringRef V = Alias->TheDef->getValueAsString(FieldName: "AsmVariantName");
1586 if (!V.empty() && V != Variant.Name)
1587 continue;
1588
1589 auto II = std::make_unique<MatchableInfo>(args: std::move(Alias));
1590
1591 II->initialize(Info: *this, SingletonRegisters, Variant, HasMnemonicFirst);
1592
1593 // Validate the alias definitions.
1594 II->validate(CommentDelimiter, IsAlias: true);
1595
1596 Matchables.push_back(x: std::move(II));
1597 }
1598 }
1599
1600 // Build info for the register classes.
1601 buildRegisterClasses(SingletonRegisters);
1602
1603 // Build info for the user defined assembly operand classes.
1604 buildOperandClasses();
1605
1606 // Build the information about matchables, now that we have fully formed
1607 // classes.
1608 std::vector<std::unique_ptr<MatchableInfo>> NewMatchables;
1609 for (auto &II : Matchables) {
1610 // Parse the tokens after the mnemonic.
1611 // Note: buildInstructionOperandReference may insert new AsmOperands, so
1612 // don't precompute the loop bound, i.e., cannot use range based for loop
1613 // here.
1614 for (size_t Idx = 0; Idx < II->AsmOperands.size(); ++Idx) {
1615 MatchableInfo::AsmOperand &Op = II->AsmOperands[Idx];
1616 StringRef Token = Op.Token;
1617 // Check for singleton registers.
1618 if (const Record *RegRecord = Op.SingletonReg) {
1619 Op.Class = RegisterClasses[RegRecord];
1620 assert(Op.Class && Op.Class->Registers.size() == 1 &&
1621 "Unexpected class for singleton register");
1622 continue;
1623 }
1624
1625 // Check for simple tokens.
1626 if (Token[0] != '$') {
1627 Op.Class = getTokenClass(Token);
1628 continue;
1629 }
1630
1631 if (Token.size() > 1 && isdigit(Token[1])) {
1632 Op.Class = getTokenClass(Token);
1633 continue;
1634 }
1635
1636 // Otherwise this is an operand reference.
1637 StringRef OperandName;
1638 if (Token[1] == '{')
1639 OperandName = Token.substr(Start: 2, N: Token.size() - 3);
1640 else
1641 OperandName = Token.substr(Start: 1);
1642
1643 if (isa<const CodeGenInstruction *>(Val: II->DefRec))
1644 buildInstructionOperandReference(II: II.get(), OpName: OperandName, AsmOpIdx: Idx);
1645 else
1646 buildAliasOperandReference(II: II.get(), OpName: OperandName, Op);
1647 }
1648
1649 if (isa<const CodeGenInstruction *>(Val: II->DefRec)) {
1650 II->buildInstructionResultOperands();
1651 // If the instruction has a two-operand alias, build up the
1652 // matchable here. We'll add them in bulk at the end to avoid
1653 // confusing this loop.
1654 StringRef Constraint =
1655 II->TheDef->getValueAsString(FieldName: "TwoOperandAliasConstraint");
1656 if (Constraint != "") {
1657 // Start by making a copy of the original matchable.
1658 auto AliasII = std::make_unique<MatchableInfo>(args&: *II);
1659
1660 // Adjust it to be a two-operand alias.
1661 AliasII->formTwoOperandAlias(Constraint);
1662
1663 // Add the alias to the matchables list.
1664 NewMatchables.push_back(x: std::move(AliasII));
1665 }
1666 } else {
1667 // FIXME: The tied operands checking is not yet integrated with the
1668 // framework for reporting multiple near misses. To prevent invalid
1669 // formats from being matched with an alias if a tied-operands check
1670 // would otherwise have disallowed it, we just disallow such constructs
1671 // in TableGen completely.
1672 II->buildAliasResultOperands(AliasConstraintsAreChecked: !ReportMultipleNearMisses);
1673 }
1674 }
1675 if (!NewMatchables.empty())
1676 Matchables.insert(position: Matchables.end(),
1677 first: std::make_move_iterator(i: NewMatchables.begin()),
1678 last: std::make_move_iterator(i: NewMatchables.end()));
1679
1680 // Process token alias definitions and set up the associated superclass
1681 // information.
1682 for (const Record *Rec : Records.getAllDerivedDefinitions(ClassName: "TokenAlias")) {
1683 ClassInfo *FromClass = getTokenClass(Token: Rec->getValueAsString(FieldName: "FromToken"));
1684 ClassInfo *ToClass = getTokenClass(Token: Rec->getValueAsString(FieldName: "ToToken"));
1685 if (FromClass == ToClass)
1686 PrintFatalError(ErrorLoc: Rec->getLoc(),
1687 Msg: "error: Destination value identical to source value.");
1688 FromClass->SuperClasses.push_back(x: ToClass);
1689 }
1690
1691 // Reorder classes so that classes precede super classes.
1692 Classes.sort();
1693
1694#ifdef EXPENSIVE_CHECKS
1695 // Verify that the table is sorted and operator < works transitively.
1696 for (auto I = Classes.begin(), E = Classes.end(); I != E; ++I) {
1697 for (auto J = I; J != E; ++J) {
1698 assert(!(*J < *I));
1699 assert(I == J || !J->isSubsetOf(*I));
1700 }
1701 }
1702#endif
1703}
1704
1705/// buildInstructionOperandReference - The specified operand is a reference to a
1706/// named operand such as $src. Resolve the Class and OperandInfo pointers.
1707void AsmMatcherInfo::buildInstructionOperandReference(MatchableInfo *II,
1708 StringRef OperandName,
1709 unsigned AsmOpIdx) {
1710 const CodeGenInstruction &CGI = *cast<const CodeGenInstruction *>(Val&: II->DefRec);
1711 const CGIOperandList &Operands = CGI.Operands;
1712 MatchableInfo::AsmOperand *Op = &II->AsmOperands[AsmOpIdx];
1713
1714 // Map this token to an operand.
1715 std::optional<unsigned> Idx = Operands.findOperandNamed(Name: OperandName);
1716 if (!Idx)
1717 PrintFatalError(ErrorLoc: II->TheDef->getLoc(),
1718 Msg: "error: unable to find operand: '" + OperandName + "'");
1719 // If the instruction operand has multiple suboperands, but the parser
1720 // match class for the asm operand is still the default "ImmAsmOperand",
1721 // then handle each suboperand separately.
1722 if (Op->SubOpIdx == -1 && Operands[*Idx].MINumOperands > 1) {
1723 const Record *Rec = Operands[*Idx].Rec;
1724 assert(Rec->isSubClassOf("Operand") && "Unexpected operand!");
1725 const Record *MatchClass = Rec->getValueAsDef(FieldName: "ParserMatchClass");
1726 if (MatchClass && MatchClass->getValueAsString(FieldName: "Name") == "Imm") {
1727 // Insert remaining suboperands after AsmOpIdx in II->AsmOperands.
1728 StringRef Token = Op->Token; // save this in case Op gets moved
1729 for (unsigned SI = 1, SE = Operands[*Idx].MINumOperands; SI != SE; ++SI) {
1730 MatchableInfo::AsmOperand NewAsmOp(/*IsIsolatedToken=*/true, Token);
1731 NewAsmOp.SubOpIdx = SI;
1732 II->AsmOperands.insert(I: II->AsmOperands.begin() + AsmOpIdx + SI,
1733 Elt: NewAsmOp);
1734 }
1735 // Replace Op with first suboperand.
1736 Op = &II->AsmOperands[AsmOpIdx]; // update the pointer in case it moved
1737 Op->SubOpIdx = 0;
1738 }
1739 }
1740
1741 // Set up the operand class.
1742 Op->Class = getOperandClass(OI: Operands[*Idx], SubOpIdx: Op->SubOpIdx);
1743 Op->OrigSrcOpName = OperandName;
1744
1745 // If the named operand is tied, canonicalize it to the untied operand.
1746 // For example, something like:
1747 // (outs GPR:$dst), (ins GPR:$src)
1748 // with an asmstring of
1749 // "inc $src"
1750 // we want to canonicalize to:
1751 // "inc $dst"
1752 // so that we know how to provide the $dst operand when filling in the result.
1753 int OITied = -1;
1754 if (Operands[*Idx].MINumOperands == 1)
1755 OITied = Operands[*Idx].getTiedRegister();
1756 if (OITied != -1) {
1757 // The tied operand index is an MIOperand index, find the operand that
1758 // contains it.
1759 auto [OpIdx, SubopIdx] = Operands.getSubOperandNumber(Op: OITied);
1760 OperandName = Operands[OpIdx].Name;
1761 Op->SubOpIdx = SubopIdx;
1762 }
1763
1764 Op->SrcOpName = OperandName;
1765}
1766
1767/// buildAliasOperandReference - When parsing an operand reference out of the
1768/// matching string (e.g. "movsx $src, $dst"), determine what the class of the
1769/// operand reference is by looking it up in the result pattern definition.
1770void AsmMatcherInfo::buildAliasOperandReference(MatchableInfo *II,
1771 StringRef OperandName,
1772 MatchableInfo::AsmOperand &Op) {
1773 const CodeGenInstAlias &CGA = *cast<const CodeGenInstAlias *>(Val&: II->DefRec);
1774
1775 // Set up the operand class.
1776 for (const auto &[ResultOp, SubOpIdx] :
1777 zip_equal(t: CGA.ResultOperands, u: CGA.ResultInstOperandIndex)) {
1778 if (ResultOp.isRecord() && ResultOp.getName() == OperandName) {
1779 // It's safe to go with the first one we find, because CodeGenInstAlias
1780 // validates that all operands with the same name have the same record.
1781 Op.SubOpIdx = SubOpIdx.second;
1782 // Use the match class from the Alias definition, not the
1783 // destination instruction, as we may have an immediate that's
1784 // being munged by the match class.
1785 Op.Class = getOperandClass(Rec: ResultOp.getRecord(), SubOpIdx: Op.SubOpIdx);
1786 Op.SrcOpName = OperandName;
1787 Op.OrigSrcOpName = OperandName;
1788 return;
1789 }
1790 }
1791
1792 PrintFatalError(ErrorLoc: II->TheDef->getLoc(),
1793 Msg: "error: unable to find operand: '" + OperandName + "'");
1794}
1795
1796void MatchableInfo::buildInstructionResultOperands() {
1797 const CodeGenInstruction *ResultInst = getResultInst();
1798
1799 // Loop over all operands of the result instruction, determining how to
1800 // populate them.
1801 for (const CGIOperandList::OperandInfo &OpInfo : ResultInst->Operands) {
1802 // If this is a tied operand, just copy from the previously handled operand.
1803 int TiedOp = -1;
1804 if (OpInfo.MINumOperands == 1)
1805 TiedOp = OpInfo.getTiedRegister();
1806 if (TiedOp != -1) {
1807 int TiedSrcOperand = findAsmOperandOriginallyNamed(N: OpInfo.Name);
1808 if (TiedSrcOperand != -1 &&
1809 ResOperands[TiedOp].Kind == ResOperand::RenderAsmOperand)
1810 ResOperands.push_back(Elt: ResOperand::getTiedOp(
1811 TiedOperandNum: TiedOp, SrcOperand1: ResOperands[TiedOp].AsmOperandNum, SrcOperand2: TiedSrcOperand));
1812 else
1813 ResOperands.push_back(Elt: ResOperand::getTiedOp(TiedOperandNum: TiedOp, SrcOperand1: 0, SrcOperand2: 0));
1814 continue;
1815 }
1816
1817 int SrcOperand = findAsmOperandNamed(N: OpInfo.Name);
1818 if (OpInfo.Name.empty() || SrcOperand == -1) {
1819 // This may happen for operands that are tied to a suboperand of a
1820 // complex operand. Simply use a dummy value here; nobody should
1821 // use this operand slot.
1822 // FIXME: The long term goal is for the MCOperand list to not contain
1823 // tied operands at all.
1824 ResOperands.push_back(Elt: ResOperand::getImmOp(Val: 0));
1825 continue;
1826 }
1827
1828 // Check if the one AsmOperand populates the entire operand.
1829 unsigned NumOperands = OpInfo.MINumOperands;
1830 if (AsmOperands[SrcOperand].SubOpIdx == -1) {
1831 ResOperands.push_back(Elt: ResOperand::getRenderedOp(AsmOpNum: SrcOperand, NumOperands));
1832 continue;
1833 }
1834
1835 // Add a separate ResOperand for each suboperand.
1836 for (unsigned AI = 0; AI < NumOperands; ++AI) {
1837 assert(AsmOperands[SrcOperand + AI].SubOpIdx == (int)AI &&
1838 AsmOperands[SrcOperand + AI].SrcOpName == OpInfo.Name &&
1839 "unexpected AsmOperands for suboperands");
1840 ResOperands.push_back(Elt: ResOperand::getRenderedOp(AsmOpNum: SrcOperand + AI, NumOperands: 1));
1841 }
1842 }
1843}
1844
1845void MatchableInfo::buildAliasResultOperands(bool AliasConstraintsAreChecked) {
1846 const CodeGenInstAlias &CGA = *cast<const CodeGenInstAlias *>(Val&: DefRec);
1847 const CodeGenInstruction *ResultInst = getResultInst();
1848
1849 // Map of: $reg -> #lastref
1850 // where $reg is the name of the operand in the asm string
1851 // where #lastref is the last processed index where $reg was referenced in
1852 // the asm string.
1853 SmallDenseMap<StringRef, int> OperandRefs;
1854
1855 // Loop over all operands of the result instruction, determining how to
1856 // populate them.
1857 unsigned AliasOpNo = 0;
1858 unsigned LastOpNo = CGA.ResultInstOperandIndex.size();
1859 for (const auto &[Idx, OpInfo] : enumerate(First: ResultInst->Operands)) {
1860 // If this is a tied operand, just copy from the previously handled operand.
1861 int TiedOp = -1;
1862 if (OpInfo.MINumOperands == 1)
1863 TiedOp = OpInfo.getTiedRegister();
1864 if (TiedOp != -1) {
1865 unsigned SrcOp1 = 0;
1866 unsigned SrcOp2 = 0;
1867
1868 // If an operand has been specified twice in the asm string,
1869 // add the two source operand's indices to the TiedOp so that
1870 // at runtime the 'tied' constraint is checked.
1871 if (ResOperands[TiedOp].Kind == ResOperand::RenderAsmOperand) {
1872 SrcOp1 = ResOperands[TiedOp].AsmOperandNum;
1873
1874 // Find the next operand (similarly named operand) in the string.
1875 StringRef Name = AsmOperands[SrcOp1].SrcOpName;
1876 auto Insert = OperandRefs.try_emplace(Key: Name, Args&: SrcOp1);
1877 SrcOp2 = findAsmOperandNamed(N: Name, LastIdx: Insert.first->second);
1878
1879 // Not updating the record in OperandRefs will cause TableGen
1880 // to fail with an error at the end of this function.
1881 if (AliasConstraintsAreChecked)
1882 Insert.first->second = SrcOp2;
1883
1884 // In case it only has one reference in the asm string,
1885 // it doesn't need to be checked for tied constraints.
1886 SrcOp2 = (SrcOp2 == (unsigned)-1) ? SrcOp1 : SrcOp2;
1887 }
1888
1889 // If the alias operand is of a different operand class, we only want
1890 // to benefit from the tied-operands check and just match the operand
1891 // as a normal, but not copy the original (TiedOp) to the result
1892 // instruction. We do this by passing -1 as the tied operand to copy.
1893 if (OpInfo.Rec->getName() !=
1894 ResultInst->Operands[TiedOp].Rec->getName()) {
1895 SrcOp1 = ResOperands[TiedOp].AsmOperandNum;
1896 int SubIdx = CGA.ResultInstOperandIndex[AliasOpNo].second;
1897 StringRef Name = CGA.ResultOperands[AliasOpNo].getName();
1898 SrcOp2 = findAsmOperand(N: Name, SubOpIdx: SubIdx);
1899 ResOperands.push_back(
1900 Elt: ResOperand::getTiedOp(TiedOperandNum: (unsigned)-1, SrcOperand1: SrcOp1, SrcOperand2: SrcOp2));
1901 } else {
1902 ResOperands.push_back(Elt: ResOperand::getTiedOp(TiedOperandNum: TiedOp, SrcOperand1: SrcOp1, SrcOperand2: SrcOp2));
1903 continue;
1904 }
1905 }
1906
1907 // Handle all the suboperands for this operand.
1908 StringRef OpName = OpInfo.Name;
1909 for (; AliasOpNo < LastOpNo &&
1910 CGA.ResultInstOperandIndex[AliasOpNo].first == Idx;
1911 ++AliasOpNo) {
1912 int SubIdx = CGA.ResultInstOperandIndex[AliasOpNo].second;
1913
1914 // Find out what operand from the asmparser that this MCInst operand
1915 // comes from.
1916 switch (CGA.ResultOperands[AliasOpNo].Kind) {
1917 case CodeGenInstAlias::ResultOperand::K_Record: {
1918 StringRef Name = CGA.ResultOperands[AliasOpNo].getName();
1919 int SrcOperand = findAsmOperand(N: Name, SubOpIdx: SubIdx);
1920 if (SrcOperand == -1)
1921 PrintFatalError(ErrorLoc: TheDef->getLoc(),
1922 Msg: "Instruction '" + TheDef->getName() +
1923 "' has operand '" + OpName +
1924 "' that doesn't appear in asm string!");
1925
1926 // Add it to the operand references. If it is added a second time, the
1927 // record won't be updated and it will fail later on.
1928 OperandRefs.try_emplace(Key: Name, Args&: SrcOperand);
1929
1930 unsigned NumOperands = (SubIdx == -1 ? OpInfo.MINumOperands : 1);
1931 ResOperands.push_back(
1932 Elt: ResOperand::getRenderedOp(AsmOpNum: SrcOperand, NumOperands));
1933 break;
1934 }
1935 case CodeGenInstAlias::ResultOperand::K_Imm: {
1936 int64_t ImmVal = CGA.ResultOperands[AliasOpNo].getImm();
1937 ResOperands.push_back(Elt: ResOperand::getImmOp(Val: ImmVal));
1938 break;
1939 }
1940 case CodeGenInstAlias::ResultOperand::K_Reg: {
1941 const Record *Reg = CGA.ResultOperands[AliasOpNo].getRegister();
1942 ResOperands.push_back(Elt: ResOperand::getRegOp(Reg));
1943 break;
1944 }
1945 }
1946 }
1947 }
1948
1949 // Check that operands are not repeated more times than is supported.
1950 for (auto &T : OperandRefs) {
1951 if (T.second != -1 && findAsmOperandNamed(N: T.first, LastIdx: T.second) != -1)
1952 PrintFatalError(ErrorLoc: TheDef->getLoc(),
1953 Msg: "Operand '" + T.first + "' can never be matched");
1954 }
1955}
1956
1957static unsigned
1958getConverterOperandID(const std::string &Name,
1959 SmallSetVector<CachedHashString, 16> &Table,
1960 bool &IsNew) {
1961 IsNew = Table.insert(X: CachedHashString(Name));
1962
1963 unsigned ID = IsNew ? Table.size() - 1 : find(Range&: Table, Val: Name) - Table.begin();
1964
1965 assert(ID < Table.size());
1966
1967 return ID;
1968}
1969
1970static unsigned
1971emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
1972 std::vector<std::unique_ptr<MatchableInfo>> &Infos,
1973 bool HasMnemonicFirst, bool HasOptionalOperands,
1974 raw_ostream &OS) {
1975 SmallSetVector<CachedHashString, 16> OperandConversionKinds;
1976 SmallSetVector<CachedHashString, 16> InstructionConversionKinds;
1977 std::vector<std::vector<uint8_t>> ConversionTable;
1978 size_t MaxRowLength = 2; // minimum is custom converter plus terminator.
1979
1980 // TargetOperandClass - This is the target's operand class, like X86Operand.
1981 std::string TargetOperandClass = Target.getName().str() + "Operand";
1982
1983 // Write the convert function to a separate stream, so we can drop it after
1984 // the enum. We'll build up the conversion handlers for the individual
1985 // operand types opportunistically as we encounter them.
1986 std::string ConvertFnBody;
1987 raw_string_ostream CvtOS(ConvertFnBody);
1988 // Start the unified conversion function.
1989 if (HasOptionalOperands) {
1990 CvtOS << "void " << Target.getName() << ClassName << "::\n"
1991 << "convertToMCInst(unsigned Kind, MCInst &Inst, "
1992 << "unsigned Opcode,\n"
1993 << " const OperandVector &Operands,\n"
1994 << " const SmallBitVector &OptionalOperandsMask,\n"
1995 << " ArrayRef<unsigned> DefaultsOffset) {\n";
1996 } else {
1997 CvtOS << "void " << Target.getName() << ClassName << "::\n"
1998 << "convertToMCInst(unsigned Kind, MCInst &Inst, "
1999 << "unsigned Opcode,\n"
2000 << " const OperandVector &Operands) {\n";
2001 }
2002 CvtOS << " assert(Kind < CVT_NUM_SIGNATURES && \"Invalid signature!\");\n";
2003 CvtOS << " const uint8_t *Converter = ConversionTable[Kind];\n";
2004 CvtOS << " Inst.setOpcode(Opcode);\n";
2005 CvtOS << " for (const uint8_t *p = Converter; *p; p += 2) {\n";
2006 if (HasOptionalOperands) {
2007 // When optional operands are involved, formal and actual operand indices
2008 // may differ. Map the former to the latter by subtracting the number of
2009 // absent optional operands.
2010 // FIXME: This is not an operand index in the CVT_Tied case
2011 CvtOS << " unsigned OpIdx = *(p + 1) - DefaultsOffset[*(p + 1)];\n";
2012 } else {
2013 CvtOS << " unsigned OpIdx = *(p + 1);\n";
2014 }
2015 CvtOS << " switch (*p) {\n";
2016 CvtOS << " default: llvm_unreachable(\"invalid conversion entry!\");\n";
2017 CvtOS << " case CVT_Reg:\n";
2018 CvtOS << " static_cast<" << TargetOperandClass
2019 << " &>(*Operands[OpIdx]).addRegOperands(Inst, 1);\n";
2020 CvtOS << " break;\n";
2021 CvtOS << " case CVT_Tied: {\n";
2022 CvtOS << " assert(*(p + 1) < (size_t)(std::end(TiedAsmOperandTable) -\n";
2023 CvtOS
2024 << " std::begin(TiedAsmOperandTable)) &&\n";
2025 CvtOS << " \"Tied operand not found\");\n";
2026 CvtOS << " unsigned TiedResOpnd = TiedAsmOperandTable[*(p + 1)][0];\n";
2027 CvtOS << " if (TiedResOpnd != (uint8_t)-1)\n";
2028 CvtOS << " Inst.addOperand(Inst.getOperand(TiedResOpnd));\n";
2029 CvtOS << " break;\n";
2030 CvtOS << " }\n";
2031
2032 std::string OperandFnBody;
2033 raw_string_ostream OpOS(OperandFnBody);
2034 // Start the operand number lookup function.
2035 OpOS << "void " << Target.getName() << ClassName << "::\n"
2036 << "convertToMapAndConstraints(unsigned Kind,\n";
2037 OpOS.indent(NumSpaces: 27);
2038 OpOS << "const OperandVector &Operands) {\n"
2039 << " assert(Kind < CVT_NUM_SIGNATURES && \"Invalid signature!\");\n"
2040 << " unsigned NumMCOperands = 0;\n"
2041 << " const uint8_t *Converter = ConversionTable[Kind];\n"
2042 << " for (const uint8_t *p = Converter; *p; p += 2) {\n"
2043 << " switch (*p) {\n"
2044 << " default: llvm_unreachable(\"invalid conversion entry!\");\n"
2045 << " case CVT_Reg:\n"
2046 << " Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);\n"
2047 << " Operands[*(p + 1)]->setConstraint(\"r\");\n"
2048 << " ++NumMCOperands;\n"
2049 << " break;\n"
2050 << " case CVT_Tied:\n"
2051 << " ++NumMCOperands;\n"
2052 << " break;\n";
2053
2054 // Pre-populate the operand conversion kinds with the standard always
2055 // available entries.
2056 OperandConversionKinds.insert(X: CachedHashString("CVT_Done"));
2057 OperandConversionKinds.insert(X: CachedHashString("CVT_Reg"));
2058 OperandConversionKinds.insert(X: CachedHashString("CVT_Tied"));
2059 enum { CVT_Done, CVT_Reg, CVT_Tied };
2060
2061 // Map of e.g. <0, 2, 3> -> "Tie_0_2_3" enum label.
2062 std::map<std::tuple<uint8_t, uint8_t, uint8_t>, std::string>
2063 TiedOperandsEnumMap;
2064
2065 for (auto &II : Infos) {
2066 // Check if we have a custom match function.
2067 StringRef AsmMatchConverter =
2068 II->getResultInst()->TheDef->getValueAsString(FieldName: "AsmMatchConverter");
2069 if (!AsmMatchConverter.empty() && II->UseInstAsmMatchConverter) {
2070 std::string Signature = ("ConvertCustom_" + AsmMatchConverter).str();
2071 II->ConversionFnKind = Signature;
2072
2073 // Check if we have already generated this signature.
2074 if (!InstructionConversionKinds.insert(X: CachedHashString(Signature)))
2075 continue;
2076
2077 // Remember this converter for the kind enum.
2078 unsigned KindID = OperandConversionKinds.size();
2079 OperandConversionKinds.insert(
2080 X: CachedHashString("CVT_" + getEnumNameForToken(Str: AsmMatchConverter)));
2081
2082 // Add the converter row for this instruction.
2083 ConversionTable.emplace_back();
2084 ConversionTable.back().push_back(x: KindID);
2085 ConversionTable.back().push_back(x: CVT_Done);
2086
2087 // Add the handler to the conversion driver function.
2088 CvtOS << " case CVT_" << getEnumNameForToken(Str: AsmMatchConverter)
2089 << ":\n"
2090 << " " << AsmMatchConverter << "(Inst, Operands);\n"
2091 << " break;\n";
2092
2093 // FIXME: Handle the operand number lookup for custom match functions.
2094 continue;
2095 }
2096
2097 // Build the conversion function signature.
2098 std::string Signature = "Convert";
2099
2100 std::vector<uint8_t> ConversionRow;
2101
2102 // Compute the convert enum and the case body.
2103 MaxRowLength = std::max(a: MaxRowLength, b: II->ResOperands.size() * 2 + 1);
2104
2105 for (const auto &[Idx, OpInfo] : enumerate(First&: II->ResOperands)) {
2106 // Generate code to populate each result operand.
2107 switch (OpInfo.Kind) {
2108 case MatchableInfo::ResOperand::RenderAsmOperand: {
2109 // This comes from something we parsed.
2110 const MatchableInfo::AsmOperand &Op =
2111 II->AsmOperands[OpInfo.AsmOperandNum];
2112
2113 // Registers are always converted the same, don't duplicate the
2114 // conversion function based on them.
2115 Signature += "__";
2116 std::string Class;
2117 Class = Op.Class->isRegisterClass() ? "Reg" : Op.Class->ClassName;
2118 Signature += Class;
2119 Signature += utostr(X: OpInfo.MINumOperands);
2120 Signature += "_" + itostr(X: OpInfo.AsmOperandNum);
2121
2122 // Add the conversion kind, if necessary, and get the associated ID
2123 // the index of its entry in the vector).
2124 std::string Name =
2125 "CVT_" +
2126 (Op.Class->isRegisterClass() ? "Reg" : Op.Class->RenderMethod);
2127 if (Op.Class->IsOptional) {
2128 // For optional operands we must also care about DefaultMethod
2129 assert(HasOptionalOperands);
2130 Name += "_" + Op.Class->DefaultMethod;
2131 }
2132 Name = getEnumNameForToken(Str: Name);
2133
2134 bool IsNewConverter = false;
2135 unsigned ID =
2136 getConverterOperandID(Name, Table&: OperandConversionKinds, IsNew&: IsNewConverter);
2137
2138 // Add the operand entry to the instruction kind conversion row.
2139 ConversionRow.push_back(x: ID);
2140 ConversionRow.push_back(x: OpInfo.AsmOperandNum + HasMnemonicFirst);
2141
2142 if (!IsNewConverter)
2143 break;
2144
2145 // This is a new operand kind. Add a handler for it to the
2146 // converter driver.
2147 CvtOS << " case " << Name << ":\n";
2148 if (Op.Class->IsOptional) {
2149 // If optional operand is not present in actual instruction then we
2150 // should call its DefaultMethod before RenderMethod
2151 assert(HasOptionalOperands);
2152 CvtOS << " if (OptionalOperandsMask[*(p + 1) - 1]) {\n"
2153 << " " << Op.Class->DefaultMethod << "()"
2154 << "->" << Op.Class->RenderMethod << "(Inst, "
2155 << OpInfo.MINumOperands << ");\n"
2156 << " } else {\n"
2157 << " static_cast<" << TargetOperandClass
2158 << " &>(*Operands[OpIdx])." << Op.Class->RenderMethod
2159 << "(Inst, " << OpInfo.MINumOperands << ");\n"
2160 << " }\n";
2161 } else {
2162 CvtOS << " static_cast<" << TargetOperandClass
2163 << " &>(*Operands[OpIdx])." << Op.Class->RenderMethod
2164 << "(Inst, " << OpInfo.MINumOperands << ");\n";
2165 }
2166 CvtOS << " break;\n";
2167
2168 // Add a handler for the operand number lookup.
2169 OpOS << " case " << Name << ":\n"
2170 << " Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);\n";
2171
2172 if (Op.Class->isRegisterClass())
2173 OpOS << " Operands[*(p + 1)]->setConstraint(\"r\");\n";
2174 else
2175 OpOS << " Operands[*(p + 1)]->setConstraint(\"m\");\n";
2176 OpOS << " NumMCOperands += " << OpInfo.MINumOperands << ";\n"
2177 << " break;\n";
2178 break;
2179 }
2180 case MatchableInfo::ResOperand::TiedOperand: {
2181 // If this operand is tied to a previous one, just copy the MCInst
2182 // operand from the earlier one.We can only tie single MCOperand values.
2183 assert(OpInfo.MINumOperands == 1 && "Not a singular MCOperand");
2184 uint8_t TiedOp = OpInfo.TiedOperands.ResOpnd;
2185 uint8_t SrcOp1 = OpInfo.TiedOperands.SrcOpnd1Idx + HasMnemonicFirst;
2186 uint8_t SrcOp2 = OpInfo.TiedOperands.SrcOpnd2Idx + HasMnemonicFirst;
2187 assert((Idx > TiedOp || TiedOp == (uint8_t)-1) &&
2188 "Tied operand precedes its target!");
2189 auto TiedTupleName = std::string("Tie") + utostr(X: TiedOp) + '_' +
2190 utostr(X: SrcOp1) + '_' + utostr(X: SrcOp2);
2191 Signature += "__" + TiedTupleName;
2192 ConversionRow.push_back(x: CVT_Tied);
2193 ConversionRow.push_back(x: TiedOp);
2194 ConversionRow.push_back(x: SrcOp1);
2195 ConversionRow.push_back(x: SrcOp2);
2196
2197 // Also create an 'enum' for this combination of tied operands.
2198 auto Key = std::tuple(TiedOp, SrcOp1, SrcOp2);
2199 TiedOperandsEnumMap.emplace(args&: Key, args&: TiedTupleName);
2200 break;
2201 }
2202 case MatchableInfo::ResOperand::ImmOperand: {
2203 int64_t Val = OpInfo.ImmVal;
2204 std::string Ty = "imm_" + itostr(X: Val);
2205 Ty = getEnumNameForToken(Str: Ty);
2206 Signature += "__" + Ty;
2207
2208 std::string Name = "CVT_" + Ty;
2209 bool IsNewConverter = false;
2210 unsigned ID =
2211 getConverterOperandID(Name, Table&: OperandConversionKinds, IsNew&: IsNewConverter);
2212 // Add the operand entry to the instruction kind conversion row.
2213 ConversionRow.push_back(x: ID);
2214 ConversionRow.push_back(x: 0);
2215
2216 if (!IsNewConverter)
2217 break;
2218
2219 CvtOS << " case " << Name << ":\n"
2220 << " Inst.addOperand(MCOperand::createImm(" << Val << "));\n"
2221 << " break;\n";
2222
2223 OpOS << " case " << Name << ":\n"
2224 << " Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);\n"
2225 << " Operands[*(p + 1)]->setConstraint(\"\");\n"
2226 << " ++NumMCOperands;\n"
2227 << " break;\n";
2228 break;
2229 }
2230 case MatchableInfo::ResOperand::RegOperand: {
2231 std::string Reg, Name;
2232 if (!OpInfo.Register) {
2233 Name = "reg0";
2234 Reg = "0";
2235 } else {
2236 Reg = getQualifiedName(R: OpInfo.Register);
2237 Name = "reg" + OpInfo.Register->getName().str();
2238 }
2239 Signature += "__" + Name;
2240 Name = "CVT_" + Name;
2241 bool IsNewConverter = false;
2242 unsigned ID =
2243 getConverterOperandID(Name, Table&: OperandConversionKinds, IsNew&: IsNewConverter);
2244 // Add the operand entry to the instruction kind conversion row.
2245 ConversionRow.push_back(x: ID);
2246 ConversionRow.push_back(x: 0);
2247
2248 if (!IsNewConverter)
2249 break;
2250 CvtOS << " case " << Name << ":\n"
2251 << " Inst.addOperand(MCOperand::createReg(" << Reg << "));\n"
2252 << " break;\n";
2253
2254 OpOS << " case " << Name << ":\n"
2255 << " Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);\n"
2256 << " Operands[*(p + 1)]->setConstraint(\"m\");\n"
2257 << " ++NumMCOperands;\n"
2258 << " break;\n";
2259 }
2260 }
2261 }
2262
2263 // If there were no operands, add to the signature to that effect
2264 if (Signature == "Convert")
2265 Signature += "_NoOperands";
2266
2267 II->ConversionFnKind = Signature;
2268
2269 // Save the signature. If we already have it, don't add a new row
2270 // to the table.
2271 if (!InstructionConversionKinds.insert(X: CachedHashString(Signature)))
2272 continue;
2273
2274 // Add the row to the table.
2275 ConversionTable.push_back(x: std::move(ConversionRow));
2276 }
2277
2278 // Finish up the converter driver function.
2279 CvtOS << " }\n }\n}\n\n";
2280
2281 // Finish up the operand number lookup function.
2282 OpOS << " }\n }\n}\n\n";
2283
2284 // Output a static table for tied operands.
2285 if (TiedOperandsEnumMap.size()) {
2286 // The number of tied operand combinations will be small in practice,
2287 // but just add the assert to be sure.
2288 assert(TiedOperandsEnumMap.size() <= 254 &&
2289 "Too many tied-operand combinations to reference with "
2290 "an 8bit offset from the conversion table, where index "
2291 "'255' is reserved as operand not to be copied.");
2292
2293 OS << "enum {\n";
2294 for (auto &KV : TiedOperandsEnumMap) {
2295 OS << " " << KV.second << ",\n";
2296 }
2297 OS << "};\n\n";
2298
2299 OS << "static const uint8_t TiedAsmOperandTable[][3] = {\n";
2300 for (auto &KV : TiedOperandsEnumMap) {
2301 OS << " /* " << KV.second << " */ { " << utostr(X: std::get<0>(t: KV.first))
2302 << ", " << utostr(X: std::get<1>(t: KV.first)) << ", "
2303 << utostr(X: std::get<2>(t: KV.first)) << " },\n";
2304 }
2305 OS << "};\n\n";
2306 } else {
2307 OS << "static const uint8_t TiedAsmOperandTable[][3] = "
2308 "{ /* empty */ {0, 0, 0} };\n\n";
2309 }
2310
2311 OS << "namespace {\n";
2312
2313 // Output the operand conversion kind enum.
2314 OS << "enum OperatorConversionKind {\n";
2315 for (const auto &Converter : OperandConversionKinds)
2316 OS << " " << Converter << ",\n";
2317 OS << " CVT_NUM_CONVERTERS\n";
2318 OS << "};\n\n";
2319
2320 // Output the instruction conversion kind enum.
2321 OS << "enum InstructionConversionKind {\n";
2322 for (const auto &Signature : InstructionConversionKinds)
2323 OS << " " << Signature << ",\n";
2324 OS << " CVT_NUM_SIGNATURES\n";
2325 OS << "};\n\n";
2326
2327 OS << "} // end anonymous namespace\n\n";
2328
2329 // Output the conversion table.
2330 OS << "static const uint8_t ConversionTable[CVT_NUM_SIGNATURES]["
2331 << MaxRowLength << "] = {\n";
2332
2333 for (unsigned Row = 0, ERow = ConversionTable.size(); Row != ERow; ++Row) {
2334 assert(ConversionTable[Row].size() % 2 == 0 && "bad conversion row!");
2335 OS << " // " << InstructionConversionKinds[Row] << "\n";
2336 OS << " { ";
2337 for (unsigned i = 0, e = ConversionTable[Row].size(); i != e; i += 2) {
2338 const auto &OCK = OperandConversionKinds[ConversionTable[Row][i]];
2339 OS << OCK << ", ";
2340 if (OCK != CachedHashString("CVT_Tied")) {
2341 OS << (unsigned)(ConversionTable[Row][i + 1]) << ", ";
2342 continue;
2343 }
2344
2345 // For a tied operand, emit a reference to the TiedAsmOperandTable
2346 // that contains the operand to copy, and the parsed operands to
2347 // check for their tied constraints.
2348 auto Key = std::tuple((uint8_t)ConversionTable[Row][i + 1],
2349 (uint8_t)ConversionTable[Row][i + 2],
2350 (uint8_t)ConversionTable[Row][i + 3]);
2351 auto TiedOpndEnum = TiedOperandsEnumMap.find(x: Key);
2352 assert(TiedOpndEnum != TiedOperandsEnumMap.end() &&
2353 "No record for tied operand pair");
2354 OS << TiedOpndEnum->second << ", ";
2355 i += 2;
2356 }
2357 OS << "CVT_Done },\n";
2358 }
2359
2360 OS << "};\n\n";
2361
2362 // Spit out the conversion driver function.
2363 OS << ConvertFnBody;
2364
2365 // Spit out the operand number lookup function.
2366 OS << OperandFnBody;
2367
2368 return ConversionTable.size();
2369}
2370
2371/// emitMatchClassEnumeration - Emit the enumeration for match class kinds.
2372static void emitMatchClassEnumeration(CodeGenTarget &Target,
2373 std::forward_list<ClassInfo> &Infos,
2374 raw_ostream &OS) {
2375 OS << "namespace {\n\n";
2376
2377 OS << "/// MatchClassKind - The kinds of classes which participate in\n"
2378 << "/// instruction matching.\n";
2379 OS << "enum MatchClassKind {\n";
2380 OS << " InvalidMatchClass = 0,\n";
2381 OS << " OptionalMatchClass = 1,\n";
2382 ClassInfo::ClassInfoKind LastKind = ClassInfo::Token;
2383 StringRef LastName = "OptionalMatchClass";
2384 for (const auto &CI : Infos) {
2385 if (LastKind == ClassInfo::Token && CI.Kind != ClassInfo::Token) {
2386 OS << " MCK_LAST_TOKEN = " << LastName << ",\n";
2387 } else if (LastKind < ClassInfo::UserClass0 &&
2388 CI.Kind >= ClassInfo::UserClass0) {
2389 OS << " MCK_LAST_REGISTER = " << LastName << ",\n";
2390 }
2391 LastKind = (ClassInfo::ClassInfoKind)CI.Kind;
2392 LastName = CI.Name;
2393
2394 OS << " " << CI.Name << ", // ";
2395 if (CI.Kind == ClassInfo::Token) {
2396 OS << "'" << CI.ValueName << "'\n";
2397 } else if (CI.isRegisterClass()) {
2398 if (!CI.ValueName.empty())
2399 OS << "register class '" << CI.ValueName << "'\n";
2400 else
2401 OS << "derived register class\n";
2402 } else {
2403 OS << "user defined class '" << CI.ValueName << "'\n";
2404 }
2405 }
2406 OS << " NumMatchClassKinds\n";
2407 OS << "};\n\n";
2408
2409 OS << "} // end anonymous namespace\n\n";
2410}
2411
2412/// emitMatchClassDiagStrings - Emit a function to get the diagnostic text to be
2413/// used when an assembly operand does not match the expected operand class.
2414static void emitOperandMatchErrorDiagStrings(AsmMatcherInfo &Info,
2415 raw_ostream &OS) {
2416 // If the target does not use DiagnosticString for any operands, don't emit
2417 // an unused function.
2418 if (llvm::all_of(Range&: Info.Classes, P: [](const ClassInfo &CI) {
2419 return CI.DiagnosticString.empty();
2420 }))
2421 return;
2422
2423 OS << "static const char *getMatchKindDiag(" << Info.Target.getName()
2424 << "AsmParser::" << Info.Target.getName()
2425 << "MatchResultTy MatchResult) {\n";
2426 OS << " switch (MatchResult) {\n";
2427
2428 for (const auto &CI : Info.Classes) {
2429 if (!CI.DiagnosticString.empty()) {
2430 assert(!CI.DiagnosticType.empty() &&
2431 "DiagnosticString set without DiagnosticType");
2432 OS << " case " << Info.Target.getName() << "AsmParser::Match_"
2433 << CI.DiagnosticType << ":\n";
2434 OS << " return \"" << CI.DiagnosticString << "\";\n";
2435 }
2436 }
2437
2438 OS << " default:\n";
2439 OS << " return nullptr;\n";
2440
2441 OS << " }\n";
2442 OS << "}\n\n";
2443}
2444
2445static void emitRegisterMatchErrorFunc(AsmMatcherInfo &Info, raw_ostream &OS) {
2446 OS << "static unsigned getDiagKindFromRegisterClass(MatchClassKind "
2447 "RegisterClass) {\n";
2448 if (none_of(Range&: Info.Classes, P: [](const ClassInfo &CI) {
2449 return CI.isRegisterClass() && !CI.DiagnosticType.empty();
2450 })) {
2451 OS << " return MCTargetAsmParser::Match_InvalidOperand;\n";
2452 } else {
2453 OS << " switch (RegisterClass) {\n";
2454 for (const auto &CI : Info.Classes) {
2455 if (CI.isRegisterClass() && !CI.DiagnosticType.empty()) {
2456 OS << " case " << CI.Name << ":\n";
2457 OS << " return " << Info.Target.getName() << "AsmParser::Match_"
2458 << CI.DiagnosticType << ";\n";
2459 }
2460 }
2461
2462 OS << " default:\n";
2463 OS << " return MCTargetAsmParser::Match_InvalidOperand;\n";
2464
2465 OS << " }\n";
2466 }
2467 OS << "}\n\n";
2468}
2469
2470/// emitValidateOperandClass - Emit the function to validate an operand class.
2471static void emitValidateOperandClass(const CodeGenTarget &Target,
2472 AsmMatcherInfo &Info, raw_ostream &OS) {
2473 OS << "static unsigned validateOperandClass(MCParsedAsmOperand &GOp, "
2474 << "MatchClassKind Kind) {\n";
2475 OS << " " << Info.Target.getName() << "Operand &Operand = ("
2476 << Info.Target.getName() << "Operand &)GOp;\n";
2477
2478 // The InvalidMatchClass is not to match any operand.
2479 OS << " if (Kind == InvalidMatchClass)\n";
2480 OS << " return MCTargetAsmParser::Match_InvalidOperand;\n\n";
2481
2482 // Check for Token operands first.
2483 // FIXME: Use a more specific diagnostic type.
2484 OS << " if (Operand.isToken() && Kind <= MCK_LAST_TOKEN)\n";
2485 OS << " return isSubclass(matchTokenString(Operand.getToken()), Kind) ?\n"
2486 << " MCTargetAsmParser::Match_Success :\n"
2487 << " MCTargetAsmParser::Match_InvalidOperand;\n\n";
2488
2489 // Check the user classes. We don't care what order since we're only
2490 // actually matching against one of them.
2491 OS << " switch (Kind) {\n"
2492 " default: break;\n";
2493 for (const auto &CI : Info.Classes) {
2494 if (!CI.isUserClass())
2495 continue;
2496
2497 OS << " case " << CI.Name << ": {\n";
2498 OS << " DiagnosticPredicate DP(Operand." << CI.PredicateMethod
2499 << "());\n";
2500 OS << " if (DP.isMatch())\n";
2501 OS << " return MCTargetAsmParser::Match_Success;\n";
2502 if (!CI.DiagnosticType.empty()) {
2503 OS << " if (DP.isNearMatch())\n";
2504 OS << " return " << Info.Target.getName() << "AsmParser::Match_"
2505 << CI.DiagnosticType << ";\n";
2506 OS << " break;\n";
2507 } else {
2508 OS << " break;\n";
2509 }
2510 OS << " }\n";
2511 }
2512 OS << " } // end switch (Kind)\n\n";
2513
2514 // Check for register operands, including sub-classes.
2515 const auto &Regs = Target.getRegBank().getRegisters();
2516 StringRef Namespace = Regs.front().TheDef->getValueAsString(FieldName: "Namespace");
2517 SmallVector<StringRef> Table(1 + Regs.size(), "InvalidMatchClass");
2518 for (const auto &RC : Info.RegisterClasses) {
2519 const auto &Reg = Target.getRegBank().getReg(RC.first);
2520 Table[Reg->EnumValue] = RC.second->Name;
2521 }
2522 OS << " if (Operand.isReg()) {\n";
2523 OS << " static constexpr uint16_t Table[" << Namespace
2524 << "::NUM_TARGET_REGS] = {\n";
2525 for (auto &MatchClassName : Table)
2526 OS << " " << MatchClassName << ",\n";
2527 OS << " };\n\n";
2528 OS << " MCRegister Reg = Operand.getReg();\n";
2529 OS << " MatchClassKind OpKind = Reg.isPhysical() ? "
2530 "(MatchClassKind)Table[Reg.id()] : InvalidMatchClass;\n";
2531 OS << " return isSubclass(OpKind, Kind) ? "
2532 << "(unsigned)MCTargetAsmParser::Match_Success :\n "
2533 << " getDiagKindFromRegisterClass(Kind);\n }\n\n";
2534
2535 // Expected operand is a register, but actual is not.
2536 OS << " if (Kind > MCK_LAST_TOKEN && Kind <= MCK_LAST_REGISTER)\n";
2537 OS << " return getDiagKindFromRegisterClass(Kind);\n\n";
2538
2539 // Generic fallthrough match failure case for operands that don't have
2540 // specialized diagnostic types.
2541 OS << " return MCTargetAsmParser::Match_InvalidOperand;\n";
2542 OS << "}\n\n";
2543}
2544
2545/// emitIsSubclass - Emit the subclass predicate function.
2546static void emitIsSubclass(CodeGenTarget &Target,
2547 std::forward_list<ClassInfo> &Infos,
2548 raw_ostream &OS) {
2549 OS << "/// isSubclass - Compute whether \\p A is a subclass of \\p B.\n";
2550 OS << "static bool isSubclass(MatchClassKind A, MatchClassKind B) {\n";
2551 OS << " if (A == B)\n";
2552 OS << " return true;\n\n";
2553
2554 // TODO: Use something like SequenceToOffsetTable to allow sequences to
2555 // overlap in this table.
2556 SmallVector<bool> SuperClassData;
2557
2558 OS << " [[maybe_unused]] static constexpr struct {\n";
2559 OS << " uint32_t Offset;\n";
2560 OS << " uint16_t Start;\n";
2561 OS << " uint16_t Length;\n";
2562 OS << " } Table[] = {\n";
2563 OS << " {0, 0, 0},\n"; // InvalidMatchClass
2564 OS << " {0, 0, 0},\n"; // OptionalMatchClass
2565 for (const auto &A : Infos) {
2566 SmallVector<bool> SuperClasses;
2567 SuperClasses.push_back(Elt: false); // InvalidMatchClass
2568 SuperClasses.push_back(Elt: A.IsOptional); // OptionalMatchClass
2569 for (const auto &B : Infos)
2570 SuperClasses.push_back(Elt: &A != &B && A.isSubsetOf(RHS: B));
2571
2572 // Trim leading and trailing zeros.
2573 auto End = find_if(Range: reverse(C&: SuperClasses), P: [](bool B) { return B; }).base();
2574 auto Start =
2575 std::find_if(first: SuperClasses.begin(), last: End, pred: [](bool B) { return B; });
2576
2577 unsigned Offset = SuperClassData.size();
2578 SuperClassData.append(in_start: Start, in_end: End);
2579
2580 OS << " {" << Offset << ", " << (Start - SuperClasses.begin()) << ", "
2581 << (End - Start) << "},\n";
2582 }
2583 OS << " };\n\n";
2584
2585 if (SuperClassData.empty()) {
2586 OS << " return false;\n";
2587 } else {
2588 // Dump the boolean data packed into bytes.
2589 SuperClassData.append(NumInputs: -SuperClassData.size() % 8, Elt: false);
2590 OS << " static constexpr uint8_t Data[] = {\n";
2591 for (unsigned I = 0, E = SuperClassData.size(); I < E; I += 8) {
2592 unsigned Byte = 0;
2593 for (unsigned J = 0; J < 8; ++J)
2594 Byte |= (unsigned)SuperClassData[I + J] << J;
2595 OS << formatv(Fmt: " {:X2},\n", Vals&: Byte);
2596 }
2597 OS << " };\n\n";
2598
2599 OS << " auto &Entry = Table[A];\n";
2600 OS << " unsigned Idx = B - Entry.Start;\n";
2601 OS << " if (Idx >= Entry.Length)\n";
2602 OS << " return false;\n";
2603 OS << " Idx += Entry.Offset;\n";
2604 OS << " return (Data[Idx / 8] >> (Idx % 8)) & 1;\n";
2605 }
2606 OS << "}\n\n";
2607}
2608
2609/// emitMatchTokenString - Emit the function to match a token string to the
2610/// appropriate match class value.
2611static void emitMatchTokenString(CodeGenTarget &Target,
2612 std::forward_list<ClassInfo> &Infos,
2613 raw_ostream &OS) {
2614 // Construct the match list.
2615 std::vector<StringMatcher::StringPair> Matches;
2616 for (const auto &CI : Infos) {
2617 if (CI.Kind == ClassInfo::Token)
2618 Matches.emplace_back(args: CI.ValueName, args: "return " + CI.Name + ";");
2619 }
2620
2621 OS << "static MatchClassKind matchTokenString(StringRef Name) {\n";
2622
2623 StringMatcher("Name", Matches, OS).Emit();
2624
2625 OS << " return InvalidMatchClass;\n";
2626 OS << "}\n\n";
2627}
2628
2629/// emitMatchRegisterName - Emit the function to match a string to the target
2630/// specific register enum.
2631static void emitMatchRegisterName(const CodeGenTarget &Target,
2632 const Record *AsmParser, raw_ostream &OS) {
2633 // Construct the match list.
2634 std::vector<StringMatcher::StringPair> Matches;
2635 const auto &Regs = Target.getRegBank().getRegisters();
2636 std::string Namespace =
2637 Regs.front().TheDef->getValueAsString(FieldName: "Namespace").str();
2638 for (const CodeGenRegister &Reg : Regs) {
2639 StringRef AsmName = Reg.TheDef->getValueAsString(FieldName: "AsmName");
2640 if (AsmName.empty())
2641 continue;
2642
2643 Matches.emplace_back(args: AsmName.str(), args: "return " + Namespace +
2644 "::" + Reg.getName().str() + ';');
2645 }
2646
2647 OS << "static MCRegister MatchRegisterName(StringRef Name) {\n";
2648
2649 bool IgnoreDuplicates =
2650 AsmParser->getValueAsBit(FieldName: "AllowDuplicateRegisterNames");
2651 StringMatcher("Name", Matches, OS).Emit(Indent: 0, IgnoreDuplicates);
2652
2653 OS << " return " << Namespace << "::NoRegister;\n";
2654 OS << "}\n\n";
2655}
2656
2657/// Emit the function to match a string to the target
2658/// specific register enum.
2659static void emitMatchRegisterAltName(const CodeGenTarget &Target,
2660 const Record *AsmParser, raw_ostream &OS) {
2661 // Construct the match list.
2662 std::vector<StringMatcher::StringPair> Matches;
2663 const auto &Regs = Target.getRegBank().getRegisters();
2664 std::string Namespace =
2665 Regs.front().TheDef->getValueAsString(FieldName: "Namespace").str();
2666 for (const CodeGenRegister &Reg : Regs) {
2667
2668 auto AltNames = Reg.TheDef->getValueAsListOfStrings(FieldName: "AltNames");
2669
2670 for (auto AltName : AltNames) {
2671 AltName = StringRef(AltName).trim();
2672
2673 // don't handle empty alternative names
2674 if (AltName.empty())
2675 continue;
2676
2677 Matches.emplace_back(args: AltName.str(), args: "return " + Namespace +
2678 "::" + Reg.getName().str() + ';');
2679 }
2680 }
2681
2682 OS << "static MCRegister MatchRegisterAltName(StringRef Name) {\n";
2683
2684 bool IgnoreDuplicates =
2685 AsmParser->getValueAsBit(FieldName: "AllowDuplicateRegisterNames");
2686 StringMatcher("Name", Matches, OS).Emit(Indent: 0, IgnoreDuplicates);
2687
2688 OS << " return " << Namespace << "::NoRegister;\n";
2689 OS << "}\n\n";
2690}
2691
2692/// emitOperandDiagnosticTypes - Emit the operand matching diagnostic types.
2693static void emitOperandDiagnosticTypes(AsmMatcherInfo &Info, raw_ostream &OS) {
2694 // Get the set of diagnostic types from all of the operand classes.
2695 std::set<StringRef> Types;
2696 for (const auto &OpClassEntry : Info.AsmOperandClasses) {
2697 if (!OpClassEntry.second->DiagnosticType.empty())
2698 Types.insert(x: OpClassEntry.second->DiagnosticType);
2699 }
2700 for (const auto &OpClassEntry : Info.RegisterClassClasses) {
2701 if (!OpClassEntry.second->DiagnosticType.empty())
2702 Types.insert(x: OpClassEntry.second->DiagnosticType);
2703 }
2704
2705 if (Types.empty())
2706 return;
2707
2708 // Now emit the enum entries.
2709 for (StringRef Type : Types)
2710 OS << " Match_" << Type << ",\n";
2711 OS << " END_OPERAND_DIAGNOSTIC_TYPES\n";
2712}
2713
2714/// emitGetSubtargetFeatureName - Emit the helper function to get the
2715/// user-level name for a subtarget feature.
2716static void emitGetSubtargetFeatureName(AsmMatcherInfo &Info, raw_ostream &OS) {
2717 OS << "// User-level names for subtarget features that participate in\n"
2718 << "// instruction matching.\n"
2719 << "static const char *getSubtargetFeatureName(uint64_t Val) {\n";
2720 if (!Info.SubtargetFeatures.empty()) {
2721 OS << " switch(Val) {\n";
2722 for (const auto &SF : Info.SubtargetFeatures) {
2723 const SubtargetFeatureInfo &SFI = SF.second;
2724 // FIXME: Totally just a placeholder name to get the algorithm working.
2725 OS << " case " << SFI.getEnumBitName() << ": return \""
2726 << SFI.TheDef->getValueAsString(FieldName: "PredicateName") << "\";\n";
2727 }
2728 OS << " default: return \"(unknown)\";\n";
2729 OS << " }\n";
2730 } else {
2731 // Nothing to emit, so skip the switch
2732 OS << " return \"(unknown)\";\n";
2733 }
2734 OS << "}\n\n";
2735}
2736
2737static std::string GetAliasRequiredFeatures(const Record *R,
2738 const AsmMatcherInfo &Info) {
2739 std::string Result;
2740
2741 bool First = true;
2742 for (const Record *RF : R->getValueAsListOfDefs(FieldName: "Predicates")) {
2743 const SubtargetFeatureInfo *F = Info.getSubtargetFeature(Def: RF);
2744 if (!F)
2745 PrintFatalError(ErrorLoc: R->getLoc(),
2746 Msg: "Predicate '" + RF->getName() +
2747 "' is not marked as an AssemblerPredicate!");
2748 if (!First)
2749 Result += " && ";
2750 Result += "Features.test(" + F->getEnumBitName() + ')';
2751 First = false;
2752 }
2753
2754 return Result;
2755}
2756
2757static void
2758emitMnemonicAliasVariant(raw_ostream &OS, const AsmMatcherInfo &Info,
2759 ArrayRef<const Record *> Aliases, unsigned Indent = 0,
2760 StringRef AsmParserVariantName = StringRef()) {
2761 // Keep track of all the aliases from a mnemonic. Use an std::map so that the
2762 // iteration order of the map is stable.
2763 std::map<std::string, std::vector<const Record *>> AliasesFromMnemonic;
2764
2765 for (const Record *R : Aliases) {
2766 // FIXME: Allow AssemblerVariantName to be a comma separated list.
2767 StringRef AsmVariantName = R->getValueAsString(FieldName: "AsmVariantName");
2768 if (AsmVariantName != AsmParserVariantName)
2769 continue;
2770 AliasesFromMnemonic[R->getValueAsString(FieldName: "FromMnemonic").lower()].push_back(
2771 x: R);
2772 }
2773 if (AliasesFromMnemonic.empty())
2774 return;
2775
2776 // Process each alias a "from" mnemonic at a time, building the code executed
2777 // by the string remapper.
2778 std::vector<StringMatcher::StringPair> Cases;
2779 for (const auto &AliasEntry : AliasesFromMnemonic) {
2780 // Loop through each alias and emit code that handles each case. If there
2781 // are two instructions without predicates, emit an error. If there is one,
2782 // emit it last.
2783 std::string MatchCode;
2784 int AliasWithNoPredicate = -1;
2785
2786 ArrayRef<const Record *> ToVec = AliasEntry.second;
2787 for (const auto &[Idx, R] : enumerate(First&: ToVec)) {
2788 std::string FeatureMask = GetAliasRequiredFeatures(R, Info);
2789
2790 // If this unconditionally matches, remember it for later and diagnose
2791 // duplicates.
2792 if (FeatureMask.empty()) {
2793 if (AliasWithNoPredicate != -1 &&
2794 R->getValueAsString(FieldName: "ToMnemonic") !=
2795 ToVec[AliasWithNoPredicate]->getValueAsString(FieldName: "ToMnemonic")) {
2796 // We can't have two different aliases from the same mnemonic with no
2797 // predicate.
2798 PrintError(
2799 ErrorLoc: ToVec[AliasWithNoPredicate]->getLoc(),
2800 Msg: "two different MnemonicAliases with the same 'from' mnemonic!");
2801 PrintFatalError(ErrorLoc: R->getLoc(), Msg: "this is the other MnemonicAlias.");
2802 }
2803
2804 AliasWithNoPredicate = Idx;
2805 continue;
2806 }
2807 if (R->getValueAsString(FieldName: "ToMnemonic") == AliasEntry.first)
2808 PrintFatalError(ErrorLoc: R->getLoc(), Msg: "MnemonicAlias to the same string");
2809
2810 if (!MatchCode.empty())
2811 MatchCode += "else ";
2812 MatchCode += "if (" + FeatureMask + ")\n";
2813 MatchCode += " Mnemonic = \"";
2814 MatchCode += R->getValueAsString(FieldName: "ToMnemonic").lower();
2815 MatchCode += "\";\n";
2816 }
2817
2818 if (AliasWithNoPredicate != -1) {
2819 const Record *R = ToVec[AliasWithNoPredicate];
2820 if (!MatchCode.empty())
2821 MatchCode += "else\n ";
2822 MatchCode += "Mnemonic = \"";
2823 MatchCode += R->getValueAsString(FieldName: "ToMnemonic").lower();
2824 MatchCode += "\";\n";
2825 }
2826
2827 MatchCode += "return;";
2828
2829 Cases.emplace_back(args: AliasEntry.first, args&: MatchCode);
2830 }
2831 StringMatcher("Mnemonic", Cases, OS).Emit(Indent);
2832}
2833
2834/// emitMnemonicAliases - If the target has any MnemonicAlias<> definitions,
2835/// emit a function for them and return true, otherwise return false.
2836static bool emitMnemonicAliases(raw_ostream &OS, const AsmMatcherInfo &Info,
2837 CodeGenTarget &Target) {
2838 // Ignore aliases when match-prefix is set.
2839 if (!MatchPrefix.empty())
2840 return false;
2841
2842 ArrayRef<const Record *> Aliases =
2843 Info.getRecords().getAllDerivedDefinitions(ClassName: "MnemonicAlias");
2844 if (Aliases.empty())
2845 return false;
2846
2847 OS << "static void applyMnemonicAliases(StringRef &Mnemonic, "
2848 "const FeatureBitset &Features, unsigned VariantID) {\n";
2849 unsigned VariantCount = Target.getAsmParserVariantCount();
2850 for (unsigned VC = 0; VC != VariantCount; ++VC) {
2851 const Record *AsmVariant = Target.getAsmParserVariant(i: VC);
2852 int AsmParserVariantNo = AsmVariant->getValueAsInt(FieldName: "Variant");
2853 StringRef AsmParserVariantName = AsmVariant->getValueAsString(FieldName: "Name");
2854
2855 // If the variant doesn't have a name, defer to the emitMnemonicAliasVariant
2856 // call after the loop.
2857 if (AsmParserVariantName.empty()) {
2858 assert(VariantCount == 1 && "Multiple variants should each be named");
2859 continue;
2860 }
2861
2862 if (VC == 0)
2863 OS << " switch (VariantID) {\n";
2864 OS << " case " << AsmParserVariantNo << ":\n";
2865 emitMnemonicAliasVariant(OS, Info, Aliases, /*Indent=*/2,
2866 AsmParserVariantName);
2867 OS << " break;\n";
2868
2869 if (VC == VariantCount - 1)
2870 OS << " }\n";
2871 }
2872
2873 // Emit aliases that apply to all variants.
2874 emitMnemonicAliasVariant(OS, Info, Aliases);
2875
2876 OS << "}\n\n";
2877
2878 return true;
2879}
2880
2881static void
2882emitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target,
2883 const AsmMatcherInfo &Info, StringRef ClassName,
2884 const StringToOffsetTable &StringTable,
2885 unsigned MaxMnemonicIndex, unsigned MaxFeaturesIndex,
2886 bool HasMnemonicFirst, const Record &AsmParser) {
2887 unsigned MaxMask = 0;
2888 for (const OperandMatchEntry &OMI : Info.OperandMatchInfo) {
2889 MaxMask |= OMI.OperandMask;
2890 }
2891
2892 // Emit the static custom operand parsing table;
2893 OS << "namespace {\n";
2894 OS << " struct OperandMatchEntry {\n";
2895 OS << " " << getMinimalTypeForRange(Range: MaxMnemonicIndex) << " Mnemonic;\n";
2896 OS << " " << getMinimalTypeForRange(Range: MaxMask) << " OperandMask;\n";
2897 OS << " "
2898 << getMinimalTypeForRange(
2899 Range: std::distance(first: Info.Classes.begin(), last: Info.Classes.end()) +
2900 2 /* Include 'InvalidMatchClass' and 'OptionalMatchClass' */)
2901 << " Class;\n";
2902 OS << " " << getMinimalTypeForRange(Range: MaxFeaturesIndex)
2903 << " RequiredFeaturesIdx;\n\n";
2904 OS << " StringRef getMnemonic() const {\n";
2905 OS << " return StringRef(MnemonicTable + Mnemonic + 1,\n";
2906 OS << " MnemonicTable[Mnemonic]);\n";
2907 OS << " }\n";
2908 OS << " };\n\n";
2909
2910 OS << " // Predicate for searching for an opcode.\n";
2911 OS << " struct LessOpcodeOperand {\n";
2912 OS << " bool operator()(const OperandMatchEntry &LHS, StringRef RHS) {\n";
2913 OS << " return LHS.getMnemonic() < RHS;\n";
2914 OS << " }\n";
2915 OS << " bool operator()(StringRef LHS, const OperandMatchEntry &RHS) {\n";
2916 OS << " return LHS < RHS.getMnemonic();\n";
2917 OS << " }\n";
2918 OS << " bool operator()(const OperandMatchEntry &LHS,";
2919 OS << " const OperandMatchEntry &RHS) {\n";
2920 OS << " return LHS.getMnemonic() < RHS.getMnemonic();\n";
2921 OS << " }\n";
2922 OS << " };\n";
2923
2924 OS << "} // end anonymous namespace\n\n";
2925
2926 OS << "static const OperandMatchEntry OperandMatchTable["
2927 << Info.OperandMatchInfo.size() << "] = {\n";
2928
2929 OS << " /* Operand List Mnemonic, Mask, Operand Class, Features */\n";
2930 for (const OperandMatchEntry &OMI : Info.OperandMatchInfo) {
2931 const MatchableInfo &II = *OMI.MI;
2932
2933 OS << " { ";
2934
2935 // Store a pascal-style length byte in the mnemonic.
2936 std::string LenMnemonic = char(II.Mnemonic.size()) + II.Mnemonic.lower();
2937 OS << *StringTable.GetStringOffset(Str: LenMnemonic) << " /* " << II.Mnemonic
2938 << " */, ";
2939
2940 OS << OMI.OperandMask;
2941 OS << " /* ";
2942 ListSeparator LS;
2943 for (int i = 0, e = 31; i != e; ++i)
2944 if (OMI.OperandMask & (1 << i))
2945 OS << LS << i;
2946 OS << " */, ";
2947
2948 OS << OMI.CI->Name;
2949
2950 // Write the required features mask.
2951 OS << ", AMFBS";
2952 if (II.RequiredFeatures.empty())
2953 OS << "_None";
2954 else
2955 for (const auto &F : II.RequiredFeatures)
2956 OS << '_' << F->TheDef->getName();
2957
2958 OS << " },\n";
2959 }
2960 OS << "};\n\n";
2961
2962 // Emit the operand class switch to call the correct custom parser for
2963 // the found operand class.
2964 OS << "ParseStatus " << Target.getName() << ClassName << "::\n"
2965 << "tryCustomParseOperand(OperandVector"
2966 << " &Operands,\n unsigned MCK) {\n\n"
2967 << " switch(MCK) {\n";
2968
2969 for (const auto &CI : Info.Classes) {
2970 if (CI.ParserMethod.empty())
2971 continue;
2972 OS << " case " << CI.Name << ":\n"
2973 << " return " << CI.ParserMethod << "(Operands);\n";
2974 }
2975
2976 OS << " default:\n";
2977 OS << " return ParseStatus::NoMatch;\n";
2978 OS << " }\n";
2979 OS << " return ParseStatus::NoMatch;\n";
2980 OS << "}\n\n";
2981
2982 // Emit the static custom operand parser. This code is very similar with
2983 // the other matcher. Also use MatchResultTy here just in case we go for
2984 // a better error handling.
2985 OS << "ParseStatus " << Target.getName() << ClassName << "::\n"
2986 << "MatchOperandParserImpl(OperandVector"
2987 << " &Operands,\n StringRef Mnemonic,\n"
2988 << " bool ParseForAllFeatures) {\n";
2989
2990 // Emit code to get the available features.
2991 OS << " // Get the current feature set.\n";
2992 OS << " const FeatureBitset &AvailableFeatures = "
2993 "getAvailableFeatures();\n\n";
2994
2995 OS << " // Get the next operand index.\n";
2996 OS << " unsigned NextOpNum = Operands.size()"
2997 << (HasMnemonicFirst ? " - 1" : "") << ";\n";
2998
2999 // Emit code to search the table.
3000 OS << " // Search the table.\n";
3001 if (HasMnemonicFirst) {
3002 OS << " auto MnemonicRange =\n";
3003 OS << " std::equal_range(std::begin(OperandMatchTable), "
3004 "std::end(OperandMatchTable),\n";
3005 OS << " Mnemonic, LessOpcodeOperand());\n\n";
3006 } else {
3007 OS << " auto MnemonicRange = std::pair(std::begin(OperandMatchTable),"
3008 " std::end(OperandMatchTable));\n";
3009 OS << " if (!Mnemonic.empty())\n";
3010 OS << " MnemonicRange =\n";
3011 OS << " std::equal_range(std::begin(OperandMatchTable), "
3012 "std::end(OperandMatchTable),\n";
3013 OS << " Mnemonic, LessOpcodeOperand());\n\n";
3014 }
3015
3016 OS << " if (MnemonicRange.first == MnemonicRange.second)\n";
3017 OS << " return ParseStatus::NoMatch;\n\n";
3018
3019 OS << " for (const OperandMatchEntry *it = MnemonicRange.first,\n"
3020 << " *ie = MnemonicRange.second; it != ie; ++it) {\n";
3021
3022 OS << " // equal_range guarantees that instruction mnemonic matches.\n";
3023 OS << " assert(Mnemonic == it->getMnemonic());\n\n";
3024
3025 // Emit check that the required features are available.
3026 OS << " // check if the available features match\n";
3027 OS << " const FeatureBitset &RequiredFeatures = "
3028 "FeatureBitsets[it->RequiredFeaturesIdx];\n";
3029 OS << " if (!ParseForAllFeatures && (AvailableFeatures & "
3030 "RequiredFeatures) != RequiredFeatures)\n";
3031 OS << " continue;\n\n";
3032
3033 // Emit check to ensure the operand number matches.
3034 OS << " // check if the operand in question has a custom parser.\n";
3035 OS << " if (!(it->OperandMask & (1 << NextOpNum)))\n";
3036 OS << " continue;\n\n";
3037
3038 // Emit call to the custom parser method
3039 StringRef ParserName = AsmParser.getValueAsString(FieldName: "OperandParserMethod");
3040 if (ParserName.empty())
3041 ParserName = "tryCustomParseOperand";
3042 OS << " // call custom parse method to handle the operand\n";
3043 OS << " ParseStatus Result = " << ParserName << "(Operands, it->Class);\n";
3044 OS << " if (!Result.isNoMatch())\n";
3045 OS << " return Result;\n";
3046 OS << " }\n\n";
3047
3048 OS << " // Okay, we had no match.\n";
3049 OS << " return ParseStatus::NoMatch;\n";
3050 OS << "}\n\n";
3051}
3052
3053static void emitAsmTiedOperandConstraints(CodeGenTarget &Target,
3054 AsmMatcherInfo &Info, raw_ostream &OS,
3055 bool HasOptionalOperands) {
3056 std::string AsmParserName =
3057 Info.AsmParser->getValueAsString(FieldName: "AsmParserClassName").str();
3058 OS << "static bool ";
3059 OS << "checkAsmTiedOperandConstraints(const " << Target.getName()
3060 << AsmParserName << "&AsmParser,\n";
3061 OS << " unsigned Kind, const OperandVector "
3062 "&Operands,\n";
3063 if (HasOptionalOperands)
3064 OS << " ArrayRef<unsigned> DefaultsOffset,\n";
3065 OS << " uint64_t &ErrorInfo) {\n";
3066 OS << " assert(Kind < CVT_NUM_SIGNATURES && \"Invalid signature!\");\n";
3067 OS << " const uint8_t *Converter = ConversionTable[Kind];\n";
3068 OS << " for (const uint8_t *p = Converter; *p; p += 2) {\n";
3069 OS << " switch (*p) {\n";
3070 OS << " case CVT_Tied: {\n";
3071 OS << " unsigned OpIdx = *(p + 1);\n";
3072 OS << " assert(OpIdx < (size_t)(std::end(TiedAsmOperandTable) -\n";
3073 OS << " std::begin(TiedAsmOperandTable)) &&\n";
3074 OS << " \"Tied operand not found\");\n";
3075 OS << " unsigned OpndNum1 = TiedAsmOperandTable[OpIdx][1];\n";
3076 OS << " unsigned OpndNum2 = TiedAsmOperandTable[OpIdx][2];\n";
3077 if (HasOptionalOperands) {
3078 // When optional operands are involved, formal and actual operand indices
3079 // may differ. Map the former to the latter by subtracting the number of
3080 // absent optional operands.
3081 OS << " OpndNum1 = OpndNum1 - DefaultsOffset[OpndNum1];\n";
3082 OS << " OpndNum2 = OpndNum2 - DefaultsOffset[OpndNum2];\n";
3083 }
3084 OS << " if (OpndNum1 != OpndNum2) {\n";
3085 OS << " auto &SrcOp1 = Operands[OpndNum1];\n";
3086 OS << " auto &SrcOp2 = Operands[OpndNum2];\n";
3087 OS << " if (!AsmParser.areEqualRegs(*SrcOp1, *SrcOp2)) {\n";
3088 OS << " ErrorInfo = OpndNum2;\n";
3089 OS << " return false;\n";
3090 OS << " }\n";
3091 OS << " }\n";
3092 OS << " break;\n";
3093 OS << " }\n";
3094 OS << " default:\n";
3095 OS << " break;\n";
3096 OS << " }\n";
3097 OS << " }\n";
3098 OS << " return true;\n";
3099 OS << "}\n\n";
3100}
3101
3102static void emitMnemonicSpellChecker(raw_ostream &OS, CodeGenTarget &Target,
3103 unsigned VariantCount) {
3104 OS << "static std::string " << Target.getName()
3105 << "MnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,"
3106 << " unsigned VariantID) {\n";
3107 if (!VariantCount)
3108 OS << " return \"\";";
3109 else {
3110 OS << " const unsigned MaxEditDist = 2;\n";
3111 OS << " std::vector<StringRef> Candidates;\n";
3112 OS << " StringRef Prev = \"\";\n\n";
3113
3114 OS << " // Find the appropriate table for this asm variant.\n";
3115 OS << " const MatchEntry *Start, *End;\n";
3116 OS << " switch (VariantID) {\n";
3117 OS << " default: llvm_unreachable(\"invalid variant!\");\n";
3118 for (unsigned VC = 0; VC != VariantCount; ++VC) {
3119 const Record *AsmVariant = Target.getAsmParserVariant(i: VC);
3120 int AsmVariantNo = AsmVariant->getValueAsInt(FieldName: "Variant");
3121 OS << " case " << AsmVariantNo << ": Start = std::begin(MatchTable" << VC
3122 << "); End = std::end(MatchTable" << VC << "); break;\n";
3123 }
3124 OS << " }\n\n";
3125 OS << " for (auto I = Start; I < End; I++) {\n";
3126 OS << " // Ignore unsupported instructions.\n";
3127 OS << " const FeatureBitset &RequiredFeatures = "
3128 "FeatureBitsets[I->RequiredFeaturesIdx];\n";
3129 OS << " if ((FBS & RequiredFeatures) != RequiredFeatures)\n";
3130 OS << " continue;\n";
3131 OS << "\n";
3132 OS << " StringRef T = I->getMnemonic();\n";
3133 OS << " // Avoid recomputing the edit distance for the same string.\n";
3134 OS << " if (T == Prev)\n";
3135 OS << " continue;\n";
3136 OS << "\n";
3137 OS << " Prev = T;\n";
3138 OS << " unsigned Dist = S.edit_distance(T, false, MaxEditDist);\n";
3139 OS << " if (Dist <= MaxEditDist)\n";
3140 OS << " Candidates.push_back(T);\n";
3141 OS << " }\n";
3142 OS << "\n";
3143 OS << " if (Candidates.empty())\n";
3144 OS << " return \"\";\n";
3145 OS << "\n";
3146 OS << " std::string Res = \", did you mean: \";\n";
3147 OS << " unsigned i = 0;\n";
3148 OS << " for (; i < Candidates.size() - 1; i++)\n";
3149 OS << " Res += Candidates[i].str() + \", \";\n";
3150 OS << " return Res + Candidates[i].str() + \"?\";\n";
3151 }
3152 OS << "}\n";
3153 OS << "\n";
3154}
3155
3156static void emitMnemonicChecker(raw_ostream &OS, CodeGenTarget &Target,
3157 unsigned VariantCount, bool HasMnemonicFirst,
3158 bool HasMnemonicAliases) {
3159 OS << "static bool " << Target.getName()
3160 << "CheckMnemonic(StringRef Mnemonic,\n";
3161 OS << " "
3162 << "const FeatureBitset &AvailableFeatures,\n";
3163 OS << " "
3164 << "unsigned VariantID) {\n";
3165
3166 if (!VariantCount) {
3167 OS << " return false;\n";
3168 } else {
3169 if (HasMnemonicAliases) {
3170 OS << " // Process all MnemonicAliases to remap the mnemonic.\n";
3171 OS << " applyMnemonicAliases(Mnemonic, AvailableFeatures, VariantID);";
3172 OS << "\n\n";
3173 }
3174 OS << " // Find the appropriate table for this asm variant.\n";
3175 OS << " const MatchEntry *Start, *End;\n";
3176 OS << " switch (VariantID) {\n";
3177 OS << " default: llvm_unreachable(\"invalid variant!\");\n";
3178 for (unsigned VC = 0; VC != VariantCount; ++VC) {
3179 const Record *AsmVariant = Target.getAsmParserVariant(i: VC);
3180 int AsmVariantNo = AsmVariant->getValueAsInt(FieldName: "Variant");
3181 OS << " case " << AsmVariantNo << ": Start = std::begin(MatchTable" << VC
3182 << "); End = std::end(MatchTable" << VC << "); break;\n";
3183 }
3184 OS << " }\n\n";
3185
3186 OS << " // Search the table.\n";
3187 if (HasMnemonicFirst) {
3188 OS << " auto MnemonicRange = "
3189 "std::equal_range(Start, End, Mnemonic, LessOpcode());\n\n";
3190 } else {
3191 OS << " auto MnemonicRange = std::pair(Start, End);\n";
3192 OS << " unsigned SIndex = Mnemonic.empty() ? 0 : 1;\n";
3193 OS << " if (!Mnemonic.empty())\n";
3194 OS << " MnemonicRange = "
3195 << "std::equal_range(Start, End, Mnemonic.lower(), LessOpcode());\n\n";
3196 }
3197
3198 OS << " if (MnemonicRange.first == MnemonicRange.second)\n";
3199 OS << " return false;\n\n";
3200
3201 OS << " for (const MatchEntry *it = MnemonicRange.first, "
3202 << "*ie = MnemonicRange.second;\n";
3203 OS << " it != ie; ++it) {\n";
3204 OS << " const FeatureBitset &RequiredFeatures =\n";
3205 OS << " FeatureBitsets[it->RequiredFeaturesIdx];\n";
3206 OS << " if ((AvailableFeatures & RequiredFeatures) == ";
3207 OS << "RequiredFeatures)\n";
3208 OS << " return true;\n";
3209 OS << " }\n";
3210 OS << " return false;\n";
3211 }
3212 OS << "}\n";
3213 OS << "\n";
3214}
3215
3216// Emit a function mapping match classes to strings, for debugging.
3217static void emitMatchClassKindNames(std::forward_list<ClassInfo> &Infos,
3218 raw_ostream &OS) {
3219 OS << "#ifndef NDEBUG\n";
3220 OS << "const char *getMatchClassName(MatchClassKind Kind) {\n";
3221 OS << " switch (Kind) {\n";
3222
3223 OS << " case InvalidMatchClass: return \"InvalidMatchClass\";\n";
3224 OS << " case OptionalMatchClass: return \"OptionalMatchClass\";\n";
3225 for (const auto &CI : Infos) {
3226 OS << " case " << CI.Name << ": return \"" << CI.Name << "\";\n";
3227 }
3228 OS << " case NumMatchClassKinds: return \"NumMatchClassKinds\";\n";
3229
3230 OS << " }\n";
3231 OS << " llvm_unreachable(\"unhandled MatchClassKind!\");\n";
3232 OS << "}\n\n";
3233 OS << "#endif // NDEBUG\n";
3234}
3235
3236static std::string
3237getNameForFeatureBitset(ArrayRef<const Record *> FeatureBitset) {
3238 std::string Name = "AMFBS";
3239 for (const Record *Feature : FeatureBitset)
3240 Name += ("_" + Feature->getName()).str();
3241 return Name;
3242}
3243
3244void AsmMatcherEmitter::run(raw_ostream &OS) {
3245 CodeGenTarget Target(Records);
3246 const Record *AsmParser = Target.getAsmParser();
3247 StringRef ClassName = AsmParser->getValueAsString(FieldName: "AsmParserClassName");
3248
3249 emitSourceFileHeader(Desc: "Assembly Matcher Source Fragment", OS, Record: Records);
3250
3251 // Compute the information on the instructions to match.
3252 AsmMatcherInfo Info(AsmParser, Target, Records);
3253 Info.buildInfo();
3254
3255 bool PreferSmallerInstructions = getPreferSmallerInstructions(Target);
3256 // Sort the instruction table using the partial order on classes. We use
3257 // stable_sort to ensure that ambiguous instructions are still
3258 // deterministically ordered.
3259 llvm::stable_sort(
3260 Range&: Info.Matchables,
3261 C: [PreferSmallerInstructions](const std::unique_ptr<MatchableInfo> &A,
3262 const std::unique_ptr<MatchableInfo> &B) {
3263 return A->shouldBeMatchedBefore(RHS: *B, PreferSmallerInstructions);
3264 });
3265
3266#ifdef EXPENSIVE_CHECKS
3267 // Verify that the table is sorted and operator < works transitively.
3268 for (auto I = Info.Matchables.begin(), E = Info.Matchables.end(); I != E;
3269 ++I) {
3270 for (auto J = I; J != E; ++J) {
3271 assert(!(*J)->shouldBeMatchedBefore(**I, PreferSmallerInstructions));
3272 }
3273 }
3274#endif
3275
3276 DEBUG_WITH_TYPE("instruction_info", {
3277 for (const auto &MI : Info.Matchables)
3278 MI->dump();
3279 });
3280
3281 // Check for ambiguous matchables.
3282 DEBUG_WITH_TYPE("ambiguous_instrs", {
3283 unsigned NumAmbiguous = 0;
3284 for (auto I = Info.Matchables.begin(), E = Info.Matchables.end(); I != E;
3285 ++I) {
3286 for (auto J = std::next(I); J != E; ++J) {
3287 const MatchableInfo &A = **I;
3288 const MatchableInfo &B = **J;
3289
3290 if (A.couldMatchAmbiguouslyWith(B, PreferSmallerInstructions)) {
3291 errs() << "warning: ambiguous matchables:\n";
3292 A.dump();
3293 errs() << "\nis incomparable with:\n";
3294 B.dump();
3295 errs() << "\n\n";
3296 ++NumAmbiguous;
3297 }
3298 }
3299 }
3300 if (NumAmbiguous)
3301 errs() << "warning: " << NumAmbiguous << " ambiguous matchables!\n";
3302 });
3303
3304 // Compute the information on the custom operand parsing.
3305 Info.buildOperandMatchInfo();
3306
3307 bool HasMnemonicFirst = AsmParser->getValueAsBit(FieldName: "HasMnemonicFirst");
3308 bool HasOptionalOperands = Info.hasOptionalOperands();
3309 bool ReportMultipleNearMisses =
3310 AsmParser->getValueAsBit(FieldName: "ReportMultipleNearMisses");
3311
3312 // Write the output.
3313
3314 // Information for the class declaration.
3315 OS << "\n#ifdef GET_ASSEMBLER_HEADER\n";
3316 OS << "#undef GET_ASSEMBLER_HEADER\n";
3317 OS << " // This should be included into the middle of the declaration of\n";
3318 OS << " // your subclasses implementation of MCTargetAsmParser.\n";
3319 OS << " FeatureBitset ComputeAvailableFeatures(const FeatureBitset &FB) "
3320 "const;\n";
3321 if (HasOptionalOperands) {
3322 OS << " void convertToMCInst(unsigned Kind, MCInst &Inst, "
3323 << "unsigned Opcode,\n"
3324 << " const OperandVector &Operands,\n"
3325 << " const SmallBitVector "
3326 "&OptionalOperandsMask,\n"
3327 << " ArrayRef<unsigned> DefaultsOffset);\n";
3328 } else {
3329 OS << " void convertToMCInst(unsigned Kind, MCInst &Inst, "
3330 << "unsigned Opcode,\n"
3331 << " const OperandVector &Operands);\n";
3332 }
3333 OS << " void convertToMapAndConstraints(unsigned Kind,\n ";
3334 OS << " const OperandVector &Operands) override;\n";
3335 OS << " unsigned MatchInstructionImpl(const OperandVector &Operands,\n"
3336 << " MCInst &Inst,\n";
3337 if (ReportMultipleNearMisses)
3338 OS << " SmallVectorImpl<NearMissInfo> "
3339 "*NearMisses,\n";
3340 else
3341 OS << " uint64_t &ErrorInfo,\n"
3342 << " FeatureBitset &MissingFeatures,\n";
3343 OS << " bool matchingInlineAsm,\n"
3344 << " unsigned VariantID = 0);\n";
3345 if (!ReportMultipleNearMisses)
3346 OS << " unsigned MatchInstructionImpl(const OperandVector &Operands,\n"
3347 << " MCInst &Inst,\n"
3348 << " uint64_t &ErrorInfo,\n"
3349 << " bool matchingInlineAsm,\n"
3350 << " unsigned VariantID = 0) {\n"
3351 << " FeatureBitset MissingFeatures;\n"
3352 << " return MatchInstructionImpl(Operands, Inst, ErrorInfo, "
3353 "MissingFeatures,\n"
3354 << " matchingInlineAsm, VariantID);\n"
3355 << " }\n\n";
3356
3357 if (!Info.OperandMatchInfo.empty()) {
3358 OS << " ParseStatus MatchOperandParserImpl(\n";
3359 OS << " OperandVector &Operands,\n";
3360 OS << " StringRef Mnemonic,\n";
3361 OS << " bool ParseForAllFeatures = false);\n";
3362
3363 OS << " ParseStatus tryCustomParseOperand(\n";
3364 OS << " OperandVector &Operands,\n";
3365 OS << " unsigned MCK);\n\n";
3366 }
3367
3368 OS << "#endif // GET_ASSEMBLER_HEADER\n\n";
3369
3370 // Emit the operand match diagnostic enum names.
3371 OS << "\n#ifdef GET_OPERAND_DIAGNOSTIC_TYPES\n";
3372 OS << "#undef GET_OPERAND_DIAGNOSTIC_TYPES\n\n";
3373 emitOperandDiagnosticTypes(Info, OS);
3374 OS << "#endif // GET_OPERAND_DIAGNOSTIC_TYPES\n\n";
3375
3376 OS << "\n#ifdef GET_REGISTER_MATCHER\n";
3377 OS << "#undef GET_REGISTER_MATCHER\n\n";
3378
3379 // Emit the subtarget feature enumeration.
3380 SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(
3381 SubtargetFeatures: Info.SubtargetFeatures, OS);
3382
3383 // Emit the function to match a register name to number.
3384 // This should be omitted for Mips target
3385 if (AsmParser->getValueAsBit(FieldName: "ShouldEmitMatchRegisterName"))
3386 emitMatchRegisterName(Target, AsmParser, OS);
3387
3388 if (AsmParser->getValueAsBit(FieldName: "ShouldEmitMatchRegisterAltName"))
3389 emitMatchRegisterAltName(Target, AsmParser, OS);
3390
3391 OS << "#endif // GET_REGISTER_MATCHER\n\n";
3392
3393 OS << "\n#ifdef GET_SUBTARGET_FEATURE_NAME\n";
3394 OS << "#undef GET_SUBTARGET_FEATURE_NAME\n\n";
3395
3396 // Generate the helper function to get the names for subtarget features.
3397 emitGetSubtargetFeatureName(Info, OS);
3398
3399 OS << "#endif // GET_SUBTARGET_FEATURE_NAME\n\n";
3400
3401 OS << "\n#ifdef GET_MATCHER_IMPLEMENTATION\n";
3402 OS << "#undef GET_MATCHER_IMPLEMENTATION\n\n";
3403
3404 // Generate the function that remaps for mnemonic aliases.
3405 bool HasMnemonicAliases = emitMnemonicAliases(OS, Info, Target);
3406
3407 // Generate the convertToMCInst function to convert operands into an MCInst.
3408 // Also, generate the convertToMapAndConstraints function for MS-style inline
3409 // assembly. The latter doesn't actually generate a MCInst.
3410 unsigned NumConverters =
3411 emitConvertFuncs(Target, ClassName, Infos&: Info.Matchables, HasMnemonicFirst,
3412 HasOptionalOperands, OS);
3413
3414 // Emit the enumeration for classes which participate in matching.
3415 emitMatchClassEnumeration(Target, Infos&: Info.Classes, OS);
3416
3417 // Emit a function to get the user-visible string to describe an operand
3418 // match failure in diagnostics.
3419 emitOperandMatchErrorDiagStrings(Info, OS);
3420
3421 // Emit a function to map register classes to operand match failure codes.
3422 emitRegisterMatchErrorFunc(Info, OS);
3423
3424 // Emit the routine to match token strings to their match class.
3425 emitMatchTokenString(Target, Infos&: Info.Classes, OS);
3426
3427 // Emit the subclass predicate routine.
3428 emitIsSubclass(Target, Infos&: Info.Classes, OS);
3429
3430 // Emit the routine to validate an operand against a match class.
3431 emitValidateOperandClass(Target, Info, OS);
3432
3433 emitMatchClassKindNames(Infos&: Info.Classes, OS);
3434
3435 // Emit the available features compute function.
3436 SubtargetFeatureInfo::emitComputeAssemblerAvailableFeatures(
3437 TargetName: Info.Target.getName(), ClassName, FuncName: "ComputeAvailableFeatures",
3438 SubtargetFeatures&: Info.SubtargetFeatures, OS);
3439
3440 if (!ReportMultipleNearMisses)
3441 emitAsmTiedOperandConstraints(Target, Info, OS, HasOptionalOperands);
3442
3443 StringToOffsetTable StringTable;
3444
3445 size_t MaxNumOperands = 0;
3446 unsigned MaxMnemonicIndex = 0;
3447 bool HasDeprecation = false;
3448 for (const auto &MI : Info.Matchables) {
3449 MaxNumOperands = std::max(a: MaxNumOperands, b: MI->AsmOperands.size());
3450 HasDeprecation |= MI->HasDeprecation;
3451
3452 // Store a pascal-style length byte in the mnemonic.
3453 std::string LenMnemonic = char(MI->Mnemonic.size()) + MI->Mnemonic.lower();
3454 MaxMnemonicIndex = std::max(
3455 a: MaxMnemonicIndex, b: StringTable.GetOrAddStringOffset(Str: LenMnemonic, appendZero: false));
3456 }
3457
3458 OS << "static const char MnemonicTable[] =\n";
3459 StringTable.EmitString(O&: OS);
3460 OS << ";\n\n";
3461
3462 std::vector<std::vector<const Record *>> FeatureBitsets;
3463 for (const auto &MI : Info.Matchables) {
3464 if (MI->RequiredFeatures.empty())
3465 continue;
3466 FeatureBitsets.emplace_back();
3467 for (const auto *F : MI->RequiredFeatures)
3468 FeatureBitsets.back().push_back(x: F->TheDef);
3469 }
3470
3471 llvm::sort(C&: FeatureBitsets,
3472 Comp: [&](ArrayRef<const Record *> A, ArrayRef<const Record *> B) {
3473 if (A.size() != B.size())
3474 return A.size() < B.size();
3475 for (const auto [ARec, BRec] : zip_equal(t&: A, u&: B)) {
3476 if (ARec->getName() != BRec->getName())
3477 return ARec->getName() < BRec->getName();
3478 }
3479 return false;
3480 });
3481 FeatureBitsets.erase(first: llvm::unique(R&: FeatureBitsets), last: FeatureBitsets.end());
3482 OS << "// Feature bitsets.\n"
3483 << "enum : " << getMinimalTypeForRange(Range: FeatureBitsets.size()) << " {\n"
3484 << " AMFBS_None,\n";
3485 for (const auto &FeatureBitset : FeatureBitsets) {
3486 if (FeatureBitset.empty())
3487 continue;
3488 OS << " " << getNameForFeatureBitset(FeatureBitset) << ",\n";
3489 }
3490 OS << "};\n\n"
3491 << "static constexpr FeatureBitset FeatureBitsets[] = {\n"
3492 << " {}, // AMFBS_None\n";
3493 for (const auto &FeatureBitset : FeatureBitsets) {
3494 if (FeatureBitset.empty())
3495 continue;
3496 OS << " {";
3497 for (const auto &Feature : FeatureBitset) {
3498 const auto &I = Info.SubtargetFeatures.find(x: Feature);
3499 assert(I != Info.SubtargetFeatures.end() && "Didn't import predicate?");
3500 OS << I->second.getEnumBitName() << ", ";
3501 }
3502 OS << "},\n";
3503 }
3504 OS << "};\n\n";
3505
3506 // Emit the static match table; unused classes get initialized to 0 which is
3507 // guaranteed to be InvalidMatchClass.
3508 //
3509 // FIXME: We can reduce the size of this table very easily. First, we change
3510 // it so that store the kinds in separate bit-fields for each index, which
3511 // only needs to be the max width used for classes at that index (we also need
3512 // to reject based on this during classification). If we then make sure to
3513 // order the match kinds appropriately (putting mnemonics last), then we
3514 // should only end up using a few bits for each class, especially the ones
3515 // following the mnemonic.
3516 OS << "namespace {\n";
3517 OS << " struct MatchEntry {\n";
3518 OS << " " << getMinimalTypeForRange(Range: MaxMnemonicIndex) << " Mnemonic;\n";
3519 OS << " uint16_t Opcode;\n";
3520 OS << " " << getMinimalTypeForRange(Range: NumConverters) << " ConvertFn;\n";
3521 OS << " " << getMinimalTypeForRange(Range: FeatureBitsets.size())
3522 << " RequiredFeaturesIdx;\n";
3523 OS << " "
3524 << getMinimalTypeForRange(
3525 Range: std::distance(first: Info.Classes.begin(), last: Info.Classes.end()) +
3526 2 /* Include 'InvalidMatchClass' and 'OptionalMatchClass' */)
3527 << " Classes[" << MaxNumOperands << "];\n";
3528 OS << " StringRef getMnemonic() const {\n";
3529 OS << " return StringRef(MnemonicTable + Mnemonic + 1,\n";
3530 OS << " MnemonicTable[Mnemonic]);\n";
3531 OS << " }\n";
3532 OS << " };\n\n";
3533
3534 OS << " // Predicate for searching for an opcode.\n";
3535 OS << " struct LessOpcode {\n";
3536 OS << " bool operator()(const MatchEntry &LHS, StringRef RHS) {\n";
3537 OS << " return LHS.getMnemonic() < RHS;\n";
3538 OS << " }\n";
3539 OS << " bool operator()(StringRef LHS, const MatchEntry &RHS) {\n";
3540 OS << " return LHS < RHS.getMnemonic();\n";
3541 OS << " }\n";
3542 OS << " bool operator()(const MatchEntry &LHS, const MatchEntry &RHS) {\n";
3543 OS << " return LHS.getMnemonic() < RHS.getMnemonic();\n";
3544 OS << " }\n";
3545 OS << " };\n";
3546
3547 OS << "} // end anonymous namespace\n\n";
3548
3549 unsigned VariantCount = Target.getAsmParserVariantCount();
3550 for (unsigned VC = 0; VC != VariantCount; ++VC) {
3551 const Record *AsmVariant = Target.getAsmParserVariant(i: VC);
3552 int AsmVariantNo = AsmVariant->getValueAsInt(FieldName: "Variant");
3553
3554 OS << "static const MatchEntry MatchTable" << VC << "[] = {\n";
3555
3556 for (const auto &MI : Info.Matchables) {
3557 if (MI->AsmVariantID != AsmVariantNo)
3558 continue;
3559
3560 // Store a pascal-style length byte in the mnemonic.
3561 std::string LenMnemonic =
3562 char(MI->Mnemonic.size()) + MI->Mnemonic.lower();
3563 OS << " { " << *StringTable.GetStringOffset(Str: LenMnemonic) << " /* "
3564 << MI->Mnemonic << " */, " << Target.getInstNamespace()
3565 << "::" << MI->getResultInst()->TheDef->getName() << ", "
3566 << MI->ConversionFnKind << ", ";
3567
3568 // Write the required features mask.
3569 OS << "AMFBS";
3570 if (MI->RequiredFeatures.empty())
3571 OS << "_None";
3572 else
3573 for (const auto &F : MI->RequiredFeatures)
3574 OS << '_' << F->TheDef->getName();
3575
3576 OS << ", { ";
3577 ListSeparator LS;
3578 for (const MatchableInfo::AsmOperand &Op : MI->AsmOperands)
3579 OS << LS << Op.Class->Name;
3580 OS << " }, },\n";
3581 }
3582
3583 OS << "};\n\n";
3584 }
3585
3586 OS << "#include \"llvm/Support/Debug.h\"\n";
3587 OS << "#include \"llvm/Support/Format.h\"\n\n";
3588
3589 // Finally, build the match function.
3590 OS << "unsigned " << Target.getName() << ClassName << "::\n"
3591 << "MatchInstructionImpl(const OperandVector &Operands,\n";
3592 OS << " MCInst &Inst,\n";
3593 if (ReportMultipleNearMisses)
3594 OS << " SmallVectorImpl<NearMissInfo> *NearMisses,\n";
3595 else
3596 OS << " uint64_t &ErrorInfo,\n"
3597 << " FeatureBitset &MissingFeatures,\n";
3598 OS << " bool matchingInlineAsm, unsigned VariantID) {\n";
3599
3600 if (!ReportMultipleNearMisses) {
3601 OS << " // Eliminate obvious mismatches.\n";
3602 OS << " if (Operands.size() > " << (MaxNumOperands + HasMnemonicFirst)
3603 << ") {\n";
3604 OS << " ErrorInfo = " << (MaxNumOperands + HasMnemonicFirst) << ";\n";
3605 OS << " return Match_InvalidOperand;\n";
3606 OS << " }\n\n";
3607 }
3608
3609 // Emit code to get the available features.
3610 OS << " // Get the current feature set.\n";
3611 OS << " const FeatureBitset &AvailableFeatures = "
3612 "getAvailableFeatures();\n\n";
3613
3614 OS << " // Get the instruction mnemonic, which is the first token.\n";
3615 if (HasMnemonicFirst) {
3616 OS << " StringRef Mnemonic = ((" << Target.getName()
3617 << "Operand &)*Operands[0]).getToken();\n\n";
3618 } else {
3619 OS << " StringRef Mnemonic;\n";
3620 OS << " if (Operands[0]->isToken())\n";
3621 OS << " Mnemonic = ((" << Target.getName()
3622 << "Operand &)*Operands[0]).getToken();\n\n";
3623 }
3624
3625 if (HasMnemonicAliases) {
3626 OS << " // Process all MnemonicAliases to remap the mnemonic.\n";
3627 OS << " applyMnemonicAliases(Mnemonic, AvailableFeatures, VariantID);\n\n";
3628 }
3629
3630 // Emit code to compute the class list for this operand vector.
3631 if (!ReportMultipleNearMisses) {
3632 OS << " // Some state to try to produce better error messages.\n";
3633 OS << " bool HadMatchOtherThanFeatures = false;\n";
3634 OS << " bool HadMatchOtherThanPredicate = false;\n";
3635 OS << " unsigned RetCode = Match_InvalidOperand;\n";
3636 OS << " MissingFeatures.set();\n";
3637 OS << " // Set ErrorInfo to the operand that mismatches if it is\n";
3638 OS << " // wrong for all instances of the instruction.\n";
3639 OS << " ErrorInfo = ~0ULL;\n";
3640 }
3641
3642 if (HasOptionalOperands) {
3643 OS << " SmallBitVector OptionalOperandsMask(" << MaxNumOperands << ");\n";
3644 }
3645
3646 // Emit code to search the table.
3647 OS << " // Find the appropriate table for this asm variant.\n";
3648 OS << " const MatchEntry *Start, *End;\n";
3649 OS << " switch (VariantID) {\n";
3650 OS << " default: llvm_unreachable(\"invalid variant!\");\n";
3651 for (unsigned VC = 0; VC != VariantCount; ++VC) {
3652 const Record *AsmVariant = Target.getAsmParserVariant(i: VC);
3653 int AsmVariantNo = AsmVariant->getValueAsInt(FieldName: "Variant");
3654 OS << " case " << AsmVariantNo << ": Start = std::begin(MatchTable" << VC
3655 << "); End = std::end(MatchTable" << VC << "); break;\n";
3656 }
3657 OS << " }\n";
3658
3659 OS << " // Search the table.\n";
3660 if (HasMnemonicFirst) {
3661 OS << " auto MnemonicRange = "
3662 "std::equal_range(Start, End, Mnemonic, LessOpcode());\n\n";
3663 } else {
3664 OS << " auto MnemonicRange = std::pair(Start, End);\n";
3665 OS << " unsigned SIndex = Mnemonic.empty() ? 0 : 1;\n";
3666 OS << " if (!Mnemonic.empty())\n";
3667 OS << " MnemonicRange = "
3668 "std::equal_range(Start, End, Mnemonic.lower(), LessOpcode());\n\n";
3669 }
3670
3671 OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"AsmMatcher: found \" "
3672 "<<\n"
3673 << " std::distance(MnemonicRange.first, MnemonicRange.second) <<\n"
3674 << " \" encodings with mnemonic '\" << Mnemonic << \"'\\n\");\n\n";
3675
3676 OS << " // Return a more specific error code if no mnemonics match.\n";
3677 OS << " if (MnemonicRange.first == MnemonicRange.second)\n";
3678 OS << " return Match_MnemonicFail;\n\n";
3679
3680 OS << " for (const MatchEntry *it = MnemonicRange.first, "
3681 << "*ie = MnemonicRange.second;\n";
3682 OS << " it != ie; ++it) {\n";
3683 OS << " const FeatureBitset &RequiredFeatures = "
3684 "FeatureBitsets[it->RequiredFeaturesIdx];\n";
3685 OS << " bool HasRequiredFeatures =\n";
3686 OS << " (AvailableFeatures & RequiredFeatures) == RequiredFeatures;\n";
3687 OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"Trying to match "
3688 "opcode \"\n";
3689 OS << " << MII.getName(it->Opcode) "
3690 "<< \"\\n\");\n";
3691
3692 if (ReportMultipleNearMisses) {
3693 OS << " // Some state to record ways in which this instruction did not "
3694 "match.\n";
3695 OS << " NearMissInfo OperandNearMiss = NearMissInfo::getSuccess();\n";
3696 OS << " NearMissInfo FeaturesNearMiss = NearMissInfo::getSuccess();\n";
3697 OS << " NearMissInfo EarlyPredicateNearMiss = "
3698 "NearMissInfo::getSuccess();\n";
3699 OS << " NearMissInfo LatePredicateNearMiss = "
3700 "NearMissInfo::getSuccess();\n";
3701 OS << " bool MultipleInvalidOperands = false;\n";
3702 }
3703
3704 if (HasMnemonicFirst) {
3705 OS << " // equal_range guarantees that instruction mnemonic matches.\n";
3706 OS << " assert(Mnemonic == it->getMnemonic());\n";
3707 }
3708
3709 // Emit check that the subclasses match.
3710 if (!ReportMultipleNearMisses)
3711 OS << " bool OperandsValid = true;\n";
3712 if (HasOptionalOperands) {
3713 OS << " OptionalOperandsMask.reset(0, " << MaxNumOperands << ");\n";
3714 }
3715 OS << " for (unsigned FormalIdx = " << (HasMnemonicFirst ? "0" : "SIndex")
3716 << ", ActualIdx = " << (HasMnemonicFirst ? "1" : "SIndex")
3717 << "; FormalIdx != " << MaxNumOperands << "; ++FormalIdx) {\n";
3718 OS << " auto Formal = "
3719 << "static_cast<MatchClassKind>(it->Classes[FormalIdx]);\n";
3720 OS << " DEBUG_WITH_TYPE(\"asm-matcher\",\n";
3721 OS << " dbgs() << \" Matching formal operand class \" "
3722 "<< getMatchClassName(Formal)\n";
3723 OS << " << \" against actual operand at index \" "
3724 "<< ActualIdx);\n";
3725 OS << " if (ActualIdx < Operands.size())\n";
3726 OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \" (\";\n";
3727 OS << " Operands[ActualIdx]->print(dbgs(), "
3728 "*getContext().getAsmInfo()); dbgs() << "
3729 "\"): \");\n";
3730 OS << " else\n";
3731 OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \": \");\n";
3732 OS << " if (ActualIdx >= Operands.size()) {\n";
3733 OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"actual operand "
3734 "index out of range\\n\");\n";
3735 if (ReportMultipleNearMisses) {
3736 OS << " bool ThisOperandValid = (Formal == "
3737 << "InvalidMatchClass) || "
3738 "isSubclass(Formal, OptionalMatchClass);\n";
3739 OS << " if (!ThisOperandValid) {\n";
3740 OS << " if (!OperandNearMiss) {\n";
3741 OS << " // Record info about match failure for later use.\n";
3742 OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"recording "
3743 "too-few-operands near miss\\n\");\n";
3744 OS << " OperandNearMiss =\n";
3745 OS << " NearMissInfo::getTooFewOperands(Formal, "
3746 "it->Opcode);\n";
3747 OS << " } else if (OperandNearMiss.getKind() != "
3748 "NearMissInfo::NearMissTooFewOperands) {\n";
3749 OS << " // If more than one operand is invalid, give up on this "
3750 "match entry.\n";
3751 OS << " DEBUG_WITH_TYPE(\n";
3752 OS << " \"asm-matcher\",\n";
3753 OS << " dbgs() << \"second invalid operand, giving up on "
3754 "this opcode\\n\");\n";
3755 OS << " MultipleInvalidOperands = true;\n";
3756 OS << " break;\n";
3757 OS << " }\n";
3758 OS << " } else {\n";
3759 OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"but formal "
3760 "operand not required\\n\");\n";
3761 OS << " if (isSubclass(Formal, OptionalMatchClass)) {\n";
3762 OS << " OptionalOperandsMask.set(FormalIdx);\n";
3763 OS << " }\n";
3764 OS << " }\n";
3765 OS << " continue;\n";
3766 } else {
3767 OS << " if (Formal == InvalidMatchClass) {\n";
3768 if (HasOptionalOperands) {
3769 OS << " OptionalOperandsMask.set(FormalIdx, " << MaxNumOperands
3770 << ");\n";
3771 }
3772 OS << " break;\n";
3773 OS << " }\n";
3774 OS << " if (isSubclass(Formal, OptionalMatchClass)) {\n";
3775 if (HasOptionalOperands) {
3776 OS << " OptionalOperandsMask.set(FormalIdx);\n";
3777 }
3778 OS << " continue;\n";
3779 OS << " }\n";
3780 OS << " OperandsValid = false;\n";
3781 OS << " ErrorInfo = ActualIdx;\n";
3782 OS << " break;\n";
3783 }
3784 OS << " }\n";
3785 OS << " MCParsedAsmOperand &Actual = *Operands[ActualIdx];\n";
3786 OS << " unsigned Diag = validateOperandClass(Actual, Formal);\n";
3787 OS << " if (Diag == Match_Success) {\n";
3788 OS << " DEBUG_WITH_TYPE(\"asm-matcher\",\n";
3789 OS << " dbgs() << \"match success using generic "
3790 "matcher\\n\");\n";
3791 OS << " ++ActualIdx;\n";
3792 OS << " continue;\n";
3793 OS << " }\n";
3794 OS << " // If the generic handler indicates an invalid operand\n";
3795 OS << " // failure, check for a special case.\n";
3796 OS << " if (Diag != Match_Success) {\n";
3797 OS << " unsigned TargetDiag = validateTargetOperandClass(Actual, "
3798 "Formal);\n";
3799 OS << " if (TargetDiag == Match_Success) {\n";
3800 OS << " DEBUG_WITH_TYPE(\"asm-matcher\",\n";
3801 OS << " dbgs() << \"match success using target "
3802 "matcher\\n\");\n";
3803 OS << " ++ActualIdx;\n";
3804 OS << " continue;\n";
3805 OS << " }\n";
3806 OS << " // If the target matcher returned a specific error code use\n";
3807 OS << " // that, else use the one from the generic matcher.\n";
3808 OS << " if (TargetDiag != Match_InvalidOperand && "
3809 "HasRequiredFeatures)\n";
3810 OS << " Diag = TargetDiag;\n";
3811 OS << " }\n";
3812 OS << " // If current formal operand wasn't matched and it is optional\n"
3813 << " // then try to match next formal operand\n";
3814 OS << " if (Diag == Match_InvalidOperand "
3815 << "&& isSubclass(Formal, OptionalMatchClass)) {\n";
3816 if (HasOptionalOperands) {
3817 OS << " OptionalOperandsMask.set(FormalIdx);\n";
3818 }
3819 OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"ignoring "
3820 "optional operand\\n\");\n";
3821 OS << " continue;\n";
3822 OS << " }\n";
3823
3824 if (ReportMultipleNearMisses) {
3825 OS << " if (!OperandNearMiss) {\n";
3826 OS << " // If this is the first invalid operand we have seen, "
3827 "record some\n";
3828 OS << " // information about it.\n";
3829 OS << " DEBUG_WITH_TYPE(\n";
3830 OS << " \"asm-matcher\",\n";
3831 OS << " dbgs()\n";
3832 OS << " << \"operand match failed, recording near-miss with "
3833 "diag code \"\n";
3834 OS << " << Diag << \"\\n\");\n";
3835 OS << " OperandNearMiss =\n";
3836 OS << " NearMissInfo::getMissedOperand(Diag, Formal, "
3837 "it->Opcode, ActualIdx);\n";
3838 OS << " ++ActualIdx;\n";
3839 OS << " } else {\n";
3840 OS << " // If more than one operand is invalid, give up on this "
3841 "match entry.\n";
3842 OS << " DEBUG_WITH_TYPE(\n";
3843 OS << " \"asm-matcher\",\n";
3844 OS << " dbgs() << \"second operand mismatch, skipping this "
3845 "opcode\\n\");\n";
3846 OS << " MultipleInvalidOperands = true;\n";
3847 OS << " break;\n";
3848 OS << " }\n";
3849 OS << " }\n\n";
3850 } else {
3851 OS << " // If this operand is broken for all of the instances of "
3852 "this\n";
3853 OS << " // mnemonic, keep track of it so we can report loc info.\n";
3854 OS << " // If we already had a match that only failed due to a\n";
3855 OS << " // target predicate, that diagnostic is preferred.\n";
3856 OS << " if (!HadMatchOtherThanPredicate &&\n";
3857 OS << " (it == MnemonicRange.first || ErrorInfo <= ActualIdx)) "
3858 "{\n";
3859 OS << " if (HasRequiredFeatures && (ErrorInfo != ActualIdx || Diag "
3860 "!= Match_InvalidOperand))\n";
3861 OS << " RetCode = Diag;\n";
3862 OS << " ErrorInfo = ActualIdx;\n";
3863 OS << " }\n";
3864 OS << " // Otherwise, just reject this instance of the mnemonic.\n";
3865 OS << " OperandsValid = false;\n";
3866 OS << " break;\n";
3867 OS << " }\n\n";
3868 }
3869
3870 if (ReportMultipleNearMisses)
3871 OS << " if (MultipleInvalidOperands) {\n";
3872 else
3873 OS << " if (!OperandsValid) {\n";
3874 OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"Opcode result: "
3875 "multiple \"\n";
3876 OS << " \"operand mismatches, "
3877 "ignoring \"\n";
3878 OS << " \"this opcode\\n\");\n";
3879 OS << " continue;\n";
3880 OS << " }\n";
3881
3882 // Emit check that the required features are available.
3883 OS << " if (!HasRequiredFeatures) {\n";
3884 if (!ReportMultipleNearMisses)
3885 OS << " HadMatchOtherThanFeatures = true;\n";
3886 OS << " FeatureBitset NewMissingFeatures = RequiredFeatures & "
3887 "~AvailableFeatures;\n";
3888 OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"Missing target "
3889 "features:\";\n";
3890 OS << " for (unsigned I = 0, E = "
3891 "NewMissingFeatures.size(); I != E; ++I)\n";
3892 OS << " if (NewMissingFeatures[I])\n";
3893 OS << " dbgs() << ' ' << I;\n";
3894 OS << " dbgs() << \"\\n\");\n";
3895 if (ReportMultipleNearMisses) {
3896 OS << " FeaturesNearMiss = "
3897 "NearMissInfo::getMissedFeature(NewMissingFeatures);\n";
3898 } else {
3899 OS << " if (NewMissingFeatures.count() <=\n"
3900 " MissingFeatures.count())\n";
3901 OS << " MissingFeatures = NewMissingFeatures;\n";
3902 OS << " continue;\n";
3903 }
3904 OS << " }\n";
3905 OS << "\n";
3906 OS << " Inst.clear();\n\n";
3907 OS << " Inst.setOpcode(it->Opcode);\n";
3908 // Verify the instruction with the target-specific match predicate function.
3909 OS << " // We have a potential match but have not rendered the operands.\n"
3910 << " // Check the target predicate to handle any context sensitive\n"
3911 " // constraints.\n"
3912 << " // For example, Ties that are referenced multiple times must be\n"
3913 " // checked here to ensure the input is the same for each match\n"
3914 " // constraints. If we leave it any later the ties will have been\n"
3915 " // canonicalized\n"
3916 << " unsigned MatchResult;\n"
3917 << " if ((MatchResult = checkEarlyTargetMatchPredicate(Inst, "
3918 "Operands)) != Match_Success) {\n"
3919 << " Inst.clear();\n";
3920 OS << " DEBUG_WITH_TYPE(\n";
3921 OS << " \"asm-matcher\",\n";
3922 OS << " dbgs() << \"Early target match predicate failed with diag "
3923 "code \"\n";
3924 OS << " << MatchResult << \"\\n\");\n";
3925 if (ReportMultipleNearMisses) {
3926 OS << " EarlyPredicateNearMiss = "
3927 "NearMissInfo::getMissedPredicate(MatchResult);\n";
3928 } else {
3929 OS << " RetCode = MatchResult;\n"
3930 << " HadMatchOtherThanPredicate = true;\n"
3931 << " continue;\n";
3932 }
3933 OS << " }\n\n";
3934
3935 if (ReportMultipleNearMisses) {
3936 OS << " // If we did not successfully match the operands, then we can't "
3937 "convert to\n";
3938 OS << " // an MCInst, so bail out on this instruction variant now.\n";
3939 OS << " if (OperandNearMiss) {\n";
3940 OS << " // If the operand mismatch was the only problem, report it as "
3941 "a near-miss.\n";
3942 OS << " if (NearMisses && !FeaturesNearMiss && "
3943 "!EarlyPredicateNearMiss) {\n";
3944 OS << " DEBUG_WITH_TYPE(\n";
3945 OS << " \"asm-matcher\",\n";
3946 OS << " dbgs()\n";
3947 OS << " << \"Opcode result: one mismatched operand, adding "
3948 "near-miss\\n\");\n";
3949 OS << " NearMisses->push_back(OperandNearMiss);\n";
3950 OS << " } else {\n";
3951 OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"Opcode result: "
3952 "multiple \"\n";
3953 OS << " \"types of "
3954 "mismatch, so not \"\n";
3955 OS << " \"reporting "
3956 "near-miss\\n\");\n";
3957 OS << " }\n";
3958 OS << " continue;\n";
3959 OS << " }\n\n";
3960 }
3961
3962 // When converting parsed operands to MCInst we need to know whether optional
3963 // operands were parsed or not so that we can choose the correct converter
3964 // function. We also need to know this when checking tied operand constraints.
3965 // DefaultsOffset is an array of deltas between the formal (MCInst) and the
3966 // actual (parsed operand array) operand indices. When all optional operands
3967 // are present, all elements of the array are zeros. If some of the optional
3968 // operands are absent, the array might look like '0, 0, 1, 1, 1, 2, 2, 3',
3969 // where each increment in value reflects the absence of an optional operand.
3970 if (HasOptionalOperands) {
3971 OS << " unsigned DefaultsOffset[" << (MaxNumOperands + 1)
3972 << "] = { 0 };\n";
3973 OS << " assert(OptionalOperandsMask.size() == " << (MaxNumOperands)
3974 << ");\n";
3975 OS << " for (unsigned i = 0, NumDefaults = 0; i < " << (MaxNumOperands)
3976 << "; ++i) {\n";
3977 OS << " DefaultsOffset[i + 1] = NumDefaults;\n";
3978 OS << " NumDefaults += (OptionalOperandsMask[i] ? 1 : 0);\n";
3979 OS << " }\n\n";
3980 }
3981
3982 OS << " if (matchingInlineAsm) {\n";
3983 OS << " convertToMapAndConstraints(it->ConvertFn, Operands);\n";
3984 if (!ReportMultipleNearMisses) {
3985 if (HasOptionalOperands) {
3986 OS << " if (!checkAsmTiedOperandConstraints(*this, it->ConvertFn, "
3987 "Operands,\n";
3988 OS << " DefaultsOffset, "
3989 "ErrorInfo))\n";
3990 } else {
3991 OS << " if (!checkAsmTiedOperandConstraints(*this, it->ConvertFn, "
3992 "Operands,\n";
3993 OS << " ErrorInfo))\n";
3994 }
3995 OS << " return Match_InvalidTiedOperand;\n";
3996 OS << "\n";
3997 }
3998 OS << " return Match_Success;\n";
3999 OS << " }\n\n";
4000 OS << " // We have selected a definite instruction, convert the parsed\n"
4001 << " // operands into the appropriate MCInst.\n";
4002 if (HasOptionalOperands) {
4003 OS << " convertToMCInst(it->ConvertFn, Inst, it->Opcode, Operands,\n"
4004 << " OptionalOperandsMask, DefaultsOffset);\n";
4005 } else {
4006 OS << " convertToMCInst(it->ConvertFn, Inst, it->Opcode, Operands);\n";
4007 }
4008 OS << "\n";
4009
4010 // Verify the instruction with the target-specific match predicate function.
4011 OS << " // We have a potential match. Check the target predicate to\n"
4012 << " // handle any context sensitive constraints.\n"
4013 << " if ((MatchResult = checkTargetMatchPredicate(Inst)) !="
4014 << " Match_Success) {\n"
4015 << " DEBUG_WITH_TYPE(\"asm-matcher\",\n"
4016 << " dbgs() << \"Target match predicate failed with "
4017 "diag code \"\n"
4018 << " << MatchResult << \"\\n\");\n"
4019 << " Inst.clear();\n";
4020 if (ReportMultipleNearMisses) {
4021 OS << " LatePredicateNearMiss = "
4022 "NearMissInfo::getMissedPredicate(MatchResult);\n";
4023 } else {
4024 OS << " RetCode = MatchResult;\n"
4025 << " HadMatchOtherThanPredicate = true;\n"
4026 << " continue;\n";
4027 }
4028 OS << " }\n\n";
4029
4030 if (ReportMultipleNearMisses) {
4031 OS << " int NumNearMisses = ((int)(bool)OperandNearMiss +\n";
4032 OS << " (int)(bool)FeaturesNearMiss +\n";
4033 OS << " (int)(bool)EarlyPredicateNearMiss +\n";
4034 OS << " (int)(bool)LatePredicateNearMiss);\n";
4035 OS << " if (NumNearMisses == 1) {\n";
4036 OS << " // We had exactly one type of near-miss, so add that to the "
4037 "list.\n";
4038 OS << " assert(!OperandNearMiss && \"OperandNearMiss was handled "
4039 "earlier\");\n";
4040 OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"Opcode result: "
4041 "found one type of \"\n";
4042 OS << " \"mismatch, so "
4043 "reporting a \"\n";
4044 OS << " \"near-miss\\n\");\n";
4045 OS << " if (NearMisses && FeaturesNearMiss)\n";
4046 OS << " NearMisses->push_back(FeaturesNearMiss);\n";
4047 OS << " else if (NearMisses && EarlyPredicateNearMiss)\n";
4048 OS << " NearMisses->push_back(EarlyPredicateNearMiss);\n";
4049 OS << " else if (NearMisses && LatePredicateNearMiss)\n";
4050 OS << " NearMisses->push_back(LatePredicateNearMiss);\n";
4051 OS << "\n";
4052 OS << " continue;\n";
4053 OS << " } else if (NumNearMisses > 1) {\n";
4054 OS << " // This instruction missed in more than one way, so ignore "
4055 "it.\n";
4056 OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"Opcode result: "
4057 "multiple \"\n";
4058 OS << " \"types of mismatch, "
4059 "so not \"\n";
4060 OS << " \"reporting "
4061 "near-miss\\n\");\n";
4062 OS << " continue;\n";
4063 OS << " }\n";
4064 }
4065
4066 // Call the post-processing function, if used.
4067 StringRef InsnCleanupFn = AsmParser->getValueAsString(FieldName: "AsmParserInstCleanup");
4068 if (!InsnCleanupFn.empty())
4069 OS << " " << InsnCleanupFn << "(Inst);\n";
4070
4071 if (HasDeprecation) {
4072 OS << " std::string Info;\n";
4073 OS << " if "
4074 "(!getParser().getTargetParser().getTargetOptions()."
4075 "MCNoDeprecatedWarn &&\n";
4076 OS << " MII.getDeprecatedInfo(Inst, getSTI(), Info)) {\n";
4077 OS << " SMLoc Loc = ((" << Target.getName()
4078 << "Operand &)*Operands[0]).getStartLoc();\n";
4079 OS << " getParser().Warning(Loc, Info, std::nullopt);\n";
4080 OS << " }\n";
4081 }
4082
4083 if (!ReportMultipleNearMisses) {
4084 if (HasOptionalOperands) {
4085 OS << " if (!checkAsmTiedOperandConstraints(*this, it->ConvertFn, "
4086 "Operands,\n";
4087 OS << " DefaultsOffset, "
4088 "ErrorInfo))\n";
4089 } else {
4090 OS << " if (!checkAsmTiedOperandConstraints(*this, it->ConvertFn, "
4091 "Operands,\n";
4092 OS << " ErrorInfo))\n";
4093 }
4094 OS << " return Match_InvalidTiedOperand;\n";
4095 OS << "\n";
4096 }
4097
4098 OS << " DEBUG_WITH_TYPE(\n";
4099 OS << " \"asm-matcher\",\n";
4100 OS << " dbgs() << \"Opcode result: complete match, selecting this "
4101 "opcode\\n\");\n";
4102 OS << " return Match_Success;\n";
4103 OS << " }\n\n";
4104
4105 if (ReportMultipleNearMisses) {
4106 OS << " // No instruction variants matched exactly.\n";
4107 OS << " return Match_NearMisses;\n";
4108 } else {
4109 OS << " // Okay, we had no match. Try to return a useful error code.\n";
4110 OS << " if (HadMatchOtherThanPredicate || !HadMatchOtherThanFeatures)\n";
4111 OS << " return RetCode;\n\n";
4112 OS << " ErrorInfo = 0;\n";
4113 OS << " return Match_MissingFeature;\n";
4114 }
4115 OS << "}\n\n";
4116
4117 if (!Info.OperandMatchInfo.empty())
4118 emitCustomOperandParsing(OS, Target, Info, ClassName, StringTable,
4119 MaxMnemonicIndex, MaxFeaturesIndex: FeatureBitsets.size(),
4120 HasMnemonicFirst, AsmParser: *AsmParser);
4121
4122 OS << "#endif // GET_MATCHER_IMPLEMENTATION\n\n";
4123
4124 OS << "\n#ifdef GET_MNEMONIC_SPELL_CHECKER\n";
4125 OS << "#undef GET_MNEMONIC_SPELL_CHECKER\n\n";
4126
4127 emitMnemonicSpellChecker(OS, Target, VariantCount);
4128
4129 OS << "#endif // GET_MNEMONIC_SPELL_CHECKER\n\n";
4130
4131 OS << "\n#ifdef GET_MNEMONIC_CHECKER\n";
4132 OS << "#undef GET_MNEMONIC_CHECKER\n\n";
4133
4134 emitMnemonicChecker(OS, Target, VariantCount, HasMnemonicFirst,
4135 HasMnemonicAliases);
4136
4137 OS << "#endif // GET_MNEMONIC_CHECKER\n\n";
4138}
4139
4140static TableGen::Emitter::OptClass<AsmMatcherEmitter>
4141 X("gen-asm-matcher", "Generate assembly instruction matcher");
4142