1198090Srdivacky//===- AsmMatcherEmitter.cpp - Generate an assembly matcher ---------------===//
2198090Srdivacky//
3198090Srdivacky//                     The LLVM Compiler Infrastructure
4198090Srdivacky//
5198090Srdivacky// This file is distributed under the University of Illinois Open Source
6198090Srdivacky// License. See LICENSE.TXT for details.
7198090Srdivacky//
8198090Srdivacky//===----------------------------------------------------------------------===//
9198090Srdivacky//
10198090Srdivacky// This tablegen backend emits a target specifier matcher for converting parsed
11218893Sdim// assembly operands in the MCInst structures. It also emits a matcher for
12218893Sdim// custom operand parsing.
13198090Srdivacky//
14218893Sdim// Converting assembly operands into MCInst structures
15218893Sdim// ---------------------------------------------------
16218893Sdim//
17198090Srdivacky// The input to the target specific matcher is a list of literal tokens and
18198090Srdivacky// operands. The target specific parser should generally eliminate any syntax
19198090Srdivacky// which is not relevant for matching; for example, comma tokens should have
20198090Srdivacky// already been consumed and eliminated by the parser. Most instructions will
21198090Srdivacky// end up with a single literal token (the instruction name) and some number of
22198090Srdivacky// operands.
23198090Srdivacky//
24198090Srdivacky// Some example inputs, for X86:
25198090Srdivacky//   'addl' (immediate ...) (register ...)
26198090Srdivacky//   'add' (immediate ...) (memory ...)
27218893Sdim//   'call' '*' %epc
28198090Srdivacky//
29198090Srdivacky// The assembly matcher is responsible for converting this input into a precise
30198090Srdivacky// machine instruction (i.e., an instruction with a well defined encoding). This
31198090Srdivacky// mapping has several properties which complicate matching:
32198090Srdivacky//
33198090Srdivacky//  - It may be ambiguous; many architectures can legally encode particular
34198090Srdivacky//    variants of an instruction in different ways (for example, using a smaller
35198090Srdivacky//    encoding for small immediates). Such ambiguities should never be
36198090Srdivacky//    arbitrarily resolved by the assembler, the assembler is always responsible
37198090Srdivacky//    for choosing the "best" available instruction.
38198090Srdivacky//
39198090Srdivacky//  - It may depend on the subtarget or the assembler context. Instructions
40198090Srdivacky//    which are invalid for the current mode, but otherwise unambiguous (e.g.,
41198090Srdivacky//    an SSE instruction in a file being assembled for i486) should be accepted
42198090Srdivacky//    and rejected by the assembler front end. However, if the proper encoding
43198090Srdivacky//    for an instruction is dependent on the assembler context then the matcher
44198090Srdivacky//    is responsible for selecting the correct machine instruction for the
45198090Srdivacky//    current mode.
46198090Srdivacky//
47198090Srdivacky// The core matching algorithm attempts to exploit the regularity in most
48198090Srdivacky// instruction sets to quickly determine the set of possibly matching
49198090Srdivacky// instructions, and the simplify the generated code. Additionally, this helps
50198090Srdivacky// to ensure that the ambiguities are intentionally resolved by the user.
51198090Srdivacky//
52198090Srdivacky// The matching is divided into two distinct phases:
53198090Srdivacky//
54198090Srdivacky//   1. Classification: Each operand is mapped to the unique set which (a)
55198090Srdivacky//      contains it, and (b) is the largest such subset for which a single
56198090Srdivacky//      instruction could match all members.
57198090Srdivacky//
58198090Srdivacky//      For register classes, we can generate these subgroups automatically. For
59198090Srdivacky//      arbitrary operands, we expect the user to define the classes and their
60198090Srdivacky//      relations to one another (for example, 8-bit signed immediates as a
61198090Srdivacky//      subset of 32-bit immediates).
62198090Srdivacky//
63198090Srdivacky//      By partitioning the operands in this way, we guarantee that for any
64198090Srdivacky//      tuple of classes, any single instruction must match either all or none
65198090Srdivacky//      of the sets of operands which could classify to that tuple.
66198090Srdivacky//
67198090Srdivacky//      In addition, the subset relation amongst classes induces a partial order
68198090Srdivacky//      on such tuples, which we use to resolve ambiguities.
69198090Srdivacky//
70198090Srdivacky//   2. The input can now be treated as a tuple of classes (static tokens are
71198090Srdivacky//      simple singleton sets). Each such tuple should generally map to a single
72198090Srdivacky//      instruction (we currently ignore cases where this isn't true, whee!!!),
73198090Srdivacky//      which we can emit a simple matcher for.
74198090Srdivacky//
75218893Sdim// Custom Operand Parsing
76218893Sdim// ----------------------
77218893Sdim//
78218893Sdim//  Some targets need a custom way to parse operands, some specific instructions
79218893Sdim//  can contain arguments that can represent processor flags and other kinds of
80245431Sdim//  identifiers that need to be mapped to specific values in the final encoded
81218893Sdim//  instructions. The target specific custom operand parsing works in the
82218893Sdim//  following way:
83218893Sdim//
84218893Sdim//   1. A operand match table is built, each entry contains a mnemonic, an
85218893Sdim//      operand class, a mask for all operand positions for that same
86218893Sdim//      class/mnemonic and target features to be checked while trying to match.
87218893Sdim//
88218893Sdim//   2. The operand matcher will try every possible entry with the same
89218893Sdim//      mnemonic and will check if the target feature for this mnemonic also
90218893Sdim//      matches. After that, if the operand to be matched has its index
91221345Sdim//      present in the mask, a successful match occurs. Otherwise, fallback
92218893Sdim//      to the regular operand parsing.
93218893Sdim//
94218893Sdim//   3. For a match success, each operand class that has a 'ParserMethod'
95218893Sdim//      becomes part of a switch from where the custom method is called.
96218893Sdim//
97198090Srdivacky//===----------------------------------------------------------------------===//
98198090Srdivacky
99198090Srdivacky#include "CodeGenTarget.h"
100198090Srdivacky#include "llvm/ADT/OwningPtr.h"
101218893Sdim#include "llvm/ADT/PointerUnion.h"
102252723Sdim#include "llvm/ADT/STLExtras.h"
103218893Sdim#include "llvm/ADT/SmallPtrSet.h"
104198090Srdivacky#include "llvm/ADT/SmallVector.h"
105198090Srdivacky#include "llvm/ADT/StringExtras.h"
106198090Srdivacky#include "llvm/Support/CommandLine.h"
107198090Srdivacky#include "llvm/Support/Debug.h"
108235633Sdim#include "llvm/Support/ErrorHandling.h"
109226890Sdim#include "llvm/TableGen/Error.h"
110226890Sdim#include "llvm/TableGen/Record.h"
111245431Sdim#include "llvm/TableGen/StringMatcher.h"
112263509Sdim#include "llvm/TableGen/StringToOffsetTable.h"
113245431Sdim#include "llvm/TableGen/TableGenBackend.h"
114245431Sdim#include <cassert>
115263509Sdim#include <cctype>
116198090Srdivacky#include <map>
117198090Srdivacky#include <set>
118263509Sdim#include <sstream>
119198090Srdivackyusing namespace llvm;
120198090Srdivacky
121198090Srdivackystatic cl::opt<std::string>
122198090SrdivackyMatchPrefix("match-prefix", cl::init(""),
123198090Srdivacky            cl::desc("Only match instructions with the given prefix"));
124198090Srdivacky
125198090Srdivackynamespace {
126218893Sdimclass AsmMatcherInfo;
127212904Sdimstruct SubtargetFeatureInfo;
128212904Sdim
129263509Sdim// Register sets are used as keys in some second-order sets TableGen creates
130263509Sdim// when generating its data structures. This means that the order of two
131263509Sdim// RegisterSets can be seen in the outputted AsmMatcher tables occasionally, and
132263509Sdim// can even affect compiler output (at least seen in diagnostics produced when
133263509Sdim// all matches fail). So we use a type that sorts them consistently.
134263509Sdimtypedef std::set<Record*, LessRecordByID> RegisterSet;
135263509Sdim
136245431Sdimclass AsmMatcherEmitter {
137245431Sdim  RecordKeeper &Records;
138245431Sdimpublic:
139245431Sdim  AsmMatcherEmitter(RecordKeeper &R) : Records(R) {}
140245431Sdim
141245431Sdim  void run(raw_ostream &o);
142245431Sdim};
143245431Sdim
144198090Srdivacky/// ClassInfo - Helper class for storing the information about a particular
145198090Srdivacky/// class of operands which can be matched.
146198090Srdivackystruct ClassInfo {
147198090Srdivacky  enum ClassInfoKind {
148198090Srdivacky    /// Invalid kind, for use as a sentinel value.
149198090Srdivacky    Invalid = 0,
150198090Srdivacky
151198090Srdivacky    /// The class for a particular token.
152198090Srdivacky    Token,
153198090Srdivacky
154198090Srdivacky    /// The (first) register class, subsequent register classes are
155198090Srdivacky    /// RegisterClass0+1, and so on.
156198090Srdivacky    RegisterClass0,
157198090Srdivacky
158198090Srdivacky    /// The (first) user defined class, subsequent user defined classes are
159198090Srdivacky    /// UserClass0+1, and so on.
160198090Srdivacky    UserClass0 = 1<<16
161198090Srdivacky  };
162198090Srdivacky
163198090Srdivacky  /// Kind - The class kind, which is either a predefined kind, or (UserClass0 +
164198090Srdivacky  /// N) for the Nth user defined class.
165198090Srdivacky  unsigned Kind;
166198090Srdivacky
167198090Srdivacky  /// SuperClasses - The super classes of this class. Note that for simplicities
168198090Srdivacky  /// sake user operands only record their immediate super class, while register
169198090Srdivacky  /// operands include all superclasses.
170198090Srdivacky  std::vector<ClassInfo*> SuperClasses;
171198090Srdivacky
172198090Srdivacky  /// Name - The full class name, suitable for use in an enum.
173198090Srdivacky  std::string Name;
174198090Srdivacky
175198090Srdivacky  /// ClassName - The unadorned generic name for this class (e.g., Token).
176198090Srdivacky  std::string ClassName;
177198090Srdivacky
178198090Srdivacky  /// ValueName - The name of the value this class represents; for a token this
179198090Srdivacky  /// is the literal token string, for an operand it is the TableGen class (or
180198090Srdivacky  /// empty if this is a derived class).
181198090Srdivacky  std::string ValueName;
182198090Srdivacky
183198090Srdivacky  /// PredicateMethod - The name of the operand method to test whether the
184198090Srdivacky  /// operand matches this class; this is not valid for Token or register kinds.
185198090Srdivacky  std::string PredicateMethod;
186198090Srdivacky
187198090Srdivacky  /// RenderMethod - The name of the operand method to add this operand to an
188198090Srdivacky  /// MCInst; this is not valid for Token or register kinds.
189198090Srdivacky  std::string RenderMethod;
190198090Srdivacky
191218893Sdim  /// ParserMethod - The name of the operand method to do a target specific
192218893Sdim  /// parsing on the operand.
193218893Sdim  std::string ParserMethod;
194218893Sdim
195198090Srdivacky  /// For register classes, the records for all the registers in this class.
196263509Sdim  RegisterSet Registers;
197198090Srdivacky
198245431Sdim  /// For custom match classes, he diagnostic kind for when the predicate fails.
199245431Sdim  std::string DiagnosticType;
200198090Srdivackypublic:
201198090Srdivacky  /// isRegisterClass() - Check if this is a register class.
202198090Srdivacky  bool isRegisterClass() const {
203198090Srdivacky    return Kind >= RegisterClass0 && Kind < UserClass0;
204198090Srdivacky  }
205198090Srdivacky
206198090Srdivacky  /// isUserClass() - Check if this is a user defined class.
207198090Srdivacky  bool isUserClass() const {
208198090Srdivacky    return Kind >= UserClass0;
209198090Srdivacky  }
210198090Srdivacky
211245431Sdim  /// isRelatedTo - Check whether this class is "related" to \p RHS. Classes
212198090Srdivacky  /// are related if they are in the same class hierarchy.
213198090Srdivacky  bool isRelatedTo(const ClassInfo &RHS) const {
214198090Srdivacky    // Tokens are only related to tokens.
215198090Srdivacky    if (Kind == Token || RHS.Kind == Token)
216198090Srdivacky      return Kind == Token && RHS.Kind == Token;
217198090Srdivacky
218198090Srdivacky    // Registers classes are only related to registers classes, and only if
219198090Srdivacky    // their intersection is non-empty.
220198090Srdivacky    if (isRegisterClass() || RHS.isRegisterClass()) {
221198090Srdivacky      if (!isRegisterClass() || !RHS.isRegisterClass())
222198090Srdivacky        return false;
223198090Srdivacky
224263509Sdim      RegisterSet Tmp;
225263509Sdim      std::insert_iterator<RegisterSet> II(Tmp, Tmp.begin());
226218893Sdim      std::set_intersection(Registers.begin(), Registers.end(),
227198090Srdivacky                            RHS.Registers.begin(), RHS.Registers.end(),
228263509Sdim                            II, LessRecordByID());
229198090Srdivacky
230198090Srdivacky      return !Tmp.empty();
231198090Srdivacky    }
232198090Srdivacky
233198090Srdivacky    // Otherwise we have two users operands; they are related if they are in the
234198090Srdivacky    // same class hierarchy.
235198090Srdivacky    //
236198090Srdivacky    // FIXME: This is an oversimplification, they should only be related if they
237198090Srdivacky    // intersect, however we don't have that information.
238198090Srdivacky    assert(isUserClass() && RHS.isUserClass() && "Unexpected class!");
239198090Srdivacky    const ClassInfo *Root = this;
240198090Srdivacky    while (!Root->SuperClasses.empty())
241198090Srdivacky      Root = Root->SuperClasses.front();
242198090Srdivacky
243198090Srdivacky    const ClassInfo *RHSRoot = &RHS;
244198090Srdivacky    while (!RHSRoot->SuperClasses.empty())
245198090Srdivacky      RHSRoot = RHSRoot->SuperClasses.front();
246218893Sdim
247198090Srdivacky    return Root == RHSRoot;
248198090Srdivacky  }
249198090Srdivacky
250245431Sdim  /// isSubsetOf - Test whether this class is a subset of \p RHS.
251198090Srdivacky  bool isSubsetOf(const ClassInfo &RHS) const {
252198090Srdivacky    // This is a subset of RHS if it is the same class...
253198090Srdivacky    if (this == &RHS)
254198090Srdivacky      return true;
255198090Srdivacky
256198090Srdivacky    // ... or if any of its super classes are a subset of RHS.
257198090Srdivacky    for (std::vector<ClassInfo*>::const_iterator it = SuperClasses.begin(),
258198090Srdivacky           ie = SuperClasses.end(); it != ie; ++it)
259198090Srdivacky      if ((*it)->isSubsetOf(RHS))
260198090Srdivacky        return true;
261198090Srdivacky
262198090Srdivacky    return false;
263198090Srdivacky  }
264198090Srdivacky
265198090Srdivacky  /// operator< - Compare two classes.
266198090Srdivacky  bool operator<(const ClassInfo &RHS) const {
267208599Srdivacky    if (this == &RHS)
268208599Srdivacky      return false;
269208599Srdivacky
270198090Srdivacky    // Unrelated classes can be ordered by kind.
271198090Srdivacky    if (!isRelatedTo(RHS))
272198090Srdivacky      return Kind < RHS.Kind;
273198090Srdivacky
274198090Srdivacky    switch (Kind) {
275198090Srdivacky    case Invalid:
276235633Sdim      llvm_unreachable("Invalid kind!");
277198090Srdivacky
278198090Srdivacky    default:
279221345Sdim      // This class precedes the RHS if it is a proper subset of the RHS.
280208599Srdivacky      if (isSubsetOf(RHS))
281210299Sed        return true;
282208599Srdivacky      if (RHS.isSubsetOf(*this))
283210299Sed        return false;
284208599Srdivacky
285208599Srdivacky      // Otherwise, order by name to ensure we have a total ordering.
286208599Srdivacky      return ValueName < RHS.ValueName;
287198090Srdivacky    }
288198090Srdivacky  }
289198090Srdivacky};
290198090Srdivacky
291245431Sdimnamespace {
292245431Sdim/// Sort ClassInfo pointers independently of pointer value.
293245431Sdimstruct LessClassInfoPtr {
294245431Sdim  bool operator()(const ClassInfo *LHS, const ClassInfo *RHS) const {
295245431Sdim    return *LHS < *RHS;
296245431Sdim  }
297245431Sdim};
298245431Sdim}
299245431Sdim
300218893Sdim/// MatchableInfo - Helper class for storing the necessary information for an
301218893Sdim/// instruction or alias which is capable of being matched.
302218893Sdimstruct MatchableInfo {
303218893Sdim  struct AsmOperand {
304218893Sdim    /// Token - This is the token that the operand came from.
305218893Sdim    StringRef Token;
306218893Sdim
307198090Srdivacky    /// The unique class instance this operand should match.
308198090Srdivacky    ClassInfo *Class;
309198090Srdivacky
310218893Sdim    /// The operand name this is, if anything.
311218893Sdim    StringRef SrcOpName;
312218893Sdim
313218893Sdim    /// The suboperand index within SrcOpName, or -1 for the entire operand.
314218893Sdim    int SubOpIdx;
315218893Sdim
316235633Sdim    /// Register record if this token is singleton register.
317235633Sdim    Record *SingletonReg;
318235633Sdim
319235633Sdim    explicit AsmOperand(StringRef T) : Token(T), Class(0), SubOpIdx(-1),
320235633Sdim                                       SingletonReg(0) {}
321198090Srdivacky  };
322198090Srdivacky
323218893Sdim  /// ResOperand - This represents a single operand in the result instruction
324218893Sdim  /// generated by the match.  In cases (like addressing modes) where a single
325218893Sdim  /// assembler operand expands to multiple MCOperands, this represents the
326218893Sdim  /// single assembler operand, not the MCOperand.
327218893Sdim  struct ResOperand {
328218893Sdim    enum {
329218893Sdim      /// RenderAsmOperand - This represents an operand result that is
330218893Sdim      /// generated by calling the render method on the assembly operand.  The
331218893Sdim      /// corresponding AsmOperand is specified by AsmOperandNum.
332218893Sdim      RenderAsmOperand,
333198090Srdivacky
334218893Sdim      /// TiedOperand - This represents a result operand that is a duplicate of
335218893Sdim      /// a previous result operand.
336218893Sdim      TiedOperand,
337198090Srdivacky
338218893Sdim      /// ImmOperand - This represents an immediate value that is dumped into
339218893Sdim      /// the operand.
340218893Sdim      ImmOperand,
341218893Sdim
342218893Sdim      /// RegOperand - This represents a fixed register that is dumped in.
343218893Sdim      RegOperand
344218893Sdim    } Kind;
345218893Sdim
346218893Sdim    union {
347218893Sdim      /// This is the operand # in the AsmOperands list that this should be
348218893Sdim      /// copied from.
349218893Sdim      unsigned AsmOperandNum;
350218893Sdim
351218893Sdim      /// TiedOperandNum - This is the (earlier) result operand that should be
352218893Sdim      /// copied from.
353218893Sdim      unsigned TiedOperandNum;
354218893Sdim
355218893Sdim      /// ImmVal - This is the immediate value added to the instruction.
356218893Sdim      int64_t ImmVal;
357218893Sdim
358218893Sdim      /// Register - This is the register record.
359218893Sdim      Record *Register;
360218893Sdim    };
361218893Sdim
362218893Sdim    /// MINumOperands - The number of MCInst operands populated by this
363218893Sdim    /// operand.
364218893Sdim    unsigned MINumOperands;
365218893Sdim
366218893Sdim    static ResOperand getRenderedOp(unsigned AsmOpNum, unsigned NumOperands) {
367218893Sdim      ResOperand X;
368218893Sdim      X.Kind = RenderAsmOperand;
369218893Sdim      X.AsmOperandNum = AsmOpNum;
370218893Sdim      X.MINumOperands = NumOperands;
371218893Sdim      return X;
372218893Sdim    }
373218893Sdim
374218893Sdim    static ResOperand getTiedOp(unsigned TiedOperandNum) {
375218893Sdim      ResOperand X;
376218893Sdim      X.Kind = TiedOperand;
377218893Sdim      X.TiedOperandNum = TiedOperandNum;
378218893Sdim      X.MINumOperands = 1;
379218893Sdim      return X;
380218893Sdim    }
381218893Sdim
382218893Sdim    static ResOperand getImmOp(int64_t Val) {
383218893Sdim      ResOperand X;
384218893Sdim      X.Kind = ImmOperand;
385218893Sdim      X.ImmVal = Val;
386218893Sdim      X.MINumOperands = 1;
387218893Sdim      return X;
388218893Sdim    }
389218893Sdim
390218893Sdim    static ResOperand getRegOp(Record *Reg) {
391218893Sdim      ResOperand X;
392218893Sdim      X.Kind = RegOperand;
393218893Sdim      X.Register = Reg;
394218893Sdim      X.MINumOperands = 1;
395218893Sdim      return X;
396218893Sdim    }
397218893Sdim  };
398218893Sdim
399235633Sdim  /// AsmVariantID - Target's assembly syntax variant no.
400235633Sdim  int AsmVariantID;
401235633Sdim
402218893Sdim  /// TheDef - This is the definition of the instruction or InstAlias that this
403218893Sdim  /// matchable came from.
404218893Sdim  Record *const TheDef;
405218893Sdim
406218893Sdim  /// DefRec - This is the definition that it came from.
407218893Sdim  PointerUnion<const CodeGenInstruction*, const CodeGenInstAlias*> DefRec;
408218893Sdim
409218893Sdim  const CodeGenInstruction *getResultInst() const {
410218893Sdim    if (DefRec.is<const CodeGenInstruction*>())
411218893Sdim      return DefRec.get<const CodeGenInstruction*>();
412218893Sdim    return DefRec.get<const CodeGenInstAlias*>()->ResultInst;
413218893Sdim  }
414218893Sdim
415218893Sdim  /// ResOperands - This is the operand list that should be built for the result
416218893Sdim  /// MCInst.
417245431Sdim  SmallVector<ResOperand, 8> ResOperands;
418218893Sdim
419198090Srdivacky  /// AsmString - The assembly string for this instruction (with variants
420218893Sdim  /// removed), e.g. "movsx $src, $dst".
421198090Srdivacky  std::string AsmString;
422198090Srdivacky
423218893Sdim  /// Mnemonic - This is the first token of the matched instruction, its
424218893Sdim  /// mnemonic.
425218893Sdim  StringRef Mnemonic;
426198090Srdivacky
427218893Sdim  /// AsmOperands - The textual operands that this instruction matches,
428218893Sdim  /// annotated with a class and where in the OperandList they were defined.
429218893Sdim  /// This directly corresponds to the tokenized AsmString after the mnemonic is
430218893Sdim  /// removed.
431245431Sdim  SmallVector<AsmOperand, 8> AsmOperands;
432198090Srdivacky
433212904Sdim  /// Predicates - The required subtarget features to match this instruction.
434212904Sdim  SmallVector<SubtargetFeatureInfo*, 4> RequiredFeatures;
435212904Sdim
436198090Srdivacky  /// ConversionFnKind - The enum value which is passed to the generated
437245431Sdim  /// convertToMCInst to convert parsed operands into an MCInst for this
438198090Srdivacky  /// function.
439198090Srdivacky  std::string ConversionFnKind;
440198090Srdivacky
441263509Sdim  /// If this instruction is deprecated in some form.
442263509Sdim  bool HasDeprecation;
443263509Sdim
444218893Sdim  MatchableInfo(const CodeGenInstruction &CGI)
445235633Sdim    : AsmVariantID(0), TheDef(CGI.TheDef), DefRec(&CGI),
446235633Sdim      AsmString(CGI.AsmString) {
447218893Sdim  }
448198090Srdivacky
449218893Sdim  MatchableInfo(const CodeGenInstAlias *Alias)
450235633Sdim    : AsmVariantID(0), TheDef(Alias->TheDef), DefRec(Alias),
451235633Sdim      AsmString(Alias->AsmString) {
452218893Sdim  }
453218893Sdim
454245431Sdim  // Two-operand aliases clone from the main matchable, but mark the second
455245431Sdim  // operand as a tied operand of the first for purposes of the assembler.
456245431Sdim  void formTwoOperandAlias(StringRef Constraint);
457245431Sdim
458245431Sdim  void initialize(const AsmMatcherInfo &Info,
459235633Sdim                  SmallPtrSet<Record*, 16> &SingletonRegisters,
460235633Sdim                  int AsmVariantNo, std::string &RegisterPrefix);
461218893Sdim
462245431Sdim  /// validate - Return true if this matchable is a valid thing to match against
463218893Sdim  /// and perform a bunch of validity checking.
464245431Sdim  bool validate(StringRef CommentDelimiter, bool Hack) const;
465218893Sdim
466235633Sdim  /// extractSingletonRegisterForAsmOperand - Extract singleton register,
467235633Sdim  /// if present, from specified token.
468235633Sdim  void
469235633Sdim  extractSingletonRegisterForAsmOperand(unsigned i, const AsmMatcherInfo &Info,
470235633Sdim                                        std::string &RegisterPrefix);
471218893Sdim
472245431Sdim  /// findAsmOperand - Find the AsmOperand with the specified name and
473218893Sdim  /// suboperand index.
474245431Sdim  int findAsmOperand(StringRef N, int SubOpIdx) const {
475218893Sdim    for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i)
476218893Sdim      if (N == AsmOperands[i].SrcOpName &&
477218893Sdim          SubOpIdx == AsmOperands[i].SubOpIdx)
478218893Sdim        return i;
479218893Sdim    return -1;
480218893Sdim  }
481218893Sdim
482245431Sdim  /// findAsmOperandNamed - Find the first AsmOperand with the specified name.
483218893Sdim  /// This does not check the suboperand index.
484245431Sdim  int findAsmOperandNamed(StringRef N) const {
485218893Sdim    for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i)
486218893Sdim      if (N == AsmOperands[i].SrcOpName)
487218893Sdim        return i;
488218893Sdim    return -1;
489218893Sdim  }
490218893Sdim
491245431Sdim  void buildInstructionResultOperands();
492245431Sdim  void buildAliasResultOperands();
493218893Sdim
494218893Sdim  /// operator< - Compare two matchables.
495218893Sdim  bool operator<(const MatchableInfo &RHS) const {
496218893Sdim    // The primary comparator is the instruction mnemonic.
497218893Sdim    if (Mnemonic != RHS.Mnemonic)
498218893Sdim      return Mnemonic < RHS.Mnemonic;
499218893Sdim
500218893Sdim    if (AsmOperands.size() != RHS.AsmOperands.size())
501218893Sdim      return AsmOperands.size() < RHS.AsmOperands.size();
502218893Sdim
503198090Srdivacky    // Compare lexicographically by operand. The matcher validates that other
504245431Sdim    // orderings wouldn't be ambiguous using \see couldMatchAmbiguouslyWith().
505218893Sdim    for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) {
506218893Sdim      if (*AsmOperands[i].Class < *RHS.AsmOperands[i].Class)
507198090Srdivacky        return true;
508218893Sdim      if (*RHS.AsmOperands[i].Class < *AsmOperands[i].Class)
509198090Srdivacky        return false;
510198090Srdivacky    }
511198090Srdivacky
512245431Sdim    // Give matches that require more features higher precedence. This is useful
513245431Sdim    // because we cannot define AssemblerPredicates with the negation of
514245431Sdim    // processor features. For example, ARM v6 "nop" may be either a HINT or
515245431Sdim    // MOV. With v6, we want to match HINT. The assembler has no way to
516245431Sdim    // predicate MOV under "NoV6", but HINT will always match first because it
517245431Sdim    // requires V6 while MOV does not.
518245431Sdim    if (RequiredFeatures.size() != RHS.RequiredFeatures.size())
519245431Sdim      return RequiredFeatures.size() > RHS.RequiredFeatures.size();
520245431Sdim
521198090Srdivacky    return false;
522198090Srdivacky  }
523198090Srdivacky
524245431Sdim  /// couldMatchAmbiguouslyWith - Check whether this matchable could
525245431Sdim  /// ambiguously match the same set of operands as \p RHS (without being a
526198090Srdivacky  /// strictly superior match).
527245431Sdim  bool couldMatchAmbiguouslyWith(const MatchableInfo &RHS) {
528218893Sdim    // The primary comparator is the instruction mnemonic.
529218893Sdim    if (Mnemonic != RHS.Mnemonic)
530218893Sdim      return false;
531218893Sdim
532198090Srdivacky    // The number of operands is unambiguous.
533218893Sdim    if (AsmOperands.size() != RHS.AsmOperands.size())
534198090Srdivacky      return false;
535198090Srdivacky
536202878Srdivacky    // Otherwise, make sure the ordering of the two instructions is unambiguous
537202878Srdivacky    // by checking that either (a) a token or operand kind discriminates them,
538202878Srdivacky    // or (b) the ordering among equivalent kinds is consistent.
539202878Srdivacky
540198090Srdivacky    // Tokens and operand kinds are unambiguous (assuming a correct target
541198090Srdivacky    // specific parser).
542218893Sdim    for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i)
543218893Sdim      if (AsmOperands[i].Class->Kind != RHS.AsmOperands[i].Class->Kind ||
544218893Sdim          AsmOperands[i].Class->Kind == ClassInfo::Token)
545218893Sdim        if (*AsmOperands[i].Class < *RHS.AsmOperands[i].Class ||
546218893Sdim            *RHS.AsmOperands[i].Class < *AsmOperands[i].Class)
547198090Srdivacky          return false;
548218893Sdim
549198090Srdivacky    // Otherwise, this operand could commute if all operands are equivalent, or
550198090Srdivacky    // there is a pair of operands that compare less than and a pair that
551198090Srdivacky    // compare greater than.
552198090Srdivacky    bool HasLT = false, HasGT = false;
553218893Sdim    for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) {
554218893Sdim      if (*AsmOperands[i].Class < *RHS.AsmOperands[i].Class)
555198090Srdivacky        HasLT = true;
556218893Sdim      if (*RHS.AsmOperands[i].Class < *AsmOperands[i].Class)
557198090Srdivacky        HasGT = true;
558198090Srdivacky    }
559198090Srdivacky
560198090Srdivacky    return !(HasLT ^ HasGT);
561198090Srdivacky  }
562198090Srdivacky
563198090Srdivacky  void dump();
564218893Sdim
565218893Sdimprivate:
566245431Sdim  void tokenizeAsmString(const AsmMatcherInfo &Info);
567198090Srdivacky};
568198090Srdivacky
569212904Sdim/// SubtargetFeatureInfo - Helper class for storing information on a subtarget
570212904Sdim/// feature which participates in instruction matching.
571212904Sdimstruct SubtargetFeatureInfo {
572212904Sdim  /// \brief The predicate record for this feature.
573212904Sdim  Record *TheDef;
574212904Sdim
575212904Sdim  /// \brief An unique index assigned to represent this feature.
576212904Sdim  unsigned Index;
577212904Sdim
578218893Sdim  SubtargetFeatureInfo(Record *D, unsigned Idx) : TheDef(D), Index(Idx) {}
579218893Sdim
580212904Sdim  /// \brief The name of the enumerated constant identifying this feature.
581218893Sdim  std::string getEnumName() const {
582218893Sdim    return "Feature_" + TheDef->getName();
583218893Sdim  }
584212904Sdim};
585212904Sdim
586218893Sdimstruct OperandMatchEntry {
587218893Sdim  unsigned OperandMask;
588218893Sdim  MatchableInfo* MI;
589218893Sdim  ClassInfo *CI;
590218893Sdim
591245431Sdim  static OperandMatchEntry create(MatchableInfo* mi, ClassInfo *ci,
592218893Sdim                                  unsigned opMask) {
593218893Sdim    OperandMatchEntry X;
594218893Sdim    X.OperandMask = opMask;
595218893Sdim    X.CI = ci;
596218893Sdim    X.MI = mi;
597218893Sdim    return X;
598218893Sdim  }
599218893Sdim};
600218893Sdim
601218893Sdim
602198090Srdivackyclass AsmMatcherInfo {
603198090Srdivackypublic:
604218893Sdim  /// Tracked Records
605218893Sdim  RecordKeeper &Records;
606218893Sdim
607198090Srdivacky  /// The tablegen AsmParser record.
608198090Srdivacky  Record *AsmParser;
609198090Srdivacky
610218893Sdim  /// Target - The target information.
611218893Sdim  CodeGenTarget &Target;
612198090Srdivacky
613198090Srdivacky  /// The classes which are needed for matching.
614198090Srdivacky  std::vector<ClassInfo*> Classes;
615198090Srdivacky
616218893Sdim  /// The information on the matchables to match.
617218893Sdim  std::vector<MatchableInfo*> Matchables;
618218893Sdim
619218893Sdim  /// Info for custom matching operands by user defined methods.
620218893Sdim  std::vector<OperandMatchEntry> OperandMatchInfo;
621218893Sdim
622198090Srdivacky  /// Map of Register records to their class information.
623245431Sdim  typedef std::map<Record*, ClassInfo*, LessRecordByID> RegisterClassesTy;
624245431Sdim  RegisterClassesTy RegisterClasses;
625198090Srdivacky
626212904Sdim  /// Map of Predicate records to their subtarget information.
627263509Sdim  std::map<Record*, SubtargetFeatureInfo*, LessRecordByID> SubtargetFeatures;
628212904Sdim
629245431Sdim  /// Map of AsmOperandClass records to their class information.
630245431Sdim  std::map<Record*, ClassInfo*> AsmOperandClasses;
631245431Sdim
632198090Srdivackyprivate:
633198090Srdivacky  /// Map of token to class information which has already been constructed.
634198090Srdivacky  std::map<std::string, ClassInfo*> TokenClasses;
635198090Srdivacky
636198090Srdivacky  /// Map of RegisterClass records to their class information.
637198090Srdivacky  std::map<Record*, ClassInfo*> RegisterClassClasses;
638198090Srdivacky
639198090Srdivackyprivate:
640198090Srdivacky  /// getTokenClass - Lookup or create the class for the given token.
641203954Srdivacky  ClassInfo *getTokenClass(StringRef Token);
642198090Srdivacky
643198090Srdivacky  /// getOperandClass - Lookup or create the class for the given operand.
644218893Sdim  ClassInfo *getOperandClass(const CGIOperandList::OperandInfo &OI,
645235633Sdim                             int SubOpIdx);
646235633Sdim  ClassInfo *getOperandClass(Record *Rec, int SubOpIdx);
647198090Srdivacky
648245431Sdim  /// buildRegisterClasses - Build the ClassInfo* instances for register
649198090Srdivacky  /// classes.
650245431Sdim  void buildRegisterClasses(SmallPtrSet<Record*, 16> &SingletonRegisters);
651198090Srdivacky
652245431Sdim  /// buildOperandClasses - Build the ClassInfo* instances for user defined
653198090Srdivacky  /// operand classes.
654245431Sdim  void buildOperandClasses();
655198090Srdivacky
656245431Sdim  void buildInstructionOperandReference(MatchableInfo *II, StringRef OpName,
657218893Sdim                                        unsigned AsmOpIdx);
658245431Sdim  void buildAliasOperandReference(MatchableInfo *II, StringRef OpName,
659218893Sdim                                  MatchableInfo::AsmOperand &Op);
660218893Sdim
661198090Srdivackypublic:
662218893Sdim  AsmMatcherInfo(Record *AsmParser,
663218893Sdim                 CodeGenTarget &Target,
664218893Sdim                 RecordKeeper &Records);
665198090Srdivacky
666245431Sdim  /// buildInfo - Construct the various tables used during matching.
667245431Sdim  void buildInfo();
668218893Sdim
669245431Sdim  /// buildOperandMatchInfo - Build the necessary information to handle user
670218893Sdim  /// defined operand parsing methods.
671245431Sdim  void buildOperandMatchInfo();
672218893Sdim
673218893Sdim  /// getSubtargetFeature - Lookup or create the subtarget feature info for the
674218893Sdim  /// given operand.
675218893Sdim  SubtargetFeatureInfo *getSubtargetFeature(Record *Def) const {
676218893Sdim    assert(Def->isSubClassOf("Predicate") && "Invalid predicate type!");
677263509Sdim    std::map<Record*, SubtargetFeatureInfo*, LessRecordByID>::const_iterator I =
678218893Sdim      SubtargetFeatures.find(Def);
679218893Sdim    return I == SubtargetFeatures.end() ? 0 : I->second;
680218893Sdim  }
681218893Sdim
682218893Sdim  RecordKeeper &getRecords() const {
683218893Sdim    return Records;
684218893Sdim  }
685198090Srdivacky};
686198090Srdivacky
687245431Sdim} // End anonymous namespace
688198090Srdivacky
689218893Sdimvoid MatchableInfo::dump() {
690218893Sdim  errs() << TheDef->getName() << " -- " << "flattened:\"" << AsmString <<"\"\n";
691218893Sdim
692218893Sdim  for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) {
693218893Sdim    AsmOperand &Op = AsmOperands[i];
694218893Sdim    errs() << "  op[" << i << "] = " << Op.Class->ClassName << " - ";
695218893Sdim    errs() << '\"' << Op.Token << "\"\n";
696198090Srdivacky  }
697218893Sdim}
698198090Srdivacky
699245431Sdimstatic std::pair<StringRef, StringRef>
700245431SdimparseTwoOperandConstraint(StringRef S, ArrayRef<SMLoc> Loc) {
701245431Sdim  // Split via the '='.
702245431Sdim  std::pair<StringRef, StringRef> Ops = S.split('=');
703245431Sdim  if (Ops.second == "")
704245431Sdim    PrintFatalError(Loc, "missing '=' in two-operand alias constraint");
705245431Sdim  // Trim whitespace and the leading '$' on the operand names.
706245431Sdim  size_t start = Ops.first.find_first_of('$');
707245431Sdim  if (start == std::string::npos)
708245431Sdim    PrintFatalError(Loc, "expected '$' prefix on asm operand name");
709245431Sdim  Ops.first = Ops.first.slice(start + 1, std::string::npos);
710245431Sdim  size_t end = Ops.first.find_last_of(" \t");
711245431Sdim  Ops.first = Ops.first.slice(0, end);
712245431Sdim  // Now the second operand.
713245431Sdim  start = Ops.second.find_first_of('$');
714245431Sdim  if (start == std::string::npos)
715245431Sdim    PrintFatalError(Loc, "expected '$' prefix on asm operand name");
716245431Sdim  Ops.second = Ops.second.slice(start + 1, std::string::npos);
717245431Sdim  end = Ops.second.find_last_of(" \t");
718245431Sdim  Ops.first = Ops.first.slice(0, end);
719245431Sdim  return Ops;
720245431Sdim}
721245431Sdim
722245431Sdimvoid MatchableInfo::formTwoOperandAlias(StringRef Constraint) {
723245431Sdim  // Figure out which operands are aliased and mark them as tied.
724245431Sdim  std::pair<StringRef, StringRef> Ops =
725245431Sdim    parseTwoOperandConstraint(Constraint, TheDef->getLoc());
726245431Sdim
727245431Sdim  // Find the AsmOperands that refer to the operands we're aliasing.
728245431Sdim  int SrcAsmOperand = findAsmOperandNamed(Ops.first);
729245431Sdim  int DstAsmOperand = findAsmOperandNamed(Ops.second);
730245431Sdim  if (SrcAsmOperand == -1)
731245431Sdim    PrintFatalError(TheDef->getLoc(),
732245431Sdim                  "unknown source two-operand alias operand '" +
733245431Sdim                  Ops.first.str() + "'.");
734245431Sdim  if (DstAsmOperand == -1)
735245431Sdim    PrintFatalError(TheDef->getLoc(),
736245431Sdim                  "unknown destination two-operand alias operand '" +
737245431Sdim                  Ops.second.str() + "'.");
738245431Sdim
739245431Sdim  // Find the ResOperand that refers to the operand we're aliasing away
740245431Sdim  // and update it to refer to the combined operand instead.
741245431Sdim  for (unsigned i = 0, e = ResOperands.size(); i != e; ++i) {
742245431Sdim    ResOperand &Op = ResOperands[i];
743245431Sdim    if (Op.Kind == ResOperand::RenderAsmOperand &&
744245431Sdim        Op.AsmOperandNum == (unsigned)SrcAsmOperand) {
745245431Sdim      Op.AsmOperandNum = DstAsmOperand;
746245431Sdim      break;
747245431Sdim    }
748245431Sdim  }
749245431Sdim  // Remove the AsmOperand for the alias operand.
750245431Sdim  AsmOperands.erase(AsmOperands.begin() + SrcAsmOperand);
751245431Sdim  // Adjust the ResOperand references to any AsmOperands that followed
752245431Sdim  // the one we just deleted.
753245431Sdim  for (unsigned i = 0, e = ResOperands.size(); i != e; ++i) {
754245431Sdim    ResOperand &Op = ResOperands[i];
755245431Sdim    switch(Op.Kind) {
756245431Sdim    default:
757245431Sdim      // Nothing to do for operands that don't reference AsmOperands.
758245431Sdim      break;
759245431Sdim    case ResOperand::RenderAsmOperand:
760245431Sdim      if (Op.AsmOperandNum > (unsigned)SrcAsmOperand)
761245431Sdim        --Op.AsmOperandNum;
762245431Sdim      break;
763245431Sdim    case ResOperand::TiedOperand:
764245431Sdim      if (Op.TiedOperandNum > (unsigned)SrcAsmOperand)
765245431Sdim        --Op.TiedOperandNum;
766245431Sdim      break;
767245431Sdim    }
768245431Sdim  }
769245431Sdim}
770245431Sdim
771245431Sdimvoid MatchableInfo::initialize(const AsmMatcherInfo &Info,
772235633Sdim                               SmallPtrSet<Record*, 16> &SingletonRegisters,
773235633Sdim                               int AsmVariantNo, std::string &RegisterPrefix) {
774235633Sdim  AsmVariantID = AsmVariantNo;
775235633Sdim  AsmString =
776235633Sdim    CodeGenInstruction::FlattenAsmStringVariants(AsmString, AsmVariantNo);
777218893Sdim
778245431Sdim  tokenizeAsmString(Info);
779218893Sdim
780218893Sdim  // Compute the require features.
781218893Sdim  std::vector<Record*> Predicates =TheDef->getValueAsListOfDefs("Predicates");
782218893Sdim  for (unsigned i = 0, e = Predicates.size(); i != e; ++i)
783218893Sdim    if (SubtargetFeatureInfo *Feature =
784218893Sdim        Info.getSubtargetFeature(Predicates[i]))
785218893Sdim      RequiredFeatures.push_back(Feature);
786218893Sdim
787218893Sdim  // Collect singleton registers, if used.
788218893Sdim  for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) {
789235633Sdim    extractSingletonRegisterForAsmOperand(i, Info, RegisterPrefix);
790235633Sdim    if (Record *Reg = AsmOperands[i].SingletonReg)
791218893Sdim      SingletonRegisters.insert(Reg);
792218893Sdim  }
793263509Sdim
794263509Sdim  const RecordVal *DepMask = TheDef->getValue("DeprecatedFeatureMask");
795263509Sdim  if (!DepMask)
796263509Sdim    DepMask = TheDef->getValue("ComplexDeprecationPredicate");
797263509Sdim
798263509Sdim  HasDeprecation =
799263509Sdim      DepMask ? !DepMask->getValue()->getAsUnquotedString().empty() : false;
800218893Sdim}
801218893Sdim
802245431Sdim/// tokenizeAsmString - Tokenize a simplified assembly string.
803245431Sdimvoid MatchableInfo::tokenizeAsmString(const AsmMatcherInfo &Info) {
804218893Sdim  StringRef String = AsmString;
805218893Sdim  unsigned Prev = 0;
806218893Sdim  bool InTok = true;
807218893Sdim  for (unsigned i = 0, e = String.size(); i != e; ++i) {
808218893Sdim    switch (String[i]) {
809218893Sdim    case '[':
810218893Sdim    case ']':
811218893Sdim    case '*':
812218893Sdim    case '!':
813218893Sdim    case ' ':
814218893Sdim    case '\t':
815218893Sdim    case ',':
816218893Sdim      if (InTok) {
817218893Sdim        AsmOperands.push_back(AsmOperand(String.slice(Prev, i)));
818218893Sdim        InTok = false;
819218893Sdim      }
820218893Sdim      if (!isspace(String[i]) && String[i] != ',')
821218893Sdim        AsmOperands.push_back(AsmOperand(String.substr(i, 1)));
822218893Sdim      Prev = i + 1;
823218893Sdim      break;
824218893Sdim
825218893Sdim    case '\\':
826218893Sdim      if (InTok) {
827218893Sdim        AsmOperands.push_back(AsmOperand(String.slice(Prev, i)));
828218893Sdim        InTok = false;
829218893Sdim      }
830218893Sdim      ++i;
831218893Sdim      assert(i != String.size() && "Invalid quoted character");
832218893Sdim      AsmOperands.push_back(AsmOperand(String.substr(i, 1)));
833218893Sdim      Prev = i + 1;
834218893Sdim      break;
835218893Sdim
836218893Sdim    case '$': {
837218893Sdim      if (InTok) {
838218893Sdim        AsmOperands.push_back(AsmOperand(String.slice(Prev, i)));
839218893Sdim        InTok = false;
840218893Sdim      }
841218893Sdim
842218893Sdim      // If this isn't "${", treat like a normal token.
843218893Sdim      if (i + 1 == String.size() || String[i + 1] != '{') {
844218893Sdim        Prev = i;
845218893Sdim        break;
846218893Sdim      }
847218893Sdim
848218893Sdim      StringRef::iterator End = std::find(String.begin() + i, String.end(),'}');
849218893Sdim      assert(End != String.end() && "Missing brace in operand reference!");
850218893Sdim      size_t EndPos = End - String.begin();
851218893Sdim      AsmOperands.push_back(AsmOperand(String.slice(i, EndPos+1)));
852218893Sdim      Prev = EndPos + 1;
853218893Sdim      i = EndPos;
854218893Sdim      break;
855198090Srdivacky    }
856198090Srdivacky
857218893Sdim    case '.':
858263509Sdim      if (!Info.AsmParser->getValueAsBit("MnemonicContainsDot")) {
859263509Sdim        if (InTok)
860263509Sdim          AsmOperands.push_back(AsmOperand(String.slice(Prev, i)));
861263509Sdim        Prev = i;
862263509Sdim      }
863218893Sdim      InTok = true;
864218893Sdim      break;
865218893Sdim
866218893Sdim    default:
867218893Sdim      InTok = true;
868198090Srdivacky    }
869218893Sdim  }
870218893Sdim  if (InTok && Prev != String.size())
871218893Sdim    AsmOperands.push_back(AsmOperand(String.substr(Prev)));
872198090Srdivacky
873218893Sdim  // The first token of the instruction is the mnemonic, which must be a
874218893Sdim  // simple string, not a $foo variable or a singleton register.
875235633Sdim  if (AsmOperands.empty())
876245431Sdim    PrintFatalError(TheDef->getLoc(),
877235633Sdim                  "Instruction '" + TheDef->getName() + "' has no tokens");
878218893Sdim  Mnemonic = AsmOperands[0].Token;
879245431Sdim  if (Mnemonic.empty())
880245431Sdim    PrintFatalError(TheDef->getLoc(),
881245431Sdim                  "Missing instruction mnemonic");
882235633Sdim  // FIXME : Check and raise an error if it is a register.
883235633Sdim  if (Mnemonic[0] == '$')
884245431Sdim    PrintFatalError(TheDef->getLoc(),
885218893Sdim                  "Invalid instruction mnemonic '" + Mnemonic.str() + "'!");
886218893Sdim
887218893Sdim  // Remove the first operand, it is tracked in the mnemonic field.
888218893Sdim  AsmOperands.erase(AsmOperands.begin());
889218893Sdim}
890218893Sdim
891245431Sdimbool MatchableInfo::validate(StringRef CommentDelimiter, bool Hack) const {
892218893Sdim  // Reject matchables with no .s string.
893218893Sdim  if (AsmString.empty())
894245431Sdim    PrintFatalError(TheDef->getLoc(), "instruction with empty asm string");
895218893Sdim
896218893Sdim  // Reject any matchables with a newline in them, they should be marked
897218893Sdim  // isCodeGenOnly if they are pseudo instructions.
898218893Sdim  if (AsmString.find('\n') != std::string::npos)
899245431Sdim    PrintFatalError(TheDef->getLoc(),
900218893Sdim                  "multiline instruction is not valid for the asmparser, "
901218893Sdim                  "mark it isCodeGenOnly");
902218893Sdim
903218893Sdim  // Remove comments from the asm string.  We know that the asmstring only
904218893Sdim  // has one line.
905218893Sdim  if (!CommentDelimiter.empty() &&
906218893Sdim      StringRef(AsmString).find(CommentDelimiter) != StringRef::npos)
907245431Sdim    PrintFatalError(TheDef->getLoc(),
908218893Sdim                  "asmstring for instruction has comment character in it, "
909218893Sdim                  "mark it isCodeGenOnly");
910218893Sdim
911218893Sdim  // Reject matchables with operand modifiers, these aren't something we can
912218893Sdim  // handle, the target should be refactored to use operands instead of
913218893Sdim  // modifiers.
914218893Sdim  //
915218893Sdim  // Also, check for instructions which reference the operand multiple times;
916218893Sdim  // this implies a constraint we would not honor.
917218893Sdim  std::set<std::string> OperandNames;
918218893Sdim  for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) {
919218893Sdim    StringRef Tok = AsmOperands[i].Token;
920218893Sdim    if (Tok[0] == '$' && Tok.find(':') != StringRef::npos)
921245431Sdim      PrintFatalError(TheDef->getLoc(),
922218893Sdim                    "matchable with operand modifier '" + Tok.str() +
923218893Sdim                    "' not supported by asm matcher.  Mark isCodeGenOnly!");
924218893Sdim
925218893Sdim    // Verify that any operand is only mentioned once.
926218893Sdim    // We reject aliases and ignore instructions for now.
927218893Sdim    if (Tok[0] == '$' && !OperandNames.insert(Tok).second) {
928218893Sdim      if (!Hack)
929245431Sdim        PrintFatalError(TheDef->getLoc(),
930218893Sdim                      "ERROR: matchable with tied operand '" + Tok.str() +
931218893Sdim                      "' can never be matched!");
932218893Sdim      // FIXME: Should reject these.  The ARM backend hits this with $lane in a
933218893Sdim      // bunch of instructions.  It is unclear what the right answer is.
934218893Sdim      DEBUG({
935218893Sdim        errs() << "warning: '" << TheDef->getName() << "': "
936218893Sdim               << "ignoring instruction with tied operand '"
937218893Sdim               << Tok.str() << "'\n";
938218893Sdim      });
939218893Sdim      return false;
940218893Sdim    }
941198090Srdivacky  }
942218893Sdim
943218893Sdim  return true;
944198090Srdivacky}
945198090Srdivacky
946235633Sdim/// extractSingletonRegisterForAsmOperand - Extract singleton register,
947235633Sdim/// if present, from specified token.
948235633Sdimvoid MatchableInfo::
949235633SdimextractSingletonRegisterForAsmOperand(unsigned OperandNo,
950235633Sdim                                      const AsmMatcherInfo &Info,
951235633Sdim                                      std::string &RegisterPrefix) {
952235633Sdim  StringRef Tok = AsmOperands[OperandNo].Token;
953235633Sdim  if (RegisterPrefix.empty()) {
954235633Sdim    std::string LoweredTok = Tok.lower();
955235633Sdim    if (const CodeGenRegister *Reg = Info.Target.getRegisterByName(LoweredTok))
956235633Sdim      AsmOperands[OperandNo].SingletonReg = Reg->TheDef;
957235633Sdim    return;
958235633Sdim  }
959218893Sdim
960235633Sdim  if (!Tok.startswith(RegisterPrefix))
961235633Sdim    return;
962235633Sdim
963235633Sdim  StringRef RegName = Tok.substr(RegisterPrefix.size());
964218893Sdim  if (const CodeGenRegister *Reg = Info.Target.getRegisterByName(RegName))
965235633Sdim    AsmOperands[OperandNo].SingletonReg = Reg->TheDef;
966218893Sdim
967218893Sdim  // If there is no register prefix (i.e. "%" in "%eax"), then this may
968218893Sdim  // be some random non-register token, just ignore it.
969235633Sdim  return;
970218893Sdim}
971218893Sdim
972203954Srdivackystatic std::string getEnumNameForToken(StringRef Str) {
973198090Srdivacky  std::string Res;
974218893Sdim
975198090Srdivacky  for (StringRef::iterator it = Str.begin(), ie = Str.end(); it != ie; ++it) {
976198090Srdivacky    switch (*it) {
977198090Srdivacky    case '*': Res += "_STAR_"; break;
978198090Srdivacky    case '%': Res += "_PCT_"; break;
979198090Srdivacky    case ':': Res += "_COLON_"; break;
980218893Sdim    case '!': Res += "_EXCLAIM_"; break;
981218893Sdim    case '.': Res += "_DOT_"; break;
982252723Sdim    case '<': Res += "_LT_"; break;
983252723Sdim    case '>': Res += "_GT_"; break;
984198090Srdivacky    default:
985252723Sdim      if ((*it >= 'A' && *it <= 'Z') ||
986252723Sdim          (*it >= 'a' && *it <= 'z') ||
987252723Sdim          (*it >= '0' && *it <= '9'))
988198090Srdivacky        Res += *it;
989218893Sdim      else
990198090Srdivacky        Res += "_" + utostr((unsigned) *it) + "_";
991198090Srdivacky    }
992198090Srdivacky  }
993198090Srdivacky
994198090Srdivacky  return Res;
995198090Srdivacky}
996198090Srdivacky
997203954SrdivackyClassInfo *AsmMatcherInfo::getTokenClass(StringRef Token) {
998198090Srdivacky  ClassInfo *&Entry = TokenClasses[Token];
999218893Sdim
1000198090Srdivacky  if (!Entry) {
1001198090Srdivacky    Entry = new ClassInfo();
1002198090Srdivacky    Entry->Kind = ClassInfo::Token;
1003198090Srdivacky    Entry->ClassName = "Token";
1004198090Srdivacky    Entry->Name = "MCK_" + getEnumNameForToken(Token);
1005198090Srdivacky    Entry->ValueName = Token;
1006198090Srdivacky    Entry->PredicateMethod = "<invalid>";
1007198090Srdivacky    Entry->RenderMethod = "<invalid>";
1008218893Sdim    Entry->ParserMethod = "";
1009245431Sdim    Entry->DiagnosticType = "";
1010198090Srdivacky    Classes.push_back(Entry);
1011198090Srdivacky  }
1012198090Srdivacky
1013198090Srdivacky  return Entry;
1014198090Srdivacky}
1015198090Srdivacky
1016198090SrdivackyClassInfo *
1017218893SdimAsmMatcherInfo::getOperandClass(const CGIOperandList::OperandInfo &OI,
1018218893Sdim                                int SubOpIdx) {
1019218893Sdim  Record *Rec = OI.Rec;
1020218893Sdim  if (SubOpIdx != -1)
1021245431Sdim    Rec = cast<DefInit>(OI.MIOperandInfo->getArg(SubOpIdx))->getDef();
1022235633Sdim  return getOperandClass(Rec, SubOpIdx);
1023235633Sdim}
1024198090Srdivacky
1025235633SdimClassInfo *
1026235633SdimAsmMatcherInfo::getOperandClass(Record *Rec, int SubOpIdx) {
1027224145Sdim  if (Rec->isSubClassOf("RegisterOperand")) {
1028224145Sdim    // RegisterOperand may have an associated ParserMatchClass. If it does,
1029224145Sdim    // use it, else just fall back to the underlying register class.
1030224145Sdim    const RecordVal *R = Rec->getValue("ParserMatchClass");
1031224145Sdim    if (R == 0 || R->getValue() == 0)
1032245431Sdim      PrintFatalError("Record `" + Rec->getName() +
1033245431Sdim        "' does not have a ParserMatchClass!\n");
1034224145Sdim
1035245431Sdim    if (DefInit *DI= dyn_cast<DefInit>(R->getValue())) {
1036224145Sdim      Record *MatchClass = DI->getDef();
1037224145Sdim      if (ClassInfo *CI = AsmOperandClasses[MatchClass])
1038224145Sdim        return CI;
1039224145Sdim    }
1040224145Sdim
1041224145Sdim    // No custom match class. Just use the register class.
1042224145Sdim    Record *ClassRec = Rec->getValueAsDef("RegClass");
1043224145Sdim    if (!ClassRec)
1044245431Sdim      PrintFatalError(Rec->getLoc(), "RegisterOperand `" + Rec->getName() +
1045224145Sdim                    "' has no associated register class!\n");
1046224145Sdim    if (ClassInfo *CI = RegisterClassClasses[ClassRec])
1047224145Sdim      return CI;
1048245431Sdim    PrintFatalError(Rec->getLoc(), "register class has no class info!");
1049224145Sdim  }
1050224145Sdim
1051224145Sdim
1052218893Sdim  if (Rec->isSubClassOf("RegisterClass")) {
1053218893Sdim    if (ClassInfo *CI = RegisterClassClasses[Rec])
1054218893Sdim      return CI;
1055245431Sdim    PrintFatalError(Rec->getLoc(), "register class has no class info!");
1056218893Sdim  }
1057198090Srdivacky
1058245431Sdim  if (!Rec->isSubClassOf("Operand"))
1059245431Sdim    PrintFatalError(Rec->getLoc(), "Operand `" + Rec->getName() +
1060245431Sdim                  "' does not derive from class Operand!\n");
1061218893Sdim  Record *MatchClass = Rec->getValueAsDef("ParserMatchClass");
1062218893Sdim  if (ClassInfo *CI = AsmOperandClasses[MatchClass])
1063198090Srdivacky    return CI;
1064198090Srdivacky
1065245431Sdim  PrintFatalError(Rec->getLoc(), "operand has no match class!");
1066198090Srdivacky}
1067198090Srdivacky
1068263509Sdimstruct LessRegisterSet {
1069263509Sdim  bool operator() (const RegisterSet &LHS, const RegisterSet & RHS) const {
1070263509Sdim    // std::set<T> defines its own compariso "operator<", but it
1071263509Sdim    // performs a lexicographical comparison by T's innate comparison
1072263509Sdim    // for some reason. We don't want non-deterministic pointer
1073263509Sdim    // comparisons so use this instead.
1074263509Sdim    return std::lexicographical_compare(LHS.begin(), LHS.end(),
1075263509Sdim                                        RHS.begin(), RHS.end(),
1076263509Sdim                                        LessRecordByID());
1077263509Sdim  }
1078263509Sdim};
1079263509Sdim
1080218893Sdimvoid AsmMatcherInfo::
1081245431SdimbuildRegisterClasses(SmallPtrSet<Record*, 16> &SingletonRegisters) {
1082224145Sdim  const std::vector<CodeGenRegister*> &Registers =
1083224145Sdim    Target.getRegBank().getRegisters();
1084226890Sdim  ArrayRef<CodeGenRegisterClass*> RegClassList =
1085226890Sdim    Target.getRegBank().getRegClasses();
1086198090Srdivacky
1087263509Sdim  typedef std::set<RegisterSet, LessRegisterSet> RegisterSetSet;
1088263509Sdim
1089198090Srdivacky  // The register sets used for matching.
1090263509Sdim  RegisterSetSet RegisterSets;
1091198090Srdivacky
1092218893Sdim  // Gather the defined sets.
1093226890Sdim  for (ArrayRef<CodeGenRegisterClass*>::const_iterator it =
1094263509Sdim         RegClassList.begin(), ie = RegClassList.end(); it != ie; ++it)
1095263509Sdim    RegisterSets.insert(RegisterSet(
1096226890Sdim        (*it)->getOrder().begin(), (*it)->getOrder().end()));
1097198090Srdivacky
1098198090Srdivacky  // Add any required singleton sets.
1099218893Sdim  for (SmallPtrSet<Record*, 16>::iterator it = SingletonRegisters.begin(),
1100218893Sdim       ie = SingletonRegisters.end(); it != ie; ++it) {
1101218893Sdim    Record *Rec = *it;
1102263509Sdim    RegisterSets.insert(RegisterSet(&Rec, &Rec + 1));
1103218893Sdim  }
1104218893Sdim
1105198090Srdivacky  // Introduce derived sets where necessary (when a register does not determine
1106198090Srdivacky  // a unique register set class), and build the mapping of registers to the set
1107198090Srdivacky  // they should classify to.
1108263509Sdim  std::map<Record*, RegisterSet> RegisterMap;
1109224145Sdim  for (std::vector<CodeGenRegister*>::const_iterator it = Registers.begin(),
1110198090Srdivacky         ie = Registers.end(); it != ie; ++it) {
1111224145Sdim    const CodeGenRegister &CGR = **it;
1112198090Srdivacky    // Compute the intersection of all sets containing this register.
1113263509Sdim    RegisterSet ContainingSet;
1114218893Sdim
1115263509Sdim    for (RegisterSetSet::iterator it = RegisterSets.begin(),
1116198090Srdivacky           ie = RegisterSets.end(); it != ie; ++it) {
1117198090Srdivacky      if (!it->count(CGR.TheDef))
1118198090Srdivacky        continue;
1119198090Srdivacky
1120198090Srdivacky      if (ContainingSet.empty()) {
1121198090Srdivacky        ContainingSet = *it;
1122218893Sdim        continue;
1123198090Srdivacky      }
1124218893Sdim
1125263509Sdim      RegisterSet Tmp;
1126218893Sdim      std::swap(Tmp, ContainingSet);
1127263509Sdim      std::insert_iterator<RegisterSet> II(ContainingSet,
1128263509Sdim                                           ContainingSet.begin());
1129263509Sdim      std::set_intersection(Tmp.begin(), Tmp.end(), it->begin(), it->end(), II,
1130263509Sdim                            LessRecordByID());
1131198090Srdivacky    }
1132198090Srdivacky
1133198090Srdivacky    if (!ContainingSet.empty()) {
1134198090Srdivacky      RegisterSets.insert(ContainingSet);
1135198090Srdivacky      RegisterMap.insert(std::make_pair(CGR.TheDef, ContainingSet));
1136198090Srdivacky    }
1137198090Srdivacky  }
1138198090Srdivacky
1139198090Srdivacky  // Construct the register classes.
1140263509Sdim  std::map<RegisterSet, ClassInfo*, LessRegisterSet> RegisterSetClasses;
1141198090Srdivacky  unsigned Index = 0;
1142263509Sdim  for (RegisterSetSet::iterator it = RegisterSets.begin(),
1143198090Srdivacky         ie = RegisterSets.end(); it != ie; ++it, ++Index) {
1144198090Srdivacky    ClassInfo *CI = new ClassInfo();
1145198090Srdivacky    CI->Kind = ClassInfo::RegisterClass0 + Index;
1146198090Srdivacky    CI->ClassName = "Reg" + utostr(Index);
1147198090Srdivacky    CI->Name = "MCK_Reg" + utostr(Index);
1148198090Srdivacky    CI->ValueName = "";
1149198090Srdivacky    CI->PredicateMethod = ""; // unused
1150198090Srdivacky    CI->RenderMethod = "addRegOperands";
1151198090Srdivacky    CI->Registers = *it;
1152245431Sdim    // FIXME: diagnostic type.
1153245431Sdim    CI->DiagnosticType = "";
1154198090Srdivacky    Classes.push_back(CI);
1155198090Srdivacky    RegisterSetClasses.insert(std::make_pair(*it, CI));
1156198090Srdivacky  }
1157198090Srdivacky
1158198090Srdivacky  // Find the superclasses; we could compute only the subgroup lattice edges,
1159198090Srdivacky  // but there isn't really a point.
1160263509Sdim  for (RegisterSetSet::iterator it = RegisterSets.begin(),
1161198090Srdivacky         ie = RegisterSets.end(); it != ie; ++it) {
1162198090Srdivacky    ClassInfo *CI = RegisterSetClasses[*it];
1163263509Sdim    for (RegisterSetSet::iterator it2 = RegisterSets.begin(),
1164198090Srdivacky           ie2 = RegisterSets.end(); it2 != ie2; ++it2)
1165218893Sdim      if (*it != *it2 &&
1166263509Sdim          std::includes(it2->begin(), it2->end(), it->begin(), it->end(),
1167263509Sdim                        LessRecordByID()))
1168198090Srdivacky        CI->SuperClasses.push_back(RegisterSetClasses[*it2]);
1169198090Srdivacky  }
1170198090Srdivacky
1171198090Srdivacky  // Name the register classes which correspond to a user defined RegisterClass.
1172226890Sdim  for (ArrayRef<CodeGenRegisterClass*>::const_iterator
1173218893Sdim       it = RegClassList.begin(), ie = RegClassList.end(); it != ie; ++it) {
1174226890Sdim    const CodeGenRegisterClass &RC = **it;
1175226890Sdim    // Def will be NULL for non-user defined register classes.
1176226890Sdim    Record *Def = RC.getDef();
1177226890Sdim    if (!Def)
1178226890Sdim      continue;
1179263509Sdim    ClassInfo *CI = RegisterSetClasses[RegisterSet(RC.getOrder().begin(),
1180263509Sdim                                                   RC.getOrder().end())];
1181198090Srdivacky    if (CI->ValueName.empty()) {
1182226890Sdim      CI->ClassName = RC.getName();
1183226890Sdim      CI->Name = "MCK_" + RC.getName();
1184226890Sdim      CI->ValueName = RC.getName();
1185198090Srdivacky    } else
1186226890Sdim      CI->ValueName = CI->ValueName + "," + RC.getName();
1187198090Srdivacky
1188226890Sdim    RegisterClassClasses.insert(std::make_pair(Def, CI));
1189198090Srdivacky  }
1190198090Srdivacky
1191198090Srdivacky  // Populate the map for individual registers.
1192263509Sdim  for (std::map<Record*, RegisterSet>::iterator it = RegisterMap.begin(),
1193198090Srdivacky         ie = RegisterMap.end(); it != ie; ++it)
1194218893Sdim    RegisterClasses[it->first] = RegisterSetClasses[it->second];
1195198090Srdivacky
1196198090Srdivacky  // Name the register classes which correspond to singleton registers.
1197218893Sdim  for (SmallPtrSet<Record*, 16>::iterator it = SingletonRegisters.begin(),
1198218893Sdim         ie = SingletonRegisters.end(); it != ie; ++it) {
1199218893Sdim    Record *Rec = *it;
1200218893Sdim    ClassInfo *CI = RegisterClasses[Rec];
1201218893Sdim    assert(CI && "Missing singleton register class info!");
1202198090Srdivacky
1203218893Sdim    if (CI->ValueName.empty()) {
1204218893Sdim      CI->ClassName = Rec->getName();
1205218893Sdim      CI->Name = "MCK_" + Rec->getName();
1206218893Sdim      CI->ValueName = Rec->getName();
1207218893Sdim    } else
1208218893Sdim      CI->ValueName = CI->ValueName + "," + Rec->getName();
1209198090Srdivacky  }
1210198090Srdivacky}
1211198090Srdivacky
1212245431Sdimvoid AsmMatcherInfo::buildOperandClasses() {
1213218893Sdim  std::vector<Record*> AsmOperands =
1214218893Sdim    Records.getAllDerivedDefinitions("AsmOperandClass");
1215203954Srdivacky
1216203954Srdivacky  // Pre-populate AsmOperandClasses map.
1217218893Sdim  for (std::vector<Record*>::iterator it = AsmOperands.begin(),
1218203954Srdivacky         ie = AsmOperands.end(); it != ie; ++it)
1219203954Srdivacky    AsmOperandClasses[*it] = new ClassInfo();
1220203954Srdivacky
1221198090Srdivacky  unsigned Index = 0;
1222218893Sdim  for (std::vector<Record*>::iterator it = AsmOperands.begin(),
1223198090Srdivacky         ie = AsmOperands.end(); it != ie; ++it, ++Index) {
1224203954Srdivacky    ClassInfo *CI = AsmOperandClasses[*it];
1225198090Srdivacky    CI->Kind = ClassInfo::UserClass0 + Index;
1226198090Srdivacky
1227208599Srdivacky    ListInit *Supers = (*it)->getValueAsListInit("SuperClasses");
1228208599Srdivacky    for (unsigned i = 0, e = Supers->getSize(); i != e; ++i) {
1229245431Sdim      DefInit *DI = dyn_cast<DefInit>(Supers->getElement(i));
1230208599Srdivacky      if (!DI) {
1231208599Srdivacky        PrintError((*it)->getLoc(), "Invalid super class reference!");
1232208599Srdivacky        continue;
1233208599Srdivacky      }
1234208599Srdivacky
1235198090Srdivacky      ClassInfo *SC = AsmOperandClasses[DI->getDef()];
1236198090Srdivacky      if (!SC)
1237198090Srdivacky        PrintError((*it)->getLoc(), "Invalid super class reference!");
1238198090Srdivacky      else
1239198090Srdivacky        CI->SuperClasses.push_back(SC);
1240198090Srdivacky    }
1241198090Srdivacky    CI->ClassName = (*it)->getValueAsString("Name");
1242198090Srdivacky    CI->Name = "MCK_" + CI->ClassName;
1243198090Srdivacky    CI->ValueName = (*it)->getName();
1244198090Srdivacky
1245198090Srdivacky    // Get or construct the predicate method name.
1246198090Srdivacky    Init *PMName = (*it)->getValueInit("PredicateMethod");
1247245431Sdim    if (StringInit *SI = dyn_cast<StringInit>(PMName)) {
1248198090Srdivacky      CI->PredicateMethod = SI->getValue();
1249198090Srdivacky    } else {
1250245431Sdim      assert(isa<UnsetInit>(PMName) && "Unexpected PredicateMethod field!");
1251198090Srdivacky      CI->PredicateMethod = "is" + CI->ClassName;
1252198090Srdivacky    }
1253198090Srdivacky
1254198090Srdivacky    // Get or construct the render method name.
1255198090Srdivacky    Init *RMName = (*it)->getValueInit("RenderMethod");
1256245431Sdim    if (StringInit *SI = dyn_cast<StringInit>(RMName)) {
1257198090Srdivacky      CI->RenderMethod = SI->getValue();
1258198090Srdivacky    } else {
1259245431Sdim      assert(isa<UnsetInit>(RMName) && "Unexpected RenderMethod field!");
1260198090Srdivacky      CI->RenderMethod = "add" + CI->ClassName + "Operands";
1261198090Srdivacky    }
1262198090Srdivacky
1263218893Sdim    // Get the parse method name or leave it as empty.
1264218893Sdim    Init *PRMName = (*it)->getValueInit("ParserMethod");
1265245431Sdim    if (StringInit *SI = dyn_cast<StringInit>(PRMName))
1266218893Sdim      CI->ParserMethod = SI->getValue();
1267218893Sdim
1268245431Sdim    // Get the diagnostic type or leave it as empty.
1269245431Sdim    // Get the parse method name or leave it as empty.
1270245431Sdim    Init *DiagnosticType = (*it)->getValueInit("DiagnosticType");
1271245431Sdim    if (StringInit *SI = dyn_cast<StringInit>(DiagnosticType))
1272245431Sdim      CI->DiagnosticType = SI->getValue();
1273245431Sdim
1274198090Srdivacky    AsmOperandClasses[*it] = CI;
1275198090Srdivacky    Classes.push_back(CI);
1276198090Srdivacky  }
1277198090Srdivacky}
1278198090Srdivacky
1279218893SdimAsmMatcherInfo::AsmMatcherInfo(Record *asmParser,
1280218893Sdim                               CodeGenTarget &target,
1281218893Sdim                               RecordKeeper &records)
1282235633Sdim  : Records(records), AsmParser(asmParser), Target(target) {
1283198090Srdivacky}
1284198090Srdivacky
1285245431Sdim/// buildOperandMatchInfo - Build the necessary information to handle user
1286218893Sdim/// defined operand parsing methods.
1287245431Sdimvoid AsmMatcherInfo::buildOperandMatchInfo() {
1288218893Sdim
1289245431Sdim  /// Map containing a mask with all operands indices that can be found for
1290218893Sdim  /// that class inside a instruction.
1291245431Sdim  typedef std::map<ClassInfo*, unsigned, LessClassInfoPtr> OpClassMaskTy;
1292245431Sdim  OpClassMaskTy OpClassMask;
1293218893Sdim
1294218893Sdim  for (std::vector<MatchableInfo*>::const_iterator it =
1295218893Sdim       Matchables.begin(), ie = Matchables.end();
1296218893Sdim       it != ie; ++it) {
1297218893Sdim    MatchableInfo &II = **it;
1298218893Sdim    OpClassMask.clear();
1299218893Sdim
1300218893Sdim    // Keep track of all operands of this instructions which belong to the
1301218893Sdim    // same class.
1302218893Sdim    for (unsigned i = 0, e = II.AsmOperands.size(); i != e; ++i) {
1303218893Sdim      MatchableInfo::AsmOperand &Op = II.AsmOperands[i];
1304218893Sdim      if (Op.Class->ParserMethod.empty())
1305218893Sdim        continue;
1306218893Sdim      unsigned &OperandMask = OpClassMask[Op.Class];
1307218893Sdim      OperandMask |= (1 << i);
1308218893Sdim    }
1309218893Sdim
1310218893Sdim    // Generate operand match info for each mnemonic/operand class pair.
1311245431Sdim    for (OpClassMaskTy::iterator iit = OpClassMask.begin(),
1312218893Sdim         iie = OpClassMask.end(); iit != iie; ++iit) {
1313218893Sdim      unsigned OpMask = iit->second;
1314218893Sdim      ClassInfo *CI = iit->first;
1315245431Sdim      OperandMatchInfo.push_back(OperandMatchEntry::create(&II, CI, OpMask));
1316218893Sdim    }
1317218893Sdim  }
1318218893Sdim}
1319218893Sdim
1320245431Sdimvoid AsmMatcherInfo::buildInfo() {
1321218893Sdim  // Build information about all of the AssemblerPredicates.
1322218893Sdim  std::vector<Record*> AllPredicates =
1323218893Sdim    Records.getAllDerivedDefinitions("Predicate");
1324218893Sdim  for (unsigned i = 0, e = AllPredicates.size(); i != e; ++i) {
1325218893Sdim    Record *Pred = AllPredicates[i];
1326218893Sdim    // Ignore predicates that are not intended for the assembler.
1327218893Sdim    if (!Pred->getValueAsBit("AssemblerMatcherPredicate"))
1328218893Sdim      continue;
1329218893Sdim
1330218893Sdim    if (Pred->getName().empty())
1331245431Sdim      PrintFatalError(Pred->getLoc(), "Predicate has no name!");
1332218893Sdim
1333218893Sdim    unsigned FeatureNo = SubtargetFeatures.size();
1334218893Sdim    SubtargetFeatures[Pred] = new SubtargetFeatureInfo(Pred, FeatureNo);
1335218893Sdim    assert(FeatureNo < 32 && "Too many subtarget features!");
1336218893Sdim  }
1337218893Sdim
1338198090Srdivacky  // Parse the instructions; we need to do this first so that we can gather the
1339198090Srdivacky  // singleton register classes.
1340218893Sdim  SmallPtrSet<Record*, 16> SingletonRegisters;
1341235633Sdim  unsigned VariantCount = Target.getAsmParserVariantCount();
1342235633Sdim  for (unsigned VC = 0; VC != VariantCount; ++VC) {
1343235633Sdim    Record *AsmVariant = Target.getAsmParserVariant(VC);
1344235633Sdim    std::string CommentDelimiter =
1345235633Sdim      AsmVariant->getValueAsString("CommentDelimiter");
1346235633Sdim    std::string RegisterPrefix = AsmVariant->getValueAsString("RegisterPrefix");
1347235633Sdim    int AsmVariantNo = AsmVariant->getValueAsInt("Variant");
1348198090Srdivacky
1349235633Sdim    for (CodeGenTarget::inst_iterator I = Target.inst_begin(),
1350235633Sdim           E = Target.inst_end(); I != E; ++I) {
1351235633Sdim      const CodeGenInstruction &CGI = **I;
1352198090Srdivacky
1353235633Sdim      // If the tblgen -match-prefix option is specified (for tblgen hackers),
1354235633Sdim      // filter the set of instructions we consider.
1355235633Sdim      if (!StringRef(CGI.TheDef->getName()).startswith(MatchPrefix))
1356235633Sdim        continue;
1357198090Srdivacky
1358235633Sdim      // Ignore "codegen only" instructions.
1359235633Sdim      if (CGI.TheDef->getValueAsBit("isCodeGenOnly"))
1360235633Sdim        continue;
1361218893Sdim
1362235633Sdim      OwningPtr<MatchableInfo> II(new MatchableInfo(CGI));
1363198090Srdivacky
1364245431Sdim      II->initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix);
1365218893Sdim
1366235633Sdim      // Ignore instructions which shouldn't be matched and diagnose invalid
1367235633Sdim      // instruction definitions with an error.
1368245431Sdim      if (!II->validate(CommentDelimiter, true))
1369235633Sdim        continue;
1370198090Srdivacky
1371235633Sdim      // Ignore "Int_*" and "*_Int" instructions, which are internal aliases.
1372235633Sdim      //
1373235633Sdim      // FIXME: This is a total hack.
1374235633Sdim      if (StringRef(II->TheDef->getName()).startswith("Int_") ||
1375235633Sdim          StringRef(II->TheDef->getName()).endswith("_Int"))
1376235633Sdim        continue;
1377198090Srdivacky
1378235633Sdim      Matchables.push_back(II.take());
1379235633Sdim    }
1380212904Sdim
1381235633Sdim    // Parse all of the InstAlias definitions and stick them in the list of
1382235633Sdim    // matchables.
1383235633Sdim    std::vector<Record*> AllInstAliases =
1384235633Sdim      Records.getAllDerivedDefinitions("InstAlias");
1385235633Sdim    for (unsigned i = 0, e = AllInstAliases.size(); i != e; ++i) {
1386235633Sdim      CodeGenInstAlias *Alias = new CodeGenInstAlias(AllInstAliases[i], Target);
1387212904Sdim
1388235633Sdim      // If the tblgen -match-prefix option is specified (for tblgen hackers),
1389235633Sdim      // filter the set of instruction aliases we consider, based on the target
1390235633Sdim      // instruction.
1391235633Sdim      if (!StringRef(Alias->ResultInst->TheDef->getName())
1392235633Sdim            .startswith( MatchPrefix))
1393235633Sdim        continue;
1394212904Sdim
1395235633Sdim      OwningPtr<MatchableInfo> II(new MatchableInfo(Alias));
1396212904Sdim
1397245431Sdim      II->initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix);
1398218893Sdim
1399235633Sdim      // Validate the alias definitions.
1400245431Sdim      II->validate(CommentDelimiter, false);
1401218893Sdim
1402235633Sdim      Matchables.push_back(II.take());
1403235633Sdim    }
1404198090Srdivacky  }
1405198090Srdivacky
1406198090Srdivacky  // Build info for the register classes.
1407245431Sdim  buildRegisterClasses(SingletonRegisters);
1408198090Srdivacky
1409198090Srdivacky  // Build info for the user defined assembly operand classes.
1410245431Sdim  buildOperandClasses();
1411198090Srdivacky
1412218893Sdim  // Build the information about matchables, now that we have fully formed
1413218893Sdim  // classes.
1414245431Sdim  std::vector<MatchableInfo*> NewMatchables;
1415218893Sdim  for (std::vector<MatchableInfo*>::iterator it = Matchables.begin(),
1416218893Sdim         ie = Matchables.end(); it != ie; ++it) {
1417218893Sdim    MatchableInfo *II = *it;
1418198090Srdivacky
1419218893Sdim    // Parse the tokens after the mnemonic.
1420245431Sdim    // Note: buildInstructionOperandReference may insert new AsmOperands, so
1421218893Sdim    // don't precompute the loop bound.
1422218893Sdim    for (unsigned i = 0; i != II->AsmOperands.size(); ++i) {
1423218893Sdim      MatchableInfo::AsmOperand &Op = II->AsmOperands[i];
1424218893Sdim      StringRef Token = Op.Token;
1425198090Srdivacky
1426198090Srdivacky      // Check for singleton registers.
1427235633Sdim      if (Record *RegRecord = II->AsmOperands[i].SingletonReg) {
1428218893Sdim        Op.Class = RegisterClasses[RegRecord];
1429198090Srdivacky        assert(Op.Class && Op.Class->Registers.size() == 1 &&
1430198090Srdivacky               "Unexpected class for singleton register");
1431198090Srdivacky        continue;
1432198090Srdivacky      }
1433198090Srdivacky
1434198090Srdivacky      // Check for simple tokens.
1435198090Srdivacky      if (Token[0] != '$') {
1436198090Srdivacky        Op.Class = getTokenClass(Token);
1437198090Srdivacky        continue;
1438198090Srdivacky      }
1439198090Srdivacky
1440218893Sdim      if (Token.size() > 1 && isdigit(Token[1])) {
1441218893Sdim        Op.Class = getTokenClass(Token);
1442218893Sdim        continue;
1443218893Sdim      }
1444218893Sdim
1445198090Srdivacky      // Otherwise this is an operand reference.
1446198090Srdivacky      StringRef OperandName;
1447198090Srdivacky      if (Token[1] == '{')
1448198090Srdivacky        OperandName = Token.substr(2, Token.size() - 3);
1449198090Srdivacky      else
1450198090Srdivacky        OperandName = Token.substr(1);
1451198090Srdivacky
1452218893Sdim      if (II->DefRec.is<const CodeGenInstruction*>())
1453245431Sdim        buildInstructionOperandReference(II, OperandName, i);
1454218893Sdim      else
1455245431Sdim        buildAliasOperandReference(II, OperandName, Op);
1456218893Sdim    }
1457198090Srdivacky
1458245431Sdim    if (II->DefRec.is<const CodeGenInstruction*>()) {
1459245431Sdim      II->buildInstructionResultOperands();
1460245431Sdim      // If the instruction has a two-operand alias, build up the
1461245431Sdim      // matchable here. We'll add them in bulk at the end to avoid
1462245431Sdim      // confusing this loop.
1463245431Sdim      std::string Constraint =
1464245431Sdim        II->TheDef->getValueAsString("TwoOperandAliasConstraint");
1465245431Sdim      if (Constraint != "") {
1466245431Sdim        // Start by making a copy of the original matchable.
1467245431Sdim        OwningPtr<MatchableInfo> AliasII(new MatchableInfo(*II));
1468245431Sdim
1469245431Sdim        // Adjust it to be a two-operand alias.
1470245431Sdim        AliasII->formTwoOperandAlias(Constraint);
1471245431Sdim
1472245431Sdim        // Add the alias to the matchables list.
1473245431Sdim        NewMatchables.push_back(AliasII.take());
1474245431Sdim      }
1475245431Sdim    } else
1476245431Sdim      II->buildAliasResultOperands();
1477218893Sdim  }
1478245431Sdim  if (!NewMatchables.empty())
1479245431Sdim    Matchables.insert(Matchables.end(), NewMatchables.begin(),
1480245431Sdim                      NewMatchables.end());
1481203954Srdivacky
1482235633Sdim  // Process token alias definitions and set up the associated superclass
1483235633Sdim  // information.
1484235633Sdim  std::vector<Record*> AllTokenAliases =
1485235633Sdim    Records.getAllDerivedDefinitions("TokenAlias");
1486235633Sdim  for (unsigned i = 0, e = AllTokenAliases.size(); i != e; ++i) {
1487235633Sdim    Record *Rec = AllTokenAliases[i];
1488235633Sdim    ClassInfo *FromClass = getTokenClass(Rec->getValueAsString("FromToken"));
1489235633Sdim    ClassInfo *ToClass = getTokenClass(Rec->getValueAsString("ToToken"));
1490235633Sdim    if (FromClass == ToClass)
1491245431Sdim      PrintFatalError(Rec->getLoc(),
1492235633Sdim                    "error: Destination value identical to source value.");
1493235633Sdim    FromClass->SuperClasses.push_back(ToClass);
1494235633Sdim  }
1495235633Sdim
1496221345Sdim  // Reorder classes so that classes precede super classes.
1497218893Sdim  std::sort(Classes.begin(), Classes.end(), less_ptr<ClassInfo>());
1498218893Sdim}
1499203954Srdivacky
1500245431Sdim/// buildInstructionOperandReference - The specified operand is a reference to a
1501218893Sdim/// named operand such as $src.  Resolve the Class and OperandInfo pointers.
1502218893Sdimvoid AsmMatcherInfo::
1503245431SdimbuildInstructionOperandReference(MatchableInfo *II,
1504218893Sdim                                 StringRef OperandName,
1505218893Sdim                                 unsigned AsmOpIdx) {
1506218893Sdim  const CodeGenInstruction &CGI = *II->DefRec.get<const CodeGenInstruction*>();
1507218893Sdim  const CGIOperandList &Operands = CGI.Operands;
1508218893Sdim  MatchableInfo::AsmOperand *Op = &II->AsmOperands[AsmOpIdx];
1509218893Sdim
1510218893Sdim  // Map this token to an operand.
1511218893Sdim  unsigned Idx;
1512218893Sdim  if (!Operands.hasOperandNamed(OperandName, Idx))
1513245431Sdim    PrintFatalError(II->TheDef->getLoc(), "error: unable to find operand: '" +
1514218893Sdim                  OperandName.str() + "'");
1515218893Sdim
1516218893Sdim  // If the instruction operand has multiple suboperands, but the parser
1517218893Sdim  // match class for the asm operand is still the default "ImmAsmOperand",
1518218893Sdim  // then handle each suboperand separately.
1519218893Sdim  if (Op->SubOpIdx == -1 && Operands[Idx].MINumOperands > 1) {
1520218893Sdim    Record *Rec = Operands[Idx].Rec;
1521218893Sdim    assert(Rec->isSubClassOf("Operand") && "Unexpected operand!");
1522218893Sdim    Record *MatchClass = Rec->getValueAsDef("ParserMatchClass");
1523218893Sdim    if (MatchClass && MatchClass->getValueAsString("Name") == "Imm") {
1524218893Sdim      // Insert remaining suboperands after AsmOpIdx in II->AsmOperands.
1525218893Sdim      StringRef Token = Op->Token; // save this in case Op gets moved
1526218893Sdim      for (unsigned SI = 1, SE = Operands[Idx].MINumOperands; SI != SE; ++SI) {
1527218893Sdim        MatchableInfo::AsmOperand NewAsmOp(Token);
1528218893Sdim        NewAsmOp.SubOpIdx = SI;
1529218893Sdim        II->AsmOperands.insert(II->AsmOperands.begin()+AsmOpIdx+SI, NewAsmOp);
1530203954Srdivacky      }
1531218893Sdim      // Replace Op with first suboperand.
1532218893Sdim      Op = &II->AsmOperands[AsmOpIdx]; // update the pointer in case it moved
1533218893Sdim      Op->SubOpIdx = 0;
1534198090Srdivacky    }
1535198090Srdivacky  }
1536198090Srdivacky
1537218893Sdim  // Set up the operand class.
1538218893Sdim  Op->Class = getOperandClass(Operands[Idx], Op->SubOpIdx);
1539218893Sdim
1540218893Sdim  // If the named operand is tied, canonicalize it to the untied operand.
1541218893Sdim  // For example, something like:
1542218893Sdim  //   (outs GPR:$dst), (ins GPR:$src)
1543218893Sdim  // with an asmstring of
1544218893Sdim  //   "inc $src"
1545218893Sdim  // we want to canonicalize to:
1546218893Sdim  //   "inc $dst"
1547218893Sdim  // so that we know how to provide the $dst operand when filling in the result.
1548252723Sdim  int OITied = -1;
1549252723Sdim  if (Operands[Idx].MINumOperands == 1)
1550252723Sdim    OITied = Operands[Idx].getTiedRegister();
1551218893Sdim  if (OITied != -1) {
1552218893Sdim    // The tied operand index is an MIOperand index, find the operand that
1553218893Sdim    // contains it.
1554218893Sdim    std::pair<unsigned, unsigned> Idx = Operands.getSubOperandNumber(OITied);
1555218893Sdim    OperandName = Operands[Idx.first].Name;
1556218893Sdim    Op->SubOpIdx = Idx.second;
1557218893Sdim  }
1558218893Sdim
1559218893Sdim  Op->SrcOpName = OperandName;
1560198090Srdivacky}
1561198090Srdivacky
1562245431Sdim/// buildAliasOperandReference - When parsing an operand reference out of the
1563218893Sdim/// matching string (e.g. "movsx $src, $dst"), determine what the class of the
1564218893Sdim/// operand reference is by looking it up in the result pattern definition.
1565245431Sdimvoid AsmMatcherInfo::buildAliasOperandReference(MatchableInfo *II,
1566218893Sdim                                                StringRef OperandName,
1567218893Sdim                                                MatchableInfo::AsmOperand &Op) {
1568218893Sdim  const CodeGenInstAlias &CGA = *II->DefRec.get<const CodeGenInstAlias*>();
1569203954Srdivacky
1570218893Sdim  // Set up the operand class.
1571218893Sdim  for (unsigned i = 0, e = CGA.ResultOperands.size(); i != e; ++i)
1572218893Sdim    if (CGA.ResultOperands[i].isRecord() &&
1573218893Sdim        CGA.ResultOperands[i].getName() == OperandName) {
1574218893Sdim      // It's safe to go with the first one we find, because CodeGenInstAlias
1575218893Sdim      // validates that all operands with the same name have the same record.
1576218893Sdim      Op.SubOpIdx = CGA.ResultInstOperandIndex[i].second;
1577235633Sdim      // Use the match class from the Alias definition, not the
1578235633Sdim      // destination instruction, as we may have an immediate that's
1579235633Sdim      // being munged by the match class.
1580235633Sdim      Op.Class = getOperandClass(CGA.ResultOperands[i].getRecord(),
1581218893Sdim                                 Op.SubOpIdx);
1582218893Sdim      Op.SrcOpName = OperandName;
1583218893Sdim      return;
1584218893Sdim    }
1585218893Sdim
1586245431Sdim  PrintFatalError(II->TheDef->getLoc(), "error: unable to find operand: '" +
1587218893Sdim                OperandName.str() + "'");
1588203954Srdivacky}
1589203954Srdivacky
1590245431Sdimvoid MatchableInfo::buildInstructionResultOperands() {
1591218893Sdim  const CodeGenInstruction *ResultInst = getResultInst();
1592218893Sdim
1593218893Sdim  // Loop over all operands of the result instruction, determining how to
1594218893Sdim  // populate them.
1595218893Sdim  for (unsigned i = 0, e = ResultInst->Operands.size(); i != e; ++i) {
1596218893Sdim    const CGIOperandList::OperandInfo &OpInfo = ResultInst->Operands[i];
1597218893Sdim
1598218893Sdim    // If this is a tied operand, just copy from the previously handled operand.
1599252723Sdim    int TiedOp = -1;
1600252723Sdim    if (OpInfo.MINumOperands == 1)
1601252723Sdim      TiedOp = OpInfo.getTiedRegister();
1602218893Sdim    if (TiedOp != -1) {
1603218893Sdim      ResOperands.push_back(ResOperand::getTiedOp(TiedOp));
1604218893Sdim      continue;
1605218893Sdim    }
1606218893Sdim
1607218893Sdim    // Find out what operand from the asmparser this MCInst operand comes from.
1608245431Sdim    int SrcOperand = findAsmOperandNamed(OpInfo.Name);
1609252723Sdim    if (OpInfo.Name.empty() || SrcOperand == -1) {
1610252723Sdim      // This may happen for operands that are tied to a suboperand of a
1611252723Sdim      // complex operand.  Simply use a dummy value here; nobody should
1612252723Sdim      // use this operand slot.
1613252723Sdim      // FIXME: The long term goal is for the MCOperand list to not contain
1614252723Sdim      // tied operands at all.
1615252723Sdim      ResOperands.push_back(ResOperand::getImmOp(0));
1616252723Sdim      continue;
1617252723Sdim    }
1618218893Sdim
1619218893Sdim    // Check if the one AsmOperand populates the entire operand.
1620218893Sdim    unsigned NumOperands = OpInfo.MINumOperands;
1621218893Sdim    if (AsmOperands[SrcOperand].SubOpIdx == -1) {
1622218893Sdim      ResOperands.push_back(ResOperand::getRenderedOp(SrcOperand, NumOperands));
1623218893Sdim      continue;
1624218893Sdim    }
1625218893Sdim
1626218893Sdim    // Add a separate ResOperand for each suboperand.
1627218893Sdim    for (unsigned AI = 0; AI < NumOperands; ++AI) {
1628218893Sdim      assert(AsmOperands[SrcOperand+AI].SubOpIdx == (int)AI &&
1629218893Sdim             AsmOperands[SrcOperand+AI].SrcOpName == OpInfo.Name &&
1630218893Sdim             "unexpected AsmOperands for suboperands");
1631218893Sdim      ResOperands.push_back(ResOperand::getRenderedOp(SrcOperand + AI, 1));
1632218893Sdim    }
1633218893Sdim  }
1634218893Sdim}
1635218893Sdim
1636245431Sdimvoid MatchableInfo::buildAliasResultOperands() {
1637218893Sdim  const CodeGenInstAlias &CGA = *DefRec.get<const CodeGenInstAlias*>();
1638218893Sdim  const CodeGenInstruction *ResultInst = getResultInst();
1639218893Sdim
1640218893Sdim  // Loop over all operands of the result instruction, determining how to
1641218893Sdim  // populate them.
1642218893Sdim  unsigned AliasOpNo = 0;
1643218893Sdim  unsigned LastOpNo = CGA.ResultInstOperandIndex.size();
1644218893Sdim  for (unsigned i = 0, e = ResultInst->Operands.size(); i != e; ++i) {
1645218893Sdim    const CGIOperandList::OperandInfo *OpInfo = &ResultInst->Operands[i];
1646218893Sdim
1647218893Sdim    // If this is a tied operand, just copy from the previously handled operand.
1648252723Sdim    int TiedOp = -1;
1649252723Sdim    if (OpInfo->MINumOperands == 1)
1650252723Sdim      TiedOp = OpInfo->getTiedRegister();
1651218893Sdim    if (TiedOp != -1) {
1652218893Sdim      ResOperands.push_back(ResOperand::getTiedOp(TiedOp));
1653218893Sdim      continue;
1654218893Sdim    }
1655218893Sdim
1656218893Sdim    // Handle all the suboperands for this operand.
1657218893Sdim    const std::string &OpName = OpInfo->Name;
1658218893Sdim    for ( ; AliasOpNo <  LastOpNo &&
1659218893Sdim            CGA.ResultInstOperandIndex[AliasOpNo].first == i; ++AliasOpNo) {
1660218893Sdim      int SubIdx = CGA.ResultInstOperandIndex[AliasOpNo].second;
1661218893Sdim
1662218893Sdim      // Find out what operand from the asmparser that this MCInst operand
1663218893Sdim      // comes from.
1664218893Sdim      switch (CGA.ResultOperands[AliasOpNo].Kind) {
1665218893Sdim      case CodeGenInstAlias::ResultOperand::K_Record: {
1666218893Sdim        StringRef Name = CGA.ResultOperands[AliasOpNo].getName();
1667245431Sdim        int SrcOperand = findAsmOperand(Name, SubIdx);
1668218893Sdim        if (SrcOperand == -1)
1669245431Sdim          PrintFatalError(TheDef->getLoc(), "Instruction '" +
1670218893Sdim                        TheDef->getName() + "' has operand '" + OpName +
1671218893Sdim                        "' that doesn't appear in asm string!");
1672218893Sdim        unsigned NumOperands = (SubIdx == -1 ? OpInfo->MINumOperands : 1);
1673218893Sdim        ResOperands.push_back(ResOperand::getRenderedOp(SrcOperand,
1674218893Sdim                                                        NumOperands));
1675218893Sdim        break;
1676218893Sdim      }
1677218893Sdim      case CodeGenInstAlias::ResultOperand::K_Imm: {
1678218893Sdim        int64_t ImmVal = CGA.ResultOperands[AliasOpNo].getImm();
1679218893Sdim        ResOperands.push_back(ResOperand::getImmOp(ImmVal));
1680218893Sdim        break;
1681218893Sdim      }
1682218893Sdim      case CodeGenInstAlias::ResultOperand::K_Reg: {
1683218893Sdim        Record *Reg = CGA.ResultOperands[AliasOpNo].getRegister();
1684218893Sdim        ResOperands.push_back(ResOperand::getRegOp(Reg));
1685218893Sdim        break;
1686218893Sdim      }
1687218893Sdim      }
1688218893Sdim    }
1689218893Sdim  }
1690218893Sdim}
1691218893Sdim
1692245431Sdimstatic unsigned getConverterOperandID(const std::string &Name,
1693245431Sdim                                      SetVector<std::string> &Table,
1694245431Sdim                                      bool &IsNew) {
1695245431Sdim  IsNew = Table.insert(Name);
1696245431Sdim
1697245431Sdim  unsigned ID = IsNew ? Table.size() - 1 :
1698245431Sdim    std::find(Table.begin(), Table.end(), Name) - Table.begin();
1699245431Sdim
1700245431Sdim  assert(ID < Table.size());
1701245431Sdim
1702245431Sdim  return ID;
1703245431Sdim}
1704245431Sdim
1705245431Sdim
1706245431Sdimstatic void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
1707245431Sdim                             std::vector<MatchableInfo*> &Infos,
1708245431Sdim                             raw_ostream &OS) {
1709245431Sdim  SetVector<std::string> OperandConversionKinds;
1710245431Sdim  SetVector<std::string> InstructionConversionKinds;
1711245431Sdim  std::vector<std::vector<uint8_t> > ConversionTable;
1712245431Sdim  size_t MaxRowLength = 2; // minimum is custom converter plus terminator.
1713245431Sdim
1714245431Sdim  // TargetOperandClass - This is the target's operand class, like X86Operand.
1715245431Sdim  std::string TargetOperandClass = Target.getName() + "Operand";
1716245431Sdim
1717198090Srdivacky  // Write the convert function to a separate stream, so we can drop it after
1718245431Sdim  // the enum. We'll build up the conversion handlers for the individual
1719245431Sdim  // operand types opportunistically as we encounter them.
1720198090Srdivacky  std::string ConvertFnBody;
1721198090Srdivacky  raw_string_ostream CvtOS(ConvertFnBody);
1722198090Srdivacky  // Start the unified conversion function.
1723245431Sdim  CvtOS << "void " << Target.getName() << ClassName << "::\n"
1724245431Sdim        << "convertToMCInst(unsigned Kind, MCInst &Inst, "
1725198090Srdivacky        << "unsigned Opcode,\n"
1726245431Sdim        << "                const SmallVectorImpl<MCParsedAsmOperand*"
1727245431Sdim        << "> &Operands) {\n"
1728245431Sdim        << "  assert(Kind < CVT_NUM_SIGNATURES && \"Invalid signature!\");\n"
1729245431Sdim        << "  const uint8_t *Converter = ConversionTable[Kind];\n"
1730245431Sdim        << "  Inst.setOpcode(Opcode);\n"
1731245431Sdim        << "  for (const uint8_t *p = Converter; *p; p+= 2) {\n"
1732245431Sdim        << "    switch (*p) {\n"
1733245431Sdim        << "    default: llvm_unreachable(\"invalid conversion entry!\");\n"
1734245431Sdim        << "    case CVT_Reg:\n"
1735245431Sdim        << "      static_cast<" << TargetOperandClass
1736245431Sdim        << "*>(Operands[*(p + 1)])->addRegOperands(Inst, 1);\n"
1737245431Sdim        << "      break;\n"
1738245431Sdim        << "    case CVT_Tied:\n"
1739245431Sdim        << "      Inst.addOperand(Inst.getOperand(*(p + 1)));\n"
1740245431Sdim        << "      break;\n";
1741198090Srdivacky
1742245431Sdim  std::string OperandFnBody;
1743245431Sdim  raw_string_ostream OpOS(OperandFnBody);
1744245431Sdim  // Start the operand number lookup function.
1745245431Sdim  OpOS << "void " << Target.getName() << ClassName << "::\n"
1746245431Sdim       << "convertToMapAndConstraints(unsigned Kind,\n";
1747245431Sdim  OpOS.indent(27);
1748245431Sdim  OpOS << "const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {\n"
1749245431Sdim       << "  assert(Kind < CVT_NUM_SIGNATURES && \"Invalid signature!\");\n"
1750245431Sdim       << "  unsigned NumMCOperands = 0;\n"
1751245431Sdim       << "  const uint8_t *Converter = ConversionTable[Kind];\n"
1752245431Sdim       << "  for (const uint8_t *p = Converter; *p; p+= 2) {\n"
1753245431Sdim       << "    switch (*p) {\n"
1754245431Sdim       << "    default: llvm_unreachable(\"invalid conversion entry!\");\n"
1755245431Sdim       << "    case CVT_Reg:\n"
1756245431Sdim       << "      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);\n"
1757252723Sdim       << "      Operands[*(p + 1)]->setConstraint(\"r\");\n"
1758245431Sdim       << "      ++NumMCOperands;\n"
1759245431Sdim       << "      break;\n"
1760245431Sdim       << "    case CVT_Tied:\n"
1761245431Sdim       << "      ++NumMCOperands;\n"
1762245431Sdim       << "      break;\n";
1763198090Srdivacky
1764245431Sdim  // Pre-populate the operand conversion kinds with the standard always
1765245431Sdim  // available entries.
1766245431Sdim  OperandConversionKinds.insert("CVT_Done");
1767245431Sdim  OperandConversionKinds.insert("CVT_Reg");
1768245431Sdim  OperandConversionKinds.insert("CVT_Tied");
1769245431Sdim  enum { CVT_Done, CVT_Reg, CVT_Tied };
1770218893Sdim
1771218893Sdim  for (std::vector<MatchableInfo*>::const_iterator it = Infos.begin(),
1772198090Srdivacky         ie = Infos.end(); it != ie; ++it) {
1773218893Sdim    MatchableInfo &II = **it;
1774198090Srdivacky
1775218893Sdim    // Check if we have a custom match function.
1776221345Sdim    std::string AsmMatchConverter =
1777221345Sdim      II.getResultInst()->TheDef->getValueAsString("AsmMatchConverter");
1778218893Sdim    if (!AsmMatchConverter.empty()) {
1779221345Sdim      std::string Signature = "ConvertCustom_" + AsmMatchConverter;
1780218893Sdim      II.ConversionFnKind = Signature;
1781203954Srdivacky
1782218893Sdim      // Check if we have already generated this signature.
1783245431Sdim      if (!InstructionConversionKinds.insert(Signature))
1784218893Sdim        continue;
1785203954Srdivacky
1786245431Sdim      // Remember this converter for the kind enum.
1787245431Sdim      unsigned KindID = OperandConversionKinds.size();
1788252723Sdim      OperandConversionKinds.insert("CVT_" +
1789252723Sdim                                    getEnumNameForToken(AsmMatchConverter));
1790198090Srdivacky
1791245431Sdim      // Add the converter row for this instruction.
1792245431Sdim      ConversionTable.push_back(std::vector<uint8_t>());
1793245431Sdim      ConversionTable.back().push_back(KindID);
1794245431Sdim      ConversionTable.back().push_back(CVT_Done);
1795245431Sdim
1796245431Sdim      // Add the handler to the conversion driver function.
1797252723Sdim      CvtOS << "    case CVT_"
1798252723Sdim            << getEnumNameForToken(AsmMatchConverter) << ":\n"
1799245431Sdim            << "      " << AsmMatchConverter << "(Inst, Operands);\n"
1800245431Sdim            << "      break;\n";
1801245431Sdim
1802245431Sdim      // FIXME: Handle the operand number lookup for custom match functions.
1803218893Sdim      continue;
1804198090Srdivacky    }
1805198090Srdivacky
1806198090Srdivacky    // Build the conversion function signature.
1807198090Srdivacky    std::string Signature = "Convert";
1808198090Srdivacky
1809245431Sdim    std::vector<uint8_t> ConversionRow;
1810245431Sdim
1811218893Sdim    // Compute the convert enum and the case body.
1812245431Sdim    MaxRowLength = std::max(MaxRowLength, II.ResOperands.size()*2 + 1 );
1813245431Sdim
1814218893Sdim    for (unsigned i = 0, e = II.ResOperands.size(); i != e; ++i) {
1815218893Sdim      const MatchableInfo::ResOperand &OpInfo = II.ResOperands[i];
1816203954Srdivacky
1817218893Sdim      // Generate code to populate each result operand.
1818218893Sdim      switch (OpInfo.Kind) {
1819218893Sdim      case MatchableInfo::ResOperand::RenderAsmOperand: {
1820218893Sdim        // This comes from something we parsed.
1821218893Sdim        MatchableInfo::AsmOperand &Op = II.AsmOperands[OpInfo.AsmOperandNum];
1822198090Srdivacky
1823218893Sdim        // Registers are always converted the same, don't duplicate the
1824218893Sdim        // conversion function based on them.
1825218893Sdim        Signature += "__";
1826245431Sdim        std::string Class;
1827245431Sdim        Class = Op.Class->isRegisterClass() ? "Reg" : Op.Class->ClassName;
1828245431Sdim        Signature += Class;
1829218893Sdim        Signature += utostr(OpInfo.MINumOperands);
1830218893Sdim        Signature += "_" + itostr(OpInfo.AsmOperandNum);
1831198090Srdivacky
1832245431Sdim        // Add the conversion kind, if necessary, and get the associated ID
1833245431Sdim        // the index of its entry in the vector).
1834245431Sdim        std::string Name = "CVT_" + (Op.Class->isRegisterClass() ? "Reg" :
1835245431Sdim                                     Op.Class->RenderMethod);
1836252723Sdim        Name = getEnumNameForToken(Name);
1837245431Sdim
1838245431Sdim        bool IsNewConverter = false;
1839245431Sdim        unsigned ID = getConverterOperandID(Name, OperandConversionKinds,
1840245431Sdim                                            IsNewConverter);
1841245431Sdim
1842245431Sdim        // Add the operand entry to the instruction kind conversion row.
1843245431Sdim        ConversionRow.push_back(ID);
1844245431Sdim        ConversionRow.push_back(OpInfo.AsmOperandNum + 1);
1845245431Sdim
1846245431Sdim        if (!IsNewConverter)
1847245431Sdim          break;
1848245431Sdim
1849245431Sdim        // This is a new operand kind. Add a handler for it to the
1850245431Sdim        // converter driver.
1851245431Sdim        CvtOS << "    case " << Name << ":\n"
1852245431Sdim              << "      static_cast<" << TargetOperandClass
1853245431Sdim              << "*>(Operands[*(p + 1)])->"
1854245431Sdim              << Op.Class->RenderMethod << "(Inst, " << OpInfo.MINumOperands
1855245431Sdim              << ");\n"
1856245431Sdim              << "      break;\n";
1857245431Sdim
1858245431Sdim        // Add a handler for the operand number lookup.
1859245431Sdim        OpOS << "    case " << Name << ":\n"
1860252723Sdim             << "      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);\n";
1861252723Sdim
1862252723Sdim        if (Op.Class->isRegisterClass())
1863252723Sdim          OpOS << "      Operands[*(p + 1)]->setConstraint(\"r\");\n";
1864252723Sdim        else
1865252723Sdim          OpOS << "      Operands[*(p + 1)]->setConstraint(\"m\");\n";
1866252723Sdim        OpOS << "      NumMCOperands += " << OpInfo.MINumOperands << ";\n"
1867245431Sdim             << "      break;\n";
1868218893Sdim        break;
1869218893Sdim      }
1870218893Sdim      case MatchableInfo::ResOperand::TiedOperand: {
1871218893Sdim        // If this operand is tied to a previous one, just copy the MCInst
1872218893Sdim        // operand from the earlier one.We can only tie single MCOperand values.
1873252723Sdim        assert(OpInfo.MINumOperands == 1 && "Not a singular MCOperand");
1874218893Sdim        unsigned TiedOp = OpInfo.TiedOperandNum;
1875221345Sdim        assert(i > TiedOp && "Tied operand precedes its target!");
1876218893Sdim        Signature += "__Tie" + utostr(TiedOp);
1877245431Sdim        ConversionRow.push_back(CVT_Tied);
1878245431Sdim        ConversionRow.push_back(TiedOp);
1879218893Sdim        break;
1880218893Sdim      }
1881218893Sdim      case MatchableInfo::ResOperand::ImmOperand: {
1882218893Sdim        int64_t Val = OpInfo.ImmVal;
1883245431Sdim        std::string Ty = "imm_" + itostr(Val);
1884245431Sdim        Signature += "__" + Ty;
1885245431Sdim
1886245431Sdim        std::string Name = "CVT_" + Ty;
1887245431Sdim        bool IsNewConverter = false;
1888245431Sdim        unsigned ID = getConverterOperandID(Name, OperandConversionKinds,
1889245431Sdim                                            IsNewConverter);
1890245431Sdim        // Add the operand entry to the instruction kind conversion row.
1891245431Sdim        ConversionRow.push_back(ID);
1892245431Sdim        ConversionRow.push_back(0);
1893245431Sdim
1894245431Sdim        if (!IsNewConverter)
1895245431Sdim          break;
1896245431Sdim
1897245431Sdim        CvtOS << "    case " << Name << ":\n"
1898245431Sdim              << "      Inst.addOperand(MCOperand::CreateImm(" << Val << "));\n"
1899245431Sdim              << "      break;\n";
1900245431Sdim
1901245431Sdim        OpOS << "    case " << Name << ":\n"
1902245431Sdim             << "      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);\n"
1903245431Sdim             << "      Operands[*(p + 1)]->setConstraint(\"\");\n"
1904245431Sdim             << "      ++NumMCOperands;\n"
1905245431Sdim             << "      break;\n";
1906218893Sdim        break;
1907218893Sdim      }
1908218893Sdim      case MatchableInfo::ResOperand::RegOperand: {
1909245431Sdim        std::string Reg, Name;
1910218893Sdim        if (OpInfo.Register == 0) {
1911245431Sdim          Name = "reg0";
1912245431Sdim          Reg = "0";
1913218893Sdim        } else {
1914245431Sdim          Reg = getQualifiedName(OpInfo.Register);
1915245431Sdim          Name = "reg" + OpInfo.Register->getName();
1916218893Sdim        }
1917245431Sdim        Signature += "__" + Name;
1918245431Sdim        Name = "CVT_" + Name;
1919245431Sdim        bool IsNewConverter = false;
1920245431Sdim        unsigned ID = getConverterOperandID(Name, OperandConversionKinds,
1921245431Sdim                                            IsNewConverter);
1922245431Sdim        // Add the operand entry to the instruction kind conversion row.
1923245431Sdim        ConversionRow.push_back(ID);
1924245431Sdim        ConversionRow.push_back(0);
1925245431Sdim
1926245431Sdim        if (!IsNewConverter)
1927245431Sdim          break;
1928245431Sdim        CvtOS << "    case " << Name << ":\n"
1929245431Sdim              << "      Inst.addOperand(MCOperand::CreateReg(" << Reg << "));\n"
1930245431Sdim              << "      break;\n";
1931245431Sdim
1932245431Sdim        OpOS << "    case " << Name << ":\n"
1933245431Sdim             << "      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);\n"
1934245431Sdim             << "      Operands[*(p + 1)]->setConstraint(\"m\");\n"
1935245431Sdim             << "      ++NumMCOperands;\n"
1936245431Sdim             << "      break;\n";
1937218893Sdim      }
1938218893Sdim      }
1939203954Srdivacky    }
1940198090Srdivacky
1941245431Sdim    // If there were no operands, add to the signature to that effect
1942245431Sdim    if (Signature == "Convert")
1943245431Sdim      Signature += "_NoOperands";
1944245431Sdim
1945198090Srdivacky    II.ConversionFnKind = Signature;
1946198090Srdivacky
1947245431Sdim    // Save the signature. If we already have it, don't add a new row
1948245431Sdim    // to the table.
1949245431Sdim    if (!InstructionConversionKinds.insert(Signature))
1950198090Srdivacky      continue;
1951198090Srdivacky
1952245431Sdim    // Add the row to the table.
1953245431Sdim    ConversionTable.push_back(ConversionRow);
1954198090Srdivacky  }
1955198090Srdivacky
1956245431Sdim  // Finish up the converter driver function.
1957245431Sdim  CvtOS << "    }\n  }\n}\n\n";
1958198090Srdivacky
1959245431Sdim  // Finish up the operand number lookup function.
1960245431Sdim  OpOS << "    }\n  }\n}\n\n";
1961198090Srdivacky
1962245431Sdim  OS << "namespace {\n";
1963198090Srdivacky
1964245431Sdim  // Output the operand conversion kind enum.
1965245431Sdim  OS << "enum OperatorConversionKind {\n";
1966245431Sdim  for (unsigned i = 0, e = OperandConversionKinds.size(); i != e; ++i)
1967245431Sdim    OS << "  " << OperandConversionKinds[i] << ",\n";
1968245431Sdim  OS << "  CVT_NUM_CONVERTERS\n";
1969198090Srdivacky  OS << "};\n\n";
1970218893Sdim
1971245431Sdim  // Output the instruction conversion kind enum.
1972245431Sdim  OS << "enum InstructionConversionKind {\n";
1973245431Sdim  for (SetVector<std::string>::const_iterator
1974245431Sdim         i = InstructionConversionKinds.begin(),
1975245431Sdim         e = InstructionConversionKinds.end(); i != e; ++i)
1976245431Sdim    OS << "  " << *i << ",\n";
1977245431Sdim  OS << "  CVT_NUM_SIGNATURES\n";
1978245431Sdim  OS << "};\n\n";
1979245431Sdim
1980245431Sdim
1981245431Sdim  OS << "} // end anonymous namespace\n\n";
1982245431Sdim
1983245431Sdim  // Output the conversion table.
1984245431Sdim  OS << "static const uint8_t ConversionTable[CVT_NUM_SIGNATURES]["
1985245431Sdim     << MaxRowLength << "] = {\n";
1986245431Sdim
1987245431Sdim  for (unsigned Row = 0, ERow = ConversionTable.size(); Row != ERow; ++Row) {
1988245431Sdim    assert(ConversionTable[Row].size() % 2 == 0 && "bad conversion row!");
1989245431Sdim    OS << "  // " << InstructionConversionKinds[Row] << "\n";
1990245431Sdim    OS << "  { ";
1991245431Sdim    for (unsigned i = 0, e = ConversionTable[Row].size(); i != e; i += 2)
1992245431Sdim      OS << OperandConversionKinds[ConversionTable[Row][i]] << ", "
1993245431Sdim         << (unsigned)(ConversionTable[Row][i + 1]) << ", ";
1994245431Sdim    OS << "CVT_Done },\n";
1995245431Sdim  }
1996245431Sdim
1997245431Sdim  OS << "};\n\n";
1998245431Sdim
1999245431Sdim  // Spit out the conversion driver function.
2000198090Srdivacky  OS << CvtOS.str();
2001245431Sdim
2002245431Sdim  // Spit out the operand number lookup function.
2003245431Sdim  OS << OpOS.str();
2004198090Srdivacky}
2005198090Srdivacky
2006245431Sdim/// emitMatchClassEnumeration - Emit the enumeration for match class kinds.
2007245431Sdimstatic void emitMatchClassEnumeration(CodeGenTarget &Target,
2008198090Srdivacky                                      std::vector<ClassInfo*> &Infos,
2009198090Srdivacky                                      raw_ostream &OS) {
2010198090Srdivacky  OS << "namespace {\n\n";
2011198090Srdivacky
2012198090Srdivacky  OS << "/// MatchClassKind - The kinds of classes which participate in\n"
2013198090Srdivacky     << "/// instruction matching.\n";
2014198090Srdivacky  OS << "enum MatchClassKind {\n";
2015198090Srdivacky  OS << "  InvalidMatchClass = 0,\n";
2016218893Sdim  for (std::vector<ClassInfo*>::iterator it = Infos.begin(),
2017198090Srdivacky         ie = Infos.end(); it != ie; ++it) {
2018198090Srdivacky    ClassInfo &CI = **it;
2019198090Srdivacky    OS << "  " << CI.Name << ", // ";
2020198090Srdivacky    if (CI.Kind == ClassInfo::Token) {
2021198090Srdivacky      OS << "'" << CI.ValueName << "'\n";
2022198090Srdivacky    } else if (CI.isRegisterClass()) {
2023198090Srdivacky      if (!CI.ValueName.empty())
2024198090Srdivacky        OS << "register class '" << CI.ValueName << "'\n";
2025198090Srdivacky      else
2026198090Srdivacky        OS << "derived register class\n";
2027198090Srdivacky    } else {
2028198090Srdivacky      OS << "user defined class '" << CI.ValueName << "'\n";
2029198090Srdivacky    }
2030198090Srdivacky  }
2031198090Srdivacky  OS << "  NumMatchClassKinds\n";
2032198090Srdivacky  OS << "};\n\n";
2033198090Srdivacky
2034198090Srdivacky  OS << "}\n\n";
2035198090Srdivacky}
2036198090Srdivacky
2037245431Sdim/// emitValidateOperandClass - Emit the function to validate an operand class.
2038245431Sdimstatic void emitValidateOperandClass(AsmMatcherInfo &Info,
2039218893Sdim                                     raw_ostream &OS) {
2040245431Sdim  OS << "static unsigned validateOperandClass(MCParsedAsmOperand *GOp, "
2041218893Sdim     << "MatchClassKind Kind) {\n";
2042218893Sdim  OS << "  " << Info.Target.getName() << "Operand &Operand = *("
2043218893Sdim     << Info.Target.getName() << "Operand*)GOp;\n";
2044198090Srdivacky
2045224145Sdim  // The InvalidMatchClass is not to match any operand.
2046224145Sdim  OS << "  if (Kind == InvalidMatchClass)\n";
2047245431Sdim  OS << "    return MCTargetAsmParser::Match_InvalidOperand;\n\n";
2048224145Sdim
2049218893Sdim  // Check for Token operands first.
2050245431Sdim  // FIXME: Use a more specific diagnostic type.
2051198090Srdivacky  OS << "  if (Operand.isToken())\n";
2052245431Sdim  OS << "    return isSubclass(matchTokenString(Operand.getToken()), Kind) ?\n"
2053245431Sdim     << "             MCTargetAsmParser::Match_Success :\n"
2054245431Sdim     << "             MCTargetAsmParser::Match_InvalidOperand;\n\n";
2055198090Srdivacky
2056218893Sdim  // Check the user classes. We don't care what order since we're only
2057218893Sdim  // actually matching against one of them.
2058218893Sdim  for (std::vector<ClassInfo*>::iterator it = Info.Classes.begin(),
2059198090Srdivacky         ie = Info.Classes.end(); it != ie; ++it) {
2060198090Srdivacky    ClassInfo &CI = **it;
2061198090Srdivacky
2062198090Srdivacky    if (!CI.isUserClass())
2063198090Srdivacky      continue;
2064198090Srdivacky
2065218893Sdim    OS << "  // '" << CI.ClassName << "' class\n";
2066245431Sdim    OS << "  if (Kind == " << CI.Name << ") {\n";
2067245431Sdim    OS << "    if (Operand." << CI.PredicateMethod << "())\n";
2068245431Sdim    OS << "      return MCTargetAsmParser::Match_Success;\n";
2069245431Sdim    if (!CI.DiagnosticType.empty())
2070245431Sdim      OS << "    return " << Info.Target.getName() << "AsmParser::Match_"
2071245431Sdim         << CI.DiagnosticType << ";\n";
2072198090Srdivacky    OS << "  }\n\n";
2073198090Srdivacky  }
2074218893Sdim
2075245431Sdim  // Check for register operands, including sub-classes.
2076245431Sdim  OS << "  if (Operand.isReg()) {\n";
2077245431Sdim  OS << "    MatchClassKind OpKind;\n";
2078245431Sdim  OS << "    switch (Operand.getReg()) {\n";
2079245431Sdim  OS << "    default: OpKind = InvalidMatchClass; break;\n";
2080245431Sdim  for (AsmMatcherInfo::RegisterClassesTy::iterator
2081245431Sdim         it = Info.RegisterClasses.begin(), ie = Info.RegisterClasses.end();
2082245431Sdim       it != ie; ++it)
2083245431Sdim    OS << "    case " << Info.Target.getName() << "::"
2084245431Sdim       << it->first->getName() << ": OpKind = " << it->second->Name
2085245431Sdim       << "; break;\n";
2086245431Sdim  OS << "    }\n";
2087245431Sdim  OS << "    return isSubclass(OpKind, Kind) ? "
2088245431Sdim     << "MCTargetAsmParser::Match_Success :\n                             "
2089245431Sdim     << "         MCTargetAsmParser::Match_InvalidOperand;\n  }\n\n";
2090245431Sdim
2091245431Sdim  // Generic fallthrough match failure case for operands that don't have
2092245431Sdim  // specialized diagnostic types.
2093245431Sdim  OS << "  return MCTargetAsmParser::Match_InvalidOperand;\n";
2094198090Srdivacky  OS << "}\n\n";
2095198090Srdivacky}
2096198090Srdivacky
2097245431Sdim/// emitIsSubclass - Emit the subclass predicate function.
2098245431Sdimstatic void emitIsSubclass(CodeGenTarget &Target,
2099198090Srdivacky                           std::vector<ClassInfo*> &Infos,
2100198090Srdivacky                           raw_ostream &OS) {
2101245431Sdim  OS << "/// isSubclass - Compute whether \\p A is a subclass of \\p B.\n";
2102235633Sdim  OS << "static bool isSubclass(MatchClassKind A, MatchClassKind B) {\n";
2103198090Srdivacky  OS << "  if (A == B)\n";
2104198090Srdivacky  OS << "    return true;\n\n";
2105198090Srdivacky
2106263509Sdim  std::string OStr;
2107263509Sdim  raw_string_ostream SS(OStr);
2108263509Sdim  unsigned Count = 0;
2109263509Sdim  SS << "  switch (A) {\n";
2110263509Sdim  SS << "  default:\n";
2111263509Sdim  SS << "    return false;\n";
2112218893Sdim  for (std::vector<ClassInfo*>::iterator it = Infos.begin(),
2113198090Srdivacky         ie = Infos.end(); it != ie; ++it) {
2114198090Srdivacky    ClassInfo &A = **it;
2115198090Srdivacky
2116235633Sdim    std::vector<StringRef> SuperClasses;
2117235633Sdim    for (std::vector<ClassInfo*>::iterator it = Infos.begin(),
2118235633Sdim         ie = Infos.end(); it != ie; ++it) {
2119235633Sdim      ClassInfo &B = **it;
2120198090Srdivacky
2121235633Sdim      if (&A != &B && A.isSubsetOf(B))
2122235633Sdim        SuperClasses.push_back(B.Name);
2123235633Sdim    }
2124198090Srdivacky
2125235633Sdim    if (SuperClasses.empty())
2126235633Sdim      continue;
2127263509Sdim    ++Count;
2128198090Srdivacky
2129263509Sdim    SS << "\n  case " << A.Name << ":\n";
2130198090Srdivacky
2131235633Sdim    if (SuperClasses.size() == 1) {
2132263509Sdim      SS << "    return B == " << SuperClasses.back().str() << ";\n";
2133235633Sdim      continue;
2134235633Sdim    }
2135198090Srdivacky
2136263509Sdim    if (!SuperClasses.empty()) {
2137263509Sdim      SS << "    switch (B) {\n";
2138263509Sdim      SS << "    default: return false;\n";
2139263509Sdim      for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i)
2140263509Sdim        SS << "    case " << SuperClasses[i].str() << ": return true;\n";
2141263509Sdim      SS << "    }\n";
2142263509Sdim    } else {
2143263509Sdim      // No case statement to emit
2144263509Sdim      SS << "    return false;\n";
2145263509Sdim    }
2146198090Srdivacky  }
2147263509Sdim  SS << "  }\n";
2148263509Sdim
2149263509Sdim  // If there were case statements emitted into the string stream, write them
2150263509Sdim  // to the output stream, otherwise write the default.
2151263509Sdim  if (Count)
2152263509Sdim    OS << SS.str();
2153263509Sdim  else
2154263509Sdim    OS << "  return false;\n";
2155263509Sdim
2156198090Srdivacky  OS << "}\n\n";
2157198090Srdivacky}
2158198090Srdivacky
2159245431Sdim/// emitMatchTokenString - Emit the function to match a token string to the
2160198090Srdivacky/// appropriate match class value.
2161245431Sdimstatic void emitMatchTokenString(CodeGenTarget &Target,
2162198090Srdivacky                                 std::vector<ClassInfo*> &Infos,
2163198090Srdivacky                                 raw_ostream &OS) {
2164198090Srdivacky  // Construct the match list.
2165218893Sdim  std::vector<StringMatcher::StringPair> Matches;
2166218893Sdim  for (std::vector<ClassInfo*>::iterator it = Infos.begin(),
2167198090Srdivacky         ie = Infos.end(); it != ie; ++it) {
2168198090Srdivacky    ClassInfo &CI = **it;
2169198090Srdivacky
2170198090Srdivacky    if (CI.Kind == ClassInfo::Token)
2171218893Sdim      Matches.push_back(StringMatcher::StringPair(CI.ValueName,
2172218893Sdim                                                  "return " + CI.Name + ";"));
2173198090Srdivacky  }
2174198090Srdivacky
2175235633Sdim  OS << "static MatchClassKind matchTokenString(StringRef Name) {\n";
2176198090Srdivacky
2177218893Sdim  StringMatcher("Name", Matches, OS).Emit();
2178198090Srdivacky
2179198090Srdivacky  OS << "  return InvalidMatchClass;\n";
2180198090Srdivacky  OS << "}\n\n";
2181198090Srdivacky}
2182198090Srdivacky
2183245431Sdim/// emitMatchRegisterName - Emit the function to match a string to the target
2184198090Srdivacky/// specific register enum.
2185245431Sdimstatic void emitMatchRegisterName(CodeGenTarget &Target, Record *AsmParser,
2186198090Srdivacky                                  raw_ostream &OS) {
2187198090Srdivacky  // Construct the match list.
2188218893Sdim  std::vector<StringMatcher::StringPair> Matches;
2189224145Sdim  const std::vector<CodeGenRegister*> &Regs =
2190224145Sdim    Target.getRegBank().getRegisters();
2191224145Sdim  for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
2192224145Sdim    const CodeGenRegister *Reg = Regs[i];
2193224145Sdim    if (Reg->TheDef->getValueAsString("AsmName").empty())
2194198090Srdivacky      continue;
2195198090Srdivacky
2196218893Sdim    Matches.push_back(StringMatcher::StringPair(
2197224145Sdim                                     Reg->TheDef->getValueAsString("AsmName"),
2198224145Sdim                                     "return " + utostr(Reg->EnumValue) + ";"));
2199198090Srdivacky  }
2200218893Sdim
2201203954Srdivacky  OS << "static unsigned MatchRegisterName(StringRef Name) {\n";
2202198090Srdivacky
2203218893Sdim  StringMatcher("Name", Matches, OS).Emit();
2204218893Sdim
2205198090Srdivacky  OS << "  return 0;\n";
2206198090Srdivacky  OS << "}\n\n";
2207198090Srdivacky}
2208198090Srdivacky
2209245431Sdim/// emitSubtargetFeatureFlagEnumeration - Emit the subtarget feature flag
2210212904Sdim/// definitions.
2211245431Sdimstatic void emitSubtargetFeatureFlagEnumeration(AsmMatcherInfo &Info,
2212212904Sdim                                                raw_ostream &OS) {
2213212904Sdim  OS << "// Flags for subtarget features that participate in "
2214212904Sdim     << "instruction matching.\n";
2215212904Sdim  OS << "enum SubtargetFeatureFlag {\n";
2216263509Sdim  for (std::map<Record*, SubtargetFeatureInfo*, LessRecordByID>::const_iterator
2217212904Sdim         it = Info.SubtargetFeatures.begin(),
2218212904Sdim         ie = Info.SubtargetFeatures.end(); it != ie; ++it) {
2219212904Sdim    SubtargetFeatureInfo &SFI = *it->second;
2220218893Sdim    OS << "  " << SFI.getEnumName() << " = (1 << " << SFI.Index << "),\n";
2221212904Sdim  }
2222212904Sdim  OS << "  Feature_None = 0\n";
2223212904Sdim  OS << "};\n\n";
2224212904Sdim}
2225212904Sdim
2226245431Sdim/// emitOperandDiagnosticTypes - Emit the operand matching diagnostic types.
2227245431Sdimstatic void emitOperandDiagnosticTypes(AsmMatcherInfo &Info, raw_ostream &OS) {
2228245431Sdim  // Get the set of diagnostic types from all of the operand classes.
2229245431Sdim  std::set<StringRef> Types;
2230245431Sdim  for (std::map<Record*, ClassInfo*>::const_iterator
2231245431Sdim       I = Info.AsmOperandClasses.begin(),
2232245431Sdim       E = Info.AsmOperandClasses.end(); I != E; ++I) {
2233245431Sdim    if (!I->second->DiagnosticType.empty())
2234245431Sdim      Types.insert(I->second->DiagnosticType);
2235245431Sdim  }
2236245431Sdim
2237245431Sdim  if (Types.empty()) return;
2238245431Sdim
2239245431Sdim  // Now emit the enum entries.
2240245431Sdim  for (std::set<StringRef>::const_iterator I = Types.begin(), E = Types.end();
2241245431Sdim       I != E; ++I)
2242245431Sdim    OS << "  Match_" << *I << ",\n";
2243245431Sdim  OS << "  END_OPERAND_DIAGNOSTIC_TYPES\n";
2244245431Sdim}
2245245431Sdim
2246245431Sdim/// emitGetSubtargetFeatureName - Emit the helper function to get the
2247245431Sdim/// user-level name for a subtarget feature.
2248245431Sdimstatic void emitGetSubtargetFeatureName(AsmMatcherInfo &Info, raw_ostream &OS) {
2249245431Sdim  OS << "// User-level names for subtarget features that participate in\n"
2250245431Sdim     << "// instruction matching.\n"
2251263509Sdim     << "static const char *getSubtargetFeatureName(unsigned Val) {\n";
2252263509Sdim  if (!Info.SubtargetFeatures.empty()) {
2253263509Sdim    OS << "  switch(Val) {\n";
2254263509Sdim    typedef std::map<Record*, SubtargetFeatureInfo*, LessRecordByID> RecFeatMap;
2255263509Sdim    for (RecFeatMap::const_iterator it = Info.SubtargetFeatures.begin(),
2256263509Sdim             ie = Info.SubtargetFeatures.end(); it != ie; ++it) {
2257263509Sdim      SubtargetFeatureInfo &SFI = *it->second;
2258263509Sdim      // FIXME: Totally just a placeholder name to get the algorithm working.
2259263509Sdim      OS << "  case " << SFI.getEnumName() << ": return \""
2260263509Sdim         << SFI.TheDef->getValueAsString("PredicateName") << "\";\n";
2261263509Sdim    }
2262263509Sdim    OS << "  default: return \"(unknown)\";\n";
2263263509Sdim    OS << "  }\n";
2264263509Sdim  } else {
2265263509Sdim    // Nothing to emit, so skip the switch
2266263509Sdim    OS << "  return \"(unknown)\";\n";
2267245431Sdim  }
2268263509Sdim  OS << "}\n\n";
2269245431Sdim}
2270245431Sdim
2271245431Sdim/// emitComputeAvailableFeatures - Emit the function to compute the list of
2272212904Sdim/// available features given a subtarget.
2273245431Sdimstatic void emitComputeAvailableFeatures(AsmMatcherInfo &Info,
2274212904Sdim                                         raw_ostream &OS) {
2275212904Sdim  std::string ClassName =
2276212904Sdim    Info.AsmParser->getValueAsString("AsmParserClassName");
2277212904Sdim
2278218893Sdim  OS << "unsigned " << Info.Target.getName() << ClassName << "::\n"
2279224145Sdim     << "ComputeAvailableFeatures(uint64_t FB) const {\n";
2280212904Sdim  OS << "  unsigned Features = 0;\n";
2281263509Sdim  for (std::map<Record*, SubtargetFeatureInfo*, LessRecordByID>::const_iterator
2282212904Sdim         it = Info.SubtargetFeatures.begin(),
2283212904Sdim         ie = Info.SubtargetFeatures.end(); it != ie; ++it) {
2284212904Sdim    SubtargetFeatureInfo &SFI = *it->second;
2285224145Sdim
2286224145Sdim    OS << "  if (";
2287235633Sdim    std::string CondStorage =
2288235633Sdim      SFI.TheDef->getValueAsString("AssemblerCondString");
2289224145Sdim    StringRef Conds = CondStorage;
2290224145Sdim    std::pair<StringRef,StringRef> Comma = Conds.split(',');
2291224145Sdim    bool First = true;
2292224145Sdim    do {
2293224145Sdim      if (!First)
2294224145Sdim        OS << " && ";
2295224145Sdim
2296224145Sdim      bool Neg = false;
2297224145Sdim      StringRef Cond = Comma.first;
2298224145Sdim      if (Cond[0] == '!') {
2299224145Sdim        Neg = true;
2300224145Sdim        Cond = Cond.substr(1);
2301224145Sdim      }
2302224145Sdim
2303224145Sdim      OS << "((FB & " << Info.Target.getName() << "::" << Cond << ")";
2304224145Sdim      if (Neg)
2305224145Sdim        OS << " == 0";
2306224145Sdim      else
2307224145Sdim        OS << " != 0";
2308224145Sdim      OS << ")";
2309224145Sdim
2310224145Sdim      if (Comma.second.empty())
2311224145Sdim        break;
2312224145Sdim
2313224145Sdim      First = false;
2314224145Sdim      Comma = Comma.second.split(',');
2315224145Sdim    } while (true);
2316224145Sdim
2317224145Sdim    OS << ")\n";
2318218893Sdim    OS << "    Features |= " << SFI.getEnumName() << ";\n";
2319212904Sdim  }
2320212904Sdim  OS << "  return Features;\n";
2321212904Sdim  OS << "}\n\n";
2322212904Sdim}
2323212904Sdim
2324218893Sdimstatic std::string GetAliasRequiredFeatures(Record *R,
2325218893Sdim                                            const AsmMatcherInfo &Info) {
2326218893Sdim  std::vector<Record*> ReqFeatures = R->getValueAsListOfDefs("Predicates");
2327218893Sdim  std::string Result;
2328218893Sdim  unsigned NumFeatures = 0;
2329218893Sdim  for (unsigned i = 0, e = ReqFeatures.size(); i != e; ++i) {
2330218893Sdim    SubtargetFeatureInfo *F = Info.getSubtargetFeature(ReqFeatures[i]);
2331218893Sdim
2332218893Sdim    if (F == 0)
2333245431Sdim      PrintFatalError(R->getLoc(), "Predicate '" + ReqFeatures[i]->getName() +
2334218893Sdim                    "' is not marked as an AssemblerPredicate!");
2335218893Sdim
2336218893Sdim    if (NumFeatures)
2337218893Sdim      Result += '|';
2338218893Sdim
2339218893Sdim    Result += F->getEnumName();
2340218893Sdim    ++NumFeatures;
2341218893Sdim  }
2342218893Sdim
2343218893Sdim  if (NumFeatures > 1)
2344218893Sdim    Result = '(' + Result + ')';
2345218893Sdim  return Result;
2346218893Sdim}
2347218893Sdim
2348252723Sdimstatic void emitMnemonicAliasVariant(raw_ostream &OS,const AsmMatcherInfo &Info,
2349252723Sdim                                     std::vector<Record*> &Aliases,
2350252723Sdim                                     unsigned Indent = 0,
2351252723Sdim                                  StringRef AsmParserVariantName = StringRef()){
2352218893Sdim  // Keep track of all the aliases from a mnemonic.  Use an std::map so that the
2353218893Sdim  // iteration order of the map is stable.
2354218893Sdim  std::map<std::string, std::vector<Record*> > AliasesFromMnemonic;
2355218893Sdim
2356218893Sdim  for (unsigned i = 0, e = Aliases.size(); i != e; ++i) {
2357218893Sdim    Record *R = Aliases[i];
2358252723Sdim    // FIXME: Allow AssemblerVariantName to be a comma separated list.
2359252723Sdim    std::string AsmVariantName = R->getValueAsString("AsmVariantName");
2360252723Sdim    if (AsmVariantName != AsmParserVariantName)
2361252723Sdim      continue;
2362218893Sdim    AliasesFromMnemonic[R->getValueAsString("FromMnemonic")].push_back(R);
2363218893Sdim  }
2364252723Sdim  if (AliasesFromMnemonic.empty())
2365252723Sdim    return;
2366263509Sdim
2367218893Sdim  // Process each alias a "from" mnemonic at a time, building the code executed
2368218893Sdim  // by the string remapper.
2369218893Sdim  std::vector<StringMatcher::StringPair> Cases;
2370218893Sdim  for (std::map<std::string, std::vector<Record*> >::iterator
2371218893Sdim       I = AliasesFromMnemonic.begin(), E = AliasesFromMnemonic.end();
2372218893Sdim       I != E; ++I) {
2373218893Sdim    const std::vector<Record*> &ToVec = I->second;
2374218893Sdim
2375218893Sdim    // Loop through each alias and emit code that handles each case.  If there
2376218893Sdim    // are two instructions without predicates, emit an error.  If there is one,
2377218893Sdim    // emit it last.
2378218893Sdim    std::string MatchCode;
2379218893Sdim    int AliasWithNoPredicate = -1;
2380218893Sdim
2381218893Sdim    for (unsigned i = 0, e = ToVec.size(); i != e; ++i) {
2382218893Sdim      Record *R = ToVec[i];
2383218893Sdim      std::string FeatureMask = GetAliasRequiredFeatures(R, Info);
2384218893Sdim
2385218893Sdim      // If this unconditionally matches, remember it for later and diagnose
2386218893Sdim      // duplicates.
2387218893Sdim      if (FeatureMask.empty()) {
2388218893Sdim        if (AliasWithNoPredicate != -1) {
2389218893Sdim          // We can't have two aliases from the same mnemonic with no predicate.
2390218893Sdim          PrintError(ToVec[AliasWithNoPredicate]->getLoc(),
2391218893Sdim                     "two MnemonicAliases with the same 'from' mnemonic!");
2392245431Sdim          PrintFatalError(R->getLoc(), "this is the other MnemonicAlias.");
2393218893Sdim        }
2394218893Sdim
2395218893Sdim        AliasWithNoPredicate = i;
2396218893Sdim        continue;
2397218893Sdim      }
2398218893Sdim      if (R->getValueAsString("ToMnemonic") == I->first)
2399245431Sdim        PrintFatalError(R->getLoc(), "MnemonicAlias to the same string");
2400218893Sdim
2401218893Sdim      if (!MatchCode.empty())
2402218893Sdim        MatchCode += "else ";
2403218893Sdim      MatchCode += "if ((Features & " + FeatureMask + ") == "+FeatureMask+")\n";
2404218893Sdim      MatchCode += "  Mnemonic = \"" +R->getValueAsString("ToMnemonic")+"\";\n";
2405218893Sdim    }
2406218893Sdim
2407218893Sdim    if (AliasWithNoPredicate != -1) {
2408218893Sdim      Record *R = ToVec[AliasWithNoPredicate];
2409218893Sdim      if (!MatchCode.empty())
2410218893Sdim        MatchCode += "else\n  ";
2411218893Sdim      MatchCode += "Mnemonic = \"" + R->getValueAsString("ToMnemonic")+"\";\n";
2412218893Sdim    }
2413218893Sdim
2414218893Sdim    MatchCode += "return;";
2415218893Sdim
2416218893Sdim    Cases.push_back(std::make_pair(I->first, MatchCode));
2417218893Sdim  }
2418252723Sdim  StringMatcher("Mnemonic", Cases, OS).Emit(Indent);
2419252723Sdim}
2420218893Sdim
2421252723Sdim/// emitMnemonicAliases - If the target has any MnemonicAlias<> definitions,
2422252723Sdim/// emit a function for them and return true, otherwise return false.
2423252723Sdimstatic bool emitMnemonicAliases(raw_ostream &OS, const AsmMatcherInfo &Info,
2424252723Sdim                                CodeGenTarget &Target) {
2425252723Sdim  // Ignore aliases when match-prefix is set.
2426252723Sdim  if (!MatchPrefix.empty())
2427252723Sdim    return false;
2428252723Sdim
2429252723Sdim  std::vector<Record*> Aliases =
2430252723Sdim    Info.getRecords().getAllDerivedDefinitions("MnemonicAlias");
2431252723Sdim  if (Aliases.empty()) return false;
2432252723Sdim
2433252723Sdim  OS << "static void applyMnemonicAliases(StringRef &Mnemonic, "
2434252723Sdim    "unsigned Features, unsigned VariantID) {\n";
2435252723Sdim  OS << "  switch (VariantID) {\n";
2436252723Sdim  unsigned VariantCount = Target.getAsmParserVariantCount();
2437252723Sdim  for (unsigned VC = 0; VC != VariantCount; ++VC) {
2438252723Sdim    Record *AsmVariant = Target.getAsmParserVariant(VC);
2439252723Sdim    int AsmParserVariantNo = AsmVariant->getValueAsInt("Variant");
2440252723Sdim    std::string AsmParserVariantName = AsmVariant->getValueAsString("Name");
2441252723Sdim    OS << "    case " << AsmParserVariantNo << ":\n";
2442252723Sdim    emitMnemonicAliasVariant(OS, Info, Aliases, /*Indent=*/2,
2443252723Sdim                             AsmParserVariantName);
2444252723Sdim    OS << "    break;\n";
2445252723Sdim  }
2446252723Sdim  OS << "  }\n";
2447252723Sdim
2448252723Sdim  // Emit aliases that apply to all variants.
2449252723Sdim  emitMnemonicAliasVariant(OS, Info, Aliases);
2450252723Sdim
2451218893Sdim  OS << "}\n\n";
2452218893Sdim
2453218893Sdim  return true;
2454218893Sdim}
2455218893Sdim
2456235633Sdimstatic const char *getMinimalTypeForRange(uint64_t Range) {
2457235633Sdim  assert(Range < 0xFFFFFFFFULL && "Enum too large");
2458235633Sdim  if (Range > 0xFFFF)
2459235633Sdim    return "uint32_t";
2460235633Sdim  if (Range > 0xFF)
2461235633Sdim    return "uint16_t";
2462235633Sdim  return "uint8_t";
2463235633Sdim}
2464235633Sdim
2465245431Sdimstatic void emitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target,
2466245431Sdim                              const AsmMatcherInfo &Info, StringRef ClassName,
2467245431Sdim                              StringToOffsetTable &StringTable,
2468245431Sdim                              unsigned MaxMnemonicIndex) {
2469245431Sdim  unsigned MaxMask = 0;
2470245431Sdim  for (std::vector<OperandMatchEntry>::const_iterator it =
2471245431Sdim       Info.OperandMatchInfo.begin(), ie = Info.OperandMatchInfo.end();
2472245431Sdim       it != ie; ++it) {
2473245431Sdim    MaxMask |= it->OperandMask;
2474245431Sdim  }
2475245431Sdim
2476218893Sdim  // Emit the static custom operand parsing table;
2477218893Sdim  OS << "namespace {\n";
2478218893Sdim  OS << "  struct OperandMatchEntry {\n";
2479235633Sdim  OS << "    " << getMinimalTypeForRange(1ULL << Info.SubtargetFeatures.size())
2480235633Sdim               << " RequiredFeatures;\n";
2481245431Sdim  OS << "    " << getMinimalTypeForRange(MaxMnemonicIndex)
2482245431Sdim               << " Mnemonic;\n";
2483235633Sdim  OS << "    " << getMinimalTypeForRange(Info.Classes.size())
2484245431Sdim               << " Class;\n";
2485245431Sdim  OS << "    " << getMinimalTypeForRange(MaxMask)
2486245431Sdim               << " OperandMask;\n\n";
2487235633Sdim  OS << "    StringRef getMnemonic() const {\n";
2488235633Sdim  OS << "      return StringRef(MnemonicTable + Mnemonic + 1,\n";
2489235633Sdim  OS << "                       MnemonicTable[Mnemonic]);\n";
2490235633Sdim  OS << "    }\n";
2491218893Sdim  OS << "  };\n\n";
2492218893Sdim
2493218893Sdim  OS << "  // Predicate for searching for an opcode.\n";
2494218893Sdim  OS << "  struct LessOpcodeOperand {\n";
2495218893Sdim  OS << "    bool operator()(const OperandMatchEntry &LHS, StringRef RHS) {\n";
2496235633Sdim  OS << "      return LHS.getMnemonic()  < RHS;\n";
2497218893Sdim  OS << "    }\n";
2498218893Sdim  OS << "    bool operator()(StringRef LHS, const OperandMatchEntry &RHS) {\n";
2499235633Sdim  OS << "      return LHS < RHS.getMnemonic();\n";
2500218893Sdim  OS << "    }\n";
2501218893Sdim  OS << "    bool operator()(const OperandMatchEntry &LHS,";
2502218893Sdim  OS << " const OperandMatchEntry &RHS) {\n";
2503235633Sdim  OS << "      return LHS.getMnemonic() < RHS.getMnemonic();\n";
2504218893Sdim  OS << "    }\n";
2505218893Sdim  OS << "  };\n";
2506218893Sdim
2507218893Sdim  OS << "} // end anonymous namespace.\n\n";
2508218893Sdim
2509218893Sdim  OS << "static const OperandMatchEntry OperandMatchTable["
2510218893Sdim     << Info.OperandMatchInfo.size() << "] = {\n";
2511218893Sdim
2512235633Sdim  OS << "  /* Operand List Mask, Mnemonic, Operand Class, Features */\n";
2513218893Sdim  for (std::vector<OperandMatchEntry>::const_iterator it =
2514218893Sdim       Info.OperandMatchInfo.begin(), ie = Info.OperandMatchInfo.end();
2515218893Sdim       it != ie; ++it) {
2516218893Sdim    const OperandMatchEntry &OMI = *it;
2517218893Sdim    const MatchableInfo &II = *OMI.MI;
2518218893Sdim
2519245431Sdim    OS << "  { ";
2520218893Sdim
2521245431Sdim    // Write the required features mask.
2522245431Sdim    if (!II.RequiredFeatures.empty()) {
2523245431Sdim      for (unsigned i = 0, e = II.RequiredFeatures.size(); i != e; ++i) {
2524245431Sdim        if (i) OS << "|";
2525245431Sdim        OS << II.RequiredFeatures[i]->getEnumName();
2526245431Sdim      }
2527245431Sdim    } else
2528245431Sdim      OS << "0";
2529245431Sdim
2530245431Sdim    // Store a pascal-style length byte in the mnemonic.
2531245431Sdim    std::string LenMnemonic = char(II.Mnemonic.size()) + II.Mnemonic.str();
2532245431Sdim    OS << ", " << StringTable.GetOrAddStringOffset(LenMnemonic, false)
2533245431Sdim       << " /* " << II.Mnemonic << " */, ";
2534245431Sdim
2535245431Sdim    OS << OMI.CI->Name;
2536245431Sdim
2537245431Sdim    OS << ", " << OMI.OperandMask;
2538218893Sdim    OS << " /* ";
2539218893Sdim    bool printComma = false;
2540218893Sdim    for (int i = 0, e = 31; i !=e; ++i)
2541218893Sdim      if (OMI.OperandMask & (1 << i)) {
2542218893Sdim        if (printComma)
2543218893Sdim          OS << ", ";
2544218893Sdim        OS << i;
2545218893Sdim        printComma = true;
2546218893Sdim      }
2547218893Sdim    OS << " */";
2548218893Sdim
2549218893Sdim    OS << " },\n";
2550218893Sdim  }
2551218893Sdim  OS << "};\n\n";
2552218893Sdim
2553218893Sdim  // Emit the operand class switch to call the correct custom parser for
2554218893Sdim  // the found operand class.
2555218893Sdim  OS << Target.getName() << ClassName << "::OperandMatchResultTy "
2556218893Sdim     << Target.getName() << ClassName << "::\n"
2557235633Sdim     << "tryCustomParseOperand(SmallVectorImpl<MCParsedAsmOperand*>"
2558218893Sdim     << " &Operands,\n                      unsigned MCK) {\n\n"
2559218893Sdim     << "  switch(MCK) {\n";
2560218893Sdim
2561218893Sdim  for (std::vector<ClassInfo*>::const_iterator it = Info.Classes.begin(),
2562218893Sdim       ie = Info.Classes.end(); it != ie; ++it) {
2563218893Sdim    ClassInfo *CI = *it;
2564218893Sdim    if (CI->ParserMethod.empty())
2565218893Sdim      continue;
2566218893Sdim    OS << "  case " << CI->Name << ":\n"
2567218893Sdim       << "    return " << CI->ParserMethod << "(Operands);\n";
2568218893Sdim  }
2569218893Sdim
2570218893Sdim  OS << "  default:\n";
2571218893Sdim  OS << "    return MatchOperand_NoMatch;\n";
2572218893Sdim  OS << "  }\n";
2573218893Sdim  OS << "  return MatchOperand_NoMatch;\n";
2574218893Sdim  OS << "}\n\n";
2575218893Sdim
2576218893Sdim  // Emit the static custom operand parser. This code is very similar with
2577218893Sdim  // the other matcher. Also use MatchResultTy here just in case we go for
2578218893Sdim  // a better error handling.
2579218893Sdim  OS << Target.getName() << ClassName << "::OperandMatchResultTy "
2580218893Sdim     << Target.getName() << ClassName << "::\n"
2581218893Sdim     << "MatchOperandParserImpl(SmallVectorImpl<MCParsedAsmOperand*>"
2582218893Sdim     << " &Operands,\n                       StringRef Mnemonic) {\n";
2583218893Sdim
2584218893Sdim  // Emit code to get the available features.
2585218893Sdim  OS << "  // Get the current feature set.\n";
2586218893Sdim  OS << "  unsigned AvailableFeatures = getAvailableFeatures();\n\n";
2587218893Sdim
2588218893Sdim  OS << "  // Get the next operand index.\n";
2589218893Sdim  OS << "  unsigned NextOpNum = Operands.size()-1;\n";
2590218893Sdim
2591218893Sdim  // Emit code to search the table.
2592218893Sdim  OS << "  // Search the table.\n";
2593218893Sdim  OS << "  std::pair<const OperandMatchEntry*, const OperandMatchEntry*>";
2594218893Sdim  OS << " MnemonicRange =\n";
2595218893Sdim  OS << "    std::equal_range(OperandMatchTable, OperandMatchTable+"
2596218893Sdim     << Info.OperandMatchInfo.size() << ", Mnemonic,\n"
2597218893Sdim     << "                     LessOpcodeOperand());\n\n";
2598218893Sdim
2599218893Sdim  OS << "  if (MnemonicRange.first == MnemonicRange.second)\n";
2600218893Sdim  OS << "    return MatchOperand_NoMatch;\n\n";
2601218893Sdim
2602218893Sdim  OS << "  for (const OperandMatchEntry *it = MnemonicRange.first,\n"
2603218893Sdim     << "       *ie = MnemonicRange.second; it != ie; ++it) {\n";
2604218893Sdim
2605218893Sdim  OS << "    // equal_range guarantees that instruction mnemonic matches.\n";
2606235633Sdim  OS << "    assert(Mnemonic == it->getMnemonic());\n\n";
2607218893Sdim
2608218893Sdim  // Emit check that the required features are available.
2609218893Sdim  OS << "    // check if the available features match\n";
2610218893Sdim  OS << "    if ((AvailableFeatures & it->RequiredFeatures) "
2611218893Sdim     << "!= it->RequiredFeatures) {\n";
2612218893Sdim  OS << "      continue;\n";
2613218893Sdim  OS << "    }\n\n";
2614218893Sdim
2615218893Sdim  // Emit check to ensure the operand number matches.
2616218893Sdim  OS << "    // check if the operand in question has a custom parser.\n";
2617218893Sdim  OS << "    if (!(it->OperandMask & (1 << NextOpNum)))\n";
2618218893Sdim  OS << "      continue;\n\n";
2619218893Sdim
2620218893Sdim  // Emit call to the custom parser method
2621218893Sdim  OS << "    // call custom parse method to handle the operand\n";
2622218893Sdim  OS << "    OperandMatchResultTy Result = ";
2623235633Sdim  OS << "tryCustomParseOperand(Operands, it->Class);\n";
2624218893Sdim  OS << "    if (Result != MatchOperand_NoMatch)\n";
2625218893Sdim  OS << "      return Result;\n";
2626218893Sdim  OS << "  }\n\n";
2627218893Sdim
2628218893Sdim  OS << "  // Okay, we had no match.\n";
2629218893Sdim  OS << "  return MatchOperand_NoMatch;\n";
2630218893Sdim  OS << "}\n\n";
2631218893Sdim}
2632218893Sdim
2633198090Srdivackyvoid AsmMatcherEmitter::run(raw_ostream &OS) {
2634218893Sdim  CodeGenTarget Target(Records);
2635198090Srdivacky  Record *AsmParser = Target.getAsmParser();
2636198090Srdivacky  std::string ClassName = AsmParser->getValueAsString("AsmParserClassName");
2637198090Srdivacky
2638198090Srdivacky  // Compute the information on the instructions to match.
2639218893Sdim  AsmMatcherInfo Info(AsmParser, Target, Records);
2640245431Sdim  Info.buildInfo();
2641198090Srdivacky
2642203954Srdivacky  // Sort the instruction table using the partial order on classes. We use
2643203954Srdivacky  // stable_sort to ensure that ambiguous instructions are still
2644203954Srdivacky  // deterministically ordered.
2645218893Sdim  std::stable_sort(Info.Matchables.begin(), Info.Matchables.end(),
2646218893Sdim                   less_ptr<MatchableInfo>());
2647218893Sdim
2648198090Srdivacky  DEBUG_WITH_TYPE("instruction_info", {
2649218893Sdim      for (std::vector<MatchableInfo*>::iterator
2650218893Sdim             it = Info.Matchables.begin(), ie = Info.Matchables.end();
2651198090Srdivacky           it != ie; ++it)
2652198090Srdivacky        (*it)->dump();
2653198090Srdivacky    });
2654198090Srdivacky
2655218893Sdim  // Check for ambiguous matchables.
2656218893Sdim  DEBUG_WITH_TYPE("ambiguous_instrs", {
2657218893Sdim    unsigned NumAmbiguous = 0;
2658218893Sdim    for (unsigned i = 0, e = Info.Matchables.size(); i != e; ++i) {
2659218893Sdim      for (unsigned j = i + 1; j != e; ++j) {
2660218893Sdim        MatchableInfo &A = *Info.Matchables[i];
2661218893Sdim        MatchableInfo &B = *Info.Matchables[j];
2662218893Sdim
2663245431Sdim        if (A.couldMatchAmbiguouslyWith(B)) {
2664218893Sdim          errs() << "warning: ambiguous matchables:\n";
2665218893Sdim          A.dump();
2666218893Sdim          errs() << "\nis incomparable with:\n";
2667218893Sdim          B.dump();
2668218893Sdim          errs() << "\n\n";
2669218893Sdim          ++NumAmbiguous;
2670218893Sdim        }
2671198090Srdivacky      }
2672198090Srdivacky    }
2673218893Sdim    if (NumAmbiguous)
2674218893Sdim      errs() << "warning: " << NumAmbiguous
2675218893Sdim             << " ambiguous matchables!\n";
2676218893Sdim  });
2677198090Srdivacky
2678218893Sdim  // Compute the information on the custom operand parsing.
2679245431Sdim  Info.buildOperandMatchInfo();
2680218893Sdim
2681198090Srdivacky  // Write the output.
2682198090Srdivacky
2683218893Sdim  // Information for the class declaration.
2684218893Sdim  OS << "\n#ifdef GET_ASSEMBLER_HEADER\n";
2685218893Sdim  OS << "#undef GET_ASSEMBLER_HEADER\n";
2686218893Sdim  OS << "  // This should be included into the middle of the declaration of\n";
2687226890Sdim  OS << "  // your subclasses implementation of MCTargetAsmParser.\n";
2688224145Sdim  OS << "  unsigned ComputeAvailableFeatures(uint64_t FeatureBits) const;\n";
2689245431Sdim  OS << "  void convertToMCInst(unsigned Kind, MCInst &Inst, "
2690218893Sdim     << "unsigned Opcode,\n"
2691218893Sdim     << "                       const SmallVectorImpl<MCParsedAsmOperand*> "
2692218893Sdim     << "&Operands);\n";
2693245431Sdim  OS << "  void convertToMapAndConstraints(unsigned Kind,\n                ";
2694245431Sdim  OS << "           const SmallVectorImpl<MCParsedAsmOperand*> &Operands);\n";
2695263509Sdim  OS << "  bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID);\n";
2696226890Sdim  OS << "  unsigned MatchInstructionImpl(\n";
2697245431Sdim  OS.indent(27);
2698245431Sdim  OS << "const SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n"
2699245431Sdim     << "                                MCInst &Inst,\n"
2700245431Sdim     << "                                unsigned &ErrorInfo,"
2701245431Sdim     << " bool matchingInlineAsm,\n"
2702245431Sdim     << "                                unsigned VariantID = 0);\n";
2703218893Sdim
2704218893Sdim  if (Info.OperandMatchInfo.size()) {
2705218893Sdim    OS << "\n  enum OperandMatchResultTy {\n";
2706218893Sdim    OS << "    MatchOperand_Success,    // operand matched successfully\n";
2707218893Sdim    OS << "    MatchOperand_NoMatch,    // operand did not match\n";
2708218893Sdim    OS << "    MatchOperand_ParseFail   // operand matched but had errors\n";
2709218893Sdim    OS << "  };\n";
2710218893Sdim    OS << "  OperandMatchResultTy MatchOperandParserImpl(\n";
2711218893Sdim    OS << "    SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n";
2712218893Sdim    OS << "    StringRef Mnemonic);\n";
2713218893Sdim
2714235633Sdim    OS << "  OperandMatchResultTy tryCustomParseOperand(\n";
2715218893Sdim    OS << "    SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n";
2716218893Sdim    OS << "    unsigned MCK);\n\n";
2717218893Sdim  }
2718218893Sdim
2719218893Sdim  OS << "#endif // GET_ASSEMBLER_HEADER_INFO\n\n";
2720218893Sdim
2721245431Sdim  // Emit the operand match diagnostic enum names.
2722245431Sdim  OS << "\n#ifdef GET_OPERAND_DIAGNOSTIC_TYPES\n";
2723245431Sdim  OS << "#undef GET_OPERAND_DIAGNOSTIC_TYPES\n\n";
2724245431Sdim  emitOperandDiagnosticTypes(Info, OS);
2725245431Sdim  OS << "#endif // GET_OPERAND_DIAGNOSTIC_TYPES\n\n";
2726245431Sdim
2727245431Sdim
2728218893Sdim  OS << "\n#ifdef GET_REGISTER_MATCHER\n";
2729218893Sdim  OS << "#undef GET_REGISTER_MATCHER\n\n";
2730218893Sdim
2731212904Sdim  // Emit the subtarget feature enumeration.
2732245431Sdim  emitSubtargetFeatureFlagEnumeration(Info, OS);
2733212904Sdim
2734198090Srdivacky  // Emit the function to match a register name to number.
2735245431Sdim  // This should be omitted for Mips target
2736245431Sdim  if (AsmParser->getValueAsBit("ShouldEmitMatchRegisterName"))
2737245431Sdim    emitMatchRegisterName(Target, AsmParser, OS);
2738198090Srdivacky
2739218893Sdim  OS << "#endif // GET_REGISTER_MATCHER\n\n";
2740218893Sdim
2741245431Sdim  OS << "\n#ifdef GET_SUBTARGET_FEATURE_NAME\n";
2742245431Sdim  OS << "#undef GET_SUBTARGET_FEATURE_NAME\n\n";
2743218893Sdim
2744245431Sdim  // Generate the helper function to get the names for subtarget features.
2745245431Sdim  emitGetSubtargetFeatureName(Info, OS);
2746245431Sdim
2747245431Sdim  OS << "#endif // GET_SUBTARGET_FEATURE_NAME\n\n";
2748245431Sdim
2749218893Sdim  OS << "\n#ifdef GET_MATCHER_IMPLEMENTATION\n";
2750218893Sdim  OS << "#undef GET_MATCHER_IMPLEMENTATION\n\n";
2751218893Sdim
2752218893Sdim  // Generate the function that remaps for mnemonic aliases.
2753252723Sdim  bool HasMnemonicAliases = emitMnemonicAliases(OS, Info, Target);
2754218893Sdim
2755245431Sdim  // Generate the convertToMCInst function to convert operands into an MCInst.
2756245431Sdim  // Also, generate the convertToMapAndConstraints function for MS-style inline
2757245431Sdim  // assembly.  The latter doesn't actually generate a MCInst.
2758245431Sdim  emitConvertFuncs(Target, ClassName, Info.Matchables, OS);
2759198090Srdivacky
2760198090Srdivacky  // Emit the enumeration for classes which participate in matching.
2761245431Sdim  emitMatchClassEnumeration(Target, Info.Classes, OS);
2762198090Srdivacky
2763198090Srdivacky  // Emit the routine to match token strings to their match class.
2764245431Sdim  emitMatchTokenString(Target, Info.Classes, OS);
2765198090Srdivacky
2766198090Srdivacky  // Emit the subclass predicate routine.
2767245431Sdim  emitIsSubclass(Target, Info.Classes, OS);
2768198090Srdivacky
2769218893Sdim  // Emit the routine to validate an operand against a match class.
2770245431Sdim  emitValidateOperandClass(Info, OS);
2771218893Sdim
2772212904Sdim  // Emit the available features compute function.
2773245431Sdim  emitComputeAvailableFeatures(Info, OS);
2774212904Sdim
2775198090Srdivacky
2776245431Sdim  StringToOffsetTable StringTable;
2777245431Sdim
2778198090Srdivacky  size_t MaxNumOperands = 0;
2779245431Sdim  unsigned MaxMnemonicIndex = 0;
2780263509Sdim  bool HasDeprecation = false;
2781218893Sdim  for (std::vector<MatchableInfo*>::const_iterator it =
2782218893Sdim         Info.Matchables.begin(), ie = Info.Matchables.end();
2783245431Sdim       it != ie; ++it) {
2784245431Sdim    MatchableInfo &II = **it;
2785245431Sdim    MaxNumOperands = std::max(MaxNumOperands, II.AsmOperands.size());
2786263509Sdim    HasDeprecation |= II.HasDeprecation;
2787198090Srdivacky
2788245431Sdim    // Store a pascal-style length byte in the mnemonic.
2789245431Sdim    std::string LenMnemonic = char(II.Mnemonic.size()) + II.Mnemonic.str();
2790245431Sdim    MaxMnemonicIndex = std::max(MaxMnemonicIndex,
2791245431Sdim                        StringTable.GetOrAddStringOffset(LenMnemonic, false));
2792245431Sdim  }
2793245431Sdim
2794245431Sdim  OS << "static const char *const MnemonicTable =\n";
2795245431Sdim  StringTable.EmitString(OS);
2796245431Sdim  OS << ";\n\n";
2797245431Sdim
2798198090Srdivacky  // Emit the static match table; unused classes get initalized to 0 which is
2799198090Srdivacky  // guaranteed to be InvalidMatchClass.
2800198090Srdivacky  //
2801198090Srdivacky  // FIXME: We can reduce the size of this table very easily. First, we change
2802198090Srdivacky  // it so that store the kinds in separate bit-fields for each index, which
2803198090Srdivacky  // only needs to be the max width used for classes at that index (we also need
2804198090Srdivacky  // to reject based on this during classification). If we then make sure to
2805198090Srdivacky  // order the match kinds appropriately (putting mnemonics last), then we
2806198090Srdivacky  // should only end up using a few bits for each class, especially the ones
2807198090Srdivacky  // following the mnemonic.
2808218893Sdim  OS << "namespace {\n";
2809218893Sdim  OS << "  struct MatchEntry {\n";
2810245431Sdim  OS << "    " << getMinimalTypeForRange(MaxMnemonicIndex)
2811245431Sdim               << " Mnemonic;\n";
2812235633Sdim  OS << "    uint16_t Opcode;\n";
2813235633Sdim  OS << "    " << getMinimalTypeForRange(Info.Matchables.size())
2814235633Sdim               << " ConvertFn;\n";
2815235633Sdim  OS << "    " << getMinimalTypeForRange(1ULL << Info.SubtargetFeatures.size())
2816235633Sdim               << " RequiredFeatures;\n";
2817235633Sdim  OS << "    " << getMinimalTypeForRange(Info.Classes.size())
2818235633Sdim               << " Classes[" << MaxNumOperands << "];\n";
2819235633Sdim  OS << "    StringRef getMnemonic() const {\n";
2820235633Sdim  OS << "      return StringRef(MnemonicTable + Mnemonic + 1,\n";
2821235633Sdim  OS << "                       MnemonicTable[Mnemonic]);\n";
2822235633Sdim  OS << "    }\n";
2823218893Sdim  OS << "  };\n\n";
2824198090Srdivacky
2825218893Sdim  OS << "  // Predicate for searching for an opcode.\n";
2826218893Sdim  OS << "  struct LessOpcode {\n";
2827218893Sdim  OS << "    bool operator()(const MatchEntry &LHS, StringRef RHS) {\n";
2828235633Sdim  OS << "      return LHS.getMnemonic() < RHS;\n";
2829218893Sdim  OS << "    }\n";
2830218893Sdim  OS << "    bool operator()(StringRef LHS, const MatchEntry &RHS) {\n";
2831235633Sdim  OS << "      return LHS < RHS.getMnemonic();\n";
2832218893Sdim  OS << "    }\n";
2833218893Sdim  OS << "    bool operator()(const MatchEntry &LHS, const MatchEntry &RHS) {\n";
2834235633Sdim  OS << "      return LHS.getMnemonic() < RHS.getMnemonic();\n";
2835218893Sdim  OS << "    }\n";
2836218893Sdim  OS << "  };\n";
2837218893Sdim
2838218893Sdim  OS << "} // end anonymous namespace.\n\n";
2839218893Sdim
2840263509Sdim  unsigned VariantCount = Target.getAsmParserVariantCount();
2841263509Sdim  for (unsigned VC = 0; VC != VariantCount; ++VC) {
2842263509Sdim    Record *AsmVariant = Target.getAsmParserVariant(VC);
2843263509Sdim    int AsmVariantNo = AsmVariant->getValueAsInt("Variant");
2844218893Sdim
2845263509Sdim    OS << "static const MatchEntry MatchTable" << VC << "[] = {\n";
2846198090Srdivacky
2847263509Sdim    for (std::vector<MatchableInfo*>::const_iterator it =
2848263509Sdim         Info.Matchables.begin(), ie = Info.Matchables.end();
2849263509Sdim         it != ie; ++it) {
2850263509Sdim      MatchableInfo &II = **it;
2851263509Sdim      if (II.AsmVariantID != AsmVariantNo)
2852263509Sdim        continue;
2853218893Sdim
2854263509Sdim      // Store a pascal-style length byte in the mnemonic.
2855263509Sdim      std::string LenMnemonic = char(II.Mnemonic.size()) + II.Mnemonic.str();
2856263509Sdim      OS << "  { " << StringTable.GetOrAddStringOffset(LenMnemonic, false)
2857263509Sdim         << " /* " << II.Mnemonic << " */, "
2858263509Sdim         << Target.getName() << "::"
2859263509Sdim         << II.getResultInst()->TheDef->getName() << ", "
2860263509Sdim         << II.ConversionFnKind << ", ";
2861212904Sdim
2862263509Sdim      // Write the required features mask.
2863263509Sdim      if (!II.RequiredFeatures.empty()) {
2864263509Sdim        for (unsigned i = 0, e = II.RequiredFeatures.size(); i != e; ++i) {
2865263509Sdim          if (i) OS << "|";
2866263509Sdim          OS << II.RequiredFeatures[i]->getEnumName();
2867263509Sdim        }
2868263509Sdim      } else
2869263509Sdim        OS << "0";
2870235633Sdim
2871263509Sdim      OS << ", { ";
2872263509Sdim      for (unsigned i = 0, e = II.AsmOperands.size(); i != e; ++i) {
2873263509Sdim        MatchableInfo::AsmOperand &Op = II.AsmOperands[i];
2874263509Sdim
2875263509Sdim        if (i) OS << ", ";
2876263509Sdim        OS << Op.Class->Name;
2877263509Sdim      }
2878263509Sdim      OS << " }, },\n";
2879235633Sdim    }
2880263509Sdim
2881263509Sdim    OS << "};\n\n";
2882198090Srdivacky  }
2883198090Srdivacky
2884218893Sdim  // A method to determine if a mnemonic is in the list.
2885218893Sdim  OS << "bool " << Target.getName() << ClassName << "::\n"
2886263509Sdim     << "mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) {\n";
2887263509Sdim  OS << "  // Find the appropriate table for this asm variant.\n";
2888263509Sdim  OS << "  const MatchEntry *Start, *End;\n";
2889263509Sdim  OS << "  switch (VariantID) {\n";
2890263509Sdim  OS << "  default: // unreachable\n";
2891263509Sdim  for (unsigned VC = 0; VC != VariantCount; ++VC) {
2892263509Sdim    Record *AsmVariant = Target.getAsmParserVariant(VC);
2893263509Sdim    int AsmVariantNo = AsmVariant->getValueAsInt("Variant");
2894263509Sdim    OS << "  case " << AsmVariantNo << ": Start = MatchTable" << VC
2895263509Sdim       << "; End = array_endof(MatchTable" << VC << "); break;\n";
2896263509Sdim  }
2897263509Sdim  OS << "  }\n";
2898218893Sdim  OS << "  // Search the table.\n";
2899218893Sdim  OS << "  std::pair<const MatchEntry*, const MatchEntry*> MnemonicRange =\n";
2900263509Sdim  OS << "    std::equal_range(Start, End, Mnemonic, LessOpcode());\n";
2901218893Sdim  OS << "  return MnemonicRange.first != MnemonicRange.second;\n";
2902218893Sdim  OS << "}\n\n";
2903212904Sdim
2904218893Sdim  // Finally, build the match function.
2905226890Sdim  OS << "unsigned "
2906218893Sdim     << Target.getName() << ClassName << "::\n"
2907218893Sdim     << "MatchInstructionImpl(const SmallVectorImpl<MCParsedAsmOperand*>"
2908218893Sdim     << " &Operands,\n";
2909245431Sdim  OS << "                     MCInst &Inst,\n"
2910245431Sdim     << "unsigned &ErrorInfo, bool matchingInlineAsm, unsigned VariantID) {\n";
2911218893Sdim
2912245431Sdim  OS << "  // Eliminate obvious mismatches.\n";
2913245431Sdim  OS << "  if (Operands.size() > " << (MaxNumOperands+1) << ") {\n";
2914245431Sdim  OS << "    ErrorInfo = " << (MaxNumOperands+1) << ";\n";
2915245431Sdim  OS << "    return Match_InvalidOperand;\n";
2916245431Sdim  OS << "  }\n\n";
2917245431Sdim
2918212904Sdim  // Emit code to get the available features.
2919212904Sdim  OS << "  // Get the current feature set.\n";
2920212904Sdim  OS << "  unsigned AvailableFeatures = getAvailableFeatures();\n\n";
2921212904Sdim
2922218893Sdim  OS << "  // Get the instruction mnemonic, which is the first token.\n";
2923218893Sdim  OS << "  StringRef Mnemonic = ((" << Target.getName()
2924218893Sdim     << "Operand*)Operands[0])->getToken();\n\n";
2925218893Sdim
2926218893Sdim  if (HasMnemonicAliases) {
2927218893Sdim    OS << "  // Process all MnemonicAliases to remap the mnemonic.\n";
2928252723Sdim    OS << "  applyMnemonicAliases(Mnemonic, AvailableFeatures, VariantID);\n\n";
2929218893Sdim  }
2930218893Sdim
2931198090Srdivacky  // Emit code to compute the class list for this operand vector.
2932218893Sdim  OS << "  // Some state to try to produce better error messages.\n";
2933226890Sdim  OS << "  bool HadMatchOtherThanFeatures = false;\n";
2934226890Sdim  OS << "  bool HadMatchOtherThanPredicate = false;\n";
2935226890Sdim  OS << "  unsigned RetCode = Match_InvalidOperand;\n";
2936245431Sdim  OS << "  unsigned MissingFeatures = ~0U;\n";
2937218893Sdim  OS << "  // Set ErrorInfo to the operand that mismatches if it is\n";
2938218893Sdim  OS << "  // wrong for all instances of the instruction.\n";
2939218893Sdim  OS << "  ErrorInfo = ~0U;\n";
2940198090Srdivacky
2941198090Srdivacky  // Emit code to search the table.
2942263509Sdim  OS << "  // Find the appropriate table for this asm variant.\n";
2943263509Sdim  OS << "  const MatchEntry *Start, *End;\n";
2944263509Sdim  OS << "  switch (VariantID) {\n";
2945263509Sdim  OS << "  default: // unreachable\n";
2946263509Sdim  for (unsigned VC = 0; VC != VariantCount; ++VC) {
2947263509Sdim    Record *AsmVariant = Target.getAsmParserVariant(VC);
2948263509Sdim    int AsmVariantNo = AsmVariant->getValueAsInt("Variant");
2949263509Sdim    OS << "  case " << AsmVariantNo << ": Start = MatchTable" << VC
2950263509Sdim       << "; End = array_endof(MatchTable" << VC << "); break;\n";
2951263509Sdim  }
2952263509Sdim  OS << "  }\n";
2953198090Srdivacky  OS << "  // Search the table.\n";
2954218893Sdim  OS << "  std::pair<const MatchEntry*, const MatchEntry*> MnemonicRange =\n";
2955263509Sdim  OS << "    std::equal_range(Start, End, Mnemonic, LessOpcode());\n\n";
2956212904Sdim
2957218893Sdim  OS << "  // Return a more specific error code if no mnemonics match.\n";
2958218893Sdim  OS << "  if (MnemonicRange.first == MnemonicRange.second)\n";
2959218893Sdim  OS << "    return Match_MnemonicFail;\n\n";
2960212904Sdim
2961218893Sdim  OS << "  for (const MatchEntry *it = MnemonicRange.first, "
2962218893Sdim     << "*ie = MnemonicRange.second;\n";
2963218893Sdim  OS << "       it != ie; ++it) {\n";
2964218893Sdim
2965218893Sdim  OS << "    // equal_range guarantees that instruction mnemonic matches.\n";
2966235633Sdim  OS << "    assert(Mnemonic == it->getMnemonic());\n";
2967218893Sdim
2968212904Sdim  // Emit check that the subclasses match.
2969218893Sdim  OS << "    bool OperandsValid = true;\n";
2970218893Sdim  OS << "    for (unsigned i = 0; i != " << MaxNumOperands << "; ++i) {\n";
2971218893Sdim  OS << "      if (i + 1 >= Operands.size()) {\n";
2972218893Sdim  OS << "        OperandsValid = (it->Classes[i] == " <<"InvalidMatchClass);\n";
2973245431Sdim  OS << "        if (!OperandsValid) ErrorInfo = i + 1;\n";
2974223017Sdim  OS << "        break;\n";
2975218893Sdim  OS << "      }\n";
2976245431Sdim  OS << "      unsigned Diag = validateOperandClass(Operands[i+1],\n";
2977245431Sdim  OS.indent(43);
2978245431Sdim  OS << "(MatchClassKind)it->Classes[i]);\n";
2979245431Sdim  OS << "      if (Diag == Match_Success)\n";
2980218893Sdim  OS << "        continue;\n";
2981252723Sdim  OS << "      // If the generic handler indicates an invalid operand\n";
2982252723Sdim  OS << "      // failure, check for a special case.\n";
2983252723Sdim  OS << "      if (Diag == Match_InvalidOperand) {\n";
2984252723Sdim  OS << "        Diag = validateTargetOperandClass(Operands[i+1],\n";
2985252723Sdim  OS.indent(43);
2986252723Sdim  OS << "(MatchClassKind)it->Classes[i]);\n";
2987252723Sdim  OS << "        if (Diag == Match_Success)\n";
2988252723Sdim  OS << "          continue;\n";
2989252723Sdim  OS << "      }\n";
2990218893Sdim  OS << "      // If this operand is broken for all of the instances of this\n";
2991218893Sdim  OS << "      // mnemonic, keep track of it so we can report loc info.\n";
2992245431Sdim  OS << "      // If we already had a match that only failed due to a\n";
2993245431Sdim  OS << "      // target predicate, that diagnostic is preferred.\n";
2994245431Sdim  OS << "      if (!HadMatchOtherThanPredicate &&\n";
2995245431Sdim  OS << "          (it == MnemonicRange.first || ErrorInfo <= i+1)) {\n";
2996218893Sdim  OS << "        ErrorInfo = i+1;\n";
2997245431Sdim  OS << "        // InvalidOperand is the default. Prefer specificity.\n";
2998245431Sdim  OS << "        if (Diag != Match_InvalidOperand)\n";
2999245431Sdim  OS << "          RetCode = Diag;\n";
3000245431Sdim  OS << "      }\n";
3001218893Sdim  OS << "      // Otherwise, just reject this instance of the mnemonic.\n";
3002218893Sdim  OS << "      OperandsValid = false;\n";
3003218893Sdim  OS << "      break;\n";
3004218893Sdim  OS << "    }\n\n";
3005218893Sdim
3006218893Sdim  OS << "    if (!OperandsValid) continue;\n";
3007218893Sdim
3008218893Sdim  // Emit check that the required features are available.
3009218893Sdim  OS << "    if ((AvailableFeatures & it->RequiredFeatures) "
3010218893Sdim     << "!= it->RequiredFeatures) {\n";
3011218893Sdim  OS << "      HadMatchOtherThanFeatures = true;\n";
3012245431Sdim  OS << "      unsigned NewMissingFeatures = it->RequiredFeatures & "
3013245431Sdim        "~AvailableFeatures;\n";
3014245431Sdim  OS << "      if (CountPopulation_32(NewMissingFeatures) <=\n"
3015245431Sdim        "          CountPopulation_32(MissingFeatures))\n";
3016245431Sdim  OS << "        MissingFeatures = NewMissingFeatures;\n";
3017218893Sdim  OS << "      continue;\n";
3018218893Sdim  OS << "    }\n";
3019198090Srdivacky  OS << "\n";
3020245431Sdim  OS << "    if (matchingInlineAsm) {\n";
3021245431Sdim  OS << "      Inst.setOpcode(it->Opcode);\n";
3022245431Sdim  OS << "      convertToMapAndConstraints(it->ConvertFn, Operands);\n";
3023245431Sdim  OS << "      return Match_Success;\n";
3024245431Sdim  OS << "    }\n\n";
3025218893Sdim  OS << "    // We have selected a definite instruction, convert the parsed\n"
3026218893Sdim     << "    // operands into the appropriate MCInst.\n";
3027245431Sdim  OS << "    convertToMCInst(it->ConvertFn, Inst, it->Opcode, Operands);\n";
3028218893Sdim  OS << "\n";
3029205407Srdivacky
3030226890Sdim  // Verify the instruction with the target-specific match predicate function.
3031226890Sdim  OS << "    // We have a potential match. Check the target predicate to\n"
3032226890Sdim     << "    // handle any context sensitive constraints.\n"
3033226890Sdim     << "    unsigned MatchResult;\n"
3034226890Sdim     << "    if ((MatchResult = checkTargetMatchPredicate(Inst)) !="
3035226890Sdim     << " Match_Success) {\n"
3036226890Sdim     << "      Inst.clear();\n"
3037226890Sdim     << "      RetCode = MatchResult;\n"
3038226890Sdim     << "      HadMatchOtherThanPredicate = true;\n"
3039226890Sdim     << "      continue;\n"
3040226890Sdim     << "    }\n\n";
3041226890Sdim
3042205407Srdivacky  // Call the post-processing function, if used.
3043205407Srdivacky  std::string InsnCleanupFn =
3044205407Srdivacky    AsmParser->getValueAsString("AsmParserInstCleanup");
3045205407Srdivacky  if (!InsnCleanupFn.empty())
3046205407Srdivacky    OS << "    " << InsnCleanupFn << "(Inst);\n";
3047205407Srdivacky
3048263509Sdim  if (HasDeprecation) {
3049263509Sdim    OS << "    std::string Info;\n";
3050263509Sdim    OS << "    if (MII.get(Inst.getOpcode()).getDeprecatedInfo(Inst, STI, Info)) {\n";
3051263509Sdim    OS << "      SMLoc Loc = ((" << Target.getName() << "Operand*)Operands[0])->getStartLoc();\n";
3052263509Sdim    OS << "      Parser.Warning(Loc, Info, None);\n";
3053263509Sdim    OS << "    }\n";
3054263509Sdim  }
3055263509Sdim
3056218893Sdim  OS << "    return Match_Success;\n";
3057198090Srdivacky  OS << "  }\n\n";
3058198090Srdivacky
3059218893Sdim  OS << "  // Okay, we had no match.  Try to return a useful error code.\n";
3060245431Sdim  OS << "  if (HadMatchOtherThanPredicate || !HadMatchOtherThanFeatures)\n";
3061245431Sdim  OS << "    return RetCode;\n\n";
3062245431Sdim  OS << "  // Missing feature matches return which features were missing\n";
3063245431Sdim  OS << "  ErrorInfo = MissingFeatures;\n";
3064226890Sdim  OS << "  return Match_MissingFeature;\n";
3065198090Srdivacky  OS << "}\n\n";
3066218893Sdim
3067218893Sdim  if (Info.OperandMatchInfo.size())
3068245431Sdim    emitCustomOperandParsing(OS, Target, Info, ClassName, StringTable,
3069245431Sdim                             MaxMnemonicIndex);
3070218893Sdim
3071218893Sdim  OS << "#endif // GET_MATCHER_IMPLEMENTATION\n\n";
3072198090Srdivacky}
3073245431Sdim
3074245431Sdimnamespace llvm {
3075245431Sdim
3076245431Sdimvoid EmitAsmMatcher(RecordKeeper &RK, raw_ostream &OS) {
3077245431Sdim  emitSourceFileHeader("Assembly Matcher Source Fragment", OS);
3078245431Sdim  AsmMatcherEmitter(RK).run(OS);
3079245431Sdim}
3080245431Sdim
3081245431Sdim} // End llvm namespace
3082