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(AsmMatcherInfo
&Info
, raw_ostream
&OS
) {
2470 OS
<< "static unsigned validateOperandClass(MCParsedAsmOperand &GOp, "
2471 << "MatchClassKind Kind) {\n";
2472 OS
<< " " << Info
.Target
.getName() << "Operand &Operand = ("
2473 << Info
.Target
.getName() << "Operand &)GOp;\n";
2475 // The InvalidMatchClass is not to match any operand.
2476 OS
<< " if (Kind == InvalidMatchClass)\n";
2477 OS
<< " return MCTargetAsmParser::Match_InvalidOperand;\n\n";
2479 // Check for Token operands first.
2480 // FIXME: Use a more specific diagnostic type.
2481 OS
<< " if (Operand.isToken() && Kind <= MCK_LAST_TOKEN)\n";
2482 OS
<< " return isSubclass(matchTokenString(Operand.getToken()), Kind) ?\n"
2483 << " MCTargetAsmParser::Match_Success :\n"
2484 << " MCTargetAsmParser::Match_InvalidOperand;\n\n";
2486 // Check the user classes. We don't care what order since we're only
2487 // actually matching against one of them.
2488 OS
<< " switch (Kind) {\n"
2489 " default: break;\n";
2490 for (const auto &CI
: Info
.Classes
) {
2491 if (!CI
.isUserClass())
2494 OS
<< " // '" << CI
.ClassName
<< "' class\n";
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 OS
<< " if (Operand.isReg()) {\n";
2513 OS
<< " MatchClassKind OpKind;\n";
2514 OS
<< " switch (Operand.getReg().id()) {\n";
2515 OS
<< " default: OpKind = InvalidMatchClass; break;\n";
2516 for (const auto &RC
: Info
.RegisterClasses
)
2517 OS
<< " case " << RC
.first
->getValueAsString("Namespace")
2518 << "::" << RC
.first
->getName() << ": OpKind = " << RC
.second
->Name
2521 OS
<< " return isSubclass(OpKind, Kind) ? "
2522 << "(unsigned)MCTargetAsmParser::Match_Success :\n "
2523 << " getDiagKindFromRegisterClass(Kind);\n }\n\n";
2525 // Expected operand is a register, but actual is not.
2526 OS
<< " if (Kind > MCK_LAST_TOKEN && Kind <= MCK_LAST_REGISTER)\n";
2527 OS
<< " return getDiagKindFromRegisterClass(Kind);\n\n";
2529 // Generic fallthrough match failure case for operands that don't have
2530 // specialized diagnostic types.
2531 OS
<< " return MCTargetAsmParser::Match_InvalidOperand;\n";
2535 /// emitIsSubclass - Emit the subclass predicate function.
2536 static void emitIsSubclass(CodeGenTarget
&Target
,
2537 std::forward_list
<ClassInfo
> &Infos
,
2539 OS
<< "/// isSubclass - Compute whether \\p A is a subclass of \\p B.\n";
2540 OS
<< "static bool isSubclass(MatchClassKind A, MatchClassKind B) {\n";
2541 OS
<< " if (A == B)\n";
2542 OS
<< " return true;\n\n";
2544 bool EmittedSwitch
= false;
2545 for (const auto &A
: Infos
) {
2546 std::vector
<StringRef
> SuperClasses
;
2548 SuperClasses
.push_back("OptionalMatchClass");
2549 for (const auto &B
: Infos
) {
2550 if (&A
!= &B
&& A
.isSubsetOf(B
))
2551 SuperClasses
.push_back(B
.Name
);
2554 if (SuperClasses
.empty())
2557 // If this is the first SuperClass, emit the switch header.
2558 if (!EmittedSwitch
) {
2559 OS
<< " switch (A) {\n";
2560 OS
<< " default:\n";
2561 OS
<< " return false;\n";
2562 EmittedSwitch
= true;
2565 OS
<< "\n case " << A
.Name
<< ":\n";
2567 if (SuperClasses
.size() == 1) {
2568 OS
<< " return B == " << SuperClasses
.back() << ";\n";
2572 if (!SuperClasses
.empty()) {
2573 OS
<< " switch (B) {\n";
2574 OS
<< " default: return false;\n";
2575 for (StringRef SC
: SuperClasses
)
2576 OS
<< " case " << SC
<< ": return true;\n";
2579 // No case statement to emit
2580 OS
<< " return false;\n";
2584 // If there were case statements emitted into the string stream write the
2589 OS
<< " return false;\n";
2594 /// emitMatchTokenString - Emit the function to match a token string to the
2595 /// appropriate match class value.
2596 static void emitMatchTokenString(CodeGenTarget
&Target
,
2597 std::forward_list
<ClassInfo
> &Infos
,
2599 // Construct the match list.
2600 std::vector
<StringMatcher::StringPair
> Matches
;
2601 for (const auto &CI
: Infos
) {
2602 if (CI
.Kind
== ClassInfo::Token
)
2603 Matches
.emplace_back(CI
.ValueName
, "return " + CI
.Name
+ ";");
2606 OS
<< "static MatchClassKind matchTokenString(StringRef Name) {\n";
2608 StringMatcher("Name", Matches
, OS
).Emit();
2610 OS
<< " return InvalidMatchClass;\n";
2614 /// emitMatchRegisterName - Emit the function to match a string to the target
2615 /// specific register enum.
2616 static void emitMatchRegisterName(const CodeGenTarget
&Target
,
2617 const Record
*AsmParser
, raw_ostream
&OS
) {
2618 // Construct the match list.
2619 std::vector
<StringMatcher::StringPair
> Matches
;
2620 const auto &Regs
= Target
.getRegBank().getRegisters();
2621 std::string Namespace
=
2622 Regs
.front().TheDef
->getValueAsString("Namespace").str();
2623 for (const CodeGenRegister
&Reg
: Regs
) {
2624 StringRef AsmName
= Reg
.TheDef
->getValueAsString("AsmName");
2625 if (AsmName
.empty())
2628 Matches
.emplace_back(AsmName
.str(), "return " + Namespace
+
2629 "::" + Reg
.getName().str() + ';');
2632 OS
<< "static MCRegister MatchRegisterName(StringRef Name) {\n";
2634 bool IgnoreDuplicates
=
2635 AsmParser
->getValueAsBit("AllowDuplicateRegisterNames");
2636 StringMatcher("Name", Matches
, OS
).Emit(0, IgnoreDuplicates
);
2638 OS
<< " return " << Namespace
<< "::NoRegister;\n";
2642 /// Emit the function to match a string to the target
2643 /// specific register enum.
2644 static void emitMatchRegisterAltName(const CodeGenTarget
&Target
,
2645 const Record
*AsmParser
, raw_ostream
&OS
) {
2646 // Construct the match list.
2647 std::vector
<StringMatcher::StringPair
> Matches
;
2648 const auto &Regs
= Target
.getRegBank().getRegisters();
2649 std::string Namespace
=
2650 Regs
.front().TheDef
->getValueAsString("Namespace").str();
2651 for (const CodeGenRegister
&Reg
: Regs
) {
2653 auto AltNames
= Reg
.TheDef
->getValueAsListOfStrings("AltNames");
2655 for (auto AltName
: AltNames
) {
2656 AltName
= StringRef(AltName
).trim();
2658 // don't handle empty alternative names
2659 if (AltName
.empty())
2662 Matches
.emplace_back(AltName
.str(), "return " + Namespace
+
2663 "::" + Reg
.getName().str() + ';');
2667 OS
<< "static MCRegister MatchRegisterAltName(StringRef Name) {\n";
2669 bool IgnoreDuplicates
=
2670 AsmParser
->getValueAsBit("AllowDuplicateRegisterNames");
2671 StringMatcher("Name", Matches
, OS
).Emit(0, IgnoreDuplicates
);
2673 OS
<< " return " << Namespace
<< "::NoRegister;\n";
2677 /// emitOperandDiagnosticTypes - Emit the operand matching diagnostic types.
2678 static void emitOperandDiagnosticTypes(AsmMatcherInfo
&Info
, raw_ostream
&OS
) {
2679 // Get the set of diagnostic types from all of the operand classes.
2680 std::set
<StringRef
> Types
;
2681 for (const auto &OpClassEntry
: Info
.AsmOperandClasses
) {
2682 if (!OpClassEntry
.second
->DiagnosticType
.empty())
2683 Types
.insert(OpClassEntry
.second
->DiagnosticType
);
2685 for (const auto &OpClassEntry
: Info
.RegisterClassClasses
) {
2686 if (!OpClassEntry
.second
->DiagnosticType
.empty())
2687 Types
.insert(OpClassEntry
.second
->DiagnosticType
);
2693 // Now emit the enum entries.
2694 for (StringRef Type
: Types
)
2695 OS
<< " Match_" << Type
<< ",\n";
2696 OS
<< " END_OPERAND_DIAGNOSTIC_TYPES\n";
2699 /// emitGetSubtargetFeatureName - Emit the helper function to get the
2700 /// user-level name for a subtarget feature.
2701 static void emitGetSubtargetFeatureName(AsmMatcherInfo
&Info
, raw_ostream
&OS
) {
2702 OS
<< "// User-level names for subtarget features that participate in\n"
2703 << "// instruction matching.\n"
2704 << "static const char *getSubtargetFeatureName(uint64_t Val) {\n";
2705 if (!Info
.SubtargetFeatures
.empty()) {
2706 OS
<< " switch(Val) {\n";
2707 for (const auto &SF
: Info
.SubtargetFeatures
) {
2708 const SubtargetFeatureInfo
&SFI
= SF
.second
;
2709 // FIXME: Totally just a placeholder name to get the algorithm working.
2710 OS
<< " case " << SFI
.getEnumBitName() << ": return \""
2711 << SFI
.TheDef
->getValueAsString("PredicateName") << "\";\n";
2713 OS
<< " default: return \"(unknown)\";\n";
2716 // Nothing to emit, so skip the switch
2717 OS
<< " return \"(unknown)\";\n";
2722 static std::string
GetAliasRequiredFeatures(const Record
*R
,
2723 const AsmMatcherInfo
&Info
) {
2727 for (const Record
*RF
: R
->getValueAsListOfDefs("Predicates")) {
2728 const SubtargetFeatureInfo
*F
= Info
.getSubtargetFeature(RF
);
2730 PrintFatalError(R
->getLoc(),
2731 "Predicate '" + RF
->getName() +
2732 "' is not marked as an AssemblerPredicate!");
2735 Result
+= "Features.test(" + F
->getEnumBitName() + ')';
2743 emitMnemonicAliasVariant(raw_ostream
&OS
, const AsmMatcherInfo
&Info
,
2744 ArrayRef
<const Record
*> Aliases
, unsigned Indent
= 0,
2745 StringRef AsmParserVariantName
= StringRef()) {
2746 // Keep track of all the aliases from a mnemonic. Use an std::map so that the
2747 // iteration order of the map is stable.
2748 std::map
<std::string
, std::vector
<const Record
*>> AliasesFromMnemonic
;
2750 for (const Record
*R
: Aliases
) {
2751 // FIXME: Allow AssemblerVariantName to be a comma separated list.
2752 StringRef AsmVariantName
= R
->getValueAsString("AsmVariantName");
2753 if (AsmVariantName
!= AsmParserVariantName
)
2755 AliasesFromMnemonic
[R
->getValueAsString("FromMnemonic").lower()].push_back(
2758 if (AliasesFromMnemonic
.empty())
2761 // Process each alias a "from" mnemonic at a time, building the code executed
2762 // by the string remapper.
2763 std::vector
<StringMatcher::StringPair
> Cases
;
2764 for (const auto &AliasEntry
: AliasesFromMnemonic
) {
2765 // Loop through each alias and emit code that handles each case. If there
2766 // are two instructions without predicates, emit an error. If there is one,
2768 std::string MatchCode
;
2769 int AliasWithNoPredicate
= -1;
2771 ArrayRef
<const Record
*> ToVec
= AliasEntry
.second
;
2772 for (const auto &[Idx
, R
] : enumerate(ToVec
)) {
2773 std::string FeatureMask
= GetAliasRequiredFeatures(R
, Info
);
2775 // If this unconditionally matches, remember it for later and diagnose
2777 if (FeatureMask
.empty()) {
2778 if (AliasWithNoPredicate
!= -1 &&
2779 R
->getValueAsString("ToMnemonic") !=
2780 ToVec
[AliasWithNoPredicate
]->getValueAsString("ToMnemonic")) {
2781 // We can't have two different aliases from the same mnemonic with no
2784 ToVec
[AliasWithNoPredicate
]->getLoc(),
2785 "two different MnemonicAliases with the same 'from' mnemonic!");
2786 PrintFatalError(R
->getLoc(), "this is the other MnemonicAlias.");
2789 AliasWithNoPredicate
= Idx
;
2792 if (R
->getValueAsString("ToMnemonic") == AliasEntry
.first
)
2793 PrintFatalError(R
->getLoc(), "MnemonicAlias to the same string");
2795 if (!MatchCode
.empty())
2796 MatchCode
+= "else ";
2797 MatchCode
+= "if (" + FeatureMask
+ ")\n";
2798 MatchCode
+= " Mnemonic = \"";
2799 MatchCode
+= R
->getValueAsString("ToMnemonic").lower();
2800 MatchCode
+= "\";\n";
2803 if (AliasWithNoPredicate
!= -1) {
2804 const Record
*R
= ToVec
[AliasWithNoPredicate
];
2805 if (!MatchCode
.empty())
2806 MatchCode
+= "else\n ";
2807 MatchCode
+= "Mnemonic = \"";
2808 MatchCode
+= R
->getValueAsString("ToMnemonic").lower();
2809 MatchCode
+= "\";\n";
2812 MatchCode
+= "return;";
2814 Cases
.push_back(std::pair(AliasEntry
.first
, MatchCode
));
2816 StringMatcher("Mnemonic", Cases
, OS
).Emit(Indent
);
2819 /// emitMnemonicAliases - If the target has any MnemonicAlias<> definitions,
2820 /// emit a function for them and return true, otherwise return false.
2821 static bool emitMnemonicAliases(raw_ostream
&OS
, const AsmMatcherInfo
&Info
,
2822 CodeGenTarget
&Target
) {
2823 // Ignore aliases when match-prefix is set.
2824 if (!MatchPrefix
.empty())
2827 ArrayRef
<const Record
*> Aliases
=
2828 Info
.getRecords().getAllDerivedDefinitions("MnemonicAlias");
2829 if (Aliases
.empty())
2832 OS
<< "static void applyMnemonicAliases(StringRef &Mnemonic, "
2833 "const FeatureBitset &Features, unsigned VariantID) {\n";
2834 unsigned VariantCount
= Target
.getAsmParserVariantCount();
2835 for (unsigned VC
= 0; VC
!= VariantCount
; ++VC
) {
2836 const Record
*AsmVariant
= Target
.getAsmParserVariant(VC
);
2837 int AsmParserVariantNo
= AsmVariant
->getValueAsInt("Variant");
2838 StringRef AsmParserVariantName
= AsmVariant
->getValueAsString("Name");
2840 // If the variant doesn't have a name, defer to the emitMnemonicAliasVariant
2841 // call after the loop.
2842 if (AsmParserVariantName
.empty()) {
2843 assert(VariantCount
== 1 && "Multiple variants should each be named");
2848 OS
<< " switch (VariantID) {\n";
2849 OS
<< " case " << AsmParserVariantNo
<< ":\n";
2850 emitMnemonicAliasVariant(OS
, Info
, Aliases
, /*Indent=*/2,
2851 AsmParserVariantName
);
2854 if (VC
== VariantCount
- 1)
2858 // Emit aliases that apply to all variants.
2859 emitMnemonicAliasVariant(OS
, Info
, Aliases
);
2867 emitCustomOperandParsing(raw_ostream
&OS
, CodeGenTarget
&Target
,
2868 const AsmMatcherInfo
&Info
, StringRef ClassName
,
2869 const StringToOffsetTable
&StringTable
,
2870 unsigned MaxMnemonicIndex
, unsigned MaxFeaturesIndex
,
2871 bool HasMnemonicFirst
, const Record
&AsmParser
) {
2872 unsigned MaxMask
= 0;
2873 for (const OperandMatchEntry
&OMI
: Info
.OperandMatchInfo
) {
2874 MaxMask
|= OMI
.OperandMask
;
2877 // Emit the static custom operand parsing table;
2878 OS
<< "namespace {\n";
2879 OS
<< " struct OperandMatchEntry {\n";
2880 OS
<< " " << getMinimalTypeForRange(MaxMnemonicIndex
) << " Mnemonic;\n";
2881 OS
<< " " << getMinimalTypeForRange(MaxMask
) << " OperandMask;\n";
2883 << getMinimalTypeForRange(
2884 std::distance(Info
.Classes
.begin(), Info
.Classes
.end()) +
2885 2 /* Include 'InvalidMatchClass' and 'OptionalMatchClass' */)
2887 OS
<< " " << getMinimalTypeForRange(MaxFeaturesIndex
)
2888 << " RequiredFeaturesIdx;\n\n";
2889 OS
<< " StringRef getMnemonic() const {\n";
2890 OS
<< " return StringRef(MnemonicTable + Mnemonic + 1,\n";
2891 OS
<< " MnemonicTable[Mnemonic]);\n";
2895 OS
<< " // Predicate for searching for an opcode.\n";
2896 OS
<< " struct LessOpcodeOperand {\n";
2897 OS
<< " bool operator()(const OperandMatchEntry &LHS, StringRef RHS) {\n";
2898 OS
<< " return LHS.getMnemonic() < RHS;\n";
2900 OS
<< " bool operator()(StringRef LHS, const OperandMatchEntry &RHS) {\n";
2901 OS
<< " return LHS < RHS.getMnemonic();\n";
2903 OS
<< " bool operator()(const OperandMatchEntry &LHS,";
2904 OS
<< " const OperandMatchEntry &RHS) {\n";
2905 OS
<< " return LHS.getMnemonic() < RHS.getMnemonic();\n";
2909 OS
<< "} // end anonymous namespace\n\n";
2911 OS
<< "static const OperandMatchEntry OperandMatchTable["
2912 << Info
.OperandMatchInfo
.size() << "] = {\n";
2914 OS
<< " /* Operand List Mnemonic, Mask, Operand Class, Features */\n";
2915 for (const OperandMatchEntry
&OMI
: Info
.OperandMatchInfo
) {
2916 const MatchableInfo
&II
= *OMI
.MI
;
2920 // Store a pascal-style length byte in the mnemonic.
2921 std::string LenMnemonic
= char(II
.Mnemonic
.size()) + II
.Mnemonic
.lower();
2922 OS
<< *StringTable
.GetStringOffset(LenMnemonic
) << " /* " << II
.Mnemonic
2925 OS
<< OMI
.OperandMask
;
2928 for (int i
= 0, e
= 31; i
!= e
; ++i
)
2929 if (OMI
.OperandMask
& (1 << i
))
2935 // Write the required features mask.
2937 if (II
.RequiredFeatures
.empty())
2940 for (const auto &F
: II
.RequiredFeatures
)
2941 OS
<< '_' << F
->TheDef
->getName();
2947 // Emit the operand class switch to call the correct custom parser for
2948 // the found operand class.
2949 OS
<< "ParseStatus " << Target
.getName() << ClassName
<< "::\n"
2950 << "tryCustomParseOperand(OperandVector"
2951 << " &Operands,\n unsigned MCK) {\n\n"
2952 << " switch(MCK) {\n";
2954 for (const auto &CI
: Info
.Classes
) {
2955 if (CI
.ParserMethod
.empty())
2957 OS
<< " case " << CI
.Name
<< ":\n"
2958 << " return " << CI
.ParserMethod
<< "(Operands);\n";
2961 OS
<< " default:\n";
2962 OS
<< " return ParseStatus::NoMatch;\n";
2964 OS
<< " return ParseStatus::NoMatch;\n";
2967 // Emit the static custom operand parser. This code is very similar with
2968 // the other matcher. Also use MatchResultTy here just in case we go for
2969 // a better error handling.
2970 OS
<< "ParseStatus " << Target
.getName() << ClassName
<< "::\n"
2971 << "MatchOperandParserImpl(OperandVector"
2972 << " &Operands,\n StringRef Mnemonic,\n"
2973 << " bool ParseForAllFeatures) {\n";
2975 // Emit code to get the available features.
2976 OS
<< " // Get the current feature set.\n";
2977 OS
<< " const FeatureBitset &AvailableFeatures = "
2978 "getAvailableFeatures();\n\n";
2980 OS
<< " // Get the next operand index.\n";
2981 OS
<< " unsigned NextOpNum = Operands.size()"
2982 << (HasMnemonicFirst
? " - 1" : "") << ";\n";
2984 // Emit code to search the table.
2985 OS
<< " // Search the table.\n";
2986 if (HasMnemonicFirst
) {
2987 OS
<< " auto MnemonicRange =\n";
2988 OS
<< " std::equal_range(std::begin(OperandMatchTable), "
2989 "std::end(OperandMatchTable),\n";
2990 OS
<< " Mnemonic, LessOpcodeOperand());\n\n";
2992 OS
<< " auto MnemonicRange = std::pair(std::begin(OperandMatchTable),"
2993 " std::end(OperandMatchTable));\n";
2994 OS
<< " if (!Mnemonic.empty())\n";
2995 OS
<< " MnemonicRange =\n";
2996 OS
<< " std::equal_range(std::begin(OperandMatchTable), "
2997 "std::end(OperandMatchTable),\n";
2998 OS
<< " Mnemonic, LessOpcodeOperand());\n\n";
3001 OS
<< " if (MnemonicRange.first == MnemonicRange.second)\n";
3002 OS
<< " return ParseStatus::NoMatch;\n\n";
3004 OS
<< " for (const OperandMatchEntry *it = MnemonicRange.first,\n"
3005 << " *ie = MnemonicRange.second; it != ie; ++it) {\n";
3007 OS
<< " // equal_range guarantees that instruction mnemonic matches.\n";
3008 OS
<< " assert(Mnemonic == it->getMnemonic());\n\n";
3010 // Emit check that the required features are available.
3011 OS
<< " // check if the available features match\n";
3012 OS
<< " const FeatureBitset &RequiredFeatures = "
3013 "FeatureBitsets[it->RequiredFeaturesIdx];\n";
3014 OS
<< " if (!ParseForAllFeatures && (AvailableFeatures & "
3015 "RequiredFeatures) != RequiredFeatures)\n";
3016 OS
<< " continue;\n\n";
3018 // Emit check to ensure the operand number matches.
3019 OS
<< " // check if the operand in question has a custom parser.\n";
3020 OS
<< " if (!(it->OperandMask & (1 << NextOpNum)))\n";
3021 OS
<< " continue;\n\n";
3023 // Emit call to the custom parser method
3024 StringRef ParserName
= AsmParser
.getValueAsString("OperandParserMethod");
3025 if (ParserName
.empty())
3026 ParserName
= "tryCustomParseOperand";
3027 OS
<< " // call custom parse method to handle the operand\n";
3028 OS
<< " ParseStatus Result = " << ParserName
<< "(Operands, it->Class);\n";
3029 OS
<< " if (!Result.isNoMatch())\n";
3030 OS
<< " return Result;\n";
3033 OS
<< " // Okay, we had no match.\n";
3034 OS
<< " return ParseStatus::NoMatch;\n";
3038 static void emitAsmTiedOperandConstraints(CodeGenTarget
&Target
,
3039 AsmMatcherInfo
&Info
, raw_ostream
&OS
,
3040 bool HasOptionalOperands
) {
3041 std::string AsmParserName
=
3042 std::string(Info
.AsmParser
->getValueAsString("AsmParserClassName"));
3043 OS
<< "static bool ";
3044 OS
<< "checkAsmTiedOperandConstraints(const " << Target
.getName()
3045 << AsmParserName
<< "&AsmParser,\n";
3046 OS
<< " unsigned Kind, const OperandVector "
3048 if (HasOptionalOperands
)
3049 OS
<< " ArrayRef<unsigned> DefaultsOffset,\n";
3050 OS
<< " uint64_t &ErrorInfo) {\n";
3051 OS
<< " assert(Kind < CVT_NUM_SIGNATURES && \"Invalid signature!\");\n";
3052 OS
<< " const uint8_t *Converter = ConversionTable[Kind];\n";
3053 OS
<< " for (const uint8_t *p = Converter; *p; p += 2) {\n";
3054 OS
<< " switch (*p) {\n";
3055 OS
<< " case CVT_Tied: {\n";
3056 OS
<< " unsigned OpIdx = *(p + 1);\n";
3057 OS
<< " assert(OpIdx < (size_t)(std::end(TiedAsmOperandTable) -\n";
3058 OS
<< " std::begin(TiedAsmOperandTable)) &&\n";
3059 OS
<< " \"Tied operand not found\");\n";
3060 OS
<< " unsigned OpndNum1 = TiedAsmOperandTable[OpIdx][1];\n";
3061 OS
<< " unsigned OpndNum2 = TiedAsmOperandTable[OpIdx][2];\n";
3062 if (HasOptionalOperands
) {
3063 // When optional operands are involved, formal and actual operand indices
3064 // may differ. Map the former to the latter by subtracting the number of
3065 // absent optional operands.
3066 OS
<< " OpndNum1 = OpndNum1 - DefaultsOffset[OpndNum1];\n";
3067 OS
<< " OpndNum2 = OpndNum2 - DefaultsOffset[OpndNum2];\n";
3069 OS
<< " if (OpndNum1 != OpndNum2) {\n";
3070 OS
<< " auto &SrcOp1 = Operands[OpndNum1];\n";
3071 OS
<< " auto &SrcOp2 = Operands[OpndNum2];\n";
3072 OS
<< " if (!AsmParser.areEqualRegs(*SrcOp1, *SrcOp2)) {\n";
3073 OS
<< " ErrorInfo = OpndNum2;\n";
3074 OS
<< " return false;\n";
3079 OS
<< " default:\n";
3083 OS
<< " return true;\n";
3087 static void emitMnemonicSpellChecker(raw_ostream
&OS
, CodeGenTarget
&Target
,
3088 unsigned VariantCount
) {
3089 OS
<< "static std::string " << Target
.getName()
3090 << "MnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,"
3091 << " unsigned VariantID) {\n";
3093 OS
<< " return \"\";";
3095 OS
<< " const unsigned MaxEditDist = 2;\n";
3096 OS
<< " std::vector<StringRef> Candidates;\n";
3097 OS
<< " StringRef Prev = \"\";\n\n";
3099 OS
<< " // Find the appropriate table for this asm variant.\n";
3100 OS
<< " const MatchEntry *Start, *End;\n";
3101 OS
<< " switch (VariantID) {\n";
3102 OS
<< " default: llvm_unreachable(\"invalid variant!\");\n";
3103 for (unsigned VC
= 0; VC
!= VariantCount
; ++VC
) {
3104 const Record
*AsmVariant
= Target
.getAsmParserVariant(VC
);
3105 int AsmVariantNo
= AsmVariant
->getValueAsInt("Variant");
3106 OS
<< " case " << AsmVariantNo
<< ": Start = std::begin(MatchTable" << VC
3107 << "); End = std::end(MatchTable" << VC
<< "); break;\n";
3110 OS
<< " for (auto I = Start; I < End; I++) {\n";
3111 OS
<< " // Ignore unsupported instructions.\n";
3112 OS
<< " const FeatureBitset &RequiredFeatures = "
3113 "FeatureBitsets[I->RequiredFeaturesIdx];\n";
3114 OS
<< " if ((FBS & RequiredFeatures) != RequiredFeatures)\n";
3115 OS
<< " continue;\n";
3117 OS
<< " StringRef T = I->getMnemonic();\n";
3118 OS
<< " // Avoid recomputing the edit distance for the same string.\n";
3119 OS
<< " if (T == Prev)\n";
3120 OS
<< " continue;\n";
3122 OS
<< " Prev = T;\n";
3123 OS
<< " unsigned Dist = S.edit_distance(T, false, MaxEditDist);\n";
3124 OS
<< " if (Dist <= MaxEditDist)\n";
3125 OS
<< " Candidates.push_back(T);\n";
3128 OS
<< " if (Candidates.empty())\n";
3129 OS
<< " return \"\";\n";
3131 OS
<< " std::string Res = \", did you mean: \";\n";
3132 OS
<< " unsigned i = 0;\n";
3133 OS
<< " for (; i < Candidates.size() - 1; i++)\n";
3134 OS
<< " Res += Candidates[i].str() + \", \";\n";
3135 OS
<< " return Res + Candidates[i].str() + \"?\";\n";
3141 static void emitMnemonicChecker(raw_ostream
&OS
, CodeGenTarget
&Target
,
3142 unsigned VariantCount
, bool HasMnemonicFirst
,
3143 bool HasMnemonicAliases
) {
3144 OS
<< "static bool " << Target
.getName()
3145 << "CheckMnemonic(StringRef Mnemonic,\n";
3147 << "const FeatureBitset &AvailableFeatures,\n";
3149 << "unsigned VariantID) {\n";
3151 if (!VariantCount
) {
3152 OS
<< " return false;\n";
3154 if (HasMnemonicAliases
) {
3155 OS
<< " // Process all MnemonicAliases to remap the mnemonic.\n";
3156 OS
<< " applyMnemonicAliases(Mnemonic, AvailableFeatures, VariantID);";
3159 OS
<< " // Find the appropriate table for this asm variant.\n";
3160 OS
<< " const MatchEntry *Start, *End;\n";
3161 OS
<< " switch (VariantID) {\n";
3162 OS
<< " default: llvm_unreachable(\"invalid variant!\");\n";
3163 for (unsigned VC
= 0; VC
!= VariantCount
; ++VC
) {
3164 const Record
*AsmVariant
= Target
.getAsmParserVariant(VC
);
3165 int AsmVariantNo
= AsmVariant
->getValueAsInt("Variant");
3166 OS
<< " case " << AsmVariantNo
<< ": Start = std::begin(MatchTable" << VC
3167 << "); End = std::end(MatchTable" << VC
<< "); break;\n";
3171 OS
<< " // Search the table.\n";
3172 if (HasMnemonicFirst
) {
3173 OS
<< " auto MnemonicRange = "
3174 "std::equal_range(Start, End, Mnemonic, LessOpcode());\n\n";
3176 OS
<< " auto MnemonicRange = std::pair(Start, End);\n";
3177 OS
<< " unsigned SIndex = Mnemonic.empty() ? 0 : 1;\n";
3178 OS
<< " if (!Mnemonic.empty())\n";
3179 OS
<< " MnemonicRange = "
3180 << "std::equal_range(Start, End, Mnemonic.lower(), LessOpcode());\n\n";
3183 OS
<< " if (MnemonicRange.first == MnemonicRange.second)\n";
3184 OS
<< " return false;\n\n";
3186 OS
<< " for (const MatchEntry *it = MnemonicRange.first, "
3187 << "*ie = MnemonicRange.second;\n";
3188 OS
<< " it != ie; ++it) {\n";
3189 OS
<< " const FeatureBitset &RequiredFeatures =\n";
3190 OS
<< " FeatureBitsets[it->RequiredFeaturesIdx];\n";
3191 OS
<< " if ((AvailableFeatures & RequiredFeatures) == ";
3192 OS
<< "RequiredFeatures)\n";
3193 OS
<< " return true;\n";
3195 OS
<< " return false;\n";
3201 // Emit a function mapping match classes to strings, for debugging.
3202 static void emitMatchClassKindNames(std::forward_list
<ClassInfo
> &Infos
,
3204 OS
<< "#ifndef NDEBUG\n";
3205 OS
<< "const char *getMatchClassName(MatchClassKind Kind) {\n";
3206 OS
<< " switch (Kind) {\n";
3208 OS
<< " case InvalidMatchClass: return \"InvalidMatchClass\";\n";
3209 OS
<< " case OptionalMatchClass: return \"OptionalMatchClass\";\n";
3210 for (const auto &CI
: Infos
) {
3211 OS
<< " case " << CI
.Name
<< ": return \"" << CI
.Name
<< "\";\n";
3213 OS
<< " case NumMatchClassKinds: return \"NumMatchClassKinds\";\n";
3216 OS
<< " llvm_unreachable(\"unhandled MatchClassKind!\");\n";
3218 OS
<< "#endif // NDEBUG\n";
3222 getNameForFeatureBitset(ArrayRef
<const Record
*> FeatureBitset
) {
3223 std::string Name
= "AMFBS";
3224 for (const Record
*Feature
: FeatureBitset
)
3225 Name
+= ("_" + Feature
->getName()).str();
3229 void AsmMatcherEmitter::run(raw_ostream
&OS
) {
3230 CodeGenTarget
Target(Records
);
3231 const Record
*AsmParser
= Target
.getAsmParser();
3232 StringRef ClassName
= AsmParser
->getValueAsString("AsmParserClassName");
3234 emitSourceFileHeader("Assembly Matcher Source Fragment", OS
, Records
);
3236 // Compute the information on the instructions to match.
3237 AsmMatcherInfo
Info(AsmParser
, Target
, Records
);
3240 bool PreferSmallerInstructions
= getPreferSmallerInstructions(Target
);
3241 // Sort the instruction table using the partial order on classes. We use
3242 // stable_sort to ensure that ambiguous instructions are still
3243 // deterministically ordered.
3246 [PreferSmallerInstructions
](const std::unique_ptr
<MatchableInfo
> &A
,
3247 const std::unique_ptr
<MatchableInfo
> &B
) {
3248 return A
->shouldBeMatchedBefore(*B
, PreferSmallerInstructions
);
3251 #ifdef EXPENSIVE_CHECKS
3252 // Verify that the table is sorted and operator < works transitively.
3253 for (auto I
= Info
.Matchables
.begin(), E
= Info
.Matchables
.end(); I
!= E
;
3255 for (auto J
= I
; J
!= E
; ++J
) {
3256 assert(!(*J
)->shouldBeMatchedBefore(**I
, PreferSmallerInstructions
));
3261 DEBUG_WITH_TYPE("instruction_info", {
3262 for (const auto &MI
: Info
.Matchables
)
3266 // Check for ambiguous matchables.
3267 DEBUG_WITH_TYPE("ambiguous_instrs", {
3268 unsigned NumAmbiguous
= 0;
3269 for (auto I
= Info
.Matchables
.begin(), E
= Info
.Matchables
.end(); I
!= E
;
3271 for (auto J
= std::next(I
); J
!= E
; ++J
) {
3272 const MatchableInfo
&A
= **I
;
3273 const MatchableInfo
&B
= **J
;
3275 if (A
.couldMatchAmbiguouslyWith(B
, PreferSmallerInstructions
)) {
3276 errs() << "warning: ambiguous matchables:\n";
3278 errs() << "\nis incomparable with:\n";
3286 errs() << "warning: " << NumAmbiguous
<< " ambiguous matchables!\n";
3289 // Compute the information on the custom operand parsing.
3290 Info
.buildOperandMatchInfo();
3292 bool HasMnemonicFirst
= AsmParser
->getValueAsBit("HasMnemonicFirst");
3293 bool HasOptionalOperands
= Info
.hasOptionalOperands();
3294 bool ReportMultipleNearMisses
=
3295 AsmParser
->getValueAsBit("ReportMultipleNearMisses");
3297 // Write the output.
3299 // Information for the class declaration.
3300 OS
<< "\n#ifdef GET_ASSEMBLER_HEADER\n";
3301 OS
<< "#undef GET_ASSEMBLER_HEADER\n";
3302 OS
<< " // This should be included into the middle of the declaration of\n";
3303 OS
<< " // your subclasses implementation of MCTargetAsmParser.\n";
3304 OS
<< " FeatureBitset ComputeAvailableFeatures(const FeatureBitset &FB) "
3306 if (HasOptionalOperands
) {
3307 OS
<< " void convertToMCInst(unsigned Kind, MCInst &Inst, "
3308 << "unsigned Opcode,\n"
3309 << " const OperandVector &Operands,\n"
3310 << " const SmallBitVector "
3311 "&OptionalOperandsMask,\n"
3312 << " ArrayRef<unsigned> DefaultsOffset);\n";
3314 OS
<< " void convertToMCInst(unsigned Kind, MCInst &Inst, "
3315 << "unsigned Opcode,\n"
3316 << " const OperandVector &Operands);\n";
3318 OS
<< " void convertToMapAndConstraints(unsigned Kind,\n ";
3319 OS
<< " const OperandVector &Operands) override;\n";
3320 OS
<< " unsigned MatchInstructionImpl(const OperandVector &Operands,\n"
3321 << " MCInst &Inst,\n";
3322 if (ReportMultipleNearMisses
)
3323 OS
<< " SmallVectorImpl<NearMissInfo> "
3326 OS
<< " uint64_t &ErrorInfo,\n"
3327 << " FeatureBitset &MissingFeatures,\n";
3328 OS
<< " bool matchingInlineAsm,\n"
3329 << " unsigned VariantID = 0);\n";
3330 if (!ReportMultipleNearMisses
)
3331 OS
<< " unsigned MatchInstructionImpl(const OperandVector &Operands,\n"
3332 << " MCInst &Inst,\n"
3333 << " uint64_t &ErrorInfo,\n"
3334 << " bool matchingInlineAsm,\n"
3335 << " unsigned VariantID = 0) {\n"
3336 << " FeatureBitset MissingFeatures;\n"
3337 << " return MatchInstructionImpl(Operands, Inst, ErrorInfo, "
3338 "MissingFeatures,\n"
3339 << " matchingInlineAsm, VariantID);\n"
3342 if (!Info
.OperandMatchInfo
.empty()) {
3343 OS
<< " ParseStatus MatchOperandParserImpl(\n";
3344 OS
<< " OperandVector &Operands,\n";
3345 OS
<< " StringRef Mnemonic,\n";
3346 OS
<< " bool ParseForAllFeatures = false);\n";
3348 OS
<< " ParseStatus tryCustomParseOperand(\n";
3349 OS
<< " OperandVector &Operands,\n";
3350 OS
<< " unsigned MCK);\n\n";
3353 OS
<< "#endif // GET_ASSEMBLER_HEADER\n\n";
3355 // Emit the operand match diagnostic enum names.
3356 OS
<< "\n#ifdef GET_OPERAND_DIAGNOSTIC_TYPES\n";
3357 OS
<< "#undef GET_OPERAND_DIAGNOSTIC_TYPES\n\n";
3358 emitOperandDiagnosticTypes(Info
, OS
);
3359 OS
<< "#endif // GET_OPERAND_DIAGNOSTIC_TYPES\n\n";
3361 OS
<< "\n#ifdef GET_REGISTER_MATCHER\n";
3362 OS
<< "#undef GET_REGISTER_MATCHER\n\n";
3364 // Emit the subtarget feature enumeration.
3365 SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(
3366 Info
.SubtargetFeatures
, OS
);
3368 // Emit the function to match a register name to number.
3369 // This should be omitted for Mips target
3370 if (AsmParser
->getValueAsBit("ShouldEmitMatchRegisterName"))
3371 emitMatchRegisterName(Target
, AsmParser
, OS
);
3373 if (AsmParser
->getValueAsBit("ShouldEmitMatchRegisterAltName"))
3374 emitMatchRegisterAltName(Target
, AsmParser
, OS
);
3376 OS
<< "#endif // GET_REGISTER_MATCHER\n\n";
3378 OS
<< "\n#ifdef GET_SUBTARGET_FEATURE_NAME\n";
3379 OS
<< "#undef GET_SUBTARGET_FEATURE_NAME\n\n";
3381 // Generate the helper function to get the names for subtarget features.
3382 emitGetSubtargetFeatureName(Info
, OS
);
3384 OS
<< "#endif // GET_SUBTARGET_FEATURE_NAME\n\n";
3386 OS
<< "\n#ifdef GET_MATCHER_IMPLEMENTATION\n";
3387 OS
<< "#undef GET_MATCHER_IMPLEMENTATION\n\n";
3389 // Generate the function that remaps for mnemonic aliases.
3390 bool HasMnemonicAliases
= emitMnemonicAliases(OS
, Info
, Target
);
3392 // Generate the convertToMCInst function to convert operands into an MCInst.
3393 // Also, generate the convertToMapAndConstraints function for MS-style inline
3394 // assembly. The latter doesn't actually generate a MCInst.
3395 unsigned NumConverters
=
3396 emitConvertFuncs(Target
, ClassName
, Info
.Matchables
, HasMnemonicFirst
,
3397 HasOptionalOperands
, OS
);
3399 // Emit the enumeration for classes which participate in matching.
3400 emitMatchClassEnumeration(Target
, Info
.Classes
, OS
);
3402 // Emit a function to get the user-visible string to describe an operand
3403 // match failure in diagnostics.
3404 emitOperandMatchErrorDiagStrings(Info
, OS
);
3406 // Emit a function to map register classes to operand match failure codes.
3407 emitRegisterMatchErrorFunc(Info
, OS
);
3409 // Emit the routine to match token strings to their match class.
3410 emitMatchTokenString(Target
, Info
.Classes
, OS
);
3412 // Emit the subclass predicate routine.
3413 emitIsSubclass(Target
, Info
.Classes
, OS
);
3415 // Emit the routine to validate an operand against a match class.
3416 emitValidateOperandClass(Info
, OS
);
3418 emitMatchClassKindNames(Info
.Classes
, OS
);
3420 // Emit the available features compute function.
3421 SubtargetFeatureInfo::emitComputeAssemblerAvailableFeatures(
3422 Info
.Target
.getName(), ClassName
, "ComputeAvailableFeatures",
3423 Info
.SubtargetFeatures
, OS
);
3425 if (!ReportMultipleNearMisses
)
3426 emitAsmTiedOperandConstraints(Target
, Info
, OS
, HasOptionalOperands
);
3428 StringToOffsetTable StringTable
;
3430 size_t MaxNumOperands
= 0;
3431 unsigned MaxMnemonicIndex
= 0;
3432 bool HasDeprecation
= false;
3433 for (const auto &MI
: Info
.Matchables
) {
3434 MaxNumOperands
= std::max(MaxNumOperands
, MI
->AsmOperands
.size());
3435 HasDeprecation
|= MI
->HasDeprecation
;
3437 // Store a pascal-style length byte in the mnemonic.
3438 std::string LenMnemonic
= char(MI
->Mnemonic
.size()) + MI
->Mnemonic
.lower();
3439 MaxMnemonicIndex
= std::max(
3440 MaxMnemonicIndex
, StringTable
.GetOrAddStringOffset(LenMnemonic
, false));
3443 OS
<< "static const char MnemonicTable[] =\n";
3444 StringTable
.EmitString(OS
);
3447 std::vector
<std::vector
<const Record
*>> FeatureBitsets
;
3448 for (const auto &MI
: Info
.Matchables
) {
3449 if (MI
->RequiredFeatures
.empty())
3451 FeatureBitsets
.emplace_back();
3452 for (const auto *F
: MI
->RequiredFeatures
)
3453 FeatureBitsets
.back().push_back(F
->TheDef
);
3456 llvm::sort(FeatureBitsets
,
3457 [&](ArrayRef
<const Record
*> A
, ArrayRef
<const Record
*> B
) {
3458 if (A
.size() != B
.size())
3459 return A
.size() < B
.size();
3460 for (const auto [ARec
, BRec
] : zip_equal(A
, B
)) {
3461 if (ARec
->getName() != BRec
->getName())
3462 return ARec
->getName() < BRec
->getName();
3466 FeatureBitsets
.erase(llvm::unique(FeatureBitsets
), FeatureBitsets
.end());
3467 OS
<< "// Feature bitsets.\n"
3468 << "enum : " << getMinimalTypeForRange(FeatureBitsets
.size()) << " {\n"
3469 << " AMFBS_None,\n";
3470 for (const auto &FeatureBitset
: FeatureBitsets
) {
3471 if (FeatureBitset
.empty())
3473 OS
<< " " << getNameForFeatureBitset(FeatureBitset
) << ",\n";
3476 << "static constexpr FeatureBitset FeatureBitsets[] = {\n"
3477 << " {}, // AMFBS_None\n";
3478 for (const auto &FeatureBitset
: FeatureBitsets
) {
3479 if (FeatureBitset
.empty())
3482 for (const auto &Feature
: FeatureBitset
) {
3483 const auto &I
= Info
.SubtargetFeatures
.find(Feature
);
3484 assert(I
!= Info
.SubtargetFeatures
.end() && "Didn't import predicate?");
3485 OS
<< I
->second
.getEnumBitName() << ", ";
3491 // Emit the static match table; unused classes get initialized to 0 which is
3492 // guaranteed to be InvalidMatchClass.
3494 // FIXME: We can reduce the size of this table very easily. First, we change
3495 // it so that store the kinds in separate bit-fields for each index, which
3496 // only needs to be the max width used for classes at that index (we also need
3497 // to reject based on this during classification). If we then make sure to
3498 // order the match kinds appropriately (putting mnemonics last), then we
3499 // should only end up using a few bits for each class, especially the ones
3500 // following the mnemonic.
3501 OS
<< "namespace {\n";
3502 OS
<< " struct MatchEntry {\n";
3503 OS
<< " " << getMinimalTypeForRange(MaxMnemonicIndex
) << " Mnemonic;\n";
3504 OS
<< " uint16_t Opcode;\n";
3505 OS
<< " " << getMinimalTypeForRange(NumConverters
) << " ConvertFn;\n";
3506 OS
<< " " << getMinimalTypeForRange(FeatureBitsets
.size())
3507 << " RequiredFeaturesIdx;\n";
3509 << getMinimalTypeForRange(
3510 std::distance(Info
.Classes
.begin(), Info
.Classes
.end()) +
3511 2 /* Include 'InvalidMatchClass' and 'OptionalMatchClass' */)
3512 << " Classes[" << MaxNumOperands
<< "];\n";
3513 OS
<< " StringRef getMnemonic() const {\n";
3514 OS
<< " return StringRef(MnemonicTable + Mnemonic + 1,\n";
3515 OS
<< " MnemonicTable[Mnemonic]);\n";
3519 OS
<< " // Predicate for searching for an opcode.\n";
3520 OS
<< " struct LessOpcode {\n";
3521 OS
<< " bool operator()(const MatchEntry &LHS, StringRef RHS) {\n";
3522 OS
<< " return LHS.getMnemonic() < RHS;\n";
3524 OS
<< " bool operator()(StringRef LHS, const MatchEntry &RHS) {\n";
3525 OS
<< " return LHS < RHS.getMnemonic();\n";
3527 OS
<< " bool operator()(const MatchEntry &LHS, const MatchEntry &RHS) {\n";
3528 OS
<< " return LHS.getMnemonic() < RHS.getMnemonic();\n";
3532 OS
<< "} // end anonymous namespace\n\n";
3534 unsigned VariantCount
= Target
.getAsmParserVariantCount();
3535 for (unsigned VC
= 0; VC
!= VariantCount
; ++VC
) {
3536 const Record
*AsmVariant
= Target
.getAsmParserVariant(VC
);
3537 int AsmVariantNo
= AsmVariant
->getValueAsInt("Variant");
3539 OS
<< "static const MatchEntry MatchTable" << VC
<< "[] = {\n";
3541 for (const auto &MI
: Info
.Matchables
) {
3542 if (MI
->AsmVariantID
!= AsmVariantNo
)
3545 // Store a pascal-style length byte in the mnemonic.
3546 std::string LenMnemonic
=
3547 char(MI
->Mnemonic
.size()) + MI
->Mnemonic
.lower();
3548 OS
<< " { " << *StringTable
.GetStringOffset(LenMnemonic
) << " /* "
3549 << MI
->Mnemonic
<< " */, " << Target
.getInstNamespace()
3550 << "::" << MI
->getResultInst()->TheDef
->getName() << ", "
3551 << MI
->ConversionFnKind
<< ", ";
3553 // Write the required features mask.
3555 if (MI
->RequiredFeatures
.empty())
3558 for (const auto &F
: MI
->RequiredFeatures
)
3559 OS
<< '_' << F
->TheDef
->getName();
3563 for (const MatchableInfo::AsmOperand
&Op
: MI
->AsmOperands
)
3564 OS
<< LS
<< Op
.Class
->Name
;
3571 OS
<< "#include \"llvm/Support/Debug.h\"\n";
3572 OS
<< "#include \"llvm/Support/Format.h\"\n\n";
3574 // Finally, build the match function.
3575 OS
<< "unsigned " << Target
.getName() << ClassName
<< "::\n"
3576 << "MatchInstructionImpl(const OperandVector &Operands,\n";
3577 OS
<< " MCInst &Inst,\n";
3578 if (ReportMultipleNearMisses
)
3579 OS
<< " SmallVectorImpl<NearMissInfo> *NearMisses,\n";
3581 OS
<< " uint64_t &ErrorInfo,\n"
3582 << " FeatureBitset &MissingFeatures,\n";
3583 OS
<< " bool matchingInlineAsm, unsigned VariantID) {\n";
3585 if (!ReportMultipleNearMisses
) {
3586 OS
<< " // Eliminate obvious mismatches.\n";
3587 OS
<< " if (Operands.size() > " << (MaxNumOperands
+ HasMnemonicFirst
)
3589 OS
<< " ErrorInfo = " << (MaxNumOperands
+ HasMnemonicFirst
) << ";\n";
3590 OS
<< " return Match_InvalidOperand;\n";
3594 // Emit code to get the available features.
3595 OS
<< " // Get the current feature set.\n";
3596 OS
<< " const FeatureBitset &AvailableFeatures = "
3597 "getAvailableFeatures();\n\n";
3599 OS
<< " // Get the instruction mnemonic, which is the first token.\n";
3600 if (HasMnemonicFirst
) {
3601 OS
<< " StringRef Mnemonic = ((" << Target
.getName()
3602 << "Operand &)*Operands[0]).getToken();\n\n";
3604 OS
<< " StringRef Mnemonic;\n";
3605 OS
<< " if (Operands[0]->isToken())\n";
3606 OS
<< " Mnemonic = ((" << Target
.getName()
3607 << "Operand &)*Operands[0]).getToken();\n\n";
3610 if (HasMnemonicAliases
) {
3611 OS
<< " // Process all MnemonicAliases to remap the mnemonic.\n";
3612 OS
<< " applyMnemonicAliases(Mnemonic, AvailableFeatures, VariantID);\n\n";
3615 // Emit code to compute the class list for this operand vector.
3616 if (!ReportMultipleNearMisses
) {
3617 OS
<< " // Some state to try to produce better error messages.\n";
3618 OS
<< " bool HadMatchOtherThanFeatures = false;\n";
3619 OS
<< " bool HadMatchOtherThanPredicate = false;\n";
3620 OS
<< " unsigned RetCode = Match_InvalidOperand;\n";
3621 OS
<< " MissingFeatures.set();\n";
3622 OS
<< " // Set ErrorInfo to the operand that mismatches if it is\n";
3623 OS
<< " // wrong for all instances of the instruction.\n";
3624 OS
<< " ErrorInfo = ~0ULL;\n";
3627 if (HasOptionalOperands
) {
3628 OS
<< " SmallBitVector OptionalOperandsMask(" << MaxNumOperands
<< ");\n";
3631 // Emit code to search the table.
3632 OS
<< " // Find the appropriate table for this asm variant.\n";
3633 OS
<< " const MatchEntry *Start, *End;\n";
3634 OS
<< " switch (VariantID) {\n";
3635 OS
<< " default: llvm_unreachable(\"invalid variant!\");\n";
3636 for (unsigned VC
= 0; VC
!= VariantCount
; ++VC
) {
3637 const Record
*AsmVariant
= Target
.getAsmParserVariant(VC
);
3638 int AsmVariantNo
= AsmVariant
->getValueAsInt("Variant");
3639 OS
<< " case " << AsmVariantNo
<< ": Start = std::begin(MatchTable" << VC
3640 << "); End = std::end(MatchTable" << VC
<< "); break;\n";
3644 OS
<< " // Search the table.\n";
3645 if (HasMnemonicFirst
) {
3646 OS
<< " auto MnemonicRange = "
3647 "std::equal_range(Start, End, Mnemonic, LessOpcode());\n\n";
3649 OS
<< " auto MnemonicRange = std::pair(Start, End);\n";
3650 OS
<< " unsigned SIndex = Mnemonic.empty() ? 0 : 1;\n";
3651 OS
<< " if (!Mnemonic.empty())\n";
3652 OS
<< " MnemonicRange = "
3653 "std::equal_range(Start, End, Mnemonic.lower(), LessOpcode());\n\n";
3656 OS
<< " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"AsmMatcher: found \" "
3658 << " std::distance(MnemonicRange.first, MnemonicRange.second) <<\n"
3659 << " \" encodings with mnemonic '\" << Mnemonic << \"'\\n\");\n\n";
3661 OS
<< " // Return a more specific error code if no mnemonics match.\n";
3662 OS
<< " if (MnemonicRange.first == MnemonicRange.second)\n";
3663 OS
<< " return Match_MnemonicFail;\n\n";
3665 OS
<< " for (const MatchEntry *it = MnemonicRange.first, "
3666 << "*ie = MnemonicRange.second;\n";
3667 OS
<< " it != ie; ++it) {\n";
3668 OS
<< " const FeatureBitset &RequiredFeatures = "
3669 "FeatureBitsets[it->RequiredFeaturesIdx];\n";
3670 OS
<< " bool HasRequiredFeatures =\n";
3671 OS
<< " (AvailableFeatures & RequiredFeatures) == RequiredFeatures;\n";
3672 OS
<< " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"Trying to match "
3674 OS
<< " << MII.getName(it->Opcode) "
3677 if (ReportMultipleNearMisses
) {
3678 OS
<< " // Some state to record ways in which this instruction did not "
3680 OS
<< " NearMissInfo OperandNearMiss = NearMissInfo::getSuccess();\n";
3681 OS
<< " NearMissInfo FeaturesNearMiss = NearMissInfo::getSuccess();\n";
3682 OS
<< " NearMissInfo EarlyPredicateNearMiss = "
3683 "NearMissInfo::getSuccess();\n";
3684 OS
<< " NearMissInfo LatePredicateNearMiss = "
3685 "NearMissInfo::getSuccess();\n";
3686 OS
<< " bool MultipleInvalidOperands = false;\n";
3689 if (HasMnemonicFirst
) {
3690 OS
<< " // equal_range guarantees that instruction mnemonic matches.\n";
3691 OS
<< " assert(Mnemonic == it->getMnemonic());\n";
3694 // Emit check that the subclasses match.
3695 if (!ReportMultipleNearMisses
)
3696 OS
<< " bool OperandsValid = true;\n";
3697 if (HasOptionalOperands
) {
3698 OS
<< " OptionalOperandsMask.reset(0, " << MaxNumOperands
<< ");\n";
3700 OS
<< " for (unsigned FormalIdx = " << (HasMnemonicFirst
? "0" : "SIndex")
3701 << ", ActualIdx = " << (HasMnemonicFirst
? "1" : "SIndex")
3702 << "; FormalIdx != " << MaxNumOperands
<< "; ++FormalIdx) {\n";
3703 OS
<< " auto Formal = "
3704 << "static_cast<MatchClassKind>(it->Classes[FormalIdx]);\n";
3705 OS
<< " DEBUG_WITH_TYPE(\"asm-matcher\",\n";
3706 OS
<< " dbgs() << \" Matching formal operand class \" "
3707 "<< getMatchClassName(Formal)\n";
3708 OS
<< " << \" against actual operand at index \" "
3710 OS
<< " if (ActualIdx < Operands.size())\n";
3711 OS
<< " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \" (\";\n";
3712 OS
<< " Operands[ActualIdx]->print(dbgs()); dbgs() << "
3715 OS
<< " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \": \");\n";
3716 OS
<< " if (ActualIdx >= Operands.size()) {\n";
3717 OS
<< " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"actual operand "
3718 "index out of range\\n\");\n";
3719 if (ReportMultipleNearMisses
) {
3720 OS
<< " bool ThisOperandValid = (Formal == "
3721 << "InvalidMatchClass) || "
3722 "isSubclass(Formal, OptionalMatchClass);\n";
3723 OS
<< " if (!ThisOperandValid) {\n";
3724 OS
<< " if (!OperandNearMiss) {\n";
3725 OS
<< " // Record info about match failure for later use.\n";
3726 OS
<< " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"recording "
3727 "too-few-operands near miss\\n\");\n";
3728 OS
<< " OperandNearMiss =\n";
3729 OS
<< " NearMissInfo::getTooFewOperands(Formal, "
3731 OS
<< " } else if (OperandNearMiss.getKind() != "
3732 "NearMissInfo::NearMissTooFewOperands) {\n";
3733 OS
<< " // If more than one operand is invalid, give up on this "
3735 OS
<< " DEBUG_WITH_TYPE(\n";
3736 OS
<< " \"asm-matcher\",\n";
3737 OS
<< " dbgs() << \"second invalid operand, giving up on "
3738 "this opcode\\n\");\n";
3739 OS
<< " MultipleInvalidOperands = true;\n";
3742 OS
<< " } else {\n";
3743 OS
<< " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"but formal "
3744 "operand not required\\n\");\n";
3745 OS
<< " if (isSubclass(Formal, OptionalMatchClass)) {\n";
3746 OS
<< " OptionalOperandsMask.set(FormalIdx);\n";
3749 OS
<< " continue;\n";
3751 OS
<< " if (Formal == InvalidMatchClass) {\n";
3752 if (HasOptionalOperands
) {
3753 OS
<< " OptionalOperandsMask.set(FormalIdx, " << MaxNumOperands
3758 OS
<< " if (isSubclass(Formal, OptionalMatchClass)) {\n";
3759 if (HasOptionalOperands
) {
3760 OS
<< " OptionalOperandsMask.set(FormalIdx);\n";
3762 OS
<< " continue;\n";
3764 OS
<< " OperandsValid = false;\n";
3765 OS
<< " ErrorInfo = ActualIdx;\n";
3769 OS
<< " MCParsedAsmOperand &Actual = *Operands[ActualIdx];\n";
3770 OS
<< " unsigned Diag = validateOperandClass(Actual, Formal);\n";
3771 OS
<< " if (Diag == Match_Success) {\n";
3772 OS
<< " DEBUG_WITH_TYPE(\"asm-matcher\",\n";
3773 OS
<< " dbgs() << \"match success using generic "
3775 OS
<< " ++ActualIdx;\n";
3776 OS
<< " continue;\n";
3778 OS
<< " // If the generic handler indicates an invalid operand\n";
3779 OS
<< " // failure, check for a special case.\n";
3780 OS
<< " if (Diag != Match_Success) {\n";
3781 OS
<< " unsigned TargetDiag = validateTargetOperandClass(Actual, "
3783 OS
<< " if (TargetDiag == Match_Success) {\n";
3784 OS
<< " DEBUG_WITH_TYPE(\"asm-matcher\",\n";
3785 OS
<< " dbgs() << \"match success using target "
3787 OS
<< " ++ActualIdx;\n";
3788 OS
<< " continue;\n";
3790 OS
<< " // If the target matcher returned a specific error code use\n";
3791 OS
<< " // that, else use the one from the generic matcher.\n";
3792 OS
<< " if (TargetDiag != Match_InvalidOperand && "
3793 "HasRequiredFeatures)\n";
3794 OS
<< " Diag = TargetDiag;\n";
3796 OS
<< " // If current formal operand wasn't matched and it is optional\n"
3797 << " // then try to match next formal operand\n";
3798 OS
<< " if (Diag == Match_InvalidOperand "
3799 << "&& isSubclass(Formal, OptionalMatchClass)) {\n";
3800 if (HasOptionalOperands
) {
3801 OS
<< " OptionalOperandsMask.set(FormalIdx);\n";
3803 OS
<< " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"ignoring "
3804 "optional operand\\n\");\n";
3805 OS
<< " continue;\n";
3808 if (ReportMultipleNearMisses
) {
3809 OS
<< " if (!OperandNearMiss) {\n";
3810 OS
<< " // If this is the first invalid operand we have seen, "
3812 OS
<< " // information about it.\n";
3813 OS
<< " DEBUG_WITH_TYPE(\n";
3814 OS
<< " \"asm-matcher\",\n";
3816 OS
<< " << \"operand match failed, recording near-miss with "
3818 OS
<< " << Diag << \"\\n\");\n";
3819 OS
<< " OperandNearMiss =\n";
3820 OS
<< " NearMissInfo::getMissedOperand(Diag, Formal, "
3821 "it->Opcode, ActualIdx);\n";
3822 OS
<< " ++ActualIdx;\n";
3823 OS
<< " } else {\n";
3824 OS
<< " // If more than one operand is invalid, give up on this "
3826 OS
<< " DEBUG_WITH_TYPE(\n";
3827 OS
<< " \"asm-matcher\",\n";
3828 OS
<< " dbgs() << \"second operand mismatch, skipping this "
3830 OS
<< " MultipleInvalidOperands = true;\n";
3835 OS
<< " // If this operand is broken for all of the instances of "
3837 OS
<< " // mnemonic, keep track of it so we can report loc info.\n";
3838 OS
<< " // If we already had a match that only failed due to a\n";
3839 OS
<< " // target predicate, that diagnostic is preferred.\n";
3840 OS
<< " if (!HadMatchOtherThanPredicate &&\n";
3841 OS
<< " (it == MnemonicRange.first || ErrorInfo <= ActualIdx)) "
3843 OS
<< " if (HasRequiredFeatures && (ErrorInfo != ActualIdx || Diag "
3844 "!= Match_InvalidOperand))\n";
3845 OS
<< " RetCode = Diag;\n";
3846 OS
<< " ErrorInfo = ActualIdx;\n";
3848 OS
<< " // Otherwise, just reject this instance of the mnemonic.\n";
3849 OS
<< " OperandsValid = false;\n";
3854 if (ReportMultipleNearMisses
)
3855 OS
<< " if (MultipleInvalidOperands) {\n";
3857 OS
<< " if (!OperandsValid) {\n";
3858 OS
<< " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"Opcode result: "
3860 OS
<< " \"operand mismatches, "
3862 OS
<< " \"this opcode\\n\");\n";
3863 OS
<< " continue;\n";
3866 // Emit check that the required features are available.
3867 OS
<< " if (!HasRequiredFeatures) {\n";
3868 if (!ReportMultipleNearMisses
)
3869 OS
<< " HadMatchOtherThanFeatures = true;\n";
3870 OS
<< " FeatureBitset NewMissingFeatures = RequiredFeatures & "
3871 "~AvailableFeatures;\n";
3872 OS
<< " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"Missing target "
3874 OS
<< " for (unsigned I = 0, E = "
3875 "NewMissingFeatures.size(); I != E; ++I)\n";
3876 OS
<< " if (NewMissingFeatures[I])\n";
3877 OS
<< " dbgs() << ' ' << I;\n";
3878 OS
<< " dbgs() << \"\\n\");\n";
3879 if (ReportMultipleNearMisses
) {
3880 OS
<< " FeaturesNearMiss = "
3881 "NearMissInfo::getMissedFeature(NewMissingFeatures);\n";
3883 OS
<< " if (NewMissingFeatures.count() <=\n"
3884 " MissingFeatures.count())\n";
3885 OS
<< " MissingFeatures = NewMissingFeatures;\n";
3886 OS
<< " continue;\n";
3890 OS
<< " Inst.clear();\n\n";
3891 OS
<< " Inst.setOpcode(it->Opcode);\n";
3892 // Verify the instruction with the target-specific match predicate function.
3893 OS
<< " // We have a potential match but have not rendered the operands.\n"
3894 << " // Check the target predicate to handle any context sensitive\n"
3895 " // constraints.\n"
3896 << " // For example, Ties that are referenced multiple times must be\n"
3897 " // checked here to ensure the input is the same for each match\n"
3898 " // constraints. If we leave it any later the ties will have been\n"
3899 " // canonicalized\n"
3900 << " unsigned MatchResult;\n"
3901 << " if ((MatchResult = checkEarlyTargetMatchPredicate(Inst, "
3902 "Operands)) != Match_Success) {\n"
3903 << " Inst.clear();\n";
3904 OS
<< " DEBUG_WITH_TYPE(\n";
3905 OS
<< " \"asm-matcher\",\n";
3906 OS
<< " dbgs() << \"Early target match predicate failed with diag "
3908 OS
<< " << MatchResult << \"\\n\");\n";
3909 if (ReportMultipleNearMisses
) {
3910 OS
<< " EarlyPredicateNearMiss = "
3911 "NearMissInfo::getMissedPredicate(MatchResult);\n";
3913 OS
<< " RetCode = MatchResult;\n"
3914 << " HadMatchOtherThanPredicate = true;\n"
3919 if (ReportMultipleNearMisses
) {
3920 OS
<< " // If we did not successfully match the operands, then we can't "
3922 OS
<< " // an MCInst, so bail out on this instruction variant now.\n";
3923 OS
<< " if (OperandNearMiss) {\n";
3924 OS
<< " // If the operand mismatch was the only problem, reprrt it as "
3926 OS
<< " if (NearMisses && !FeaturesNearMiss && "
3927 "!EarlyPredicateNearMiss) {\n";
3928 OS
<< " DEBUG_WITH_TYPE(\n";
3929 OS
<< " \"asm-matcher\",\n";
3931 OS
<< " << \"Opcode result: one mismatched operand, adding "
3932 "near-miss\\n\");\n";
3933 OS
<< " NearMisses->push_back(OperandNearMiss);\n";
3934 OS
<< " } else {\n";
3935 OS
<< " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"Opcode result: "
3937 OS
<< " \"types of "
3938 "mismatch, so not \"\n";
3939 OS
<< " \"reporting "
3940 "near-miss\\n\");\n";
3942 OS
<< " continue;\n";
3946 // When converting parsed operands to MCInst we need to know whether optional
3947 // operands were parsed or not so that we can choose the correct converter
3948 // function. We also need to know this when checking tied operand constraints.
3949 // DefaultsOffset is an array of deltas between the formal (MCInst) and the
3950 // actual (parsed operand array) operand indices. When all optional operands
3951 // are present, all elements of the array are zeros. If some of the optional
3952 // operands are absent, the array might look like '0, 0, 1, 1, 1, 2, 2, 3',
3953 // where each increment in value reflects the absence of an optional operand.
3954 if (HasOptionalOperands
) {
3955 OS
<< " unsigned DefaultsOffset[" << (MaxNumOperands
+ 1)
3957 OS
<< " assert(OptionalOperandsMask.size() == " << (MaxNumOperands
)
3959 OS
<< " for (unsigned i = 0, NumDefaults = 0; i < " << (MaxNumOperands
)
3961 OS
<< " DefaultsOffset[i + 1] = NumDefaults;\n";
3962 OS
<< " NumDefaults += (OptionalOperandsMask[i] ? 1 : 0);\n";
3966 OS
<< " if (matchingInlineAsm) {\n";
3967 OS
<< " convertToMapAndConstraints(it->ConvertFn, Operands);\n";
3968 if (!ReportMultipleNearMisses
) {
3969 if (HasOptionalOperands
) {
3970 OS
<< " if (!checkAsmTiedOperandConstraints(*this, it->ConvertFn, "
3972 OS
<< " DefaultsOffset, "
3975 OS
<< " if (!checkAsmTiedOperandConstraints(*this, it->ConvertFn, "
3977 OS
<< " ErrorInfo))\n";
3979 OS
<< " return Match_InvalidTiedOperand;\n";
3982 OS
<< " return Match_Success;\n";
3984 OS
<< " // We have selected a definite instruction, convert the parsed\n"
3985 << " // operands into the appropriate MCInst.\n";
3986 if (HasOptionalOperands
) {
3987 OS
<< " convertToMCInst(it->ConvertFn, Inst, it->Opcode, Operands,\n"
3988 << " OptionalOperandsMask, DefaultsOffset);\n";
3990 OS
<< " convertToMCInst(it->ConvertFn, Inst, it->Opcode, Operands);\n";
3994 // Verify the instruction with the target-specific match predicate function.
3995 OS
<< " // We have a potential match. Check the target predicate to\n"
3996 << " // handle any context sensitive constraints.\n"
3997 << " if ((MatchResult = checkTargetMatchPredicate(Inst)) !="
3998 << " Match_Success) {\n"
3999 << " DEBUG_WITH_TYPE(\"asm-matcher\",\n"
4000 << " dbgs() << \"Target match predicate failed with "
4002 << " << MatchResult << \"\\n\");\n"
4003 << " Inst.clear();\n";
4004 if (ReportMultipleNearMisses
) {
4005 OS
<< " LatePredicateNearMiss = "
4006 "NearMissInfo::getMissedPredicate(MatchResult);\n";
4008 OS
<< " RetCode = MatchResult;\n"
4009 << " HadMatchOtherThanPredicate = true;\n"
4014 if (ReportMultipleNearMisses
) {
4015 OS
<< " int NumNearMisses = ((int)(bool)OperandNearMiss +\n";
4016 OS
<< " (int)(bool)FeaturesNearMiss +\n";
4017 OS
<< " (int)(bool)EarlyPredicateNearMiss +\n";
4018 OS
<< " (int)(bool)LatePredicateNearMiss);\n";
4019 OS
<< " if (NumNearMisses == 1) {\n";
4020 OS
<< " // We had exactly one type of near-miss, so add that to the "
4022 OS
<< " assert(!OperandNearMiss && \"OperandNearMiss was handled "
4024 OS
<< " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"Opcode result: "
4025 "found one type of \"\n";
4026 OS
<< " \"mismatch, so "
4028 OS
<< " \"near-miss\\n\");\n";
4029 OS
<< " if (NearMisses && FeaturesNearMiss)\n";
4030 OS
<< " NearMisses->push_back(FeaturesNearMiss);\n";
4031 OS
<< " else if (NearMisses && EarlyPredicateNearMiss)\n";
4032 OS
<< " NearMisses->push_back(EarlyPredicateNearMiss);\n";
4033 OS
<< " else if (NearMisses && LatePredicateNearMiss)\n";
4034 OS
<< " NearMisses->push_back(LatePredicateNearMiss);\n";
4036 OS
<< " continue;\n";
4037 OS
<< " } else if (NumNearMisses > 1) {\n";
4038 OS
<< " // This instruction missed in more than one way, so ignore "
4040 OS
<< " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"Opcode result: "
4042 OS
<< " \"types of mismatch, "
4044 OS
<< " \"reporting "
4045 "near-miss\\n\");\n";
4046 OS
<< " continue;\n";
4050 // Call the post-processing function, if used.
4051 StringRef InsnCleanupFn
= AsmParser
->getValueAsString("AsmParserInstCleanup");
4052 if (!InsnCleanupFn
.empty())
4053 OS
<< " " << InsnCleanupFn
<< "(Inst);\n";
4055 if (HasDeprecation
) {
4056 OS
<< " std::string Info;\n";
4058 "(!getParser().getTargetParser().getTargetOptions()."
4059 "MCNoDeprecatedWarn &&\n";
4060 OS
<< " MII.getDeprecatedInfo(Inst, getSTI(), Info)) {\n";
4061 OS
<< " SMLoc Loc = ((" << Target
.getName()
4062 << "Operand &)*Operands[0]).getStartLoc();\n";
4063 OS
<< " getParser().Warning(Loc, Info, std::nullopt);\n";
4067 if (!ReportMultipleNearMisses
) {
4068 if (HasOptionalOperands
) {
4069 OS
<< " if (!checkAsmTiedOperandConstraints(*this, it->ConvertFn, "
4071 OS
<< " DefaultsOffset, "
4074 OS
<< " if (!checkAsmTiedOperandConstraints(*this, it->ConvertFn, "
4076 OS
<< " ErrorInfo))\n";
4078 OS
<< " return Match_InvalidTiedOperand;\n";
4082 OS
<< " DEBUG_WITH_TYPE(\n";
4083 OS
<< " \"asm-matcher\",\n";
4084 OS
<< " dbgs() << \"Opcode result: complete match, selecting this "
4086 OS
<< " return Match_Success;\n";
4089 if (ReportMultipleNearMisses
) {
4090 OS
<< " // No instruction variants matched exactly.\n";
4091 OS
<< " return Match_NearMisses;\n";
4093 OS
<< " // Okay, we had no match. Try to return a useful error code.\n";
4094 OS
<< " if (HadMatchOtherThanPredicate || !HadMatchOtherThanFeatures)\n";
4095 OS
<< " return RetCode;\n\n";
4096 OS
<< " ErrorInfo = 0;\n";
4097 OS
<< " return Match_MissingFeature;\n";
4101 if (!Info
.OperandMatchInfo
.empty())
4102 emitCustomOperandParsing(OS
, Target
, Info
, ClassName
, StringTable
,
4103 MaxMnemonicIndex
, FeatureBitsets
.size(),
4104 HasMnemonicFirst
, *AsmParser
);
4106 OS
<< "#endif // GET_MATCHER_IMPLEMENTATION\n\n";
4108 OS
<< "\n#ifdef GET_MNEMONIC_SPELL_CHECKER\n";
4109 OS
<< "#undef GET_MNEMONIC_SPELL_CHECKER\n\n";
4111 emitMnemonicSpellChecker(OS
, Target
, VariantCount
);
4113 OS
<< "#endif // GET_MNEMONIC_SPELL_CHECKER\n\n";
4115 OS
<< "\n#ifdef GET_MNEMONIC_CHECKER\n";
4116 OS
<< "#undef GET_MNEMONIC_CHECKER\n\n";
4118 emitMnemonicChecker(OS
, Target
, VariantCount
, HasMnemonicFirst
,
4119 HasMnemonicAliases
);
4121 OS
<< "#endif // GET_MNEMONIC_CHECKER\n\n";
4124 static TableGen::Emitter::OptClass
<AsmMatcherEmitter
>
4125 X("gen-asm-matcher", "Generate assembly instruction matcher");