1 //===- AsmMatcherEmitter.cpp - Generate an assembly matcher ---------------===//
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
7 //===----------------------------------------------------------------------===//
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.
13 // Converting assembly operands into MCInst structures
14 // ---------------------------------------------------
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
23 // Some example inputs, for X86:
24 // 'addl' (immediate ...) (register ...)
25 // 'add' (immediate ...) (memory ...)
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:
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.
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
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.
51 // The matching is divided into two distinct phases:
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.
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).
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.
66 // In addition, the subset relation amongst classes induces a partial order
67 // on such tuples, which we use to resolve ambiguities.
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.
74 // Custom Operand Parsing
75 // ----------------------
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
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.
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.
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.
96 //===----------------------------------------------------------------------===//
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/TableGen/Error.h"
114 #include "llvm/TableGen/Record.h"
115 #include "llvm/TableGen/StringMatcher.h"
116 #include "llvm/TableGen/StringToOffsetTable.h"
117 #include "llvm/TableGen/TableGenBackend.h"
120 #include <forward_list>
124 using namespace llvm
;
126 #define DEBUG_TYPE "asm-matcher-emitter"
128 cl::OptionCategory
AsmMatcherEmitterCat("Options for -gen-asm-matcher");
130 static cl::opt
<std::string
>
131 MatchPrefix("match-prefix", cl::init(""),
132 cl::desc("Only match instructions with the given prefix"),
133 cl::cat(AsmMatcherEmitterCat
));
136 class AsmMatcherInfo
;
138 // Register sets are used as keys in some second-order sets TableGen creates
139 // when generating its data structures. This means that the order of two
140 // RegisterSets can be seen in the outputted AsmMatcher tables occasionally, and
141 // can even affect compiler output (at least seen in diagnostics produced when
142 // all matches fail). So we use a type that sorts them consistently.
143 typedef std::set
<const Record
*, LessRecordByID
> RegisterSet
;
145 class AsmMatcherEmitter
{
146 const RecordKeeper
&Records
;
149 AsmMatcherEmitter(const RecordKeeper
&R
) : Records(R
) {}
151 void run(raw_ostream
&o
);
154 /// ClassInfo - Helper class for storing the information about a particular
155 /// class of operands which can be matched.
158 /// Invalid kind, for use as a sentinel value.
161 /// The class for a particular token.
164 /// The (first) register class, subsequent register classes are
165 /// RegisterClass0+1, and so on.
168 /// The (first) user defined class, subsequent user defined classes are
169 /// UserClass0+1, and so on.
173 /// Kind - The class kind, which is either a predefined kind, or (UserClass0 +
174 /// N) for the Nth user defined class.
177 /// SuperClasses - The super classes of this class. Note that for simplicities
178 /// sake user operands only record their immediate super class, while register
179 /// operands include all superclasses.
180 std::vector
<ClassInfo
*> SuperClasses
;
182 /// Name - The full class name, suitable for use in an enum.
185 /// ClassName - The unadorned generic name for this class (e.g., Token).
186 std::string ClassName
;
188 /// ValueName - The name of the value this class represents; for a token this
189 /// is the literal token string, for an operand it is the TableGen class (or
190 /// empty if this is a derived class).
191 std::string ValueName
;
193 /// PredicateMethod - The name of the operand method to test whether the
194 /// operand matches this class; this is not valid for Token or register kinds.
195 std::string PredicateMethod
;
197 /// RenderMethod - The name of the operand method to add this operand to an
198 /// MCInst; this is not valid for Token or register kinds.
199 std::string RenderMethod
;
201 /// ParserMethod - The name of the operand method to do a target specific
202 /// parsing on the operand.
203 std::string ParserMethod
;
205 /// For register classes: the records for all the registers in this class.
206 RegisterSet Registers
;
208 /// For custom match classes: the diagnostic kind for when the predicate
210 std::string DiagnosticType
;
212 /// For custom match classes: the diagnostic string for when the predicate
214 std::string DiagnosticString
;
216 /// Is this operand optional and not always required.
219 /// DefaultMethod - The name of the method that returns the default operand
220 /// for optional operand
221 std::string DefaultMethod
;
224 /// isRegisterClass() - Check if this is a register class.
225 bool isRegisterClass() const {
226 return Kind
>= RegisterClass0
&& Kind
< UserClass0
;
229 /// isUserClass() - Check if this is a user defined class.
230 bool isUserClass() const { return Kind
>= UserClass0
; }
232 /// isRelatedTo - Check whether this class is "related" to \p RHS. Classes
233 /// are related if they are in the same class hierarchy.
234 bool isRelatedTo(const ClassInfo
&RHS
) const {
235 // Tokens are only related to tokens.
236 if (Kind
== Token
|| RHS
.Kind
== Token
)
237 return Kind
== Token
&& RHS
.Kind
== Token
;
239 // Registers classes are only related to registers classes, and only if
240 // their intersection is non-empty.
241 if (isRegisterClass() || RHS
.isRegisterClass()) {
242 if (!isRegisterClass() || !RHS
.isRegisterClass())
245 std::vector
<const Record
*> Tmp
;
246 std::set_intersection(Registers
.begin(), Registers
.end(),
247 RHS
.Registers
.begin(), RHS
.Registers
.end(),
248 std::back_inserter(Tmp
), LessRecordByID());
253 // Otherwise we have two users operands; they are related if they are in the
254 // same class hierarchy.
256 // FIXME: This is an oversimplification, they should only be related if they
257 // intersect, however we don't have that information.
258 assert(isUserClass() && RHS
.isUserClass() && "Unexpected class!");
259 const ClassInfo
*Root
= this;
260 while (!Root
->SuperClasses
.empty())
261 Root
= Root
->SuperClasses
.front();
263 const ClassInfo
*RHSRoot
= &RHS
;
264 while (!RHSRoot
->SuperClasses
.empty())
265 RHSRoot
= RHSRoot
->SuperClasses
.front();
267 return Root
== RHSRoot
;
270 /// isSubsetOf - Test whether this class is a subset of \p RHS.
271 bool isSubsetOf(const ClassInfo
&RHS
) const {
272 // This is a subset of RHS if it is the same class...
276 // ... or if any of its super classes are a subset of RHS.
277 SmallVector
<const ClassInfo
*, 16> Worklist(SuperClasses
.begin(),
279 SmallPtrSet
<const ClassInfo
*, 16> Visited
;
280 while (!Worklist
.empty()) {
281 auto *CI
= Worklist
.pop_back_val();
284 for (auto *Super
: CI
->SuperClasses
)
285 if (Visited
.insert(Super
).second
)
286 Worklist
.push_back(Super
);
292 int getTreeDepth() const {
294 const ClassInfo
*Root
= this;
295 while (!Root
->SuperClasses
.empty()) {
297 Root
= Root
->SuperClasses
.front();
302 const ClassInfo
*findRoot() const {
303 const ClassInfo
*Root
= this;
304 while (!Root
->SuperClasses
.empty())
305 Root
= Root
->SuperClasses
.front();
309 /// Compare two classes. This does not produce a total ordering, but does
310 /// guarantee that subclasses are sorted before their parents, and that the
311 /// ordering is transitive.
312 bool operator<(const ClassInfo
&RHS
) const {
316 // First, enforce the ordering between the three different types of class.
317 // Tokens sort before registers, which sort before user classes.
319 if (RHS
.Kind
!= Token
)
321 assert(RHS
.Kind
== Token
);
322 } else if (isRegisterClass()) {
323 if (RHS
.Kind
== Token
)
325 else if (RHS
.isUserClass())
327 assert(RHS
.isRegisterClass());
328 } else if (isUserClass()) {
329 if (!RHS
.isUserClass())
331 assert(RHS
.isUserClass());
333 llvm_unreachable("Unknown ClassInfoKind");
336 if (Kind
== Token
|| isUserClass()) {
337 // Related tokens and user classes get sorted by depth in the inheritence
338 // tree (so that subclasses are before their parents).
339 if (isRelatedTo(RHS
)) {
340 if (getTreeDepth() > RHS
.getTreeDepth())
342 if (getTreeDepth() < RHS
.getTreeDepth())
345 // Unrelated tokens and user classes are ordered by the name of their
346 // root nodes, so that there is a consistent ordering between
347 // unconnected trees.
348 return findRoot()->ValueName
< RHS
.findRoot()->ValueName
;
350 } else if (isRegisterClass()) {
351 // For register sets, sort by number of registers. This guarantees that
352 // a set will always sort before all of it's strict supersets.
353 if (Registers
.size() != RHS
.Registers
.size())
354 return Registers
.size() < RHS
.Registers
.size();
356 llvm_unreachable("Unknown ClassInfoKind");
359 // FIXME: We should be able to just return false here, as we only need a
360 // partial order (we use stable sorts, so this is deterministic) and the
361 // name of a class shouldn't be significant. However, some of the backends
362 // accidentally rely on this behaviour, so it will have to stay like this
363 // until they are fixed.
364 return ValueName
< RHS
.ValueName
;
368 class AsmVariantInfo
{
370 StringRef RegisterPrefix
;
371 StringRef TokenizingCharacters
;
372 StringRef SeparatorCharacters
;
373 StringRef BreakCharacters
;
378 bool getPreferSmallerInstructions(CodeGenTarget
const &Target
) {
379 return Target
.getAsmParser()->getValueAsBit("PreferSmallerInstructions");
382 /// MatchableInfo - Helper class for storing the necessary information for an
383 /// instruction or alias which is capable of being matched.
384 struct MatchableInfo
{
386 /// Token - This is the token that the operand came from.
389 /// The unique class instance this operand should match.
392 /// The operand name this is, if anything.
395 /// The operand name this is, before renaming for tied operands.
396 StringRef OrigSrcOpName
;
398 /// The suboperand index within SrcOpName, or -1 for the entire operand.
401 /// Whether the token is "isolated", i.e., it is preceded and followed
403 bool IsIsolatedToken
;
405 /// Register record if this token is singleton register.
406 const Record
*SingletonReg
;
408 explicit AsmOperand(bool IsIsolatedToken
, StringRef T
)
409 : Token(T
), Class(nullptr), SubOpIdx(-1),
410 IsIsolatedToken(IsIsolatedToken
), SingletonReg(nullptr) {}
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.
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.
424 /// TiedOperand - This represents a result operand that is a duplicate of
425 /// a previous result operand.
428 /// ImmOperand - This represents an immediate value that is dumped into
432 /// RegOperand - This represents a fixed register that is dumped in.
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
{
441 unsigned SrcOpnd1Idx
;
442 unsigned SrcOpnd2Idx
;
446 /// This is the operand # in the AsmOperands list that this should be
448 unsigned AsmOperandNum
;
450 /// Description of tied operands.
451 TiedOperandsTuple TiedOperands
;
453 /// ImmVal - This is the immediate value added to the instruction.
456 /// Register - This is the register record.
457 const Record
*Register
;
460 /// MINumOperands - The number of MCInst operands populated by this
462 unsigned MINumOperands
;
464 static ResOperand
getRenderedOp(unsigned AsmOpNum
, unsigned NumOperands
) {
466 X
.Kind
= RenderAsmOperand
;
467 X
.AsmOperandNum
= AsmOpNum
;
468 X
.MINumOperands
= NumOperands
;
472 static ResOperand
getTiedOp(unsigned TiedOperandNum
, unsigned SrcOperand1
,
473 unsigned SrcOperand2
) {
475 X
.Kind
= TiedOperand
;
476 X
.TiedOperands
= {TiedOperandNum
, SrcOperand1
, SrcOperand2
};
481 static ResOperand
getImmOp(int64_t Val
) {
489 static ResOperand
getRegOp(const Record
*Reg
) {
498 /// AsmVariantID - Target's assembly syntax variant no.
501 /// AsmString - The assembly string for this instruction (with variants
502 /// removed), e.g. "movsx $src, $dst".
503 std::string AsmString
;
505 /// TheDef - This is the definition of the instruction or InstAlias that this
506 /// matchable came from.
507 const Record
*const TheDef
;
509 // ResInstSize - The size of the resulting instruction for this matchable.
510 unsigned ResInstSize
;
512 /// DefRec - This is the definition that it came from.
513 PointerUnion
<const CodeGenInstruction
*, const CodeGenInstAlias
*> DefRec
;
515 const CodeGenInstruction
*getResultInst() const {
516 if (isa
<const CodeGenInstruction
*>(DefRec
))
517 return cast
<const CodeGenInstruction
*>(DefRec
);
518 return cast
<const CodeGenInstAlias
*>(DefRec
)->ResultInst
;
521 /// ResOperands - This is the operand list that should be built for the result
523 SmallVector
<ResOperand
, 8> ResOperands
;
525 /// Mnemonic - This is the first token of the matched instruction, its
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
533 SmallVector
<AsmOperand
, 8> AsmOperands
;
535 /// Predicates - The required subtarget features to match this instruction.
536 SmallVector
<const SubtargetFeatureInfo
*, 4> RequiredFeatures
;
538 /// ConversionFnKind - The enum value which is passed to the generated
539 /// convertToMCInst to convert parsed operands into an MCInst for this
541 std::string ConversionFnKind
;
543 /// If this instruction is deprecated in some form.
544 bool HasDeprecation
= false;
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
;
551 MatchableInfo(const CodeGenInstruction
&CGI
)
552 : AsmVariantID(0), AsmString(CGI
.AsmString
), TheDef(CGI
.TheDef
),
553 ResInstSize(TheDef
->getValueAsInt("Size")), DefRec(&CGI
),
554 UseInstAsmMatchConverter(true) {}
556 MatchableInfo(std::unique_ptr
<const CodeGenInstAlias
> Alias
)
557 : AsmVariantID(0), AsmString(Alias
->AsmString
), TheDef(Alias
->TheDef
),
558 ResInstSize(Alias
->ResultInst
->TheDef
->getValueAsInt("Size")),
559 DefRec(Alias
.release()), UseInstAsmMatchConverter(TheDef
->getValueAsBit(
560 "UseInstAsmMatchConverter")) {}
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
));
577 delete dyn_cast_if_present
<const CodeGenInstAlias
*>(DefRec
);
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
);
584 void initialize(const AsmMatcherInfo
&Info
,
585 SmallPtrSetImpl
<const Record
*> &SingletonRegisters
,
586 AsmVariantInfo
const &Variant
, bool HasMnemonicFirst
);
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;
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(AsmOperands
, [&](const AsmOperand
&Op
) {
596 return Op
.SrcOpName
== N
&& Op
.SubOpIdx
== SubOpIdx
;
598 return (I
!= AsmOperands
.end()) ? I
- AsmOperands
.begin() : -1;
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 {
605 llvm::find_if(llvm::drop_begin(AsmOperands
, LastIdx
+ 1),
606 [&](const AsmOperand
&Op
) { return Op
.SrcOpName
== N
; });
607 return (I
!= AsmOperands
.end()) ? I
- AsmOperands
.begin() : -1;
610 int findAsmOperandOriginallyNamed(StringRef N
) const {
611 auto I
= find_if(AsmOperands
, [&](const AsmOperand
&Op
) {
612 return Op
.OrigSrcOpName
== N
;
614 return (I
!= AsmOperands
.end()) ? I
- AsmOperands
.begin() : -1;
617 void buildInstructionResultOperands();
618 void buildAliasResultOperands(bool AliasConstraintsAreChecked
);
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
.Mnemonic
))
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
;
632 if (AsmOperands
.size() != RHS
.AsmOperands
.size())
633 return AsmOperands
.size() < RHS
.AsmOperands
.size();
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(AsmOperands
, RHS
.AsmOperands
)) {
638 if (*LHSOp
.Class
< *RHSOp
.Class
)
640 if (*RHSOp
.Class
< *LHSOp
.Class
)
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("Instruction") &&
650 getResultInst()->TheDef
->getValueAsBit("HasPositionOrder") &&
651 RHS
.getResultInst()->TheDef
->isSubClassOf("Instruction") &&
652 RHS
.getResultInst()->TheDef
->getValueAsBit("HasPositionOrder"))
653 return getResultInst()->TheDef
->getID() <
654 RHS
.getResultInst()->TheDef
->getID();
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();
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
)
677 // Different variants can't conflict.
678 if (AsmVariantID
!= RHS
.AsmVariantID
)
681 // The size of instruction is unambiguous.
682 if (PreferSmallerInstructions
&& ResInstSize
!= RHS
.ResInstSize
)
685 // The number of operands is unambiguous.
686 if (AsmOperands
.size() != RHS
.AsmOperands
.size())
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.
693 // Tokens and operand kinds are unambiguous (assuming a correct target
695 for (const auto &[LHSOp
, RHSOp
] : zip_equal(AsmOperands
, 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
)
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(AsmOperands
, RHS
.AsmOperands
)) {
707 if (*LHSOp
.Class
< *RHSOp
.Class
)
709 if (*RHSOp
.Class
< *LHSOp
.Class
)
713 return HasLT
== HasGT
;
719 void tokenizeAsmString(AsmMatcherInfo
const &Info
,
720 AsmVariantInfo
const &Variant
);
721 void addAsmOperand(StringRef Token
, bool IsIsolatedToken
= false);
724 struct OperandMatchEntry
{
725 unsigned OperandMask
;
726 const MatchableInfo
*MI
;
729 static OperandMatchEntry
create(const MatchableInfo
*mi
, ClassInfo
*ci
,
732 X
.OperandMask
= opMask
;
739 class AsmMatcherInfo
{
742 const RecordKeeper
&Records
;
744 /// The tablegen AsmParser record.
745 const Record
*AsmParser
;
747 /// Target - The target information.
748 const CodeGenTarget
&Target
;
750 /// The classes which are needed for matching.
751 std::forward_list
<ClassInfo
> Classes
;
753 /// The information on the matchables to match.
754 std::vector
<std::unique_ptr
<MatchableInfo
>> Matchables
;
756 /// Info for custom matching operands by user defined methods.
757 std::vector
<OperandMatchEntry
> OperandMatchInfo
;
759 /// Map of Register records to their class information.
760 typedef std::map
<const Record
*, ClassInfo
*, LessRecordByID
>
762 RegisterClassesTy RegisterClasses
;
764 /// Map of Predicate records to their subtarget information.
765 SubtargetFeatureInfoMap SubtargetFeatures
;
767 /// Map of AsmOperandClass records to their class information.
768 std::map
<const Record
*, ClassInfo
*> AsmOperandClasses
;
770 /// Map of RegisterClass records to their class information.
771 std::map
<const Record
*, ClassInfo
*> RegisterClassClasses
;
774 /// Map of token to class information which has already been constructed.
775 std::map
<std::string
, ClassInfo
*> TokenClasses
;
778 /// getTokenClass - Lookup or create the class for the given token.
779 ClassInfo
*getTokenClass(StringRef Token
);
781 /// getOperandClass - Lookup or create the class for the given operand.
782 ClassInfo
*getOperandClass(const CGIOperandList::OperandInfo
&OI
,
784 ClassInfo
*getOperandClass(const Record
*Rec
, int SubOpIdx
);
786 /// buildRegisterClasses - Build the ClassInfo* instances for register
789 buildRegisterClasses(SmallPtrSetImpl
<const Record
*> &SingletonRegisters
);
791 /// buildOperandClasses - Build the ClassInfo* instances for user defined
793 void buildOperandClasses();
795 void buildInstructionOperandReference(MatchableInfo
*II
, StringRef OpName
,
797 void buildAliasOperandReference(MatchableInfo
*II
, StringRef OpName
,
798 MatchableInfo::AsmOperand
&Op
);
801 AsmMatcherInfo(const Record
*AsmParser
, const CodeGenTarget
&Target
,
802 const RecordKeeper
&Records
);
804 /// Construct the various tables used during matching.
807 /// buildOperandMatchInfo - Build the necessary information to handle user
808 /// defined operand parsing methods.
809 void buildOperandMatchInfo();
811 /// getSubtargetFeature - Lookup or create the subtarget feature info for the
813 const SubtargetFeatureInfo
*getSubtargetFeature(const Record
*Def
) const {
814 assert(Def
->isSubClassOf("Predicate") && "Invalid predicate type!");
815 const auto &I
= SubtargetFeatures
.find(Def
);
816 return I
== SubtargetFeatures
.end() ? nullptr : &I
->second
;
819 const RecordKeeper
&getRecords() const { return Records
; }
821 bool hasOptionalOperands() const {
822 return any_of(Classes
,
823 [](const ClassInfo
&Class
) { return Class
.IsOptional
; });
827 } // end anonymous namespace
829 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
830 LLVM_DUMP_METHOD
void MatchableInfo::dump() const {
831 errs() << TheDef
->getName() << " -- "
832 << "flattened:\"" << AsmString
<< "\"\n";
834 errs() << " variant: " << AsmVariantID
<< "\n";
836 for (const auto &[Idx
, Op
] : enumerate(AsmOperands
)) {
837 errs() << " op[" << Idx
<< "] = " << Op
.Class
->ClassName
<< " - ";
838 errs() << '\"' << Op
.Token
<< "\"\n";
843 static std::pair
<StringRef
, StringRef
>
844 parseTwoOperandConstraint(StringRef S
, ArrayRef
<SMLoc
> Loc
) {
845 // Split via the '='.
846 std::pair
<StringRef
, StringRef
> Ops
= S
.split('=');
847 if (Ops
.second
== "")
848 PrintFatalError(Loc
, "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('$');
851 if (start
== std::string::npos
)
852 PrintFatalError(Loc
, "expected '$' prefix on asm operand name");
853 Ops
.first
= Ops
.first
.substr(start
+ 1);
854 size_t end
= Ops
.first
.find_last_of(" \t");
855 Ops
.first
= Ops
.first
.slice(0, end
);
856 // Now the second operand.
857 start
= Ops
.second
.find_first_of('$');
858 if (start
== std::string::npos
)
859 PrintFatalError(Loc
, "expected '$' prefix on asm operand name");
860 Ops
.second
= Ops
.second
.substr(start
+ 1);
861 end
= Ops
.second
.find_last_of(" \t");
862 Ops
.first
= Ops
.first
.slice(0, end
);
866 void MatchableInfo::formTwoOperandAlias(StringRef Constraint
) {
867 // Figure out which operands are aliased and mark them as tied.
868 std::pair
<StringRef
, StringRef
> Ops
=
869 parseTwoOperandConstraint(Constraint
, TheDef
->getLoc());
871 // Find the AsmOperands that refer to the operands we're aliasing.
872 int SrcAsmOperand
= findAsmOperandNamed(Ops
.first
);
873 int DstAsmOperand
= findAsmOperandNamed(Ops
.second
);
874 if (SrcAsmOperand
== -1)
875 PrintFatalError(TheDef
->getLoc(),
876 "unknown source two-operand alias operand '" + Ops
.first
+
878 if (DstAsmOperand
== -1)
879 PrintFatalError(TheDef
->getLoc(),
880 "unknown destination two-operand alias operand '" +
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
;
892 // Remove the AsmOperand for the alias operand.
893 AsmOperands
.erase(AsmOperands
.begin() + SrcAsmOperand
);
894 // Adjust the ResOperand references to any AsmOperands that followed
895 // the one we just deleted.
896 for (ResOperand
&Op
: ResOperands
) {
899 // Nothing to do for operands that don't reference AsmOperands.
901 case ResOperand::RenderAsmOperand
:
902 if (Op
.AsmOperandNum
> (unsigned)SrcAsmOperand
)
909 /// extractSingletonRegisterForAsmOperand - Extract singleton register,
910 /// if present, from specified token.
911 static void extractSingletonRegisterForAsmOperand(MatchableInfo::AsmOperand
&Op
,
912 const AsmMatcherInfo
&Info
,
913 StringRef RegisterPrefix
) {
914 StringRef Tok
= Op
.Token
;
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
)
921 if (RegisterPrefix
.empty()) {
922 std::string LoweredTok
= Tok
.lower();
923 if (const CodeGenRegister
*Reg
= Info
.Target
.getRegisterByName(LoweredTok
))
924 Op
.SingletonReg
= Reg
->TheDef
;
928 if (!Tok
.starts_with(RegisterPrefix
))
931 StringRef RegName
= Tok
.substr(RegisterPrefix
.size());
932 if (const CodeGenRegister
*Reg
= Info
.Target
.getRegisterByName(RegName
))
933 Op
.SingletonReg
= Reg
->TheDef
;
935 // If there is no register prefix (i.e. "%" in "%eax"), then this may
936 // be some random non-register token, just ignore it.
939 void 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
.AsmVariantNo
);
947 tokenizeAsmString(Info
, Variant
);
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(TheDef
->getLoc(),
953 "Instruction '" + TheDef
->getName() + "' has no tokens");
955 assert(!AsmOperands
[0].Token
.empty());
956 if (HasMnemonicFirst
) {
957 Mnemonic
= AsmOperands
[0].Token
;
958 if (Mnemonic
[0] == '$')
959 PrintFatalError(TheDef
->getLoc(),
960 "Invalid instruction mnemonic '" + Mnemonic
+ "'!");
962 // Remove the first operand, it is tracked in the mnemonic field.
963 AsmOperands
.erase(AsmOperands
.begin());
964 } else if (AsmOperands
[0].Token
[0] != '$')
965 Mnemonic
= AsmOperands
[0].Token
;
967 // Compute the require features.
968 for (const Record
*Predicate
: TheDef
->getValueAsListOfDefs("Predicates"))
969 if (const SubtargetFeatureInfo
*Feature
=
970 Info
.getSubtargetFeature(Predicate
))
971 RequiredFeatures
.push_back(Feature
);
973 // Collect singleton registers, if used.
974 for (MatchableInfo::AsmOperand
&Op
: AsmOperands
) {
975 extractSingletonRegisterForAsmOperand(Op
, Info
, Variant
.RegisterPrefix
);
977 SingletonRegisters
.insert(Op
.SingletonReg
);
980 const RecordVal
*DepMask
= TheDef
->getValue("DeprecatedFeatureMask");
982 DepMask
= TheDef
->getValue("ComplexDeprecationPredicate");
985 DepMask
? !DepMask
->getValue()->getAsUnquotedString().empty() : false;
988 /// Append an AsmOperand for the given substring of AsmString.
989 void MatchableInfo::addAsmOperand(StringRef Token
, bool IsIsolatedToken
) {
990 AsmOperands
.push_back(AsmOperand(IsIsolatedToken
, Token
));
993 /// tokenizeAsmString - Tokenize a simplified assembly string.
994 void MatchableInfo::tokenizeAsmString(const AsmMatcherInfo
&Info
,
995 AsmVariantInfo
const &Variant
) {
996 StringRef String
= AsmString
;
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(Char
)) {
1004 addAsmOperand(String
.substr(Prev
, i
- Prev
), false);
1006 IsIsolatedToken
= false;
1011 if (Variant
.TokenizingCharacters
.contains(Char
)) {
1013 addAsmOperand(String
.substr(Prev
, i
- Prev
), IsIsolatedToken
);
1015 IsIsolatedToken
= false;
1017 addAsmOperand(String
.substr(i
, 1), IsIsolatedToken
);
1019 IsIsolatedToken
= true;
1022 if (Variant
.SeparatorCharacters
.contains(Char
)) {
1024 addAsmOperand(String
.substr(Prev
, i
- Prev
), IsIsolatedToken
);
1028 IsIsolatedToken
= true;
1035 addAsmOperand(String
.substr(Prev
, i
- Prev
), false);
1037 IsIsolatedToken
= false;
1040 assert(i
!= String
.size() && "Invalid quoted character");
1041 addAsmOperand(String
.substr(i
, 1), IsIsolatedToken
);
1043 IsIsolatedToken
= false;
1048 addAsmOperand(String
.substr(Prev
, i
- Prev
), IsIsolatedToken
);
1050 IsIsolatedToken
= false;
1053 // If this isn't "${", start new identifier looking like "$xxx"
1054 if (i
+ 1 == String
.size() || String
[i
+ 1] != '{') {
1059 size_t EndPos
= String
.find('}', i
);
1060 assert(EndPos
!= StringRef::npos
&&
1061 "Missing brace in operand reference!");
1062 addAsmOperand(String
.substr(i
, EndPos
+ 1 - i
), IsIsolatedToken
);
1065 IsIsolatedToken
= false;
1074 if (InTok
&& Prev
!= String
.size())
1075 addAsmOperand(String
.substr(Prev
), IsIsolatedToken
);
1078 bool MatchableInfo::validate(StringRef CommentDelimiter
, bool IsAlias
) const {
1079 // Reject matchables with no .s string.
1080 if (AsmString
.empty())
1081 PrintFatalError(TheDef
->getLoc(), "instruction with empty asm string");
1083 // Reject any matchables with a newline in them, they should be marked
1084 // isCodeGenOnly if they are pseudo instructions.
1085 if (AsmString
.find('\n') != std::string::npos
)
1086 PrintFatalError(TheDef
->getLoc(),
1087 "multiline instruction is not valid for the asmparser, "
1088 "mark it isCodeGenOnly");
1090 // Remove comments from the asm string. We know that the asmstring only
1092 if (!CommentDelimiter
.empty() &&
1093 StringRef(AsmString
).contains(CommentDelimiter
))
1094 PrintFatalError(TheDef
->getLoc(),
1095 "asmstring for instruction has comment character in it, "
1096 "mark it isCodeGenOnly");
1098 // Reject matchables with operand modifiers, these aren't something we can
1099 // handle, the target should be refactored to use operands instead of
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(':'))
1111 "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("AsmMatchConverter").empty() &&
1116 Tok
[0] == '$' && !OperandNames
.insert(std::string(Tok
)).second
) {
1118 errs() << "warning: '" << TheDef
->getName() << "': "
1119 << "ignoring instruction with tied operand '" << Tok
<< "'\n";
1128 static std::string
getEnumNameForToken(StringRef Str
) {
1131 for (char C
: Str
) {
1164 Res
+= "_" + utostr((unsigned)C
) + "_";
1171 ClassInfo
*AsmMatcherInfo::getTokenClass(StringRef Token
) {
1172 ClassInfo
*&Entry
= TokenClasses
[std::string(Token
)];
1175 Classes
.emplace_front();
1176 Entry
= &Classes
.front();
1177 Entry
->Kind
= ClassInfo::Token
;
1178 Entry
->ClassName
= "Token";
1179 Entry
->Name
= "MCK_" + getEnumNameForToken(Token
);
1180 Entry
->ValueName
= std::string(Token
);
1181 Entry
->PredicateMethod
= "<invalid>";
1182 Entry
->RenderMethod
= "<invalid>";
1183 Entry
->ParserMethod
= "";
1184 Entry
->DiagnosticType
= "";
1185 Entry
->IsOptional
= false;
1186 Entry
->DefaultMethod
= "<invalid>";
1193 AsmMatcherInfo::getOperandClass(const CGIOperandList::OperandInfo
&OI
,
1195 const Record
*Rec
= OI
.Rec
;
1197 Rec
= cast
<DefInit
>(OI
.MIOperandInfo
->getArg(SubOpIdx
))->getDef();
1198 return getOperandClass(Rec
, SubOpIdx
);
1201 ClassInfo
*AsmMatcherInfo::getOperandClass(const Record
*Rec
, int SubOpIdx
) {
1202 if (Rec
->isSubClassOf("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("ParserMatchClass");
1206 if (!R
|| !R
->getValue())
1207 PrintFatalError(Rec
->getLoc(),
1208 "Record `" + Rec
->getName() +
1209 "' does not have a ParserMatchClass!\n");
1211 if (const DefInit
*DI
= dyn_cast
<DefInit
>(R
->getValue())) {
1212 const Record
*MatchClass
= DI
->getDef();
1213 if (ClassInfo
*CI
= AsmOperandClasses
[MatchClass
])
1217 // No custom match class. Just use the register class.
1218 const Record
*ClassRec
= Rec
->getValueAsDef("RegClass");
1220 PrintFatalError(Rec
->getLoc(),
1221 "RegisterOperand `" + Rec
->getName() +
1222 "' has no associated register class!\n");
1223 if (ClassInfo
*CI
= RegisterClassClasses
[ClassRec
])
1225 PrintFatalError(Rec
->getLoc(), "register class has no class info!");
1228 if (Rec
->isSubClassOf("RegisterClass")) {
1229 if (ClassInfo
*CI
= RegisterClassClasses
[Rec
])
1231 PrintFatalError(Rec
->getLoc(), "register class has no class info!");
1234 if (!Rec
->isSubClassOf("Operand"))
1235 PrintFatalError(Rec
->getLoc(),
1236 "Operand `" + Rec
->getName() +
1237 "' does not derive from class Operand!\n");
1238 const Record
*MatchClass
= Rec
->getValueAsDef("ParserMatchClass");
1239 if (ClassInfo
*CI
= AsmOperandClasses
[MatchClass
])
1242 PrintFatalError(Rec
->getLoc(), "operand has no match class!");
1245 struct 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(LHS
.begin(), LHS
.end(), RHS
.begin(),
1252 RHS
.end(), LessRecordByID());
1256 void AsmMatcherInfo::buildRegisterClasses(
1257 SmallPtrSetImpl
<const Record
*> &SingletonRegisters
) {
1258 const auto &Registers
= Target
.getRegBank().getRegisters();
1259 auto &RegClassList
= Target
.getRegBank().getRegClasses();
1261 typedef std::set
<RegisterSet
, LessRegisterSet
> RegisterSetSet
;
1263 // The register sets used for matching.
1264 RegisterSetSet RegisterSets
;
1266 // Gather the defined sets.
1267 for (const CodeGenRegisterClass
&RC
: RegClassList
)
1268 RegisterSets
.insert(
1269 RegisterSet(RC
.getOrder().begin(), RC
.getOrder().end()));
1271 // Add any required singleton sets.
1272 for (const Record
*Rec
: SingletonRegisters
) {
1273 RegisterSets
.insert(RegisterSet(&Rec
, &Rec
+ 1));
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
;
1284 for (const RegisterSet
&RS
: RegisterSets
) {
1285 if (!RS
.count(CGR
.TheDef
))
1288 if (ContainingSet
.empty()) {
1294 std::set_intersection(ContainingSet
.begin(), ContainingSet
.end(),
1295 RS
.begin(), RS
.end(),
1296 std::inserter(Tmp
, Tmp
.begin()), LessRecordByID());
1297 ContainingSet
= std::move(Tmp
);
1300 if (!ContainingSet
.empty()) {
1301 RegisterSets
.insert(ContainingSet
);
1302 RegisterMap
.insert(std::pair(CGR
.TheDef
, ContainingSet
));
1306 // Construct the register classes.
1307 std::map
<RegisterSet
, ClassInfo
*, LessRegisterSet
> RegisterSetClasses
;
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(Index
);
1314 CI
->Name
= "MCK_Reg" + utostr(Index
);
1316 CI
->PredicateMethod
= ""; // unused
1317 CI
->RenderMethod
= "addRegOperands";
1319 // FIXME: diagnostic type.
1320 CI
->DiagnosticType
= "";
1321 CI
->IsOptional
= false;
1322 CI
->DefaultMethod
= ""; // unused
1323 RegisterSetClasses
.insert(std::pair(RS
, CI
));
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
&& std::includes(RS2
.begin(), RS2
.end(), RS
.begin(),
1333 RS
.end(), LessRecordByID()))
1334 CI
->SuperClasses
.push_back(RegisterSetClasses
[RS2
]);
1337 // Name the register classes which correspond to a user defined RegisterClass.
1338 for (const CodeGenRegisterClass
&RC
: RegClassList
) {
1339 // Def will be NULL for non-user defined register classes.
1340 const Record
*Def
= RC
.getDef();
1343 ClassInfo
*CI
= RegisterSetClasses
[RegisterSet(RC
.getOrder().begin(),
1344 RC
.getOrder().end())];
1345 if (CI
->ValueName
.empty()) {
1346 CI
->ClassName
= RC
.getName();
1347 CI
->Name
= "MCK_" + RC
.getName();
1348 CI
->ValueName
= RC
.getName();
1350 CI
->ValueName
= CI
->ValueName
+ "," + RC
.getName();
1352 const Init
*DiagnosticType
= Def
->getValueInit("DiagnosticType");
1353 if (const StringInit
*SI
= dyn_cast
<StringInit
>(DiagnosticType
))
1354 CI
->DiagnosticType
= std::string(SI
->getValue());
1356 const Init
*DiagnosticString
= Def
->getValueInit("DiagnosticString");
1357 if (const StringInit
*SI
= dyn_cast
<StringInit
>(DiagnosticString
))
1358 CI
->DiagnosticString
= std::string(SI
->getValue());
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();
1365 RegisterClassClasses
.insert(std::pair(Def
, CI
));
1368 // Populate the map for individual registers.
1369 for (auto &It
: RegisterMap
)
1370 RegisterClasses
[It
.first
] = RegisterSetClasses
[It
.second
];
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!");
1377 if (CI
->ValueName
.empty()) {
1378 CI
->ClassName
= std::string(Rec
->getName());
1379 CI
->Name
= "MCK_" + Rec
->getName().str();
1380 CI
->ValueName
= std::string(Rec
->getName());
1382 CI
->ValueName
= CI
->ValueName
+ "," + Rec
->getName().str();
1386 void AsmMatcherInfo::buildOperandClasses() {
1387 ArrayRef
<const Record
*> AsmOperands
=
1388 Records
.getAllDerivedDefinitions("AsmOperandClass");
1390 // Pre-populate AsmOperandClasses map.
1391 for (const Record
*Rec
: AsmOperands
) {
1392 Classes
.emplace_front();
1393 AsmOperandClasses
[Rec
] = &Classes
.front();
1397 for (const Record
*Rec
: AsmOperands
) {
1398 ClassInfo
*CI
= AsmOperandClasses
[Rec
];
1399 CI
->Kind
= ClassInfo::UserClass0
+ Index
;
1401 const ListInit
*Supers
= Rec
->getValueAsListInit("SuperClasses");
1402 for (const Init
*I
: Supers
->getValues()) {
1403 const DefInit
*DI
= dyn_cast
<DefInit
>(I
);
1405 PrintError(Rec
->getLoc(), "Invalid super class reference!");
1409 ClassInfo
*SC
= AsmOperandClasses
[DI
->getDef()];
1411 PrintError(Rec
->getLoc(), "Invalid super class reference!");
1413 CI
->SuperClasses
.push_back(SC
);
1415 CI
->ClassName
= std::string(Rec
->getValueAsString("Name"));
1416 CI
->Name
= "MCK_" + CI
->ClassName
;
1417 CI
->ValueName
= std::string(Rec
->getName());
1419 // Get or construct the predicate method name.
1420 const Init
*PMName
= Rec
->getValueInit("PredicateMethod");
1421 if (const StringInit
*SI
= dyn_cast
<StringInit
>(PMName
)) {
1422 CI
->PredicateMethod
= std::string(SI
->getValue());
1424 assert(isa
<UnsetInit
>(PMName
) && "Unexpected PredicateMethod field!");
1425 CI
->PredicateMethod
= "is" + CI
->ClassName
;
1428 // Get or construct the render method name.
1429 const Init
*RMName
= Rec
->getValueInit("RenderMethod");
1430 if (const StringInit
*SI
= dyn_cast
<StringInit
>(RMName
)) {
1431 CI
->RenderMethod
= std::string(SI
->getValue());
1433 assert(isa
<UnsetInit
>(RMName
) && "Unexpected RenderMethod field!");
1434 CI
->RenderMethod
= "add" + CI
->ClassName
+ "Operands";
1437 // Get the parse method name or leave it as empty.
1438 const Init
*PRMName
= Rec
->getValueInit("ParserMethod");
1439 if (const StringInit
*SI
= dyn_cast
<StringInit
>(PRMName
))
1440 CI
->ParserMethod
= std::string(SI
->getValue());
1442 // Get the diagnostic type and string or leave them as empty.
1443 const Init
*DiagnosticType
= Rec
->getValueInit("DiagnosticType");
1444 if (const StringInit
*SI
= dyn_cast
<StringInit
>(DiagnosticType
))
1445 CI
->DiagnosticType
= std::string(SI
->getValue());
1446 const Init
*DiagnosticString
= Rec
->getValueInit("DiagnosticString");
1447 if (const StringInit
*SI
= dyn_cast
<StringInit
>(DiagnosticString
))
1448 CI
->DiagnosticString
= std::string(SI
->getValue());
1449 // If we have a DiagnosticString, we need a DiagnosticType for use within
1451 if (!CI
->DiagnosticString
.empty() && CI
->DiagnosticType
.empty())
1452 CI
->DiagnosticType
= CI
->ClassName
;
1454 const Init
*IsOptional
= Rec
->getValueInit("IsOptional");
1455 if (const BitInit
*BI
= dyn_cast
<BitInit
>(IsOptional
))
1456 CI
->IsOptional
= BI
->getValue();
1458 // Get or construct the default method name.
1459 const Init
*DMName
= Rec
->getValueInit("DefaultMethod");
1460 if (const StringInit
*SI
= dyn_cast
<StringInit
>(DMName
)) {
1461 CI
->DefaultMethod
= std::string(SI
->getValue());
1463 assert(isa
<UnsetInit
>(DMName
) && "Unexpected DefaultMethod field!");
1464 CI
->DefaultMethod
= "default" + CI
->ClassName
+ "Operands";
1471 AsmMatcherInfo::AsmMatcherInfo(const Record
*asmParser
,
1472 const CodeGenTarget
&target
,
1473 const RecordKeeper
&records
)
1474 : Records(records
), AsmParser(asmParser
), Target(target
) {}
1476 /// buildOperandMatchInfo - Build the necessary information to handle user
1477 /// defined operand parsing methods.
1478 void AsmMatcherInfo::buildOperandMatchInfo() {
1479 /// Map containing a mask with all operands indices that can be found for
1480 /// that class inside a instruction.
1481 typedef std::map
<ClassInfo
*, unsigned, deref
<std::less
<>>> OpClassMaskTy
;
1482 OpClassMaskTy OpClassMask
;
1484 bool CallCustomParserForAllOperands
=
1485 AsmParser
->getValueAsBit("CallCustomParserForAllOperands");
1486 for (const auto &MI
: Matchables
) {
1487 OpClassMask
.clear();
1489 // Keep track of all operands of this instructions which belong to the
1491 unsigned NumOptionalOps
= 0;
1492 for (const auto &[Idx
, Op
] : enumerate(MI
->AsmOperands
)) {
1493 if (CallCustomParserForAllOperands
|| !Op
.Class
->ParserMethod
.empty()) {
1494 unsigned &OperandMask
= OpClassMask
[Op
.Class
];
1495 OperandMask
|= maskTrailingOnes
<unsigned>(NumOptionalOps
+ 1)
1496 << (Idx
- NumOptionalOps
);
1498 if (Op
.Class
->IsOptional
)
1502 // Generate operand match info for each mnemonic/operand class pair.
1503 for (const auto [CI
, OpMask
] : OpClassMask
) {
1504 OperandMatchInfo
.push_back(
1505 OperandMatchEntry::create(MI
.get(), CI
, OpMask
));
1510 void AsmMatcherInfo::buildInfo() {
1511 // Build information about all of the AssemblerPredicates.
1512 SubtargetFeaturesInfoVec SubtargetFeaturePairs
=
1513 SubtargetFeatureInfo::getAll(Records
);
1514 SubtargetFeatures
.insert(SubtargetFeaturePairs
.begin(),
1515 SubtargetFeaturePairs
.end());
1517 for (const auto &Pair
: SubtargetFeatures
)
1518 LLVM_DEBUG(Pair
.second
.dump());
1521 bool HasMnemonicFirst
= AsmParser
->getValueAsBit("HasMnemonicFirst");
1522 bool ReportMultipleNearMisses
=
1523 AsmParser
->getValueAsBit("ReportMultipleNearMisses");
1525 // Parse the instructions; we need to do this first so that we can gather the
1526 // singleton register classes.
1527 SmallPtrSet
<const Record
*, 16> SingletonRegisters
;
1528 unsigned VariantCount
= Target
.getAsmParserVariantCount();
1529 for (unsigned VC
= 0; VC
!= VariantCount
; ++VC
) {
1530 const Record
*AsmVariant
= Target
.getAsmParserVariant(VC
);
1531 StringRef CommentDelimiter
=
1532 AsmVariant
->getValueAsString("CommentDelimiter");
1533 AsmVariantInfo Variant
;
1534 Variant
.RegisterPrefix
= AsmVariant
->getValueAsString("RegisterPrefix");
1535 Variant
.TokenizingCharacters
=
1536 AsmVariant
->getValueAsString("TokenizingCharacters");
1537 Variant
.SeparatorCharacters
=
1538 AsmVariant
->getValueAsString("SeparatorCharacters");
1539 Variant
.BreakCharacters
= AsmVariant
->getValueAsString("BreakCharacters");
1540 Variant
.Name
= AsmVariant
->getValueAsString("Name");
1541 Variant
.AsmVariantNo
= AsmVariant
->getValueAsInt("Variant");
1543 for (const CodeGenInstruction
*CGI
: Target
.getInstructionsByEnumValue()) {
1545 // If the tblgen -match-prefix option is specified (for tblgen hackers),
1546 // filter the set of instructions we consider.
1547 if (!StringRef(CGI
->TheDef
->getName()).starts_with(MatchPrefix
))
1550 // Ignore "codegen only" instructions.
1551 if (CGI
->TheDef
->getValueAsBit("isCodeGenOnly"))
1554 // Ignore instructions for different instructions
1555 StringRef V
= CGI
->TheDef
->getValueAsString("AsmVariantName");
1556 if (!V
.empty() && V
!= Variant
.Name
)
1559 auto II
= std::make_unique
<MatchableInfo
>(*CGI
);
1561 II
->initialize(*this, SingletonRegisters
, Variant
, HasMnemonicFirst
);
1563 // Ignore instructions which shouldn't be matched and diagnose invalid
1564 // instruction definitions with an error.
1565 if (!II
->validate(CommentDelimiter
, false))
1568 Matchables
.push_back(std::move(II
));
1571 // Parse all of the InstAlias definitions and stick them in the list of
1573 for (const Record
*InstAlias
:
1574 Records
.getAllDerivedDefinitions("InstAlias")) {
1575 auto Alias
= std::make_unique
<CodeGenInstAlias
>(InstAlias
, Target
);
1577 // If the tblgen -match-prefix option is specified (for tblgen hackers),
1578 // filter the set of instruction aliases we consider, based on the target
1580 if (!StringRef(Alias
->ResultInst
->TheDef
->getName())
1581 .starts_with(MatchPrefix
))
1584 StringRef V
= Alias
->TheDef
->getValueAsString("AsmVariantName");
1585 if (!V
.empty() && V
!= Variant
.Name
)
1588 auto II
= std::make_unique
<MatchableInfo
>(std::move(Alias
));
1590 II
->initialize(*this, SingletonRegisters
, Variant
, HasMnemonicFirst
);
1592 // Validate the alias definitions.
1593 II
->validate(CommentDelimiter
, true);
1595 Matchables
.push_back(std::move(II
));
1599 // Build info for the register classes.
1600 buildRegisterClasses(SingletonRegisters
);
1602 // Build info for the user defined assembly operand classes.
1603 buildOperandClasses();
1605 // Build the information about matchables, now that we have fully formed
1607 std::vector
<std::unique_ptr
<MatchableInfo
>> NewMatchables
;
1608 for (auto &II
: Matchables
) {
1609 // Parse the tokens after the mnemonic.
1610 // Note: buildInstructionOperandReference may insert new AsmOperands, so
1611 // don't precompute the loop bound, i.e., cannot use range based for loop
1613 for (size_t Idx
= 0; Idx
< II
->AsmOperands
.size(); ++Idx
) {
1614 MatchableInfo::AsmOperand
&Op
= II
->AsmOperands
[Idx
];
1615 StringRef Token
= Op
.Token
;
1616 // Check for singleton registers.
1617 if (const Record
*RegRecord
= Op
.SingletonReg
) {
1618 Op
.Class
= RegisterClasses
[RegRecord
];
1619 assert(Op
.Class
&& Op
.Class
->Registers
.size() == 1 &&
1620 "Unexpected class for singleton register");
1624 // Check for simple tokens.
1625 if (Token
[0] != '$') {
1626 Op
.Class
= getTokenClass(Token
);
1630 if (Token
.size() > 1 && isdigit(Token
[1])) {
1631 Op
.Class
= getTokenClass(Token
);
1635 // Otherwise this is an operand reference.
1636 StringRef OperandName
;
1637 if (Token
[1] == '{')
1638 OperandName
= Token
.substr(2, Token
.size() - 3);
1640 OperandName
= Token
.substr(1);
1642 if (isa
<const CodeGenInstruction
*>(II
->DefRec
))
1643 buildInstructionOperandReference(II
.get(), OperandName
, Idx
);
1645 buildAliasOperandReference(II
.get(), OperandName
, Op
);
1648 if (isa
<const CodeGenInstruction
*>(II
->DefRec
)) {
1649 II
->buildInstructionResultOperands();
1650 // If the instruction has a two-operand alias, build up the
1651 // matchable here. We'll add them in bulk at the end to avoid
1652 // confusing this loop.
1653 StringRef Constraint
=
1654 II
->TheDef
->getValueAsString("TwoOperandAliasConstraint");
1655 if (Constraint
!= "") {
1656 // Start by making a copy of the original matchable.
1657 auto AliasII
= std::make_unique
<MatchableInfo
>(*II
);
1659 // Adjust it to be a two-operand alias.
1660 AliasII
->formTwoOperandAlias(Constraint
);
1662 // Add the alias to the matchables list.
1663 NewMatchables
.push_back(std::move(AliasII
));
1666 // FIXME: The tied operands checking is not yet integrated with the
1667 // framework for reporting multiple near misses. To prevent invalid
1668 // formats from being matched with an alias if a tied-operands check
1669 // would otherwise have disallowed it, we just disallow such constructs
1670 // in TableGen completely.
1671 II
->buildAliasResultOperands(!ReportMultipleNearMisses
);
1673 if (!NewMatchables
.empty())
1674 Matchables
.insert(Matchables
.end(),
1675 std::make_move_iterator(NewMatchables
.begin()),
1676 std::make_move_iterator(NewMatchables
.end()));
1678 // Process token alias definitions and set up the associated superclass
1680 for (const Record
*Rec
: Records
.getAllDerivedDefinitions("TokenAlias")) {
1681 ClassInfo
*FromClass
= getTokenClass(Rec
->getValueAsString("FromToken"));
1682 ClassInfo
*ToClass
= getTokenClass(Rec
->getValueAsString("ToToken"));
1683 if (FromClass
== ToClass
)
1684 PrintFatalError(Rec
->getLoc(),
1685 "error: Destination value identical to source value.");
1686 FromClass
->SuperClasses
.push_back(ToClass
);
1689 // Reorder classes so that classes precede super classes.
1692 #ifdef EXPENSIVE_CHECKS
1693 // Verify that the table is sorted and operator < works transitively.
1694 for (auto I
= Classes
.begin(), E
= Classes
.end(); I
!= E
; ++I
) {
1695 for (auto J
= I
; J
!= E
; ++J
) {
1697 assert(I
== J
|| !J
->isSubsetOf(*I
));
1703 /// buildInstructionOperandReference - The specified operand is a reference to a
1704 /// named operand such as $src. Resolve the Class and OperandInfo pointers.
1705 void AsmMatcherInfo::buildInstructionOperandReference(MatchableInfo
*II
,
1706 StringRef OperandName
,
1707 unsigned AsmOpIdx
) {
1708 const CodeGenInstruction
&CGI
= *cast
<const CodeGenInstruction
*>(II
->DefRec
);
1709 const CGIOperandList
&Operands
= CGI
.Operands
;
1710 MatchableInfo::AsmOperand
*Op
= &II
->AsmOperands
[AsmOpIdx
];
1712 // Map this token to an operand.
1714 if (!Operands
.hasOperandNamed(OperandName
, Idx
))
1715 PrintFatalError(II
->TheDef
->getLoc(),
1716 "error: unable to find operand: '" + OperandName
+ "'");
1718 // If the instruction operand has multiple suboperands, but the parser
1719 // match class for the asm operand is still the default "ImmAsmOperand",
1720 // then handle each suboperand separately.
1721 if (Op
->SubOpIdx
== -1 && Operands
[Idx
].MINumOperands
> 1) {
1722 const Record
*Rec
= Operands
[Idx
].Rec
;
1723 assert(Rec
->isSubClassOf("Operand") && "Unexpected operand!");
1724 const Record
*MatchClass
= Rec
->getValueAsDef("ParserMatchClass");
1725 if (MatchClass
&& MatchClass
->getValueAsString("Name") == "Imm") {
1726 // Insert remaining suboperands after AsmOpIdx in II->AsmOperands.
1727 StringRef Token
= Op
->Token
; // save this in case Op gets moved
1728 for (unsigned SI
= 1, SE
= Operands
[Idx
].MINumOperands
; SI
!= SE
; ++SI
) {
1729 MatchableInfo::AsmOperand
NewAsmOp(/*IsIsolatedToken=*/true, Token
);
1730 NewAsmOp
.SubOpIdx
= SI
;
1731 II
->AsmOperands
.insert(II
->AsmOperands
.begin() + AsmOpIdx
+ SI
,
1734 // Replace Op with first suboperand.
1735 Op
= &II
->AsmOperands
[AsmOpIdx
]; // update the pointer in case it moved
1740 // Set up the operand class.
1741 Op
->Class
= getOperandClass(Operands
[Idx
], Op
->SubOpIdx
);
1742 Op
->OrigSrcOpName
= OperandName
;
1744 // If the named operand is tied, canonicalize it to the untied operand.
1745 // For example, something like:
1746 // (outs GPR:$dst), (ins GPR:$src)
1747 // with an asmstring of
1749 // we want to canonicalize to:
1751 // so that we know how to provide the $dst operand when filling in the result.
1753 if (Operands
[Idx
].MINumOperands
== 1)
1754 OITied
= Operands
[Idx
].getTiedRegister();
1756 // The tied operand index is an MIOperand index, find the operand that
1758 std::pair
<unsigned, unsigned> Idx
= Operands
.getSubOperandNumber(OITied
);
1759 OperandName
= Operands
[Idx
.first
].Name
;
1760 Op
->SubOpIdx
= Idx
.second
;
1763 Op
->SrcOpName
= OperandName
;
1766 /// buildAliasOperandReference - When parsing an operand reference out of the
1767 /// matching string (e.g. "movsx $src, $dst"), determine what the class of the
1768 /// operand reference is by looking it up in the result pattern definition.
1769 void AsmMatcherInfo::buildAliasOperandReference(MatchableInfo
*II
,
1770 StringRef OperandName
,
1771 MatchableInfo::AsmOperand
&Op
) {
1772 const CodeGenInstAlias
&CGA
= *cast
<const CodeGenInstAlias
*>(II
->DefRec
);
1774 // Set up the operand class.
1775 for (const auto &[ResultOp
, SubOpIdx
] :
1776 zip_equal(CGA
.ResultOperands
, CGA
.ResultInstOperandIndex
)) {
1777 if (ResultOp
.isRecord() && ResultOp
.getName() == OperandName
) {
1778 // It's safe to go with the first one we find, because CodeGenInstAlias
1779 // validates that all operands with the same name have the same record.
1780 Op
.SubOpIdx
= SubOpIdx
.second
;
1781 // Use the match class from the Alias definition, not the
1782 // destination instruction, as we may have an immediate that's
1783 // being munged by the match class.
1784 Op
.Class
= getOperandClass(ResultOp
.getRecord(), Op
.SubOpIdx
);
1785 Op
.SrcOpName
= OperandName
;
1786 Op
.OrigSrcOpName
= OperandName
;
1791 PrintFatalError(II
->TheDef
->getLoc(),
1792 "error: unable to find operand: '" + OperandName
+ "'");
1795 void MatchableInfo::buildInstructionResultOperands() {
1796 const CodeGenInstruction
*ResultInst
= getResultInst();
1798 // Loop over all operands of the result instruction, determining how to
1800 for (const CGIOperandList::OperandInfo
&OpInfo
: ResultInst
->Operands
) {
1801 // If this is a tied operand, just copy from the previously handled operand.
1803 if (OpInfo
.MINumOperands
== 1)
1804 TiedOp
= OpInfo
.getTiedRegister();
1806 int TiedSrcOperand
= findAsmOperandOriginallyNamed(OpInfo
.Name
);
1807 if (TiedSrcOperand
!= -1 &&
1808 ResOperands
[TiedOp
].Kind
== ResOperand::RenderAsmOperand
)
1809 ResOperands
.push_back(ResOperand::getTiedOp(
1810 TiedOp
, ResOperands
[TiedOp
].AsmOperandNum
, TiedSrcOperand
));
1812 ResOperands
.push_back(ResOperand::getTiedOp(TiedOp
, 0, 0));
1816 int SrcOperand
= findAsmOperandNamed(OpInfo
.Name
);
1817 if (OpInfo
.Name
.empty() || SrcOperand
== -1) {
1818 // This may happen for operands that are tied to a suboperand of a
1819 // complex operand. Simply use a dummy value here; nobody should
1820 // use this operand slot.
1821 // FIXME: The long term goal is for the MCOperand list to not contain
1822 // tied operands at all.
1823 ResOperands
.push_back(ResOperand::getImmOp(0));
1827 // Check if the one AsmOperand populates the entire operand.
1828 unsigned NumOperands
= OpInfo
.MINumOperands
;
1829 if (AsmOperands
[SrcOperand
].SubOpIdx
== -1) {
1830 ResOperands
.push_back(ResOperand::getRenderedOp(SrcOperand
, NumOperands
));
1834 // Add a separate ResOperand for each suboperand.
1835 for (unsigned AI
= 0; AI
< NumOperands
; ++AI
) {
1836 assert(AsmOperands
[SrcOperand
+ AI
].SubOpIdx
== (int)AI
&&
1837 AsmOperands
[SrcOperand
+ AI
].SrcOpName
== OpInfo
.Name
&&
1838 "unexpected AsmOperands for suboperands");
1839 ResOperands
.push_back(ResOperand::getRenderedOp(SrcOperand
+ AI
, 1));
1844 void MatchableInfo::buildAliasResultOperands(bool AliasConstraintsAreChecked
) {
1845 const CodeGenInstAlias
&CGA
= *cast
<const CodeGenInstAlias
*>(DefRec
);
1846 const CodeGenInstruction
*ResultInst
= getResultInst();
1848 // Map of: $reg -> #lastref
1849 // where $reg is the name of the operand in the asm string
1850 // where #lastref is the last processed index where $reg was referenced in
1852 SmallDenseMap
<StringRef
, int> OperandRefs
;
1854 // Loop over all operands of the result instruction, determining how to
1856 unsigned AliasOpNo
= 0;
1857 unsigned LastOpNo
= CGA
.ResultInstOperandIndex
.size();
1858 for (const auto &[Idx
, OpInfo
] : enumerate(ResultInst
->Operands
)) {
1859 // If this is a tied operand, just copy from the previously handled operand.
1861 if (OpInfo
.MINumOperands
== 1)
1862 TiedOp
= OpInfo
.getTiedRegister();
1864 unsigned SrcOp1
= 0;
1865 unsigned SrcOp2
= 0;
1867 // If an operand has been specified twice in the asm string,
1868 // add the two source operand's indices to the TiedOp so that
1869 // at runtime the 'tied' constraint is checked.
1870 if (ResOperands
[TiedOp
].Kind
== ResOperand::RenderAsmOperand
) {
1871 SrcOp1
= ResOperands
[TiedOp
].AsmOperandNum
;
1873 // Find the next operand (similarly named operand) in the string.
1874 StringRef Name
= AsmOperands
[SrcOp1
].SrcOpName
;
1875 auto Insert
= OperandRefs
.try_emplace(Name
, SrcOp1
);
1876 SrcOp2
= findAsmOperandNamed(Name
, Insert
.first
->second
);
1878 // Not updating the record in OperandRefs will cause TableGen
1879 // to fail with an error at the end of this function.
1880 if (AliasConstraintsAreChecked
)
1881 Insert
.first
->second
= SrcOp2
;
1883 // In case it only has one reference in the asm string,
1884 // it doesn't need to be checked for tied constraints.
1885 SrcOp2
= (SrcOp2
== (unsigned)-1) ? SrcOp1
: SrcOp2
;
1888 // If the alias operand is of a different operand class, we only want
1889 // to benefit from the tied-operands check and just match the operand
1890 // as a normal, but not copy the original (TiedOp) to the result
1891 // instruction. We do this by passing -1 as the tied operand to copy.
1892 if (OpInfo
.Rec
->getName() !=
1893 ResultInst
->Operands
[TiedOp
].Rec
->getName()) {
1894 SrcOp1
= ResOperands
[TiedOp
].AsmOperandNum
;
1895 int SubIdx
= CGA
.ResultInstOperandIndex
[AliasOpNo
].second
;
1896 StringRef Name
= CGA
.ResultOperands
[AliasOpNo
].getName();
1897 SrcOp2
= findAsmOperand(Name
, SubIdx
);
1898 ResOperands
.push_back(
1899 ResOperand::getTiedOp((unsigned)-1, SrcOp1
, SrcOp2
));
1901 ResOperands
.push_back(ResOperand::getTiedOp(TiedOp
, SrcOp1
, SrcOp2
));
1906 // Handle all the suboperands for this operand.
1907 const std::string
&OpName
= OpInfo
.Name
;
1908 for (; AliasOpNo
< LastOpNo
&&
1909 CGA
.ResultInstOperandIndex
[AliasOpNo
].first
== Idx
;
1911 int SubIdx
= CGA
.ResultInstOperandIndex
[AliasOpNo
].second
;
1913 // Find out what operand from the asmparser that this MCInst operand
1915 switch (CGA
.ResultOperands
[AliasOpNo
].Kind
) {
1916 case CodeGenInstAlias::ResultOperand::K_Record
: {
1917 StringRef Name
= CGA
.ResultOperands
[AliasOpNo
].getName();
1918 int SrcOperand
= findAsmOperand(Name
, SubIdx
);
1919 if (SrcOperand
== -1)
1920 PrintFatalError(TheDef
->getLoc(),
1921 "Instruction '" + TheDef
->getName() +
1922 "' has operand '" + OpName
+
1923 "' that doesn't appear in asm string!");
1925 // Add it to the operand references. If it is added a second time, the
1926 // record won't be updated and it will fail later on.
1927 OperandRefs
.try_emplace(Name
, SrcOperand
);
1929 unsigned NumOperands
= (SubIdx
== -1 ? OpInfo
.MINumOperands
: 1);
1930 ResOperands
.push_back(
1931 ResOperand::getRenderedOp(SrcOperand
, NumOperands
));
1934 case CodeGenInstAlias::ResultOperand::K_Imm
: {
1935 int64_t ImmVal
= CGA
.ResultOperands
[AliasOpNo
].getImm();
1936 ResOperands
.push_back(ResOperand::getImmOp(ImmVal
));
1939 case CodeGenInstAlias::ResultOperand::K_Reg
: {
1940 const Record
*Reg
= CGA
.ResultOperands
[AliasOpNo
].getRegister();
1941 ResOperands
.push_back(ResOperand::getRegOp(Reg
));
1948 // Check that operands are not repeated more times than is supported.
1949 for (auto &T
: OperandRefs
) {
1950 if (T
.second
!= -1 && findAsmOperandNamed(T
.first
, T
.second
) != -1)
1951 PrintFatalError(TheDef
->getLoc(),
1952 "Operand '" + T
.first
+ "' can never be matched");
1957 getConverterOperandID(const std::string
&Name
,
1958 SmallSetVector
<CachedHashString
, 16> &Table
,
1960 IsNew
= Table
.insert(CachedHashString(Name
));
1962 unsigned ID
= IsNew
? Table
.size() - 1 : find(Table
, Name
) - Table
.begin();
1964 assert(ID
< Table
.size());
1970 emitConvertFuncs(CodeGenTarget
&Target
, StringRef ClassName
,
1971 std::vector
<std::unique_ptr
<MatchableInfo
>> &Infos
,
1972 bool HasMnemonicFirst
, bool HasOptionalOperands
,
1974 SmallSetVector
<CachedHashString
, 16> OperandConversionKinds
;
1975 SmallSetVector
<CachedHashString
, 16> InstructionConversionKinds
;
1976 std::vector
<std::vector
<uint8_t>> ConversionTable
;
1977 size_t MaxRowLength
= 2; // minimum is custom converter plus terminator.
1979 // TargetOperandClass - This is the target's operand class, like X86Operand.
1980 std::string TargetOperandClass
= Target
.getName().str() + "Operand";
1982 // Write the convert function to a separate stream, so we can drop it after
1983 // the enum. We'll build up the conversion handlers for the individual
1984 // operand types opportunistically as we encounter them.
1985 std::string ConvertFnBody
;
1986 raw_string_ostream
CvtOS(ConvertFnBody
);
1987 // Start the unified conversion function.
1988 if (HasOptionalOperands
) {
1989 CvtOS
<< "void " << Target
.getName() << ClassName
<< "::\n"
1990 << "convertToMCInst(unsigned Kind, MCInst &Inst, "
1991 << "unsigned Opcode,\n"
1992 << " const OperandVector &Operands,\n"
1993 << " const SmallBitVector &OptionalOperandsMask,\n"
1994 << " ArrayRef<unsigned> DefaultsOffset) {\n";
1996 CvtOS
<< "void " << Target
.getName() << ClassName
<< "::\n"
1997 << "convertToMCInst(unsigned Kind, MCInst &Inst, "
1998 << "unsigned Opcode,\n"
1999 << " const OperandVector &Operands) {\n";
2001 CvtOS
<< " assert(Kind < CVT_NUM_SIGNATURES && \"Invalid signature!\");\n";
2002 CvtOS
<< " const uint8_t *Converter = ConversionTable[Kind];\n";
2003 CvtOS
<< " Inst.setOpcode(Opcode);\n";
2004 CvtOS
<< " for (const uint8_t *p = Converter; *p; p += 2) {\n";
2005 if (HasOptionalOperands
) {
2006 // When optional operands are involved, formal and actual operand indices
2007 // may differ. Map the former to the latter by subtracting the number of
2008 // absent optional operands.
2009 // FIXME: This is not an operand index in the CVT_Tied case
2010 CvtOS
<< " unsigned OpIdx = *(p + 1) - DefaultsOffset[*(p + 1)];\n";
2012 CvtOS
<< " unsigned OpIdx = *(p + 1);\n";
2014 CvtOS
<< " switch (*p) {\n";
2015 CvtOS
<< " default: llvm_unreachable(\"invalid conversion entry!\");\n";
2016 CvtOS
<< " case CVT_Reg:\n";
2017 CvtOS
<< " static_cast<" << TargetOperandClass
2018 << " &>(*Operands[OpIdx]).addRegOperands(Inst, 1);\n";
2019 CvtOS
<< " break;\n";
2020 CvtOS
<< " case CVT_Tied: {\n";
2021 CvtOS
<< " assert(*(p + 1) < (size_t)(std::end(TiedAsmOperandTable) -\n";
2023 << " std::begin(TiedAsmOperandTable)) &&\n";
2024 CvtOS
<< " \"Tied operand not found\");\n";
2025 CvtOS
<< " unsigned TiedResOpnd = TiedAsmOperandTable[*(p + 1)][0];\n";
2026 CvtOS
<< " if (TiedResOpnd != (uint8_t)-1)\n";
2027 CvtOS
<< " Inst.addOperand(Inst.getOperand(TiedResOpnd));\n";
2028 CvtOS
<< " break;\n";
2031 std::string OperandFnBody
;
2032 raw_string_ostream
OpOS(OperandFnBody
);
2033 // Start the operand number lookup function.
2034 OpOS
<< "void " << Target
.getName() << ClassName
<< "::\n"
2035 << "convertToMapAndConstraints(unsigned Kind,\n";
2037 OpOS
<< "const OperandVector &Operands) {\n"
2038 << " assert(Kind < CVT_NUM_SIGNATURES && \"Invalid signature!\");\n"
2039 << " unsigned NumMCOperands = 0;\n"
2040 << " const uint8_t *Converter = ConversionTable[Kind];\n"
2041 << " for (const uint8_t *p = Converter; *p; p += 2) {\n"
2042 << " switch (*p) {\n"
2043 << " default: llvm_unreachable(\"invalid conversion entry!\");\n"
2044 << " case CVT_Reg:\n"
2045 << " Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);\n"
2046 << " Operands[*(p + 1)]->setConstraint(\"r\");\n"
2047 << " ++NumMCOperands;\n"
2049 << " case CVT_Tied:\n"
2050 << " ++NumMCOperands;\n"
2053 // Pre-populate the operand conversion kinds with the standard always
2054 // available entries.
2055 OperandConversionKinds
.insert(CachedHashString("CVT_Done"));
2056 OperandConversionKinds
.insert(CachedHashString("CVT_Reg"));
2057 OperandConversionKinds
.insert(CachedHashString("CVT_Tied"));
2058 enum { CVT_Done
, CVT_Reg
, CVT_Tied
};
2060 // Map of e.g. <0, 2, 3> -> "Tie_0_2_3" enum label.
2061 std::map
<std::tuple
<uint8_t, uint8_t, uint8_t>, std::string
>
2062 TiedOperandsEnumMap
;
2064 for (auto &II
: Infos
) {
2065 // Check if we have a custom match function.
2066 StringRef AsmMatchConverter
=
2067 II
->getResultInst()->TheDef
->getValueAsString("AsmMatchConverter");
2068 if (!AsmMatchConverter
.empty() && II
->UseInstAsmMatchConverter
) {
2069 std::string Signature
= ("ConvertCustom_" + AsmMatchConverter
).str();
2070 II
->ConversionFnKind
= Signature
;
2072 // Check if we have already generated this signature.
2073 if (!InstructionConversionKinds
.insert(CachedHashString(Signature
)))
2076 // Remember this converter for the kind enum.
2077 unsigned KindID
= OperandConversionKinds
.size();
2078 OperandConversionKinds
.insert(
2079 CachedHashString("CVT_" + getEnumNameForToken(AsmMatchConverter
)));
2081 // Add the converter row for this instruction.
2082 ConversionTable
.emplace_back();
2083 ConversionTable
.back().push_back(KindID
);
2084 ConversionTable
.back().push_back(CVT_Done
);
2086 // Add the handler to the conversion driver function.
2087 CvtOS
<< " case CVT_" << getEnumNameForToken(AsmMatchConverter
)
2089 << " " << AsmMatchConverter
<< "(Inst, Operands);\n"
2092 // FIXME: Handle the operand number lookup for custom match functions.
2096 // Build the conversion function signature.
2097 std::string Signature
= "Convert";
2099 std::vector
<uint8_t> ConversionRow
;
2101 // Compute the convert enum and the case body.
2102 MaxRowLength
= std::max(MaxRowLength
, II
->ResOperands
.size() * 2 + 1);
2104 for (const auto &[Idx
, OpInfo
] : enumerate(II
->ResOperands
)) {
2105 // Generate code to populate each result operand.
2106 switch (OpInfo
.Kind
) {
2107 case MatchableInfo::ResOperand::RenderAsmOperand
: {
2108 // This comes from something we parsed.
2109 const MatchableInfo::AsmOperand
&Op
=
2110 II
->AsmOperands
[OpInfo
.AsmOperandNum
];
2112 // Registers are always converted the same, don't duplicate the
2113 // conversion function based on them.
2116 Class
= Op
.Class
->isRegisterClass() ? "Reg" : Op
.Class
->ClassName
;
2118 Signature
+= utostr(OpInfo
.MINumOperands
);
2119 Signature
+= "_" + itostr(OpInfo
.AsmOperandNum
);
2121 // Add the conversion kind, if necessary, and get the associated ID
2122 // the index of its entry in the vector).
2125 (Op
.Class
->isRegisterClass() ? "Reg" : Op
.Class
->RenderMethod
);
2126 if (Op
.Class
->IsOptional
) {
2127 // For optional operands we must also care about DefaultMethod
2128 assert(HasOptionalOperands
);
2129 Name
+= "_" + Op
.Class
->DefaultMethod
;
2131 Name
= getEnumNameForToken(Name
);
2133 bool IsNewConverter
= false;
2135 getConverterOperandID(Name
, OperandConversionKinds
, IsNewConverter
);
2137 // Add the operand entry to the instruction kind conversion row.
2138 ConversionRow
.push_back(ID
);
2139 ConversionRow
.push_back(OpInfo
.AsmOperandNum
+ HasMnemonicFirst
);
2141 if (!IsNewConverter
)
2144 // This is a new operand kind. Add a handler for it to the
2145 // converter driver.
2146 CvtOS
<< " case " << Name
<< ":\n";
2147 if (Op
.Class
->IsOptional
) {
2148 // If optional operand is not present in actual instruction then we
2149 // should call its DefaultMethod before RenderMethod
2150 assert(HasOptionalOperands
);
2151 CvtOS
<< " if (OptionalOperandsMask[*(p + 1) - 1]) {\n"
2152 << " " << Op
.Class
->DefaultMethod
<< "()"
2153 << "->" << Op
.Class
->RenderMethod
<< "(Inst, "
2154 << OpInfo
.MINumOperands
<< ");\n"
2156 << " static_cast<" << TargetOperandClass
2157 << " &>(*Operands[OpIdx])." << Op
.Class
->RenderMethod
2158 << "(Inst, " << OpInfo
.MINumOperands
<< ");\n"
2161 CvtOS
<< " static_cast<" << TargetOperandClass
2162 << " &>(*Operands[OpIdx])." << Op
.Class
->RenderMethod
2163 << "(Inst, " << OpInfo
.MINumOperands
<< ");\n";
2165 CvtOS
<< " break;\n";
2167 // Add a handler for the operand number lookup.
2168 OpOS
<< " case " << Name
<< ":\n"
2169 << " Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);\n";
2171 if (Op
.Class
->isRegisterClass())
2172 OpOS
<< " Operands[*(p + 1)]->setConstraint(\"r\");\n";
2174 OpOS
<< " Operands[*(p + 1)]->setConstraint(\"m\");\n";
2175 OpOS
<< " NumMCOperands += " << OpInfo
.MINumOperands
<< ";\n"
2179 case MatchableInfo::ResOperand::TiedOperand
: {
2180 // If this operand is tied to a previous one, just copy the MCInst
2181 // operand from the earlier one.We can only tie single MCOperand values.
2182 assert(OpInfo
.MINumOperands
== 1 && "Not a singular MCOperand");
2183 uint8_t TiedOp
= OpInfo
.TiedOperands
.ResOpnd
;
2184 uint8_t SrcOp1
= OpInfo
.TiedOperands
.SrcOpnd1Idx
+ HasMnemonicFirst
;
2185 uint8_t SrcOp2
= OpInfo
.TiedOperands
.SrcOpnd2Idx
+ HasMnemonicFirst
;
2186 assert((Idx
> TiedOp
|| TiedOp
== (uint8_t)-1) &&
2187 "Tied operand precedes its target!");
2188 auto TiedTupleName
= std::string("Tie") + utostr(TiedOp
) + '_' +
2189 utostr(SrcOp1
) + '_' + utostr(SrcOp2
);
2190 Signature
+= "__" + TiedTupleName
;
2191 ConversionRow
.push_back(CVT_Tied
);
2192 ConversionRow
.push_back(TiedOp
);
2193 ConversionRow
.push_back(SrcOp1
);
2194 ConversionRow
.push_back(SrcOp2
);
2196 // Also create an 'enum' for this combination of tied operands.
2197 auto Key
= std::tuple(TiedOp
, SrcOp1
, SrcOp2
);
2198 TiedOperandsEnumMap
.emplace(Key
, TiedTupleName
);
2201 case MatchableInfo::ResOperand::ImmOperand
: {
2202 int64_t Val
= OpInfo
.ImmVal
;
2203 std::string Ty
= "imm_" + itostr(Val
);
2204 Ty
= getEnumNameForToken(Ty
);
2205 Signature
+= "__" + Ty
;
2207 std::string Name
= "CVT_" + Ty
;
2208 bool IsNewConverter
= false;
2210 getConverterOperandID(Name
, OperandConversionKinds
, IsNewConverter
);
2211 // Add the operand entry to the instruction kind conversion row.
2212 ConversionRow
.push_back(ID
);
2213 ConversionRow
.push_back(0);
2215 if (!IsNewConverter
)
2218 CvtOS
<< " case " << Name
<< ":\n"
2219 << " Inst.addOperand(MCOperand::createImm(" << Val
<< "));\n"
2222 OpOS
<< " case " << Name
<< ":\n"
2223 << " Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);\n"
2224 << " Operands[*(p + 1)]->setConstraint(\"\");\n"
2225 << " ++NumMCOperands;\n"
2229 case MatchableInfo::ResOperand::RegOperand
: {
2230 std::string Reg
, Name
;
2231 if (!OpInfo
.Register
) {
2235 Reg
= getQualifiedName(OpInfo
.Register
);
2236 Name
= "reg" + OpInfo
.Register
->getName().str();
2238 Signature
+= "__" + Name
;
2239 Name
= "CVT_" + Name
;
2240 bool IsNewConverter
= false;
2242 getConverterOperandID(Name
, OperandConversionKinds
, IsNewConverter
);
2243 // Add the operand entry to the instruction kind conversion row.
2244 ConversionRow
.push_back(ID
);
2245 ConversionRow
.push_back(0);
2247 if (!IsNewConverter
)
2249 CvtOS
<< " case " << Name
<< ":\n"
2250 << " Inst.addOperand(MCOperand::createReg(" << Reg
<< "));\n"
2253 OpOS
<< " case " << Name
<< ":\n"
2254 << " Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);\n"
2255 << " Operands[*(p + 1)]->setConstraint(\"m\");\n"
2256 << " ++NumMCOperands;\n"
2262 // If there were no operands, add to the signature to that effect
2263 if (Signature
== "Convert")
2264 Signature
+= "_NoOperands";
2266 II
->ConversionFnKind
= Signature
;
2268 // Save the signature. If we already have it, don't add a new row
2270 if (!InstructionConversionKinds
.insert(CachedHashString(Signature
)))
2273 // Add the row to the table.
2274 ConversionTable
.push_back(std::move(ConversionRow
));
2277 // Finish up the converter driver function.
2278 CvtOS
<< " }\n }\n}\n\n";
2280 // Finish up the operand number lookup function.
2281 OpOS
<< " }\n }\n}\n\n";
2283 // Output a static table for tied operands.
2284 if (TiedOperandsEnumMap
.size()) {
2285 // The number of tied operand combinations will be small in practice,
2286 // but just add the assert to be sure.
2287 assert(TiedOperandsEnumMap
.size() <= 254 &&
2288 "Too many tied-operand combinations to reference with "
2289 "an 8bit offset from the conversion table, where index "
2290 "'255' is reserved as operand not to be copied.");
2293 for (auto &KV
: TiedOperandsEnumMap
) {
2294 OS
<< " " << KV
.second
<< ",\n";
2298 OS
<< "static const uint8_t TiedAsmOperandTable[][3] = {\n";
2299 for (auto &KV
: TiedOperandsEnumMap
) {
2300 OS
<< " /* " << KV
.second
<< " */ { " << utostr(std::get
<0>(KV
.first
))
2301 << ", " << utostr(std::get
<1>(KV
.first
)) << ", "
2302 << utostr(std::get
<2>(KV
.first
)) << " },\n";
2306 OS
<< "static const uint8_t TiedAsmOperandTable[][3] = "
2307 "{ /* empty */ {0, 0, 0} };\n\n";
2309 OS
<< "namespace {\n";
2311 // Output the operand conversion kind enum.
2312 OS
<< "enum OperatorConversionKind {\n";
2313 for (const auto &Converter
: OperandConversionKinds
)
2314 OS
<< " " << Converter
<< ",\n";
2315 OS
<< " CVT_NUM_CONVERTERS\n";
2318 // Output the instruction conversion kind enum.
2319 OS
<< "enum InstructionConversionKind {\n";
2320 for (const auto &Signature
: InstructionConversionKinds
)
2321 OS
<< " " << Signature
<< ",\n";
2322 OS
<< " CVT_NUM_SIGNATURES\n";
2325 OS
<< "} // end anonymous namespace\n\n";
2327 // Output the conversion table.
2328 OS
<< "static const uint8_t ConversionTable[CVT_NUM_SIGNATURES]["
2329 << MaxRowLength
<< "] = {\n";
2331 for (unsigned Row
= 0, ERow
= ConversionTable
.size(); Row
!= ERow
; ++Row
) {
2332 assert(ConversionTable
[Row
].size() % 2 == 0 && "bad conversion row!");
2333 OS
<< " // " << InstructionConversionKinds
[Row
] << "\n";
2335 for (unsigned i
= 0, e
= ConversionTable
[Row
].size(); i
!= e
; i
+= 2) {
2336 OS
<< OperandConversionKinds
[ConversionTable
[Row
][i
]] << ", ";
2337 if (OperandConversionKinds
[ConversionTable
[Row
][i
]] !=
2338 CachedHashString("CVT_Tied")) {
2339 OS
<< (unsigned)(ConversionTable
[Row
][i
+ 1]) << ", ";
2343 // For a tied operand, emit a reference to the TiedAsmOperandTable
2344 // that contains the operand to copy, and the parsed operands to
2345 // check for their tied constraints.
2346 auto Key
= std::tuple((uint8_t)ConversionTable
[Row
][i
+ 1],
2347 (uint8_t)ConversionTable
[Row
][i
+ 2],
2348 (uint8_t)ConversionTable
[Row
][i
+ 3]);
2349 auto TiedOpndEnum
= TiedOperandsEnumMap
.find(Key
);
2350 assert(TiedOpndEnum
!= TiedOperandsEnumMap
.end() &&
2351 "No record for tied operand pair");
2352 OS
<< TiedOpndEnum
->second
<< ", ";
2355 OS
<< "CVT_Done },\n";
2360 // Spit out the conversion driver function.
2361 OS
<< ConvertFnBody
;
2363 // Spit out the operand number lookup function.
2364 OS
<< OperandFnBody
;
2366 return ConversionTable
.size();
2369 /// emitMatchClassEnumeration - Emit the enumeration for match class kinds.
2370 static void emitMatchClassEnumeration(CodeGenTarget
&Target
,
2371 std::forward_list
<ClassInfo
> &Infos
,
2373 OS
<< "namespace {\n\n";
2375 OS
<< "/// MatchClassKind - The kinds of classes which participate in\n"
2376 << "/// instruction matching.\n";
2377 OS
<< "enum MatchClassKind {\n";
2378 OS
<< " InvalidMatchClass = 0,\n";
2379 OS
<< " OptionalMatchClass = 1,\n";
2380 ClassInfo::ClassInfoKind LastKind
= ClassInfo::Token
;
2381 StringRef LastName
= "OptionalMatchClass";
2382 for (const auto &CI
: Infos
) {
2383 if (LastKind
== ClassInfo::Token
&& CI
.Kind
!= ClassInfo::Token
) {
2384 OS
<< " MCK_LAST_TOKEN = " << LastName
<< ",\n";
2385 } else if (LastKind
< ClassInfo::UserClass0
&&
2386 CI
.Kind
>= ClassInfo::UserClass0
) {
2387 OS
<< " MCK_LAST_REGISTER = " << LastName
<< ",\n";
2389 LastKind
= (ClassInfo::ClassInfoKind
)CI
.Kind
;
2392 OS
<< " " << CI
.Name
<< ", // ";
2393 if (CI
.Kind
== ClassInfo::Token
) {
2394 OS
<< "'" << CI
.ValueName
<< "'\n";
2395 } else if (CI
.isRegisterClass()) {
2396 if (!CI
.ValueName
.empty())
2397 OS
<< "register class '" << CI
.ValueName
<< "'\n";
2399 OS
<< "derived register class\n";
2401 OS
<< "user defined class '" << CI
.ValueName
<< "'\n";
2404 OS
<< " NumMatchClassKinds\n";
2407 OS
<< "} // end anonymous namespace\n\n";
2410 /// emitMatchClassDiagStrings - Emit a function to get the diagnostic text to be
2411 /// used when an assembly operand does not match the expected operand class.
2412 static void emitOperandMatchErrorDiagStrings(AsmMatcherInfo
&Info
,
2414 // If the target does not use DiagnosticString for any operands, don't emit
2415 // an unused function.
2416 if (llvm::all_of(Info
.Classes
, [](const ClassInfo
&CI
) {
2417 return CI
.DiagnosticString
.empty();
2421 OS
<< "static const char *getMatchKindDiag(" << Info
.Target
.getName()
2422 << "AsmParser::" << Info
.Target
.getName()
2423 << "MatchResultTy MatchResult) {\n";
2424 OS
<< " switch (MatchResult) {\n";
2426 for (const auto &CI
: Info
.Classes
) {
2427 if (!CI
.DiagnosticString
.empty()) {
2428 assert(!CI
.DiagnosticType
.empty() &&
2429 "DiagnosticString set without DiagnosticType");
2430 OS
<< " case " << Info
.Target
.getName() << "AsmParser::Match_"
2431 << CI
.DiagnosticType
<< ":\n";
2432 OS
<< " return \"" << CI
.DiagnosticString
<< "\";\n";
2436 OS
<< " default:\n";
2437 OS
<< " return nullptr;\n";
2443 static void emitRegisterMatchErrorFunc(AsmMatcherInfo
&Info
, raw_ostream
&OS
) {
2444 OS
<< "static unsigned getDiagKindFromRegisterClass(MatchClassKind "
2445 "RegisterClass) {\n";
2446 if (none_of(Info
.Classes
, [](const ClassInfo
&CI
) {
2447 return CI
.isRegisterClass() && !CI
.DiagnosticType
.empty();
2449 OS
<< " return MCTargetAsmParser::Match_InvalidOperand;\n";
2451 OS
<< " switch (RegisterClass) {\n";
2452 for (const auto &CI
: Info
.Classes
) {
2453 if (CI
.isRegisterClass() && !CI
.DiagnosticType
.empty()) {
2454 OS
<< " case " << CI
.Name
<< ":\n";
2455 OS
<< " return " << Info
.Target
.getName() << "AsmParser::Match_"
2456 << CI
.DiagnosticType
<< ";\n";
2460 OS
<< " default:\n";
2461 OS
<< " return MCTargetAsmParser::Match_InvalidOperand;\n";
2468 /// emitValidateOperandClass - Emit the function to validate an operand class.
2469 static void emitValidateOperandClass(const CodeGenTarget
&Target
,
2470 AsmMatcherInfo
&Info
, raw_ostream
&OS
) {
2471 OS
<< "static unsigned validateOperandClass(MCParsedAsmOperand &GOp, "
2472 << "MatchClassKind Kind) {\n";
2473 OS
<< " " << Info
.Target
.getName() << "Operand &Operand = ("
2474 << Info
.Target
.getName() << "Operand &)GOp;\n";
2476 // The InvalidMatchClass is not to match any operand.
2477 OS
<< " if (Kind == InvalidMatchClass)\n";
2478 OS
<< " return MCTargetAsmParser::Match_InvalidOperand;\n\n";
2480 // Check for Token operands first.
2481 // FIXME: Use a more specific diagnostic type.
2482 OS
<< " if (Operand.isToken() && Kind <= MCK_LAST_TOKEN)\n";
2483 OS
<< " return isSubclass(matchTokenString(Operand.getToken()), Kind) ?\n"
2484 << " MCTargetAsmParser::Match_Success :\n"
2485 << " MCTargetAsmParser::Match_InvalidOperand;\n\n";
2487 // Check the user classes. We don't care what order since we're only
2488 // actually matching against one of them.
2489 OS
<< " switch (Kind) {\n"
2490 " default: break;\n";
2491 for (const auto &CI
: Info
.Classes
) {
2492 if (!CI
.isUserClass())
2495 OS
<< " case " << CI
.Name
<< ": {\n";
2496 OS
<< " DiagnosticPredicate DP(Operand." << CI
.PredicateMethod
2498 OS
<< " if (DP.isMatch())\n";
2499 OS
<< " return MCTargetAsmParser::Match_Success;\n";
2500 if (!CI
.DiagnosticType
.empty()) {
2501 OS
<< " if (DP.isNearMatch())\n";
2502 OS
<< " return " << Info
.Target
.getName() << "AsmParser::Match_"
2503 << CI
.DiagnosticType
<< ";\n";
2509 OS
<< " } // end switch (Kind)\n\n";
2511 // Check for register operands, including sub-classes.
2512 const auto &Regs
= Target
.getRegBank().getRegisters();
2513 StringRef Namespace
= Regs
.front().TheDef
->getValueAsString("Namespace");
2514 SmallVector
<StringRef
> Table(1 + Regs
.size(), "InvalidMatchClass");
2515 for (const auto &RC
: Info
.RegisterClasses
) {
2516 const auto &Reg
= Target
.getRegBank().getReg(RC
.first
);
2517 Table
[Reg
->EnumValue
] = RC
.second
->Name
;
2519 OS
<< " if (Operand.isReg()) {\n";
2520 OS
<< " static constexpr uint16_t Table[" << Namespace
2521 << "::NUM_TARGET_REGS] = {\n";
2522 for (auto &MatchClassName
: Table
)
2523 OS
<< " " << MatchClassName
<< ",\n";
2525 OS
<< " unsigned RegID = Operand.getReg().id();\n";
2526 OS
<< " MatchClassKind OpKind = MCRegister::isPhysicalRegister(RegID) ? "
2527 "(MatchClassKind)Table[RegID] : InvalidMatchClass;\n";
2528 OS
<< " return isSubclass(OpKind, Kind) ? "
2529 << "(unsigned)MCTargetAsmParser::Match_Success :\n "
2530 << " getDiagKindFromRegisterClass(Kind);\n }\n\n";
2532 // Expected operand is a register, but actual is not.
2533 OS
<< " if (Kind > MCK_LAST_TOKEN && Kind <= MCK_LAST_REGISTER)\n";
2534 OS
<< " return getDiagKindFromRegisterClass(Kind);\n\n";
2536 // Generic fallthrough match failure case for operands that don't have
2537 // specialized diagnostic types.
2538 OS
<< " return MCTargetAsmParser::Match_InvalidOperand;\n";
2542 /// emitIsSubclass - Emit the subclass predicate function.
2543 static void emitIsSubclass(CodeGenTarget
&Target
,
2544 std::forward_list
<ClassInfo
> &Infos
,
2546 OS
<< "/// isSubclass - Compute whether \\p A is a subclass of \\p B.\n";
2547 OS
<< "static bool isSubclass(MatchClassKind A, MatchClassKind B) {\n";
2548 OS
<< " if (A == B)\n";
2549 OS
<< " return true;\n\n";
2551 // TODO: Use something like SequenceToOffsetTable to allow sequences to
2552 // overlap in this table.
2553 SmallVector
<bool> SuperClassData
;
2555 OS
<< " [[maybe_unused]] static constexpr struct {\n";
2556 OS
<< " uint32_t Offset;\n";
2557 OS
<< " uint16_t Start;\n";
2558 OS
<< " uint16_t Length;\n";
2559 OS
<< " } Table[] = {\n";
2560 OS
<< " {0, 0, 0},\n"; // InvalidMatchClass
2561 OS
<< " {0, 0, 0},\n"; // OptionalMatchClass
2562 for (const auto &A
: Infos
) {
2563 SmallVector
<bool> SuperClasses
;
2564 SuperClasses
.push_back(false); // InvalidMatchClass
2565 SuperClasses
.push_back(A
.IsOptional
); // OptionalMatchClass
2566 for (const auto &B
: Infos
)
2567 SuperClasses
.push_back(&A
!= &B
&& A
.isSubsetOf(B
));
2569 // Trim leading and trailing zeros.
2570 auto End
= find_if(reverse(SuperClasses
), [](bool B
) { return B
; }).base();
2572 std::find_if(SuperClasses
.begin(), End
, [](bool B
) { return B
; });
2574 unsigned Offset
= SuperClassData
.size();
2575 SuperClassData
.append(Start
, End
);
2577 OS
<< " {" << Offset
<< ", " << (Start
- SuperClasses
.begin()) << ", "
2578 << (End
- Start
) << "},\n";
2582 if (SuperClassData
.empty()) {
2583 OS
<< " return false;\n";
2585 // Dump the boolean data packed into bytes.
2586 SuperClassData
.append(-SuperClassData
.size() % 8, false);
2587 OS
<< " static constexpr uint8_t Data[] = {\n";
2588 for (unsigned I
= 0, E
= SuperClassData
.size(); I
< E
; I
+= 8) {
2590 for (unsigned J
= 0; J
< 8; ++J
)
2591 Byte
|= (unsigned)SuperClassData
[I
+ J
] << J
;
2592 OS
<< formatv(" {:X2},\n", Byte
);
2596 OS
<< " auto &Entry = Table[A];\n";
2597 OS
<< " unsigned Idx = B - Entry.Start;\n";
2598 OS
<< " if (Idx >= Entry.Length)\n";
2599 OS
<< " return false;\n";
2600 OS
<< " Idx += Entry.Offset;\n";
2601 OS
<< " return (Data[Idx / 8] >> (Idx % 8)) & 1;\n";
2606 /// emitMatchTokenString - Emit the function to match a token string to the
2607 /// appropriate match class value.
2608 static void emitMatchTokenString(CodeGenTarget
&Target
,
2609 std::forward_list
<ClassInfo
> &Infos
,
2611 // Construct the match list.
2612 std::vector
<StringMatcher::StringPair
> Matches
;
2613 for (const auto &CI
: Infos
) {
2614 if (CI
.Kind
== ClassInfo::Token
)
2615 Matches
.emplace_back(CI
.ValueName
, "return " + CI
.Name
+ ";");
2618 OS
<< "static MatchClassKind matchTokenString(StringRef Name) {\n";
2620 StringMatcher("Name", Matches
, OS
).Emit();
2622 OS
<< " return InvalidMatchClass;\n";
2626 /// emitMatchRegisterName - Emit the function to match a string to the target
2627 /// specific register enum.
2628 static void emitMatchRegisterName(const CodeGenTarget
&Target
,
2629 const Record
*AsmParser
, raw_ostream
&OS
) {
2630 // Construct the match list.
2631 std::vector
<StringMatcher::StringPair
> Matches
;
2632 const auto &Regs
= Target
.getRegBank().getRegisters();
2633 std::string Namespace
=
2634 Regs
.front().TheDef
->getValueAsString("Namespace").str();
2635 for (const CodeGenRegister
&Reg
: Regs
) {
2636 StringRef AsmName
= Reg
.TheDef
->getValueAsString("AsmName");
2637 if (AsmName
.empty())
2640 Matches
.emplace_back(AsmName
.str(), "return " + Namespace
+
2641 "::" + Reg
.getName().str() + ';');
2644 OS
<< "static MCRegister MatchRegisterName(StringRef Name) {\n";
2646 bool IgnoreDuplicates
=
2647 AsmParser
->getValueAsBit("AllowDuplicateRegisterNames");
2648 StringMatcher("Name", Matches
, OS
).Emit(0, IgnoreDuplicates
);
2650 OS
<< " return " << Namespace
<< "::NoRegister;\n";
2654 /// Emit the function to match a string to the target
2655 /// specific register enum.
2656 static void emitMatchRegisterAltName(const CodeGenTarget
&Target
,
2657 const Record
*AsmParser
, raw_ostream
&OS
) {
2658 // Construct the match list.
2659 std::vector
<StringMatcher::StringPair
> Matches
;
2660 const auto &Regs
= Target
.getRegBank().getRegisters();
2661 std::string Namespace
=
2662 Regs
.front().TheDef
->getValueAsString("Namespace").str();
2663 for (const CodeGenRegister
&Reg
: Regs
) {
2665 auto AltNames
= Reg
.TheDef
->getValueAsListOfStrings("AltNames");
2667 for (auto AltName
: AltNames
) {
2668 AltName
= StringRef(AltName
).trim();
2670 // don't handle empty alternative names
2671 if (AltName
.empty())
2674 Matches
.emplace_back(AltName
.str(), "return " + Namespace
+
2675 "::" + Reg
.getName().str() + ';');
2679 OS
<< "static MCRegister MatchRegisterAltName(StringRef Name) {\n";
2681 bool IgnoreDuplicates
=
2682 AsmParser
->getValueAsBit("AllowDuplicateRegisterNames");
2683 StringMatcher("Name", Matches
, OS
).Emit(0, IgnoreDuplicates
);
2685 OS
<< " return " << Namespace
<< "::NoRegister;\n";
2689 /// emitOperandDiagnosticTypes - Emit the operand matching diagnostic types.
2690 static void emitOperandDiagnosticTypes(AsmMatcherInfo
&Info
, raw_ostream
&OS
) {
2691 // Get the set of diagnostic types from all of the operand classes.
2692 std::set
<StringRef
> Types
;
2693 for (const auto &OpClassEntry
: Info
.AsmOperandClasses
) {
2694 if (!OpClassEntry
.second
->DiagnosticType
.empty())
2695 Types
.insert(OpClassEntry
.second
->DiagnosticType
);
2697 for (const auto &OpClassEntry
: Info
.RegisterClassClasses
) {
2698 if (!OpClassEntry
.second
->DiagnosticType
.empty())
2699 Types
.insert(OpClassEntry
.second
->DiagnosticType
);
2705 // Now emit the enum entries.
2706 for (StringRef Type
: Types
)
2707 OS
<< " Match_" << Type
<< ",\n";
2708 OS
<< " END_OPERAND_DIAGNOSTIC_TYPES\n";
2711 /// emitGetSubtargetFeatureName - Emit the helper function to get the
2712 /// user-level name for a subtarget feature.
2713 static void emitGetSubtargetFeatureName(AsmMatcherInfo
&Info
, raw_ostream
&OS
) {
2714 OS
<< "// User-level names for subtarget features that participate in\n"
2715 << "// instruction matching.\n"
2716 << "static const char *getSubtargetFeatureName(uint64_t Val) {\n";
2717 if (!Info
.SubtargetFeatures
.empty()) {
2718 OS
<< " switch(Val) {\n";
2719 for (const auto &SF
: Info
.SubtargetFeatures
) {
2720 const SubtargetFeatureInfo
&SFI
= SF
.second
;
2721 // FIXME: Totally just a placeholder name to get the algorithm working.
2722 OS
<< " case " << SFI
.getEnumBitName() << ": return \""
2723 << SFI
.TheDef
->getValueAsString("PredicateName") << "\";\n";
2725 OS
<< " default: return \"(unknown)\";\n";
2728 // Nothing to emit, so skip the switch
2729 OS
<< " return \"(unknown)\";\n";
2734 static std::string
GetAliasRequiredFeatures(const Record
*R
,
2735 const AsmMatcherInfo
&Info
) {
2739 for (const Record
*RF
: R
->getValueAsListOfDefs("Predicates")) {
2740 const SubtargetFeatureInfo
*F
= Info
.getSubtargetFeature(RF
);
2742 PrintFatalError(R
->getLoc(),
2743 "Predicate '" + RF
->getName() +
2744 "' is not marked as an AssemblerPredicate!");
2747 Result
+= "Features.test(" + F
->getEnumBitName() + ')';
2755 emitMnemonicAliasVariant(raw_ostream
&OS
, const AsmMatcherInfo
&Info
,
2756 ArrayRef
<const Record
*> Aliases
, unsigned Indent
= 0,
2757 StringRef AsmParserVariantName
= StringRef()) {
2758 // Keep track of all the aliases from a mnemonic. Use an std::map so that the
2759 // iteration order of the map is stable.
2760 std::map
<std::string
, std::vector
<const Record
*>> AliasesFromMnemonic
;
2762 for (const Record
*R
: Aliases
) {
2763 // FIXME: Allow AssemblerVariantName to be a comma separated list.
2764 StringRef AsmVariantName
= R
->getValueAsString("AsmVariantName");
2765 if (AsmVariantName
!= AsmParserVariantName
)
2767 AliasesFromMnemonic
[R
->getValueAsString("FromMnemonic").lower()].push_back(
2770 if (AliasesFromMnemonic
.empty())
2773 // Process each alias a "from" mnemonic at a time, building the code executed
2774 // by the string remapper.
2775 std::vector
<StringMatcher::StringPair
> Cases
;
2776 for (const auto &AliasEntry
: AliasesFromMnemonic
) {
2777 // Loop through each alias and emit code that handles each case. If there
2778 // are two instructions without predicates, emit an error. If there is one,
2780 std::string MatchCode
;
2781 int AliasWithNoPredicate
= -1;
2783 ArrayRef
<const Record
*> ToVec
= AliasEntry
.second
;
2784 for (const auto &[Idx
, R
] : enumerate(ToVec
)) {
2785 std::string FeatureMask
= GetAliasRequiredFeatures(R
, Info
);
2787 // If this unconditionally matches, remember it for later and diagnose
2789 if (FeatureMask
.empty()) {
2790 if (AliasWithNoPredicate
!= -1 &&
2791 R
->getValueAsString("ToMnemonic") !=
2792 ToVec
[AliasWithNoPredicate
]->getValueAsString("ToMnemonic")) {
2793 // We can't have two different aliases from the same mnemonic with no
2796 ToVec
[AliasWithNoPredicate
]->getLoc(),
2797 "two different MnemonicAliases with the same 'from' mnemonic!");
2798 PrintFatalError(R
->getLoc(), "this is the other MnemonicAlias.");
2801 AliasWithNoPredicate
= Idx
;
2804 if (R
->getValueAsString("ToMnemonic") == AliasEntry
.first
)
2805 PrintFatalError(R
->getLoc(), "MnemonicAlias to the same string");
2807 if (!MatchCode
.empty())
2808 MatchCode
+= "else ";
2809 MatchCode
+= "if (" + FeatureMask
+ ")\n";
2810 MatchCode
+= " Mnemonic = \"";
2811 MatchCode
+= R
->getValueAsString("ToMnemonic").lower();
2812 MatchCode
+= "\";\n";
2815 if (AliasWithNoPredicate
!= -1) {
2816 const Record
*R
= ToVec
[AliasWithNoPredicate
];
2817 if (!MatchCode
.empty())
2818 MatchCode
+= "else\n ";
2819 MatchCode
+= "Mnemonic = \"";
2820 MatchCode
+= R
->getValueAsString("ToMnemonic").lower();
2821 MatchCode
+= "\";\n";
2824 MatchCode
+= "return;";
2826 Cases
.push_back(std::pair(AliasEntry
.first
, MatchCode
));
2828 StringMatcher("Mnemonic", Cases
, OS
).Emit(Indent
);
2831 /// emitMnemonicAliases - If the target has any MnemonicAlias<> definitions,
2832 /// emit a function for them and return true, otherwise return false.
2833 static bool emitMnemonicAliases(raw_ostream
&OS
, const AsmMatcherInfo
&Info
,
2834 CodeGenTarget
&Target
) {
2835 // Ignore aliases when match-prefix is set.
2836 if (!MatchPrefix
.empty())
2839 ArrayRef
<const Record
*> Aliases
=
2840 Info
.getRecords().getAllDerivedDefinitions("MnemonicAlias");
2841 if (Aliases
.empty())
2844 OS
<< "static void applyMnemonicAliases(StringRef &Mnemonic, "
2845 "const FeatureBitset &Features, unsigned VariantID) {\n";
2846 unsigned VariantCount
= Target
.getAsmParserVariantCount();
2847 for (unsigned VC
= 0; VC
!= VariantCount
; ++VC
) {
2848 const Record
*AsmVariant
= Target
.getAsmParserVariant(VC
);
2849 int AsmParserVariantNo
= AsmVariant
->getValueAsInt("Variant");
2850 StringRef AsmParserVariantName
= AsmVariant
->getValueAsString("Name");
2852 // If the variant doesn't have a name, defer to the emitMnemonicAliasVariant
2853 // call after the loop.
2854 if (AsmParserVariantName
.empty()) {
2855 assert(VariantCount
== 1 && "Multiple variants should each be named");
2860 OS
<< " switch (VariantID) {\n";
2861 OS
<< " case " << AsmParserVariantNo
<< ":\n";
2862 emitMnemonicAliasVariant(OS
, Info
, Aliases
, /*Indent=*/2,
2863 AsmParserVariantName
);
2866 if (VC
== VariantCount
- 1)
2870 // Emit aliases that apply to all variants.
2871 emitMnemonicAliasVariant(OS
, Info
, Aliases
);
2879 emitCustomOperandParsing(raw_ostream
&OS
, CodeGenTarget
&Target
,
2880 const AsmMatcherInfo
&Info
, StringRef ClassName
,
2881 const StringToOffsetTable
&StringTable
,
2882 unsigned MaxMnemonicIndex
, unsigned MaxFeaturesIndex
,
2883 bool HasMnemonicFirst
, const Record
&AsmParser
) {
2884 unsigned MaxMask
= 0;
2885 for (const OperandMatchEntry
&OMI
: Info
.OperandMatchInfo
) {
2886 MaxMask
|= OMI
.OperandMask
;
2889 // Emit the static custom operand parsing table;
2890 OS
<< "namespace {\n";
2891 OS
<< " struct OperandMatchEntry {\n";
2892 OS
<< " " << getMinimalTypeForRange(MaxMnemonicIndex
) << " Mnemonic;\n";
2893 OS
<< " " << getMinimalTypeForRange(MaxMask
) << " OperandMask;\n";
2895 << getMinimalTypeForRange(
2896 std::distance(Info
.Classes
.begin(), Info
.Classes
.end()) +
2897 2 /* Include 'InvalidMatchClass' and 'OptionalMatchClass' */)
2899 OS
<< " " << getMinimalTypeForRange(MaxFeaturesIndex
)
2900 << " RequiredFeaturesIdx;\n\n";
2901 OS
<< " StringRef getMnemonic() const {\n";
2902 OS
<< " return StringRef(MnemonicTable + Mnemonic + 1,\n";
2903 OS
<< " MnemonicTable[Mnemonic]);\n";
2907 OS
<< " // Predicate for searching for an opcode.\n";
2908 OS
<< " struct LessOpcodeOperand {\n";
2909 OS
<< " bool operator()(const OperandMatchEntry &LHS, StringRef RHS) {\n";
2910 OS
<< " return LHS.getMnemonic() < RHS;\n";
2912 OS
<< " bool operator()(StringRef LHS, const OperandMatchEntry &RHS) {\n";
2913 OS
<< " return LHS < RHS.getMnemonic();\n";
2915 OS
<< " bool operator()(const OperandMatchEntry &LHS,";
2916 OS
<< " const OperandMatchEntry &RHS) {\n";
2917 OS
<< " return LHS.getMnemonic() < RHS.getMnemonic();\n";
2921 OS
<< "} // end anonymous namespace\n\n";
2923 OS
<< "static const OperandMatchEntry OperandMatchTable["
2924 << Info
.OperandMatchInfo
.size() << "] = {\n";
2926 OS
<< " /* Operand List Mnemonic, Mask, Operand Class, Features */\n";
2927 for (const OperandMatchEntry
&OMI
: Info
.OperandMatchInfo
) {
2928 const MatchableInfo
&II
= *OMI
.MI
;
2932 // Store a pascal-style length byte in the mnemonic.
2933 std::string LenMnemonic
= char(II
.Mnemonic
.size()) + II
.Mnemonic
.lower();
2934 OS
<< *StringTable
.GetStringOffset(LenMnemonic
) << " /* " << II
.Mnemonic
2937 OS
<< OMI
.OperandMask
;
2940 for (int i
= 0, e
= 31; i
!= e
; ++i
)
2941 if (OMI
.OperandMask
& (1 << i
))
2947 // Write the required features mask.
2949 if (II
.RequiredFeatures
.empty())
2952 for (const auto &F
: II
.RequiredFeatures
)
2953 OS
<< '_' << F
->TheDef
->getName();
2959 // Emit the operand class switch to call the correct custom parser for
2960 // the found operand class.
2961 OS
<< "ParseStatus " << Target
.getName() << ClassName
<< "::\n"
2962 << "tryCustomParseOperand(OperandVector"
2963 << " &Operands,\n unsigned MCK) {\n\n"
2964 << " switch(MCK) {\n";
2966 for (const auto &CI
: Info
.Classes
) {
2967 if (CI
.ParserMethod
.empty())
2969 OS
<< " case " << CI
.Name
<< ":\n"
2970 << " return " << CI
.ParserMethod
<< "(Operands);\n";
2973 OS
<< " default:\n";
2974 OS
<< " return ParseStatus::NoMatch;\n";
2976 OS
<< " return ParseStatus::NoMatch;\n";
2979 // Emit the static custom operand parser. This code is very similar with
2980 // the other matcher. Also use MatchResultTy here just in case we go for
2981 // a better error handling.
2982 OS
<< "ParseStatus " << Target
.getName() << ClassName
<< "::\n"
2983 << "MatchOperandParserImpl(OperandVector"
2984 << " &Operands,\n StringRef Mnemonic,\n"
2985 << " bool ParseForAllFeatures) {\n";
2987 // Emit code to get the available features.
2988 OS
<< " // Get the current feature set.\n";
2989 OS
<< " const FeatureBitset &AvailableFeatures = "
2990 "getAvailableFeatures();\n\n";
2992 OS
<< " // Get the next operand index.\n";
2993 OS
<< " unsigned NextOpNum = Operands.size()"
2994 << (HasMnemonicFirst
? " - 1" : "") << ";\n";
2996 // Emit code to search the table.
2997 OS
<< " // Search the table.\n";
2998 if (HasMnemonicFirst
) {
2999 OS
<< " auto MnemonicRange =\n";
3000 OS
<< " std::equal_range(std::begin(OperandMatchTable), "
3001 "std::end(OperandMatchTable),\n";
3002 OS
<< " Mnemonic, LessOpcodeOperand());\n\n";
3004 OS
<< " auto MnemonicRange = std::pair(std::begin(OperandMatchTable),"
3005 " std::end(OperandMatchTable));\n";
3006 OS
<< " if (!Mnemonic.empty())\n";
3007 OS
<< " MnemonicRange =\n";
3008 OS
<< " std::equal_range(std::begin(OperandMatchTable), "
3009 "std::end(OperandMatchTable),\n";
3010 OS
<< " Mnemonic, LessOpcodeOperand());\n\n";
3013 OS
<< " if (MnemonicRange.first == MnemonicRange.second)\n";
3014 OS
<< " return ParseStatus::NoMatch;\n\n";
3016 OS
<< " for (const OperandMatchEntry *it = MnemonicRange.first,\n"
3017 << " *ie = MnemonicRange.second; it != ie; ++it) {\n";
3019 OS
<< " // equal_range guarantees that instruction mnemonic matches.\n";
3020 OS
<< " assert(Mnemonic == it->getMnemonic());\n\n";
3022 // Emit check that the required features are available.
3023 OS
<< " // check if the available features match\n";
3024 OS
<< " const FeatureBitset &RequiredFeatures = "
3025 "FeatureBitsets[it->RequiredFeaturesIdx];\n";
3026 OS
<< " if (!ParseForAllFeatures && (AvailableFeatures & "
3027 "RequiredFeatures) != RequiredFeatures)\n";
3028 OS
<< " continue;\n\n";
3030 // Emit check to ensure the operand number matches.
3031 OS
<< " // check if the operand in question has a custom parser.\n";
3032 OS
<< " if (!(it->OperandMask & (1 << NextOpNum)))\n";
3033 OS
<< " continue;\n\n";
3035 // Emit call to the custom parser method
3036 StringRef ParserName
= AsmParser
.getValueAsString("OperandParserMethod");
3037 if (ParserName
.empty())
3038 ParserName
= "tryCustomParseOperand";
3039 OS
<< " // call custom parse method to handle the operand\n";
3040 OS
<< " ParseStatus Result = " << ParserName
<< "(Operands, it->Class);\n";
3041 OS
<< " if (!Result.isNoMatch())\n";
3042 OS
<< " return Result;\n";
3045 OS
<< " // Okay, we had no match.\n";
3046 OS
<< " return ParseStatus::NoMatch;\n";
3050 static void emitAsmTiedOperandConstraints(CodeGenTarget
&Target
,
3051 AsmMatcherInfo
&Info
, raw_ostream
&OS
,
3052 bool HasOptionalOperands
) {
3053 std::string AsmParserName
=
3054 std::string(Info
.AsmParser
->getValueAsString("AsmParserClassName"));
3055 OS
<< "static bool ";
3056 OS
<< "checkAsmTiedOperandConstraints(const " << Target
.getName()
3057 << AsmParserName
<< "&AsmParser,\n";
3058 OS
<< " unsigned Kind, const OperandVector "
3060 if (HasOptionalOperands
)
3061 OS
<< " ArrayRef<unsigned> DefaultsOffset,\n";
3062 OS
<< " uint64_t &ErrorInfo) {\n";
3063 OS
<< " assert(Kind < CVT_NUM_SIGNATURES && \"Invalid signature!\");\n";
3064 OS
<< " const uint8_t *Converter = ConversionTable[Kind];\n";
3065 OS
<< " for (const uint8_t *p = Converter; *p; p += 2) {\n";
3066 OS
<< " switch (*p) {\n";
3067 OS
<< " case CVT_Tied: {\n";
3068 OS
<< " unsigned OpIdx = *(p + 1);\n";
3069 OS
<< " assert(OpIdx < (size_t)(std::end(TiedAsmOperandTable) -\n";
3070 OS
<< " std::begin(TiedAsmOperandTable)) &&\n";
3071 OS
<< " \"Tied operand not found\");\n";
3072 OS
<< " unsigned OpndNum1 = TiedAsmOperandTable[OpIdx][1];\n";
3073 OS
<< " unsigned OpndNum2 = TiedAsmOperandTable[OpIdx][2];\n";
3074 if (HasOptionalOperands
) {
3075 // When optional operands are involved, formal and actual operand indices
3076 // may differ. Map the former to the latter by subtracting the number of
3077 // absent optional operands.
3078 OS
<< " OpndNum1 = OpndNum1 - DefaultsOffset[OpndNum1];\n";
3079 OS
<< " OpndNum2 = OpndNum2 - DefaultsOffset[OpndNum2];\n";
3081 OS
<< " if (OpndNum1 != OpndNum2) {\n";
3082 OS
<< " auto &SrcOp1 = Operands[OpndNum1];\n";
3083 OS
<< " auto &SrcOp2 = Operands[OpndNum2];\n";
3084 OS
<< " if (!AsmParser.areEqualRegs(*SrcOp1, *SrcOp2)) {\n";
3085 OS
<< " ErrorInfo = OpndNum2;\n";
3086 OS
<< " return false;\n";
3091 OS
<< " default:\n";
3095 OS
<< " return true;\n";
3099 static void emitMnemonicSpellChecker(raw_ostream
&OS
, CodeGenTarget
&Target
,
3100 unsigned VariantCount
) {
3101 OS
<< "static std::string " << Target
.getName()
3102 << "MnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,"
3103 << " unsigned VariantID) {\n";
3105 OS
<< " return \"\";";
3107 OS
<< " const unsigned MaxEditDist = 2;\n";
3108 OS
<< " std::vector<StringRef> Candidates;\n";
3109 OS
<< " StringRef Prev = \"\";\n\n";
3111 OS
<< " // Find the appropriate table for this asm variant.\n";
3112 OS
<< " const MatchEntry *Start, *End;\n";
3113 OS
<< " switch (VariantID) {\n";
3114 OS
<< " default: llvm_unreachable(\"invalid variant!\");\n";
3115 for (unsigned VC
= 0; VC
!= VariantCount
; ++VC
) {
3116 const Record
*AsmVariant
= Target
.getAsmParserVariant(VC
);
3117 int AsmVariantNo
= AsmVariant
->getValueAsInt("Variant");
3118 OS
<< " case " << AsmVariantNo
<< ": Start = std::begin(MatchTable" << VC
3119 << "); End = std::end(MatchTable" << VC
<< "); break;\n";
3122 OS
<< " for (auto I = Start; I < End; I++) {\n";
3123 OS
<< " // Ignore unsupported instructions.\n";
3124 OS
<< " const FeatureBitset &RequiredFeatures = "
3125 "FeatureBitsets[I->RequiredFeaturesIdx];\n";
3126 OS
<< " if ((FBS & RequiredFeatures) != RequiredFeatures)\n";
3127 OS
<< " continue;\n";
3129 OS
<< " StringRef T = I->getMnemonic();\n";
3130 OS
<< " // Avoid recomputing the edit distance for the same string.\n";
3131 OS
<< " if (T == Prev)\n";
3132 OS
<< " continue;\n";
3134 OS
<< " Prev = T;\n";
3135 OS
<< " unsigned Dist = S.edit_distance(T, false, MaxEditDist);\n";
3136 OS
<< " if (Dist <= MaxEditDist)\n";
3137 OS
<< " Candidates.push_back(T);\n";
3140 OS
<< " if (Candidates.empty())\n";
3141 OS
<< " return \"\";\n";
3143 OS
<< " std::string Res = \", did you mean: \";\n";
3144 OS
<< " unsigned i = 0;\n";
3145 OS
<< " for (; i < Candidates.size() - 1; i++)\n";
3146 OS
<< " Res += Candidates[i].str() + \", \";\n";
3147 OS
<< " return Res + Candidates[i].str() + \"?\";\n";
3153 static void emitMnemonicChecker(raw_ostream
&OS
, CodeGenTarget
&Target
,
3154 unsigned VariantCount
, bool HasMnemonicFirst
,
3155 bool HasMnemonicAliases
) {
3156 OS
<< "static bool " << Target
.getName()
3157 << "CheckMnemonic(StringRef Mnemonic,\n";
3159 << "const FeatureBitset &AvailableFeatures,\n";
3161 << "unsigned VariantID) {\n";
3163 if (!VariantCount
) {
3164 OS
<< " return false;\n";
3166 if (HasMnemonicAliases
) {
3167 OS
<< " // Process all MnemonicAliases to remap the mnemonic.\n";
3168 OS
<< " applyMnemonicAliases(Mnemonic, AvailableFeatures, VariantID);";
3171 OS
<< " // Find the appropriate table for this asm variant.\n";
3172 OS
<< " const MatchEntry *Start, *End;\n";
3173 OS
<< " switch (VariantID) {\n";
3174 OS
<< " default: llvm_unreachable(\"invalid variant!\");\n";
3175 for (unsigned VC
= 0; VC
!= VariantCount
; ++VC
) {
3176 const Record
*AsmVariant
= Target
.getAsmParserVariant(VC
);
3177 int AsmVariantNo
= AsmVariant
->getValueAsInt("Variant");
3178 OS
<< " case " << AsmVariantNo
<< ": Start = std::begin(MatchTable" << VC
3179 << "); End = std::end(MatchTable" << VC
<< "); break;\n";
3183 OS
<< " // Search the table.\n";
3184 if (HasMnemonicFirst
) {
3185 OS
<< " auto MnemonicRange = "
3186 "std::equal_range(Start, End, Mnemonic, LessOpcode());\n\n";
3188 OS
<< " auto MnemonicRange = std::pair(Start, End);\n";
3189 OS
<< " unsigned SIndex = Mnemonic.empty() ? 0 : 1;\n";
3190 OS
<< " if (!Mnemonic.empty())\n";
3191 OS
<< " MnemonicRange = "
3192 << "std::equal_range(Start, End, Mnemonic.lower(), LessOpcode());\n\n";
3195 OS
<< " if (MnemonicRange.first == MnemonicRange.second)\n";
3196 OS
<< " return false;\n\n";
3198 OS
<< " for (const MatchEntry *it = MnemonicRange.first, "
3199 << "*ie = MnemonicRange.second;\n";
3200 OS
<< " it != ie; ++it) {\n";
3201 OS
<< " const FeatureBitset &RequiredFeatures =\n";
3202 OS
<< " FeatureBitsets[it->RequiredFeaturesIdx];\n";
3203 OS
<< " if ((AvailableFeatures & RequiredFeatures) == ";
3204 OS
<< "RequiredFeatures)\n";
3205 OS
<< " return true;\n";
3207 OS
<< " return false;\n";
3213 // Emit a function mapping match classes to strings, for debugging.
3214 static void emitMatchClassKindNames(std::forward_list
<ClassInfo
> &Infos
,
3216 OS
<< "#ifndef NDEBUG\n";
3217 OS
<< "const char *getMatchClassName(MatchClassKind Kind) {\n";
3218 OS
<< " switch (Kind) {\n";
3220 OS
<< " case InvalidMatchClass: return \"InvalidMatchClass\";\n";
3221 OS
<< " case OptionalMatchClass: return \"OptionalMatchClass\";\n";
3222 for (const auto &CI
: Infos
) {
3223 OS
<< " case " << CI
.Name
<< ": return \"" << CI
.Name
<< "\";\n";
3225 OS
<< " case NumMatchClassKinds: return \"NumMatchClassKinds\";\n";
3228 OS
<< " llvm_unreachable(\"unhandled MatchClassKind!\");\n";
3230 OS
<< "#endif // NDEBUG\n";
3234 getNameForFeatureBitset(ArrayRef
<const Record
*> FeatureBitset
) {
3235 std::string Name
= "AMFBS";
3236 for (const Record
*Feature
: FeatureBitset
)
3237 Name
+= ("_" + Feature
->getName()).str();
3241 void AsmMatcherEmitter::run(raw_ostream
&OS
) {
3242 CodeGenTarget
Target(Records
);
3243 const Record
*AsmParser
= Target
.getAsmParser();
3244 StringRef ClassName
= AsmParser
->getValueAsString("AsmParserClassName");
3246 emitSourceFileHeader("Assembly Matcher Source Fragment", OS
, Records
);
3248 // Compute the information on the instructions to match.
3249 AsmMatcherInfo
Info(AsmParser
, Target
, Records
);
3252 bool PreferSmallerInstructions
= getPreferSmallerInstructions(Target
);
3253 // Sort the instruction table using the partial order on classes. We use
3254 // stable_sort to ensure that ambiguous instructions are still
3255 // deterministically ordered.
3258 [PreferSmallerInstructions
](const std::unique_ptr
<MatchableInfo
> &A
,
3259 const std::unique_ptr
<MatchableInfo
> &B
) {
3260 return A
->shouldBeMatchedBefore(*B
, PreferSmallerInstructions
);
3263 #ifdef EXPENSIVE_CHECKS
3264 // Verify that the table is sorted and operator < works transitively.
3265 for (auto I
= Info
.Matchables
.begin(), E
= Info
.Matchables
.end(); I
!= E
;
3267 for (auto J
= I
; J
!= E
; ++J
) {
3268 assert(!(*J
)->shouldBeMatchedBefore(**I
, PreferSmallerInstructions
));
3273 DEBUG_WITH_TYPE("instruction_info", {
3274 for (const auto &MI
: Info
.Matchables
)
3278 // Check for ambiguous matchables.
3279 DEBUG_WITH_TYPE("ambiguous_instrs", {
3280 unsigned NumAmbiguous
= 0;
3281 for (auto I
= Info
.Matchables
.begin(), E
= Info
.Matchables
.end(); I
!= E
;
3283 for (auto J
= std::next(I
); J
!= E
; ++J
) {
3284 const MatchableInfo
&A
= **I
;
3285 const MatchableInfo
&B
= **J
;
3287 if (A
.couldMatchAmbiguouslyWith(B
, PreferSmallerInstructions
)) {
3288 errs() << "warning: ambiguous matchables:\n";
3290 errs() << "\nis incomparable with:\n";
3298 errs() << "warning: " << NumAmbiguous
<< " ambiguous matchables!\n";
3301 // Compute the information on the custom operand parsing.
3302 Info
.buildOperandMatchInfo();
3304 bool HasMnemonicFirst
= AsmParser
->getValueAsBit("HasMnemonicFirst");
3305 bool HasOptionalOperands
= Info
.hasOptionalOperands();
3306 bool ReportMultipleNearMisses
=
3307 AsmParser
->getValueAsBit("ReportMultipleNearMisses");
3309 // Write the output.
3311 // Information for the class declaration.
3312 OS
<< "\n#ifdef GET_ASSEMBLER_HEADER\n";
3313 OS
<< "#undef GET_ASSEMBLER_HEADER\n";
3314 OS
<< " // This should be included into the middle of the declaration of\n";
3315 OS
<< " // your subclasses implementation of MCTargetAsmParser.\n";
3316 OS
<< " FeatureBitset ComputeAvailableFeatures(const FeatureBitset &FB) "
3318 if (HasOptionalOperands
) {
3319 OS
<< " void convertToMCInst(unsigned Kind, MCInst &Inst, "
3320 << "unsigned Opcode,\n"
3321 << " const OperandVector &Operands,\n"
3322 << " const SmallBitVector "
3323 "&OptionalOperandsMask,\n"
3324 << " ArrayRef<unsigned> DefaultsOffset);\n";
3326 OS
<< " void convertToMCInst(unsigned Kind, MCInst &Inst, "
3327 << "unsigned Opcode,\n"
3328 << " const OperandVector &Operands);\n";
3330 OS
<< " void convertToMapAndConstraints(unsigned Kind,\n ";
3331 OS
<< " const OperandVector &Operands) override;\n";
3332 OS
<< " unsigned MatchInstructionImpl(const OperandVector &Operands,\n"
3333 << " MCInst &Inst,\n";
3334 if (ReportMultipleNearMisses
)
3335 OS
<< " SmallVectorImpl<NearMissInfo> "
3338 OS
<< " uint64_t &ErrorInfo,\n"
3339 << " FeatureBitset &MissingFeatures,\n";
3340 OS
<< " bool matchingInlineAsm,\n"
3341 << " unsigned VariantID = 0);\n";
3342 if (!ReportMultipleNearMisses
)
3343 OS
<< " unsigned MatchInstructionImpl(const OperandVector &Operands,\n"
3344 << " MCInst &Inst,\n"
3345 << " uint64_t &ErrorInfo,\n"
3346 << " bool matchingInlineAsm,\n"
3347 << " unsigned VariantID = 0) {\n"
3348 << " FeatureBitset MissingFeatures;\n"
3349 << " return MatchInstructionImpl(Operands, Inst, ErrorInfo, "
3350 "MissingFeatures,\n"
3351 << " matchingInlineAsm, VariantID);\n"
3354 if (!Info
.OperandMatchInfo
.empty()) {
3355 OS
<< " ParseStatus MatchOperandParserImpl(\n";
3356 OS
<< " OperandVector &Operands,\n";
3357 OS
<< " StringRef Mnemonic,\n";
3358 OS
<< " bool ParseForAllFeatures = false);\n";
3360 OS
<< " ParseStatus tryCustomParseOperand(\n";
3361 OS
<< " OperandVector &Operands,\n";
3362 OS
<< " unsigned MCK);\n\n";
3365 OS
<< "#endif // GET_ASSEMBLER_HEADER\n\n";
3367 // Emit the operand match diagnostic enum names.
3368 OS
<< "\n#ifdef GET_OPERAND_DIAGNOSTIC_TYPES\n";
3369 OS
<< "#undef GET_OPERAND_DIAGNOSTIC_TYPES\n\n";
3370 emitOperandDiagnosticTypes(Info
, OS
);
3371 OS
<< "#endif // GET_OPERAND_DIAGNOSTIC_TYPES\n\n";
3373 OS
<< "\n#ifdef GET_REGISTER_MATCHER\n";
3374 OS
<< "#undef GET_REGISTER_MATCHER\n\n";
3376 // Emit the subtarget feature enumeration.
3377 SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(
3378 Info
.SubtargetFeatures
, OS
);
3380 // Emit the function to match a register name to number.
3381 // This should be omitted for Mips target
3382 if (AsmParser
->getValueAsBit("ShouldEmitMatchRegisterName"))
3383 emitMatchRegisterName(Target
, AsmParser
, OS
);
3385 if (AsmParser
->getValueAsBit("ShouldEmitMatchRegisterAltName"))
3386 emitMatchRegisterAltName(Target
, AsmParser
, OS
);
3388 OS
<< "#endif // GET_REGISTER_MATCHER\n\n";
3390 OS
<< "\n#ifdef GET_SUBTARGET_FEATURE_NAME\n";
3391 OS
<< "#undef GET_SUBTARGET_FEATURE_NAME\n\n";
3393 // Generate the helper function to get the names for subtarget features.
3394 emitGetSubtargetFeatureName(Info
, OS
);
3396 OS
<< "#endif // GET_SUBTARGET_FEATURE_NAME\n\n";
3398 OS
<< "\n#ifdef GET_MATCHER_IMPLEMENTATION\n";
3399 OS
<< "#undef GET_MATCHER_IMPLEMENTATION\n\n";
3401 // Generate the function that remaps for mnemonic aliases.
3402 bool HasMnemonicAliases
= emitMnemonicAliases(OS
, Info
, Target
);
3404 // Generate the convertToMCInst function to convert operands into an MCInst.
3405 // Also, generate the convertToMapAndConstraints function for MS-style inline
3406 // assembly. The latter doesn't actually generate a MCInst.
3407 unsigned NumConverters
=
3408 emitConvertFuncs(Target
, ClassName
, Info
.Matchables
, HasMnemonicFirst
,
3409 HasOptionalOperands
, OS
);
3411 // Emit the enumeration for classes which participate in matching.
3412 emitMatchClassEnumeration(Target
, Info
.Classes
, OS
);
3414 // Emit a function to get the user-visible string to describe an operand
3415 // match failure in diagnostics.
3416 emitOperandMatchErrorDiagStrings(Info
, OS
);
3418 // Emit a function to map register classes to operand match failure codes.
3419 emitRegisterMatchErrorFunc(Info
, OS
);
3421 // Emit the routine to match token strings to their match class.
3422 emitMatchTokenString(Target
, Info
.Classes
, OS
);
3424 // Emit the subclass predicate routine.
3425 emitIsSubclass(Target
, Info
.Classes
, OS
);
3427 // Emit the routine to validate an operand against a match class.
3428 emitValidateOperandClass(Target
, Info
, OS
);
3430 emitMatchClassKindNames(Info
.Classes
, OS
);
3432 // Emit the available features compute function.
3433 SubtargetFeatureInfo::emitComputeAssemblerAvailableFeatures(
3434 Info
.Target
.getName(), ClassName
, "ComputeAvailableFeatures",
3435 Info
.SubtargetFeatures
, OS
);
3437 if (!ReportMultipleNearMisses
)
3438 emitAsmTiedOperandConstraints(Target
, Info
, OS
, HasOptionalOperands
);
3440 StringToOffsetTable StringTable
;
3442 size_t MaxNumOperands
= 0;
3443 unsigned MaxMnemonicIndex
= 0;
3444 bool HasDeprecation
= false;
3445 for (const auto &MI
: Info
.Matchables
) {
3446 MaxNumOperands
= std::max(MaxNumOperands
, MI
->AsmOperands
.size());
3447 HasDeprecation
|= MI
->HasDeprecation
;
3449 // Store a pascal-style length byte in the mnemonic.
3450 std::string LenMnemonic
= char(MI
->Mnemonic
.size()) + MI
->Mnemonic
.lower();
3451 MaxMnemonicIndex
= std::max(
3452 MaxMnemonicIndex
, StringTable
.GetOrAddStringOffset(LenMnemonic
, false));
3455 OS
<< "static const char MnemonicTable[] =\n";
3456 StringTable
.EmitString(OS
);
3459 std::vector
<std::vector
<const Record
*>> FeatureBitsets
;
3460 for (const auto &MI
: Info
.Matchables
) {
3461 if (MI
->RequiredFeatures
.empty())
3463 FeatureBitsets
.emplace_back();
3464 for (const auto *F
: MI
->RequiredFeatures
)
3465 FeatureBitsets
.back().push_back(F
->TheDef
);
3468 llvm::sort(FeatureBitsets
,
3469 [&](ArrayRef
<const Record
*> A
, ArrayRef
<const Record
*> B
) {
3470 if (A
.size() != B
.size())
3471 return A
.size() < B
.size();
3472 for (const auto [ARec
, BRec
] : zip_equal(A
, B
)) {
3473 if (ARec
->getName() != BRec
->getName())
3474 return ARec
->getName() < BRec
->getName();
3478 FeatureBitsets
.erase(llvm::unique(FeatureBitsets
), FeatureBitsets
.end());
3479 OS
<< "// Feature bitsets.\n"
3480 << "enum : " << getMinimalTypeForRange(FeatureBitsets
.size()) << " {\n"
3481 << " AMFBS_None,\n";
3482 for (const auto &FeatureBitset
: FeatureBitsets
) {
3483 if (FeatureBitset
.empty())
3485 OS
<< " " << getNameForFeatureBitset(FeatureBitset
) << ",\n";
3488 << "static constexpr FeatureBitset FeatureBitsets[] = {\n"
3489 << " {}, // AMFBS_None\n";
3490 for (const auto &FeatureBitset
: FeatureBitsets
) {
3491 if (FeatureBitset
.empty())
3494 for (const auto &Feature
: FeatureBitset
) {
3495 const auto &I
= Info
.SubtargetFeatures
.find(Feature
);
3496 assert(I
!= Info
.SubtargetFeatures
.end() && "Didn't import predicate?");
3497 OS
<< I
->second
.getEnumBitName() << ", ";
3503 // Emit the static match table; unused classes get initialized to 0 which is
3504 // guaranteed to be InvalidMatchClass.
3506 // FIXME: We can reduce the size of this table very easily. First, we change
3507 // it so that store the kinds in separate bit-fields for each index, which
3508 // only needs to be the max width used for classes at that index (we also need
3509 // to reject based on this during classification). If we then make sure to
3510 // order the match kinds appropriately (putting mnemonics last), then we
3511 // should only end up using a few bits for each class, especially the ones
3512 // following the mnemonic.
3513 OS
<< "namespace {\n";
3514 OS
<< " struct MatchEntry {\n";
3515 OS
<< " " << getMinimalTypeForRange(MaxMnemonicIndex
) << " Mnemonic;\n";
3516 OS
<< " uint16_t Opcode;\n";
3517 OS
<< " " << getMinimalTypeForRange(NumConverters
) << " ConvertFn;\n";
3518 OS
<< " " << getMinimalTypeForRange(FeatureBitsets
.size())
3519 << " RequiredFeaturesIdx;\n";
3521 << getMinimalTypeForRange(
3522 std::distance(Info
.Classes
.begin(), Info
.Classes
.end()) +
3523 2 /* Include 'InvalidMatchClass' and 'OptionalMatchClass' */)
3524 << " Classes[" << MaxNumOperands
<< "];\n";
3525 OS
<< " StringRef getMnemonic() const {\n";
3526 OS
<< " return StringRef(MnemonicTable + Mnemonic + 1,\n";
3527 OS
<< " MnemonicTable[Mnemonic]);\n";
3531 OS
<< " // Predicate for searching for an opcode.\n";
3532 OS
<< " struct LessOpcode {\n";
3533 OS
<< " bool operator()(const MatchEntry &LHS, StringRef RHS) {\n";
3534 OS
<< " return LHS.getMnemonic() < RHS;\n";
3536 OS
<< " bool operator()(StringRef LHS, const MatchEntry &RHS) {\n";
3537 OS
<< " return LHS < RHS.getMnemonic();\n";
3539 OS
<< " bool operator()(const MatchEntry &LHS, const MatchEntry &RHS) {\n";
3540 OS
<< " return LHS.getMnemonic() < RHS.getMnemonic();\n";
3544 OS
<< "} // end anonymous namespace\n\n";
3546 unsigned VariantCount
= Target
.getAsmParserVariantCount();
3547 for (unsigned VC
= 0; VC
!= VariantCount
; ++VC
) {
3548 const Record
*AsmVariant
= Target
.getAsmParserVariant(VC
);
3549 int AsmVariantNo
= AsmVariant
->getValueAsInt("Variant");
3551 OS
<< "static const MatchEntry MatchTable" << VC
<< "[] = {\n";
3553 for (const auto &MI
: Info
.Matchables
) {
3554 if (MI
->AsmVariantID
!= AsmVariantNo
)
3557 // Store a pascal-style length byte in the mnemonic.
3558 std::string LenMnemonic
=
3559 char(MI
->Mnemonic
.size()) + MI
->Mnemonic
.lower();
3560 OS
<< " { " << *StringTable
.GetStringOffset(LenMnemonic
) << " /* "
3561 << MI
->Mnemonic
<< " */, " << Target
.getInstNamespace()
3562 << "::" << MI
->getResultInst()->TheDef
->getName() << ", "
3563 << MI
->ConversionFnKind
<< ", ";
3565 // Write the required features mask.
3567 if (MI
->RequiredFeatures
.empty())
3570 for (const auto &F
: MI
->RequiredFeatures
)
3571 OS
<< '_' << F
->TheDef
->getName();
3575 for (const MatchableInfo::AsmOperand
&Op
: MI
->AsmOperands
)
3576 OS
<< LS
<< Op
.Class
->Name
;
3583 OS
<< "#include \"llvm/Support/Debug.h\"\n";
3584 OS
<< "#include \"llvm/Support/Format.h\"\n\n";
3586 // Finally, build the match function.
3587 OS
<< "unsigned " << Target
.getName() << ClassName
<< "::\n"
3588 << "MatchInstructionImpl(const OperandVector &Operands,\n";
3589 OS
<< " MCInst &Inst,\n";
3590 if (ReportMultipleNearMisses
)
3591 OS
<< " SmallVectorImpl<NearMissInfo> *NearMisses,\n";
3593 OS
<< " uint64_t &ErrorInfo,\n"
3594 << " FeatureBitset &MissingFeatures,\n";
3595 OS
<< " bool matchingInlineAsm, unsigned VariantID) {\n";
3597 if (!ReportMultipleNearMisses
) {
3598 OS
<< " // Eliminate obvious mismatches.\n";
3599 OS
<< " if (Operands.size() > " << (MaxNumOperands
+ HasMnemonicFirst
)
3601 OS
<< " ErrorInfo = " << (MaxNumOperands
+ HasMnemonicFirst
) << ";\n";
3602 OS
<< " return Match_InvalidOperand;\n";
3606 // Emit code to get the available features.
3607 OS
<< " // Get the current feature set.\n";
3608 OS
<< " const FeatureBitset &AvailableFeatures = "
3609 "getAvailableFeatures();\n\n";
3611 OS
<< " // Get the instruction mnemonic, which is the first token.\n";
3612 if (HasMnemonicFirst
) {
3613 OS
<< " StringRef Mnemonic = ((" << Target
.getName()
3614 << "Operand &)*Operands[0]).getToken();\n\n";
3616 OS
<< " StringRef Mnemonic;\n";
3617 OS
<< " if (Operands[0]->isToken())\n";
3618 OS
<< " Mnemonic = ((" << Target
.getName()
3619 << "Operand &)*Operands[0]).getToken();\n\n";
3622 if (HasMnemonicAliases
) {
3623 OS
<< " // Process all MnemonicAliases to remap the mnemonic.\n";
3624 OS
<< " applyMnemonicAliases(Mnemonic, AvailableFeatures, VariantID);\n\n";
3627 // Emit code to compute the class list for this operand vector.
3628 if (!ReportMultipleNearMisses
) {
3629 OS
<< " // Some state to try to produce better error messages.\n";
3630 OS
<< " bool HadMatchOtherThanFeatures = false;\n";
3631 OS
<< " bool HadMatchOtherThanPredicate = false;\n";
3632 OS
<< " unsigned RetCode = Match_InvalidOperand;\n";
3633 OS
<< " MissingFeatures.set();\n";
3634 OS
<< " // Set ErrorInfo to the operand that mismatches if it is\n";
3635 OS
<< " // wrong for all instances of the instruction.\n";
3636 OS
<< " ErrorInfo = ~0ULL;\n";
3639 if (HasOptionalOperands
) {
3640 OS
<< " SmallBitVector OptionalOperandsMask(" << MaxNumOperands
<< ");\n";
3643 // Emit code to search the table.
3644 OS
<< " // Find the appropriate table for this asm variant.\n";
3645 OS
<< " const MatchEntry *Start, *End;\n";
3646 OS
<< " switch (VariantID) {\n";
3647 OS
<< " default: llvm_unreachable(\"invalid variant!\");\n";
3648 for (unsigned VC
= 0; VC
!= VariantCount
; ++VC
) {
3649 const Record
*AsmVariant
= Target
.getAsmParserVariant(VC
);
3650 int AsmVariantNo
= AsmVariant
->getValueAsInt("Variant");
3651 OS
<< " case " << AsmVariantNo
<< ": Start = std::begin(MatchTable" << VC
3652 << "); End = std::end(MatchTable" << VC
<< "); break;\n";
3656 OS
<< " // Search the table.\n";
3657 if (HasMnemonicFirst
) {
3658 OS
<< " auto MnemonicRange = "
3659 "std::equal_range(Start, End, Mnemonic, LessOpcode());\n\n";
3661 OS
<< " auto MnemonicRange = std::pair(Start, End);\n";
3662 OS
<< " unsigned SIndex = Mnemonic.empty() ? 0 : 1;\n";
3663 OS
<< " if (!Mnemonic.empty())\n";
3664 OS
<< " MnemonicRange = "
3665 "std::equal_range(Start, End, Mnemonic.lower(), LessOpcode());\n\n";
3668 OS
<< " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"AsmMatcher: found \" "
3670 << " std::distance(MnemonicRange.first, MnemonicRange.second) <<\n"
3671 << " \" encodings with mnemonic '\" << Mnemonic << \"'\\n\");\n\n";
3673 OS
<< " // Return a more specific error code if no mnemonics match.\n";
3674 OS
<< " if (MnemonicRange.first == MnemonicRange.second)\n";
3675 OS
<< " return Match_MnemonicFail;\n\n";
3677 OS
<< " for (const MatchEntry *it = MnemonicRange.first, "
3678 << "*ie = MnemonicRange.second;\n";
3679 OS
<< " it != ie; ++it) {\n";
3680 OS
<< " const FeatureBitset &RequiredFeatures = "
3681 "FeatureBitsets[it->RequiredFeaturesIdx];\n";
3682 OS
<< " bool HasRequiredFeatures =\n";
3683 OS
<< " (AvailableFeatures & RequiredFeatures) == RequiredFeatures;\n";
3684 OS
<< " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"Trying to match "
3686 OS
<< " << MII.getName(it->Opcode) "
3689 if (ReportMultipleNearMisses
) {
3690 OS
<< " // Some state to record ways in which this instruction did not "
3692 OS
<< " NearMissInfo OperandNearMiss = NearMissInfo::getSuccess();\n";
3693 OS
<< " NearMissInfo FeaturesNearMiss = NearMissInfo::getSuccess();\n";
3694 OS
<< " NearMissInfo EarlyPredicateNearMiss = "
3695 "NearMissInfo::getSuccess();\n";
3696 OS
<< " NearMissInfo LatePredicateNearMiss = "
3697 "NearMissInfo::getSuccess();\n";
3698 OS
<< " bool MultipleInvalidOperands = false;\n";
3701 if (HasMnemonicFirst
) {
3702 OS
<< " // equal_range guarantees that instruction mnemonic matches.\n";
3703 OS
<< " assert(Mnemonic == it->getMnemonic());\n";
3706 // Emit check that the subclasses match.
3707 if (!ReportMultipleNearMisses
)
3708 OS
<< " bool OperandsValid = true;\n";
3709 if (HasOptionalOperands
) {
3710 OS
<< " OptionalOperandsMask.reset(0, " << MaxNumOperands
<< ");\n";
3712 OS
<< " for (unsigned FormalIdx = " << (HasMnemonicFirst
? "0" : "SIndex")
3713 << ", ActualIdx = " << (HasMnemonicFirst
? "1" : "SIndex")
3714 << "; FormalIdx != " << MaxNumOperands
<< "; ++FormalIdx) {\n";
3715 OS
<< " auto Formal = "
3716 << "static_cast<MatchClassKind>(it->Classes[FormalIdx]);\n";
3717 OS
<< " DEBUG_WITH_TYPE(\"asm-matcher\",\n";
3718 OS
<< " dbgs() << \" Matching formal operand class \" "
3719 "<< getMatchClassName(Formal)\n";
3720 OS
<< " << \" against actual operand at index \" "
3722 OS
<< " if (ActualIdx < Operands.size())\n";
3723 OS
<< " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \" (\";\n";
3724 OS
<< " Operands[ActualIdx]->print(dbgs()); dbgs() << "
3727 OS
<< " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \": \");\n";
3728 OS
<< " if (ActualIdx >= Operands.size()) {\n";
3729 OS
<< " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"actual operand "
3730 "index out of range\\n\");\n";
3731 if (ReportMultipleNearMisses
) {
3732 OS
<< " bool ThisOperandValid = (Formal == "
3733 << "InvalidMatchClass) || "
3734 "isSubclass(Formal, OptionalMatchClass);\n";
3735 OS
<< " if (!ThisOperandValid) {\n";
3736 OS
<< " if (!OperandNearMiss) {\n";
3737 OS
<< " // Record info about match failure for later use.\n";
3738 OS
<< " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"recording "
3739 "too-few-operands near miss\\n\");\n";
3740 OS
<< " OperandNearMiss =\n";
3741 OS
<< " NearMissInfo::getTooFewOperands(Formal, "
3743 OS
<< " } else if (OperandNearMiss.getKind() != "
3744 "NearMissInfo::NearMissTooFewOperands) {\n";
3745 OS
<< " // If more than one operand is invalid, give up on this "
3747 OS
<< " DEBUG_WITH_TYPE(\n";
3748 OS
<< " \"asm-matcher\",\n";
3749 OS
<< " dbgs() << \"second invalid operand, giving up on "
3750 "this opcode\\n\");\n";
3751 OS
<< " MultipleInvalidOperands = true;\n";
3754 OS
<< " } else {\n";
3755 OS
<< " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"but formal "
3756 "operand not required\\n\");\n";
3757 OS
<< " if (isSubclass(Formal, OptionalMatchClass)) {\n";
3758 OS
<< " OptionalOperandsMask.set(FormalIdx);\n";
3761 OS
<< " continue;\n";
3763 OS
<< " if (Formal == InvalidMatchClass) {\n";
3764 if (HasOptionalOperands
) {
3765 OS
<< " OptionalOperandsMask.set(FormalIdx, " << MaxNumOperands
3770 OS
<< " if (isSubclass(Formal, OptionalMatchClass)) {\n";
3771 if (HasOptionalOperands
) {
3772 OS
<< " OptionalOperandsMask.set(FormalIdx);\n";
3774 OS
<< " continue;\n";
3776 OS
<< " OperandsValid = false;\n";
3777 OS
<< " ErrorInfo = ActualIdx;\n";
3781 OS
<< " MCParsedAsmOperand &Actual = *Operands[ActualIdx];\n";
3782 OS
<< " unsigned Diag = validateOperandClass(Actual, Formal);\n";
3783 OS
<< " if (Diag == Match_Success) {\n";
3784 OS
<< " DEBUG_WITH_TYPE(\"asm-matcher\",\n";
3785 OS
<< " dbgs() << \"match success using generic "
3787 OS
<< " ++ActualIdx;\n";
3788 OS
<< " continue;\n";
3790 OS
<< " // If the generic handler indicates an invalid operand\n";
3791 OS
<< " // failure, check for a special case.\n";
3792 OS
<< " if (Diag != Match_Success) {\n";
3793 OS
<< " unsigned TargetDiag = validateTargetOperandClass(Actual, "
3795 OS
<< " if (TargetDiag == Match_Success) {\n";
3796 OS
<< " DEBUG_WITH_TYPE(\"asm-matcher\",\n";
3797 OS
<< " dbgs() << \"match success using target "
3799 OS
<< " ++ActualIdx;\n";
3800 OS
<< " continue;\n";
3802 OS
<< " // If the target matcher returned a specific error code use\n";
3803 OS
<< " // that, else use the one from the generic matcher.\n";
3804 OS
<< " if (TargetDiag != Match_InvalidOperand && "
3805 "HasRequiredFeatures)\n";
3806 OS
<< " Diag = TargetDiag;\n";
3808 OS
<< " // If current formal operand wasn't matched and it is optional\n"
3809 << " // then try to match next formal operand\n";
3810 OS
<< " if (Diag == Match_InvalidOperand "
3811 << "&& isSubclass(Formal, OptionalMatchClass)) {\n";
3812 if (HasOptionalOperands
) {
3813 OS
<< " OptionalOperandsMask.set(FormalIdx);\n";
3815 OS
<< " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"ignoring "
3816 "optional operand\\n\");\n";
3817 OS
<< " continue;\n";
3820 if (ReportMultipleNearMisses
) {
3821 OS
<< " if (!OperandNearMiss) {\n";
3822 OS
<< " // If this is the first invalid operand we have seen, "
3824 OS
<< " // information about it.\n";
3825 OS
<< " DEBUG_WITH_TYPE(\n";
3826 OS
<< " \"asm-matcher\",\n";
3828 OS
<< " << \"operand match failed, recording near-miss with "
3830 OS
<< " << Diag << \"\\n\");\n";
3831 OS
<< " OperandNearMiss =\n";
3832 OS
<< " NearMissInfo::getMissedOperand(Diag, Formal, "
3833 "it->Opcode, ActualIdx);\n";
3834 OS
<< " ++ActualIdx;\n";
3835 OS
<< " } else {\n";
3836 OS
<< " // If more than one operand is invalid, give up on this "
3838 OS
<< " DEBUG_WITH_TYPE(\n";
3839 OS
<< " \"asm-matcher\",\n";
3840 OS
<< " dbgs() << \"second operand mismatch, skipping this "
3842 OS
<< " MultipleInvalidOperands = true;\n";
3847 OS
<< " // If this operand is broken for all of the instances of "
3849 OS
<< " // mnemonic, keep track of it so we can report loc info.\n";
3850 OS
<< " // If we already had a match that only failed due to a\n";
3851 OS
<< " // target predicate, that diagnostic is preferred.\n";
3852 OS
<< " if (!HadMatchOtherThanPredicate &&\n";
3853 OS
<< " (it == MnemonicRange.first || ErrorInfo <= ActualIdx)) "
3855 OS
<< " if (HasRequiredFeatures && (ErrorInfo != ActualIdx || Diag "
3856 "!= Match_InvalidOperand))\n";
3857 OS
<< " RetCode = Diag;\n";
3858 OS
<< " ErrorInfo = ActualIdx;\n";
3860 OS
<< " // Otherwise, just reject this instance of the mnemonic.\n";
3861 OS
<< " OperandsValid = false;\n";
3866 if (ReportMultipleNearMisses
)
3867 OS
<< " if (MultipleInvalidOperands) {\n";
3869 OS
<< " if (!OperandsValid) {\n";
3870 OS
<< " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"Opcode result: "
3872 OS
<< " \"operand mismatches, "
3874 OS
<< " \"this opcode\\n\");\n";
3875 OS
<< " continue;\n";
3878 // Emit check that the required features are available.
3879 OS
<< " if (!HasRequiredFeatures) {\n";
3880 if (!ReportMultipleNearMisses
)
3881 OS
<< " HadMatchOtherThanFeatures = true;\n";
3882 OS
<< " FeatureBitset NewMissingFeatures = RequiredFeatures & "
3883 "~AvailableFeatures;\n";
3884 OS
<< " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"Missing target "
3886 OS
<< " for (unsigned I = 0, E = "
3887 "NewMissingFeatures.size(); I != E; ++I)\n";
3888 OS
<< " if (NewMissingFeatures[I])\n";
3889 OS
<< " dbgs() << ' ' << I;\n";
3890 OS
<< " dbgs() << \"\\n\");\n";
3891 if (ReportMultipleNearMisses
) {
3892 OS
<< " FeaturesNearMiss = "
3893 "NearMissInfo::getMissedFeature(NewMissingFeatures);\n";
3895 OS
<< " if (NewMissingFeatures.count() <=\n"
3896 " MissingFeatures.count())\n";
3897 OS
<< " MissingFeatures = NewMissingFeatures;\n";
3898 OS
<< " continue;\n";
3902 OS
<< " Inst.clear();\n\n";
3903 OS
<< " Inst.setOpcode(it->Opcode);\n";
3904 // Verify the instruction with the target-specific match predicate function.
3905 OS
<< " // We have a potential match but have not rendered the operands.\n"
3906 << " // Check the target predicate to handle any context sensitive\n"
3907 " // constraints.\n"
3908 << " // For example, Ties that are referenced multiple times must be\n"
3909 " // checked here to ensure the input is the same for each match\n"
3910 " // constraints. If we leave it any later the ties will have been\n"
3911 " // canonicalized\n"
3912 << " unsigned MatchResult;\n"
3913 << " if ((MatchResult = checkEarlyTargetMatchPredicate(Inst, "
3914 "Operands)) != Match_Success) {\n"
3915 << " Inst.clear();\n";
3916 OS
<< " DEBUG_WITH_TYPE(\n";
3917 OS
<< " \"asm-matcher\",\n";
3918 OS
<< " dbgs() << \"Early target match predicate failed with diag "
3920 OS
<< " << MatchResult << \"\\n\");\n";
3921 if (ReportMultipleNearMisses
) {
3922 OS
<< " EarlyPredicateNearMiss = "
3923 "NearMissInfo::getMissedPredicate(MatchResult);\n";
3925 OS
<< " RetCode = MatchResult;\n"
3926 << " HadMatchOtherThanPredicate = true;\n"
3931 if (ReportMultipleNearMisses
) {
3932 OS
<< " // If we did not successfully match the operands, then we can't "
3934 OS
<< " // an MCInst, so bail out on this instruction variant now.\n";
3935 OS
<< " if (OperandNearMiss) {\n";
3936 OS
<< " // If the operand mismatch was the only problem, reprrt it as "
3938 OS
<< " if (NearMisses && !FeaturesNearMiss && "
3939 "!EarlyPredicateNearMiss) {\n";
3940 OS
<< " DEBUG_WITH_TYPE(\n";
3941 OS
<< " \"asm-matcher\",\n";
3943 OS
<< " << \"Opcode result: one mismatched operand, adding "
3944 "near-miss\\n\");\n";
3945 OS
<< " NearMisses->push_back(OperandNearMiss);\n";
3946 OS
<< " } else {\n";
3947 OS
<< " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"Opcode result: "
3949 OS
<< " \"types of "
3950 "mismatch, so not \"\n";
3951 OS
<< " \"reporting "
3952 "near-miss\\n\");\n";
3954 OS
<< " continue;\n";
3958 // When converting parsed operands to MCInst we need to know whether optional
3959 // operands were parsed or not so that we can choose the correct converter
3960 // function. We also need to know this when checking tied operand constraints.
3961 // DefaultsOffset is an array of deltas between the formal (MCInst) and the
3962 // actual (parsed operand array) operand indices. When all optional operands
3963 // are present, all elements of the array are zeros. If some of the optional
3964 // operands are absent, the array might look like '0, 0, 1, 1, 1, 2, 2, 3',
3965 // where each increment in value reflects the absence of an optional operand.
3966 if (HasOptionalOperands
) {
3967 OS
<< " unsigned DefaultsOffset[" << (MaxNumOperands
+ 1)
3969 OS
<< " assert(OptionalOperandsMask.size() == " << (MaxNumOperands
)
3971 OS
<< " for (unsigned i = 0, NumDefaults = 0; i < " << (MaxNumOperands
)
3973 OS
<< " DefaultsOffset[i + 1] = NumDefaults;\n";
3974 OS
<< " NumDefaults += (OptionalOperandsMask[i] ? 1 : 0);\n";
3978 OS
<< " if (matchingInlineAsm) {\n";
3979 OS
<< " convertToMapAndConstraints(it->ConvertFn, Operands);\n";
3980 if (!ReportMultipleNearMisses
) {
3981 if (HasOptionalOperands
) {
3982 OS
<< " if (!checkAsmTiedOperandConstraints(*this, it->ConvertFn, "
3984 OS
<< " DefaultsOffset, "
3987 OS
<< " if (!checkAsmTiedOperandConstraints(*this, it->ConvertFn, "
3989 OS
<< " ErrorInfo))\n";
3991 OS
<< " return Match_InvalidTiedOperand;\n";
3994 OS
<< " return Match_Success;\n";
3996 OS
<< " // We have selected a definite instruction, convert the parsed\n"
3997 << " // operands into the appropriate MCInst.\n";
3998 if (HasOptionalOperands
) {
3999 OS
<< " convertToMCInst(it->ConvertFn, Inst, it->Opcode, Operands,\n"
4000 << " OptionalOperandsMask, DefaultsOffset);\n";
4002 OS
<< " convertToMCInst(it->ConvertFn, Inst, it->Opcode, Operands);\n";
4006 // Verify the instruction with the target-specific match predicate function.
4007 OS
<< " // We have a potential match. Check the target predicate to\n"
4008 << " // handle any context sensitive constraints.\n"
4009 << " if ((MatchResult = checkTargetMatchPredicate(Inst)) !="
4010 << " Match_Success) {\n"
4011 << " DEBUG_WITH_TYPE(\"asm-matcher\",\n"
4012 << " dbgs() << \"Target match predicate failed with "
4014 << " << MatchResult << \"\\n\");\n"
4015 << " Inst.clear();\n";
4016 if (ReportMultipleNearMisses
) {
4017 OS
<< " LatePredicateNearMiss = "
4018 "NearMissInfo::getMissedPredicate(MatchResult);\n";
4020 OS
<< " RetCode = MatchResult;\n"
4021 << " HadMatchOtherThanPredicate = true;\n"
4026 if (ReportMultipleNearMisses
) {
4027 OS
<< " int NumNearMisses = ((int)(bool)OperandNearMiss +\n";
4028 OS
<< " (int)(bool)FeaturesNearMiss +\n";
4029 OS
<< " (int)(bool)EarlyPredicateNearMiss +\n";
4030 OS
<< " (int)(bool)LatePredicateNearMiss);\n";
4031 OS
<< " if (NumNearMisses == 1) {\n";
4032 OS
<< " // We had exactly one type of near-miss, so add that to the "
4034 OS
<< " assert(!OperandNearMiss && \"OperandNearMiss was handled "
4036 OS
<< " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"Opcode result: "
4037 "found one type of \"\n";
4038 OS
<< " \"mismatch, so "
4040 OS
<< " \"near-miss\\n\");\n";
4041 OS
<< " if (NearMisses && FeaturesNearMiss)\n";
4042 OS
<< " NearMisses->push_back(FeaturesNearMiss);\n";
4043 OS
<< " else if (NearMisses && EarlyPredicateNearMiss)\n";
4044 OS
<< " NearMisses->push_back(EarlyPredicateNearMiss);\n";
4045 OS
<< " else if (NearMisses && LatePredicateNearMiss)\n";
4046 OS
<< " NearMisses->push_back(LatePredicateNearMiss);\n";
4048 OS
<< " continue;\n";
4049 OS
<< " } else if (NumNearMisses > 1) {\n";
4050 OS
<< " // This instruction missed in more than one way, so ignore "
4052 OS
<< " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"Opcode result: "
4054 OS
<< " \"types of mismatch, "
4056 OS
<< " \"reporting "
4057 "near-miss\\n\");\n";
4058 OS
<< " continue;\n";
4062 // Call the post-processing function, if used.
4063 StringRef InsnCleanupFn
= AsmParser
->getValueAsString("AsmParserInstCleanup");
4064 if (!InsnCleanupFn
.empty())
4065 OS
<< " " << InsnCleanupFn
<< "(Inst);\n";
4067 if (HasDeprecation
) {
4068 OS
<< " std::string Info;\n";
4070 "(!getParser().getTargetParser().getTargetOptions()."
4071 "MCNoDeprecatedWarn &&\n";
4072 OS
<< " MII.getDeprecatedInfo(Inst, getSTI(), Info)) {\n";
4073 OS
<< " SMLoc Loc = ((" << Target
.getName()
4074 << "Operand &)*Operands[0]).getStartLoc();\n";
4075 OS
<< " getParser().Warning(Loc, Info, std::nullopt);\n";
4079 if (!ReportMultipleNearMisses
) {
4080 if (HasOptionalOperands
) {
4081 OS
<< " if (!checkAsmTiedOperandConstraints(*this, it->ConvertFn, "
4083 OS
<< " DefaultsOffset, "
4086 OS
<< " if (!checkAsmTiedOperandConstraints(*this, it->ConvertFn, "
4088 OS
<< " ErrorInfo))\n";
4090 OS
<< " return Match_InvalidTiedOperand;\n";
4094 OS
<< " DEBUG_WITH_TYPE(\n";
4095 OS
<< " \"asm-matcher\",\n";
4096 OS
<< " dbgs() << \"Opcode result: complete match, selecting this "
4098 OS
<< " return Match_Success;\n";
4101 if (ReportMultipleNearMisses
) {
4102 OS
<< " // No instruction variants matched exactly.\n";
4103 OS
<< " return Match_NearMisses;\n";
4105 OS
<< " // Okay, we had no match. Try to return a useful error code.\n";
4106 OS
<< " if (HadMatchOtherThanPredicate || !HadMatchOtherThanFeatures)\n";
4107 OS
<< " return RetCode;\n\n";
4108 OS
<< " ErrorInfo = 0;\n";
4109 OS
<< " return Match_MissingFeature;\n";
4113 if (!Info
.OperandMatchInfo
.empty())
4114 emitCustomOperandParsing(OS
, Target
, Info
, ClassName
, StringTable
,
4115 MaxMnemonicIndex
, FeatureBitsets
.size(),
4116 HasMnemonicFirst
, *AsmParser
);
4118 OS
<< "#endif // GET_MATCHER_IMPLEMENTATION\n\n";
4120 OS
<< "\n#ifdef GET_MNEMONIC_SPELL_CHECKER\n";
4121 OS
<< "#undef GET_MNEMONIC_SPELL_CHECKER\n\n";
4123 emitMnemonicSpellChecker(OS
, Target
, VariantCount
);
4125 OS
<< "#endif // GET_MNEMONIC_SPELL_CHECKER\n\n";
4127 OS
<< "\n#ifdef GET_MNEMONIC_CHECKER\n";
4128 OS
<< "#undef GET_MNEMONIC_CHECKER\n\n";
4130 emitMnemonicChecker(OS
, Target
, VariantCount
, HasMnemonicFirst
,
4131 HasMnemonicAliases
);
4133 OS
<< "#endif // GET_MNEMONIC_CHECKER\n\n";
4136 static TableGen::Emitter::OptClass
<AsmMatcherEmitter
>
4137 X("gen-asm-matcher", "Generate assembly instruction matcher");