AsmMatcherEmitter.cpp revision 4c1d2baa7c3303302fec9a15ebc4021bd5d45002
1d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar//===- AsmMatcherEmitter.cpp - Generate an assembly matcher ---------------===//
2d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar//
3d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar//                     The LLVM Compiler Infrastructure
4d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar//
5d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar// This file is distributed under the University of Illinois Open Source
6d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar// License. See LICENSE.TXT for details.
7d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar//
8d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar//===----------------------------------------------------------------------===//
9d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar//
10d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar// This tablegen backend emits a target specifier matcher for converting parsed
11e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// assembly operands in the MCInst structures. It also emits a matcher for
12e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// custom operand parsing.
13e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes//
14e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// Converting assembly operands into MCInst structures
15e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// ---------------------------------------------------
16d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar//
1720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// The input to the target specific matcher is a list of literal tokens and
1820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// operands. The target specific parser should generally eliminate any syntax
1920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// which is not relevant for matching; for example, comma tokens should have
2020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// already been consumed and eliminated by the parser. Most instructions will
2120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// end up with a single literal token (the instruction name) and some number of
2220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// operands.
2320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//
2420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// Some example inputs, for X86:
2520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//   'addl' (immediate ...) (register ...)
2620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//   'add' (immediate ...) (memory ...)
27a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach//   'call' '*' %epc
2820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//
2920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// The assembly matcher is responsible for converting this input into a precise
3020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// machine instruction (i.e., an instruction with a well defined encoding). This
3120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// mapping has several properties which complicate matching:
3220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//
3320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//  - It may be ambiguous; many architectures can legally encode particular
3420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//    variants of an instruction in different ways (for example, using a smaller
3520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//    encoding for small immediates). Such ambiguities should never be
3620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//    arbitrarily resolved by the assembler, the assembler is always responsible
3720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//    for choosing the "best" available instruction.
3820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//
3920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//  - It may depend on the subtarget or the assembler context. Instructions
4020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//    which are invalid for the current mode, but otherwise unambiguous (e.g.,
4120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//    an SSE instruction in a file being assembled for i486) should be accepted
4220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//    and rejected by the assembler front end. However, if the proper encoding
4320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//    for an instruction is dependent on the assembler context then the matcher
4420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//    is responsible for selecting the correct machine instruction for the
4520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//    current mode.
4620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//
4720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// The core matching algorithm attempts to exploit the regularity in most
4820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// instruction sets to quickly determine the set of possibly matching
4920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// instructions, and the simplify the generated code. Additionally, this helps
5020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// to ensure that the ambiguities are intentionally resolved by the user.
5120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//
5220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// The matching is divided into two distinct phases:
5320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//
5420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//   1. Classification: Each operand is mapped to the unique set which (a)
5520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//      contains it, and (b) is the largest such subset for which a single
5620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//      instruction could match all members.
5720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//
5820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//      For register classes, we can generate these subgroups automatically. For
5920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//      arbitrary operands, we expect the user to define the classes and their
6020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//      relations to one another (for example, 8-bit signed immediates as a
6120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//      subset of 32-bit immediates).
6220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//
6320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//      By partitioning the operands in this way, we guarantee that for any
6420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//      tuple of classes, any single instruction must match either all or none
6520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//      of the sets of operands which could classify to that tuple.
6620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//
6720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//      In addition, the subset relation amongst classes induces a partial order
6820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//      on such tuples, which we use to resolve ambiguities.
6920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//
7020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//   2. The input can now be treated as a tuple of classes (static tokens are
7120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//      simple singleton sets). Each such tuple should generally map to a single
7220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//      instruction (we currently ignore cases where this isn't true, whee!!!),
7320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//      which we can emit a simple matcher for.
7420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar//
75e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// Custom Operand Parsing
76e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// ----------------------
77e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes//
78e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes//  Some targets need a custom way to parse operands, some specific instructions
79e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes//  can contain arguments that can represent processor flags and other kinds of
80e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes//  identifiers that need to be mapped to specific valeus in the final encoded
81e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes//  instructions. The target specific custom operand parsing works in the
82e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes//  following way:
83e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes//
84e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes//   1. A operand match table is built, each entry contains a mnemonic, an
85e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes//      operand class, a mask for all operand positions for that same
86e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes//      class/mnemonic and target features to be checked while trying to match.
87e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes//
88e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes//   2. The operand matcher will try every possible entry with the same
89e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes//      mnemonic and will check if the target feature for this mnemonic also
90e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes//      matches. After that, if the operand to be matched has its index
917a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner//      present in the mask, a successful match occurs. Otherwise, fallback
92e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes//      to the regular operand parsing.
93e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes//
94e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes//   3. For a match success, each operand class that has a 'ParserMethod'
95e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes//      becomes part of a switch from where the custom method is called.
96e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes//
97d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar//===----------------------------------------------------------------------===//
98d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar
99d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar#include "CodeGenTarget.h"
100a4c5ecfb1bc0101c1b42a4d81bb427482b52cecfBenjamin Kramer#include "StringToOffsetTable.h"
10120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar#include "llvm/ADT/OwningPtr.h"
102c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner#include "llvm/ADT/PointerUnion.h"
1031de88235781c45c0afc0c7500d65b59775196c4cChris Lattner#include "llvm/ADT/SmallPtrSet.h"
104a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar#include "llvm/ADT/SmallVector.h"
105606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar#include "llvm/ADT/STLExtras.h"
10620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar#include "llvm/ADT/StringExtras.h"
10720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar#include "llvm/Support/CommandLine.h"
108a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar#include "llvm/Support/Debug.h"
109655b8de7b2ab773a977e0c524307e71354d8af29Craig Topper#include "llvm/Support/ErrorHandling.h"
1107c788888872233748da10a8177a9a1eb176c1bc8Peter Collingbourne#include "llvm/TableGen/Error.h"
1117c788888872233748da10a8177a9a1eb176c1bc8Peter Collingbourne#include "llvm/TableGen/Record.h"
112f657da2e4896732f306a9e62261418112e7337ceDouglas Gregor#include "llvm/TableGen/StringMatcher.h"
1136f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include "llvm/TableGen/TableGenBackend.h"
1146f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include <cassert>
115b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar#include <map>
116b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar#include <set>
117d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbarusing namespace llvm;
118d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar
1192724915c171b08fa9f7f9e54a46ea81708d9c5b2Daniel Dunbarstatic cl::opt<std::string>
120606e8ad796f72824f5509e2657c44eca025d4bafDaniel DunbarMatchPrefix("match-prefix", cl::init(""),
121606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar            cl::desc("Only match instructions with the given prefix"));
12220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
12320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbarnamespace {
124828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilsonclass AsmMatcherInfo;
12554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbarstruct SubtargetFeatureInfo;
12654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar
1276f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenclass AsmMatcherEmitter {
1286f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  RecordKeeper &Records;
1296f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenpublic:
1306f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  AsmMatcherEmitter(RecordKeeper &R) : Records(R) {}
1316f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
1326f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  void run(raw_ostream &o);
1336f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen};
1346f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
135a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar/// ClassInfo - Helper class for storing the information about a particular
136a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar/// class of operands which can be matched.
137a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarstruct ClassInfo {
138606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar  enum ClassInfoKind {
139ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    /// Invalid kind, for use as a sentinel value.
140ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    Invalid = 0,
141ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
142ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    /// The class for a particular token.
143ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    Token,
144ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
145ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    /// The (first) register class, subsequent register classes are
146ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    /// RegisterClass0+1, and so on.
147ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    RegisterClass0,
148ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
149ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    /// The (first) user defined class, subsequent user defined classes are
150ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    /// UserClass0+1, and so on.
151ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    UserClass0 = 1<<16
152606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar  };
153606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar
154606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar  /// Kind - The class kind, which is either a predefined kind, or (UserClass0 +
155606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar  /// N) for the Nth user defined class.
156606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar  unsigned Kind;
157a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
158ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  /// SuperClasses - The super classes of this class. Note that for simplicities
159ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  /// sake user operands only record their immediate super class, while register
160ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  /// operands include all superclasses.
161ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  std::vector<ClassInfo*> SuperClasses;
1625fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar
1636745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar  /// Name - The full class name, suitable for use in an enum.
164a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  std::string Name;
165a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
1666745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar  /// ClassName - The unadorned generic name for this class (e.g., Token).
1676745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar  std::string ClassName;
1686745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar
169a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  /// ValueName - The name of the value this class represents; for a token this
170a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  /// is the literal token string, for an operand it is the TableGen class (or
171a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  /// empty if this is a derived class).
172a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  std::string ValueName;
173a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
174a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  /// PredicateMethod - The name of the operand method to test whether the
175ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  /// operand matches this class; this is not valid for Token or register kinds.
176a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  std::string PredicateMethod;
177a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
178a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  /// RenderMethod - The name of the operand method to add this operand to an
179ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  /// MCInst; this is not valid for Token or register kinds.
180a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  std::string RenderMethod;
181606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar
182e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  /// ParserMethod - The name of the operand method to do a target specific
183e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  /// parsing on the operand.
184e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  std::string ParserMethod;
185e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
1868409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar  /// For register classes, the records for all the registers in this class.
1878409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar  std::set<Record*> Registers;
1888409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar
1894dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  /// For custom match classes, he diagnostic kind for when the predicate fails.
1904dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  std::string DiagnosticType;
1918409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbarpublic:
192ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  /// isRegisterClass() - Check if this is a register class.
193ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  bool isRegisterClass() const {
194ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    return Kind >= RegisterClass0 && Kind < UserClass0;
195ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  }
196ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
1975fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar  /// isUserClass() - Check if this is a user defined class.
1985fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar  bool isUserClass() const {
1995fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar    return Kind >= UserClass0;
2005fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar  }
2015fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar
202ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  /// isRelatedTo - Check whether this class is "related" to \arg RHS. Classes
203ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  /// are related if they are in the same class hierarchy.
204ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  bool isRelatedTo(const ClassInfo &RHS) const {
205ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    // Tokens are only related to tokens.
206ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    if (Kind == Token || RHS.Kind == Token)
207ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar      return Kind == Token && RHS.Kind == Token;
208ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
2098409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar    // Registers classes are only related to registers classes, and only if
2108409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar    // their intersection is non-empty.
2118409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar    if (isRegisterClass() || RHS.isRegisterClass()) {
2128409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar      if (!isRegisterClass() || !RHS.isRegisterClass())
2138409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar        return false;
2148409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar
2158409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar      std::set<Record*> Tmp;
2168409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar      std::insert_iterator< std::set<Record*> > II(Tmp, Tmp.begin());
217a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach      std::set_intersection(Registers.begin(), Registers.end(),
2188409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar                            RHS.Registers.begin(), RHS.Registers.end(),
2198409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar                            II);
2208409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar
2218409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar      return !Tmp.empty();
2228409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar    }
223ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
224ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    // Otherwise we have two users operands; they are related if they are in the
225ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    // same class hierarchy.
2268409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar    //
2278409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar    // FIXME: This is an oversimplification, they should only be related if they
2288409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar    // intersect, however we don't have that information.
229ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    assert(isUserClass() && RHS.isUserClass() && "Unexpected class!");
230ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    const ClassInfo *Root = this;
231ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    while (!Root->SuperClasses.empty())
232ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar      Root = Root->SuperClasses.front();
233ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
2348409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar    const ClassInfo *RHSRoot = &RHS;
235ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    while (!RHSRoot->SuperClasses.empty())
236ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar      RHSRoot = RHSRoot->SuperClasses.front();
237a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
238ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    return Root == RHSRoot;
239ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  }
240ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
241a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach  /// isSubsetOf - Test whether this class is a subset of \arg RHS;
242ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  bool isSubsetOf(const ClassInfo &RHS) const {
243ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    // This is a subset of RHS if it is the same class...
244ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    if (this == &RHS)
245ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar      return true;
246ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
247ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    // ... or if any of its super classes are a subset of RHS.
248ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    for (std::vector<ClassInfo*>::const_iterator it = SuperClasses.begin(),
249ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar           ie = SuperClasses.end(); it != ie; ++it)
250ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar      if ((*it)->isSubsetOf(RHS))
251ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar        return true;
252ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
253ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    return false;
2545fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar  }
2555fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar
256606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar  /// operator< - Compare two classes.
257606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar  bool operator<(const ClassInfo &RHS) const {
258368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar    if (this == &RHS)
259368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar      return false;
260368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar
261ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    // Unrelated classes can be ordered by kind.
262ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    if (!isRelatedTo(RHS))
263606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar      return Kind < RHS.Kind;
264606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar
265606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar    switch (Kind) {
2666745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar    case Invalid:
267655b8de7b2ab773a977e0c524307e71354d8af29Craig Topper      llvm_unreachable("Invalid kind!");
268606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar
269606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar    default:
2707a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner      // This class precedes the RHS if it is a proper subset of the RHS.
271368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar      if (isSubsetOf(RHS))
2723472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands        return true;
273368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar      if (RHS.isSubsetOf(*this))
2743472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands        return false;
275368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar
276368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar      // Otherwise, order by name to ensure we have a total ordering.
277368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar      return ValueName < RHS.ValueName;
278606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar    }
279606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar  }
280a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar};
281a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
28222bc5c4184a497353e33195dd12541a4f08b008aChris Lattner/// MatchableInfo - Helper class for storing the necessary information for an
28322bc5c4184a497353e33195dd12541a4f08b008aChris Lattner/// instruction or alias which is capable of being matched.
28422bc5c4184a497353e33195dd12541a4f08b008aChris Lattnerstruct MatchableInfo {
285c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner  struct AsmOperand {
286d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    /// Token - This is the token that the operand came from.
287d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    StringRef Token;
288828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
289a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    /// The unique class instance this operand should match.
290a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    ClassInfo *Class;
291a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
292567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner    /// The operand name this is, if anything.
293567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner    StringRef SrcOpName;
294a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson
295a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    /// The suboperand index within SrcOpName, or -1 for the entire operand.
296a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    int SubOpIdx;
297828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
29863faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel    /// Register record if this token is singleton register.
29963faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel    Record *SingletonReg;
30063faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel
301f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach    explicit AsmOperand(StringRef T) : Token(T), Class(0), SubOpIdx(-1),
30211fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach                                       SingletonReg(0) {}
30320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  };
304828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
3051d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner  /// ResOperand - This represents a single operand in the result instruction
3061d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner  /// generated by the match.  In cases (like addressing modes) where a single
3071d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner  /// assembler operand expands to multiple MCOperands, this represents the
3081d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner  /// single assembler operand, not the MCOperand.
3091d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner  struct ResOperand {
3101d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner    enum {
3111d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      /// RenderAsmOperand - This represents an operand result that is
3121d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      /// generated by calling the render method on the assembly operand.  The
3131d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      /// corresponding AsmOperand is specified by AsmOperandNum.
3141d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      RenderAsmOperand,
315828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
3161d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      /// TiedOperand - This represents a result operand that is a duplicate of
3171d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      /// a previous result operand.
31898c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      TiedOperand,
319828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
32098c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      /// ImmOperand - This represents an immediate value that is dumped into
32198c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      /// the operand.
32290fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner      ImmOperand,
323828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
32490fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner      /// RegOperand - This represents a fixed register that is dumped in.
32590fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner      RegOperand
3261d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner    } Kind;
327828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
3281d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner    union {
3291d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      /// This is the operand # in the AsmOperands list that this should be
3301d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      /// copied from.
3311d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      unsigned AsmOperandNum;
332828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
3331d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      /// TiedOperandNum - This is the (earlier) result operand that should be
3341d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      /// copied from.
3351d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      unsigned TiedOperandNum;
336828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
33798c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      /// ImmVal - This is the immediate value added to the instruction.
33898c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      int64_t ImmVal;
339828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
34090fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner      /// Register - This is the register record.
34190fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner      Record *Register;
3421d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner    };
343828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
344a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    /// MINumOperands - The number of MCInst operands populated by this
345a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    /// operand.
346a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    unsigned MINumOperands;
347828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
348a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    static ResOperand getRenderedOp(unsigned AsmOpNum, unsigned NumOperands) {
3491d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      ResOperand X;
3501d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      X.Kind = RenderAsmOperand;
3511d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      X.AsmOperandNum = AsmOpNum;
352a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      X.MINumOperands = NumOperands;
3531d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      return X;
3541d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner    }
355828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
356a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    static ResOperand getTiedOp(unsigned TiedOperandNum) {
3571d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      ResOperand X;
3581d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      X.Kind = TiedOperand;
3591d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      X.TiedOperandNum = TiedOperandNum;
360a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      X.MINumOperands = 1;
3611d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      return X;
3621d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner    }
363828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
364a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    static ResOperand getImmOp(int64_t Val) {
36598c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      ResOperand X;
36698c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      X.Kind = ImmOperand;
36798c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      X.ImmVal = Val;
368a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      X.MINumOperands = 1;
36998c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      return X;
37098c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner    }
371828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
372a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    static ResOperand getRegOp(Record *Reg) {
37390fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner      ResOperand X;
37490fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner      X.Kind = RegOperand;
37590fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner      X.Register = Reg;
376a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      X.MINumOperands = 1;
37790fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner      return X;
37890fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner    }
3791d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner  };
38020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
38156315d319c104dc96187444e1e19711a1c801166Devang Patel  /// AsmVariantID - Target's assembly syntax variant no.
38256315d319c104dc96187444e1e19711a1c801166Devang Patel  int AsmVariantID;
38356315d319c104dc96187444e1e19711a1c801166Devang Patel
3843b5aec67ef174c74ff6620ddd71ad3b0cb39030cChris Lattner  /// TheDef - This is the definition of the instruction or InstAlias that this
3853b5aec67ef174c74ff6620ddd71ad3b0cb39030cChris Lattner  /// matchable came from.
3865bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner  Record *const TheDef;
387828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
388c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner  /// DefRec - This is the definition that it came from.
389c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner  PointerUnion<const CodeGenInstruction*, const CodeGenInstAlias*> DefRec;
390828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
391662e5a30e864e71111b885d3da3cdd184772035dChris Lattner  const CodeGenInstruction *getResultInst() const {
392662e5a30e864e71111b885d3da3cdd184772035dChris Lattner    if (DefRec.is<const CodeGenInstruction*>())
393662e5a30e864e71111b885d3da3cdd184772035dChris Lattner      return DefRec.get<const CodeGenInstruction*>();
394662e5a30e864e71111b885d3da3cdd184772035dChris Lattner    return DefRec.get<const CodeGenInstAlias*>()->ResultInst;
395662e5a30e864e71111b885d3da3cdd184772035dChris Lattner  }
396828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
3971d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner  /// ResOperands - This is the operand list that should be built for the result
3981d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner  /// MCInst.
399b423d18a00eed4968d6df7415449259b09b7d67eJim Grosbach  SmallVector<ResOperand, 8> ResOperands;
40020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
40120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  /// AsmString - The assembly string for this instruction (with variants
4023b5aec67ef174c74ff6620ddd71ad3b0cb39030cChris Lattner  /// removed), e.g. "movsx $src, $dst".
40320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  std::string AsmString;
40420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
405d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner  /// Mnemonic - This is the first token of the matched instruction, its
406d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner  /// mnemonic.
407d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner  StringRef Mnemonic;
408828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
4093116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner  /// AsmOperands - The textual operands that this instruction matches,
4103b5aec67ef174c74ff6620ddd71ad3b0cb39030cChris Lattner  /// annotated with a class and where in the OperandList they were defined.
4113b5aec67ef174c74ff6620ddd71ad3b0cb39030cChris Lattner  /// This directly corresponds to the tokenized AsmString after the mnemonic is
4123b5aec67ef174c74ff6620ddd71ad3b0cb39030cChris Lattner  /// removed.
413b423d18a00eed4968d6df7415449259b09b7d67eJim Grosbach  SmallVector<AsmOperand, 8> AsmOperands;
41420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
41554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  /// Predicates - The required subtarget features to match this instruction.
41654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  SmallVector<SubtargetFeatureInfo*, 4> RequiredFeatures;
41754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar
418b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar  /// ConversionFnKind - The enum value which is passed to the generated
419b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar  /// ConvertToMCInst to convert parsed operands into an MCInst for this
420b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar  /// function.
421b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar  std::string ConversionFnKind;
422828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
42322bc5c4184a497353e33195dd12541a4f08b008aChris Lattner  MatchableInfo(const CodeGenInstruction &CGI)
424f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach    : AsmVariantID(0), TheDef(CGI.TheDef), DefRec(&CGI),
42556315d319c104dc96187444e1e19711a1c801166Devang Patel      AsmString(CGI.AsmString) {
4265bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner  }
4275bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner
42822bc5c4184a497353e33195dd12541a4f08b008aChris Lattner  MatchableInfo(const CodeGenInstAlias *Alias)
429f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach    : AsmVariantID(0), TheDef(Alias->TheDef), DefRec(Alias),
43056315d319c104dc96187444e1e19711a1c801166Devang Patel      AsmString(Alias->AsmString) {
431c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner  }
432828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
433c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  // Two-operand aliases clone from the main matchable, but mark the second
434c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  // operand as a tied operand of the first for purposes of the assembler.
435c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  void formTwoOperandAlias(StringRef Constraint);
436c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach
4378caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  void initialize(const AsmMatcherInfo &Info,
438f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach                  SmallPtrSet<Record*, 16> &SingletonRegisters,
43911fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach                  int AsmVariantNo, std::string &RegisterPrefix);
440828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
4418caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  /// validate - Return true if this matchable is a valid thing to match against
44222bc5c4184a497353e33195dd12541a4f08b008aChris Lattner  /// and perform a bunch of validity checking.
4438caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  bool validate(StringRef CommentDelimiter, bool Hack) const;
444828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
445f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach  /// extractSingletonRegisterForAsmOperand - Extract singleton register,
44663faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel  /// if present, from specified token.
44763faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel  void
44863faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel  extractSingletonRegisterForAsmOperand(unsigned i, const AsmMatcherInfo &Info,
44963faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel                                        std::string &RegisterPrefix);
45020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
4518caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  /// findAsmOperand - Find the AsmOperand with the specified name and
452a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson  /// suboperand index.
4538caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  int findAsmOperand(StringRef N, int SubOpIdx) const {
454a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i)
455a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      if (N == AsmOperands[i].SrcOpName &&
456a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson          SubOpIdx == AsmOperands[i].SubOpIdx)
457a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson        return i;
458a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    return -1;
459a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson  }
460828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
4618caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  /// findAsmOperandNamed - Find the first AsmOperand with the specified name.
462a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson  /// This does not check the suboperand index.
4638caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  int findAsmOperandNamed(StringRef N) const {
464ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner    for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i)
465ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner      if (N == AsmOperands[i].SrcOpName)
466ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner        return i;
467ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner    return -1;
468ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner  }
469828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
4708caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  void buildInstructionResultOperands();
4718caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  void buildAliasResultOperands();
4721d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner
47322bc5c4184a497353e33195dd12541a4f08b008aChris Lattner  /// operator< - Compare two matchables.
47422bc5c4184a497353e33195dd12541a4f08b008aChris Lattner  bool operator<(const MatchableInfo &RHS) const {
475e206fcf0e9c7e79c7f42ff2151f3fb58cba70674Chris Lattner    // The primary comparator is the instruction mnemonic.
476d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    if (Mnemonic != RHS.Mnemonic)
477d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      return Mnemonic < RHS.Mnemonic;
478a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
4793116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner    if (AsmOperands.size() != RHS.AsmOperands.size())
4803116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner      return AsmOperands.size() < RHS.AsmOperands.size();
4812b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar
482db2ddb5dc57319eff249144f1d9a553a3278d2e0Daniel Dunbar    // Compare lexicographically by operand. The matcher validates that other
4838caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach    // orderings wouldn't be ambiguous using \see couldMatchAmbiguouslyWith().
4843116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner    for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) {
4853116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner      if (*AsmOperands[i].Class < *RHS.AsmOperands[i].Class)
4862b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar        return true;
4873116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner      if (*RHS.AsmOperands[i].Class < *AsmOperands[i].Class)
488db2ddb5dc57319eff249144f1d9a553a3278d2e0Daniel Dunbar        return false;
489db2ddb5dc57319eff249144f1d9a553a3278d2e0Daniel Dunbar    }
490db2ddb5dc57319eff249144f1d9a553a3278d2e0Daniel Dunbar
4912b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar    return false;
4922b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar  }
493606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar
4948caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  /// couldMatchAmbiguouslyWith - Check whether this matchable could
4952b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar  /// ambiguously match the same set of operands as \arg RHS (without being a
4962b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar  /// strictly superior match).
4978caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  bool couldMatchAmbiguouslyWith(const MatchableInfo &RHS) {
498e66b7ebfb426c7ed9bc911e9708321e2d8510b41Chris Lattner    // The primary comparator is the instruction mnemonic.
499d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    if (Mnemonic != RHS.Mnemonic)
500e66b7ebfb426c7ed9bc911e9708321e2d8510b41Chris Lattner      return false;
501828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
5022b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar    // The number of operands is unambiguous.
5033116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner    if (AsmOperands.size() != RHS.AsmOperands.size())
5042b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar      return false;
505606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar
5061402f0b2cac017ab997f71ab4909a2ccfea7be4bDaniel Dunbar    // Otherwise, make sure the ordering of the two instructions is unambiguous
5071402f0b2cac017ab997f71ab4909a2ccfea7be4bDaniel Dunbar    // by checking that either (a) a token or operand kind discriminates them,
5081402f0b2cac017ab997f71ab4909a2ccfea7be4bDaniel Dunbar    // or (b) the ordering among equivalent kinds is consistent.
5091402f0b2cac017ab997f71ab4909a2ccfea7be4bDaniel Dunbar
5102b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar    // Tokens and operand kinds are unambiguous (assuming a correct target
5112b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar    // specific parser).
5123116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner    for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i)
5133116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner      if (AsmOperands[i].Class->Kind != RHS.AsmOperands[i].Class->Kind ||
5143116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner          AsmOperands[i].Class->Kind == ClassInfo::Token)
5153116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner        if (*AsmOperands[i].Class < *RHS.AsmOperands[i].Class ||
5163116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner            *RHS.AsmOperands[i].Class < *AsmOperands[i].Class)
5172b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar          return false;
518a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
5192b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar    // Otherwise, this operand could commute if all operands are equivalent, or
5202b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar    // there is a pair of operands that compare less than and a pair that
5212b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar    // compare greater than.
5222b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar    bool HasLT = false, HasGT = false;
5233116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner    for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) {
5243116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner      if (*AsmOperands[i].Class < *RHS.AsmOperands[i].Class)
5252b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar        HasLT = true;
5263116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner      if (*RHS.AsmOperands[i].Class < *AsmOperands[i].Class)
5272b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar        HasGT = true;
5282b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar    }
529606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar
5302b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar    return !(HasLT ^ HasGT);
531606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar  }
532606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar
53320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  void dump();
534828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
535d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattnerprivate:
5368caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  void tokenizeAsmString(const AsmMatcherInfo &Info);
53720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar};
53820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
53954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar/// SubtargetFeatureInfo - Helper class for storing information on a subtarget
54054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar/// feature which participates in instruction matching.
54154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbarstruct SubtargetFeatureInfo {
54254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  /// \brief The predicate record for this feature.
54354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  Record *TheDef;
54454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar
54554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  /// \brief An unique index assigned to represent this feature.
54654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  unsigned Index;
54754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar
5480aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner  SubtargetFeatureInfo(Record *D, unsigned Idx) : TheDef(D), Index(Idx) {}
549828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
55054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  /// \brief The name of the enumerated constant identifying this feature.
5510aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner  std::string getEnumName() const {
5520aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner    return "Feature_" + TheDef->getName();
5530aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner  }
55454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar};
55554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar
556e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopesstruct OperandMatchEntry {
557e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  unsigned OperandMask;
558e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  MatchableInfo* MI;
559e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  ClassInfo *CI;
560e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
5618caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  static OperandMatchEntry create(MatchableInfo* mi, ClassInfo *ci,
562e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes                                  unsigned opMask) {
563e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    OperandMatchEntry X;
564e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    X.OperandMask = opMask;
565e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    X.CI = ci;
566e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    X.MI = mi;
567e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    return X;
568e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  }
569e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes};
570e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
571e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
572a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarclass AsmMatcherInfo {
573a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarpublic:
57467db883487fca3472fdde51e931657e22d4d0495Chris Lattner  /// Tracked Records
5759c6b60eb28d2717008f8d6ff52f7666ebc81113dChris Lattner  RecordKeeper &Records;
57667db883487fca3472fdde51e931657e22d4d0495Chris Lattner
57759fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar  /// The tablegen AsmParser record.
57859fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar  Record *AsmParser;
57959fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar
58002bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner  /// Target - The target information.
58102bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner  CodeGenTarget &Target;
58202bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner
583a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  /// The classes which are needed for matching.
584a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  std::vector<ClassInfo*> Classes;
585a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
58622bc5c4184a497353e33195dd12541a4f08b008aChris Lattner  /// The information on the matchables to match.
58722bc5c4184a497353e33195dd12541a4f08b008aChris Lattner  std::vector<MatchableInfo*> Matchables;
588a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
589e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  /// Info for custom matching operands by user defined methods.
590e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  std::vector<OperandMatchEntry> OperandMatchInfo;
591e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
592ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  /// Map of Register records to their class information.
593ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  std::map<Record*, ClassInfo*> RegisterClasses;
594ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
59554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  /// Map of Predicate records to their subtarget information.
59654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  std::map<Record*, SubtargetFeatureInfo*> SubtargetFeatures;
597828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
5984dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  /// Map of AsmOperandClass records to their class information.
5994dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  std::map<Record*, ClassInfo*> AsmOperandClasses;
6004dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach
601a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarprivate:
602a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  /// Map of token to class information which has already been constructed.
603a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  std::map<std::string, ClassInfo*> TokenClasses;
604a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
605ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  /// Map of RegisterClass records to their class information.
606ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  std::map<Record*, ClassInfo*> RegisterClassClasses;
607a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
608a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarprivate:
609a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  /// getTokenClass - Lookup or create the class for the given token.
610b8d6e98e566724f58344d275a4bd675249bb713aChris Lattner  ClassInfo *getTokenClass(StringRef Token);
611a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
612a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  /// getOperandClass - Lookup or create the class for the given operand.
613a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson  ClassInfo *getOperandClass(const CGIOperandList::OperandInfo &OI,
61448c1f84b104fd32109d809a56f5ebbf461c0910cJim Grosbach                             int SubOpIdx);
61548c1f84b104fd32109d809a56f5ebbf461c0910cJim Grosbach  ClassInfo *getOperandClass(Record *Rec, int SubOpIdx);
616a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
6178caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  /// buildRegisterClasses - Build the ClassInfo* instances for register
618ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  /// classes.
6198caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  void buildRegisterClasses(SmallPtrSet<Record*, 16> &SingletonRegisters);
620ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
6218caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  /// buildOperandClasses - Build the ClassInfo* instances for user defined
622ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  /// operand classes.
6238caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  void buildOperandClasses();
624ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
6258caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  void buildInstructionOperandReference(MatchableInfo *II, StringRef OpName,
626a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson                                        unsigned AsmOpIdx);
6278caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  void buildAliasOperandReference(MatchableInfo *II, StringRef OpName,
628c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner                                  MatchableInfo::AsmOperand &Op);
629828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
630a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarpublic:
631828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson  AsmMatcherInfo(Record *AsmParser,
632828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson                 CodeGenTarget &Target,
6339c6b60eb28d2717008f8d6ff52f7666ebc81113dChris Lattner                 RecordKeeper &Records);
63459fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar
6358caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  /// buildInfo - Construct the various tables used during matching.
6368caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  void buildInfo();
637828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
6388caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  /// buildOperandMatchInfo - Build the necessary information to handle user
639e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  /// defined operand parsing methods.
6408caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  void buildOperandMatchInfo();
641e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
6426fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner  /// getSubtargetFeature - Lookup or create the subtarget feature info for the
6436fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner  /// given operand.
6446fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner  SubtargetFeatureInfo *getSubtargetFeature(Record *Def) const {
6456fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner    assert(Def->isSubClassOf("Predicate") && "Invalid predicate type!");
6466fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner    std::map<Record*, SubtargetFeatureInfo*>::const_iterator I =
6476fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner      SubtargetFeatures.find(Def);
6486fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner    return I == SubtargetFeatures.end() ? 0 : I->second;
6496fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner  }
65067db883487fca3472fdde51e931657e22d4d0495Chris Lattner
6519c6b60eb28d2717008f8d6ff52f7666ebc81113dChris Lattner  RecordKeeper &getRecords() const {
6529c6b60eb28d2717008f8d6ff52f7666ebc81113dChris Lattner    return Records;
65367db883487fca3472fdde51e931657e22d4d0495Chris Lattner  }
654a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar};
655a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
6566f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End anonymous namespace
65720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
65822bc5c4184a497353e33195dd12541a4f08b008aChris Lattnervoid MatchableInfo::dump() {
6595abd1ebcb380664ae5010395b217e01f7190046cChris Lattner  errs() << TheDef->getName() << " -- " << "flattened:\"" << AsmString <<"\"\n";
660a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
6613116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner  for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) {
662c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner    AsmOperand &Op = AsmOperands[i];
6636745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar    errs() << "  op[" << i << "] = " << Op.Class->ClassName << " - ";
6640bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner    errs() << '\"' << Op.Token << "\"\n";
66520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
66620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar}
667a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
668c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbachstatic std::pair<StringRef, StringRef>
669c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim GrosbachparseTwoOperandConstraint(StringRef S, SMLoc Loc) {
670c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  // Split via the '='.
671c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  std::pair<StringRef, StringRef> Ops = S.split('=');
672c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  if (Ops.second == "")
673c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach    throw TGError(Loc, "missing '=' in two-operand alias constraint");
674c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  // Trim whitespace and the leading '$' on the operand names.
675c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  size_t start = Ops.first.find_first_of('$');
676c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  if (start == std::string::npos)
677c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach    throw TGError(Loc, "expected '$' prefix on asm operand name");
678c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  Ops.first = Ops.first.slice(start + 1, std::string::npos);
679c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  size_t end = Ops.first.find_last_of(" \t");
680c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  Ops.first = Ops.first.slice(0, end);
681c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  // Now the second operand.
682c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  start = Ops.second.find_first_of('$');
683c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  if (start == std::string::npos)
684c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach    throw TGError(Loc, "expected '$' prefix on asm operand name");
685c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  Ops.second = Ops.second.slice(start + 1, std::string::npos);
686c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  end = Ops.second.find_last_of(" \t");
687c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  Ops.first = Ops.first.slice(0, end);
688c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  return Ops;
689c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach}
690c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach
691c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbachvoid MatchableInfo::formTwoOperandAlias(StringRef Constraint) {
692c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  // Figure out which operands are aliased and mark them as tied.
693c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  std::pair<StringRef, StringRef> Ops =
694c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach    parseTwoOperandConstraint(Constraint, TheDef->getLoc());
695c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach
696c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  // Find the AsmOperands that refer to the operands we're aliasing.
697c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  int SrcAsmOperand = findAsmOperandNamed(Ops.first);
698c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  int DstAsmOperand = findAsmOperandNamed(Ops.second);
699c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  if (SrcAsmOperand == -1)
700c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach    throw TGError(TheDef->getLoc(),
701c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach                  "unknown source two-operand alias operand '" +
702c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach                  Ops.first.str() + "'.");
703c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  if (DstAsmOperand == -1)
704c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach    throw TGError(TheDef->getLoc(),
705c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach                  "unknown destination two-operand alias operand '" +
706c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach                  Ops.second.str() + "'.");
707c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach
708c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  // Find the ResOperand that refers to the operand we're aliasing away
709c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  // and update it to refer to the combined operand instead.
710c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  for (unsigned i = 0, e = ResOperands.size(); i != e; ++i) {
711c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach    ResOperand &Op = ResOperands[i];
712c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach    if (Op.Kind == ResOperand::RenderAsmOperand &&
713c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach        Op.AsmOperandNum == (unsigned)SrcAsmOperand) {
714c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach      Op.AsmOperandNum = DstAsmOperand;
715c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach      break;
716c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach    }
717c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  }
718c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  // Remove the AsmOperand for the alias operand.
719c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  AsmOperands.erase(AsmOperands.begin() + SrcAsmOperand);
720c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  // Adjust the ResOperand references to any AsmOperands that followed
721c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  // the one we just deleted.
722c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  for (unsigned i = 0, e = ResOperands.size(); i != e; ++i) {
723c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach    ResOperand &Op = ResOperands[i];
724c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach    switch(Op.Kind) {
725c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach    default:
726c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach      // Nothing to do for operands that don't reference AsmOperands.
727c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach      break;
728c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach    case ResOperand::RenderAsmOperand:
729c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach      if (Op.AsmOperandNum > (unsigned)SrcAsmOperand)
730c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach        --Op.AsmOperandNum;
731c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach      break;
732c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach    case ResOperand::TiedOperand:
733c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach      if (Op.TiedOperandNum > (unsigned)SrcAsmOperand)
734c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach        --Op.TiedOperandNum;
735c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach      break;
736c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach    }
737c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  }
738c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach}
739c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach
7408caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachvoid MatchableInfo::initialize(const AsmMatcherInfo &Info,
74163faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel                               SmallPtrSet<Record*, 16> &SingletonRegisters,
74263faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel                               int AsmVariantNo, std::string &RegisterPrefix) {
74356315d319c104dc96187444e1e19711a1c801166Devang Patel  AsmVariantID = AsmVariantNo;
744f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach  AsmString =
74563faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel    CodeGenInstruction::FlattenAsmStringVariants(AsmString, AsmVariantNo);
746828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
7478caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  tokenizeAsmString(Info);
748828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
749c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner  // Compute the require features.
750c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner  std::vector<Record*> Predicates =TheDef->getValueAsListOfDefs("Predicates");
751c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner  for (unsigned i = 0, e = Predicates.size(); i != e; ++i)
752c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner    if (SubtargetFeatureInfo *Feature =
753c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner        Info.getSubtargetFeature(Predicates[i]))
754c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner      RequiredFeatures.push_back(Feature);
755828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
756c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner  // Collect singleton registers, if used.
757d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner  for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) {
75863faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel    extractSingletonRegisterForAsmOperand(i, Info, RegisterPrefix);
75963faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel    if (Record *Reg = AsmOperands[i].SingletonReg)
760c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner      SingletonRegisters.insert(Reg);
761c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner  }
762c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner}
763c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner
7648caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach/// tokenizeAsmString - Tokenize a simplified assembly string.
7658caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachvoid MatchableInfo::tokenizeAsmString(const AsmMatcherInfo &Info) {
766d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner  StringRef String = AsmString;
767d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner  unsigned Prev = 0;
768d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner  bool InTok = true;
769d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner  for (unsigned i = 0, e = String.size(); i != e; ++i) {
770d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    switch (String[i]) {
771d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    case '[':
772d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    case ']':
773d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    case '*':
774d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    case '!':
775d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    case ' ':
776d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    case '\t':
777d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    case ',':
778d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      if (InTok) {
779c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner        AsmOperands.push_back(AsmOperand(String.slice(Prev, i)));
780d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner        InTok = false;
781d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      }
782d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      if (!isspace(String[i]) && String[i] != ',')
783c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner        AsmOperands.push_back(AsmOperand(String.substr(i, 1)));
784d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      Prev = i + 1;
785d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      break;
786d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner
787d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    case '\\':
788d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      if (InTok) {
789c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner        AsmOperands.push_back(AsmOperand(String.slice(Prev, i)));
790d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner        InTok = false;
791d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      }
792d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      ++i;
793d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      assert(i != String.size() && "Invalid quoted character");
794c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner      AsmOperands.push_back(AsmOperand(String.substr(i, 1)));
795d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      Prev = i + 1;
796d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      break;
797d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner
798d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    case '$': {
7997ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner      if (InTok) {
8007ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner        AsmOperands.push_back(AsmOperand(String.slice(Prev, i)));
8017ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner        InTok = false;
8027ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner      }
803828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
804d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      // If this isn't "${", treat like a normal token.
805d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      if (i + 1 == String.size() || String[i + 1] != '{') {
806d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner        Prev = i;
807d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner        break;
808d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      }
809d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner
810d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      StringRef::iterator End = std::find(String.begin() + i, String.end(),'}');
811d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      assert(End != String.end() && "Missing brace in operand reference!");
812d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      size_t EndPos = End - String.begin();
813c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner      AsmOperands.push_back(AsmOperand(String.slice(i, EndPos+1)));
814d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      Prev = EndPos + 1;
815d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      i = EndPos;
816d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      break;
817d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    }
818d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner
819d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    case '.':
820d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      if (InTok)
821c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner        AsmOperands.push_back(AsmOperand(String.slice(Prev, i)));
822d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      Prev = i;
823d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      InTok = true;
824d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      break;
825d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner
826d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    default:
827d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      InTok = true;
828d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    }
829d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner  }
830d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner  if (InTok && Prev != String.size())
831c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner    AsmOperands.push_back(AsmOperand(String.substr(Prev)));
832828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
833d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner  // The first token of the instruction is the mnemonic, which must be a
834d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner  // simple string, not a $foo variable or a singleton register.
8354a2242cea0e9fdb36276807b1d4ddd7cd1a15bd4Jim Grosbach  if (AsmOperands.empty())
8364a2242cea0e9fdb36276807b1d4ddd7cd1a15bd4Jim Grosbach    throw TGError(TheDef->getLoc(),
8374a2242cea0e9fdb36276807b1d4ddd7cd1a15bd4Jim Grosbach                  "Instruction '" + TheDef->getName() + "' has no tokens");
838d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner  Mnemonic = AsmOperands[0].Token;
8398e27c9615938298bd03a7884964a0f5e0e80542dJim Grosbach  if (Mnemonic.empty())
8408e27c9615938298bd03a7884964a0f5e0e80542dJim Grosbach    throw TGError(TheDef->getLoc(),
8418e27c9615938298bd03a7884964a0f5e0e80542dJim Grosbach                  "Missing instruction mnemonic");
84263faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel  // FIXME : Check and raise an error if it is a register.
843b78307fc58025713fd98c8414fa8f29720f37a76Devang Patel  if (Mnemonic[0] == '$')
844d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    throw TGError(TheDef->getLoc(),
845d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner                  "Invalid instruction mnemonic '" + Mnemonic.str() + "'!");
846828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
847d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner  // Remove the first operand, it is tracked in the mnemonic field.
848d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner  AsmOperands.erase(AsmOperands.begin());
849d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner}
850d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner
8518caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachbool MatchableInfo::validate(StringRef CommentDelimiter, bool Hack) const {
85222bc5c4184a497353e33195dd12541a4f08b008aChris Lattner  // Reject matchables with no .s string.
8535bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner  if (AsmString.empty())
8545bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner    throw TGError(TheDef->getLoc(), "instruction with empty asm string");
855828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
85622bc5c4184a497353e33195dd12541a4f08b008aChris Lattner  // Reject any matchables with a newline in them, they should be marked
8575bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner  // isCodeGenOnly if they are pseudo instructions.
8585bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner  if (AsmString.find('\n') != std::string::npos)
8595bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner    throw TGError(TheDef->getLoc(),
8605bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner                  "multiline instruction is not valid for the asmparser, "
8615bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner                  "mark it isCodeGenOnly");
862828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
8634164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner  // Remove comments from the asm string.  We know that the asmstring only
8644164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner  // has one line.
8654164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner  if (!CommentDelimiter.empty() &&
8664164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner      StringRef(AsmString).find(CommentDelimiter) != StringRef::npos)
8674164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner    throw TGError(TheDef->getLoc(),
8684164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner                  "asmstring for instruction has comment character in it, "
8694164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner                  "mark it isCodeGenOnly");
870828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
87122bc5c4184a497353e33195dd12541a4f08b008aChris Lattner  // Reject matchables with operand modifiers, these aren't something we can
872906bc368bc0fe18682edc0743ada41f62e436383Bob Wilson  // handle, the target should be refactored to use operands instead of
873906bc368bc0fe18682edc0743ada41f62e436383Bob Wilson  // modifiers.
8745bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner  //
8755bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner  // Also, check for instructions which reference the operand multiple times;
8765bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner  // this implies a constraint we would not honor.
8775bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner  std::set<std::string> OperandNames;
878d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner  for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) {
879d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    StringRef Tok = AsmOperands[i].Token;
880d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    if (Tok[0] == '$' && Tok.find(':') != StringRef::npos)
8815bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner      throw TGError(TheDef->getLoc(),
882d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner                    "matchable with operand modifier '" + Tok.str() +
8835bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner                    "' not supported by asm matcher.  Mark isCodeGenOnly!");
884828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
88522bc5c4184a497353e33195dd12541a4f08b008aChris Lattner    // Verify that any operand is only mentioned once.
886d51257a4368d52e2340073bc7ccd83f3c3f1c04dChris Lattner    // We reject aliases and ignore instructions for now.
887d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    if (Tok[0] == '$' && !OperandNames.insert(Tok).second) {
88822bc5c4184a497353e33195dd12541a4f08b008aChris Lattner      if (!Hack)
88922bc5c4184a497353e33195dd12541a4f08b008aChris Lattner        throw TGError(TheDef->getLoc(),
890d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner                      "ERROR: matchable with tied operand '" + Tok.str() +
89122bc5c4184a497353e33195dd12541a4f08b008aChris Lattner                      "' can never be matched!");
89222bc5c4184a497353e33195dd12541a4f08b008aChris Lattner      // FIXME: Should reject these.  The ARM backend hits this with $lane in a
89322bc5c4184a497353e33195dd12541a4f08b008aChris Lattner      // bunch of instructions.  It is unclear what the right answer is.
8945bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner      DEBUG({
8955abd1ebcb380664ae5010395b217e01f7190046cChris Lattner        errs() << "warning: '" << TheDef->getName() << "': "
89622bc5c4184a497353e33195dd12541a4f08b008aChris Lattner               << "ignoring instruction with tied operand '"
897d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner               << Tok.str() << "'\n";
8985bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner      });
8995bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner      return false;
9005bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner    }
9015bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner  }
902828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
9035bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner  return true;
9045bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner}
9055bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner
906f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach/// extractSingletonRegisterForAsmOperand - Extract singleton register,
907d06b01c038e00f6af50a1b6d4c71389037e00212Devang Patel/// if present, from specified token.
90863faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patelvoid MatchableInfo::
909f35307ceac57194094f207f0920fbd22231f5331Jim GrosbachextractSingletonRegisterForAsmOperand(unsigned OperandNo,
910d06b01c038e00f6af50a1b6d4c71389037e00212Devang Patel                                      const AsmMatcherInfo &Info,
91111fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach                                      std::string &RegisterPrefix) {
912d06b01c038e00f6af50a1b6d4c71389037e00212Devang Patel  StringRef Tok = AsmOperands[OperandNo].Token;
91363faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel  if (RegisterPrefix.empty()) {
914d06b01c038e00f6af50a1b6d4c71389037e00212Devang Patel    std::string LoweredTok = Tok.lower();
915d06b01c038e00f6af50a1b6d4c71389037e00212Devang Patel    if (const CodeGenRegister *Reg = Info.Target.getRegisterByName(LoweredTok))
916d06b01c038e00f6af50a1b6d4c71389037e00212Devang Patel      AsmOperands[OperandNo].SingletonReg = Reg->TheDef;
91763faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel    return;
918f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach  }
91963faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel
92063faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel  if (!Tok.startswith(RegisterPrefix))
92163faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel    return;
922828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
92363faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel  StringRef RegName = Tok.substr(RegisterPrefix.size());
924ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner  if (const CodeGenRegister *Reg = Info.Target.getRegisterByName(RegName))
925d06b01c038e00f6af50a1b6d4c71389037e00212Devang Patel    AsmOperands[OperandNo].SingletonReg = Reg->TheDef;
926828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
9271de88235781c45c0afc0c7500d65b59775196c4cChris Lattner  // If there is no register prefix (i.e. "%" in "%eax"), then this may
9281de88235781c45c0afc0c7500d65b59775196c4cChris Lattner  // be some random non-register token, just ignore it.
92963faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel  return;
93002bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner}
93102bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner
932b8d6e98e566724f58344d275a4bd675249bb713aChris Lattnerstatic std::string getEnumNameForToken(StringRef Str) {
933a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  std::string Res;
934a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
935a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  for (StringRef::iterator it = Str.begin(), ie = Str.end(); it != ie; ++it) {
936a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    switch (*it) {
937a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    case '*': Res += "_STAR_"; break;
938a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    case '%': Res += "_PCT_"; break;
939a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    case ':': Res += "_COLON_"; break;
940bd9c77bc9ad384d046a7967d160ad96f61916d9dBill Wendling    case '!': Res += "_EXCLAIM_"; break;
9410ef755d9051a79680326d6144a2401660fc93e57Bill Wendling    case '.': Res += "_DOT_"; break;
942a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    default:
94339ee036f407bd0c94cb993cf9b97348843cfafa4Chris Lattner      if (isalnum(*it))
944a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar        Res += *it;
94539ee036f407bd0c94cb993cf9b97348843cfafa4Chris Lattner      else
946a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar        Res += "_" + utostr((unsigned) *it) + "_";
947a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    }
948a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  }
94920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
950a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  return Res;
951a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar}
952a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
953b8d6e98e566724f58344d275a4bd675249bb713aChris LattnerClassInfo *AsmMatcherInfo::getTokenClass(StringRef Token) {
954a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  ClassInfo *&Entry = TokenClasses[Token];
955a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
956a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  if (!Entry) {
957a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    Entry = new ClassInfo();
958a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    Entry->Kind = ClassInfo::Token;
9596745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar    Entry->ClassName = "Token";
960a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    Entry->Name = "MCK_" + getEnumNameForToken(Token);
961a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    Entry->ValueName = Token;
962a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    Entry->PredicateMethod = "<invalid>";
963a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    Entry->RenderMethod = "<invalid>";
964e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    Entry->ParserMethod = "";
9654dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach    Entry->DiagnosticType = "";
966a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    Classes.push_back(Entry);
967a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  }
968a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
969a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  return Entry;
970a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar}
971a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
972a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel DunbarClassInfo *
973a49c7dfb360154070c08b8eb94ad31711d1babaeBob WilsonAsmMatcherInfo::getOperandClass(const CGIOperandList::OperandInfo &OI,
974a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson                                int SubOpIdx) {
975a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson  Record *Rec = OI.Rec;
976a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson  if (SubOpIdx != -1)
97705bce0beee87512e52428d4b80f5a8e79a949576David Greene    Rec = dynamic_cast<DefInit*>(OI.MIOperandInfo->getArg(SubOpIdx))->getDef();
97848c1f84b104fd32109d809a56f5ebbf461c0910cJim Grosbach  return getOperandClass(Rec, SubOpIdx);
97948c1f84b104fd32109d809a56f5ebbf461c0910cJim Grosbach}
980a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson
98148c1f84b104fd32109d809a56f5ebbf461c0910cJim GrosbachClassInfo *
98248c1f84b104fd32109d809a56f5ebbf461c0910cJim GrosbachAsmMatcherInfo::getOperandClass(Record *Rec, int SubOpIdx) {
983bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson  if (Rec->isSubClassOf("RegisterOperand")) {
984bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson    // RegisterOperand may have an associated ParserMatchClass. If it does,
985bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson    // use it, else just fall back to the underlying register class.
986bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson    const RecordVal *R = Rec->getValue("ParserMatchClass");
987bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson    if (R == 0 || R->getValue() == 0)
988bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson      throw "Record `" + Rec->getName() +
989bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson        "' does not have a ParserMatchClass!\n";
990bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson
99105bce0beee87512e52428d4b80f5a8e79a949576David Greene    if (DefInit *DI= dynamic_cast<DefInit*>(R->getValue())) {
992bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson      Record *MatchClass = DI->getDef();
993bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson      if (ClassInfo *CI = AsmOperandClasses[MatchClass])
994bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson        return CI;
995bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson    }
996bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson
997bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson    // No custom match class. Just use the register class.
998bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson    Record *ClassRec = Rec->getValueAsDef("RegClass");
999bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson    if (!ClassRec)
1000bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson      throw TGError(Rec->getLoc(), "RegisterOperand `" + Rec->getName() +
1001bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson                    "' has no associated register class!\n");
1002bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson    if (ClassInfo *CI = RegisterClassClasses[ClassRec])
1003bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson      return CI;
1004bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson    throw TGError(Rec->getLoc(), "register class has no class info!");
1005bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson  }
1006bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson
1007bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson
1008a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson  if (Rec->isSubClassOf("RegisterClass")) {
1009a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    if (ClassInfo *CI = RegisterClassClasses[Rec])
1010ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner      return CI;
1011a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    throw TGError(Rec->getLoc(), "register class has no class info!");
1012ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  }
1013338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar
1014a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson  assert(Rec->isSubClassOf("Operand") && "Unexpected operand!");
1015a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson  Record *MatchClass = Rec->getValueAsDef("ParserMatchClass");
1016ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner  if (ClassInfo *CI = AsmOperandClasses[MatchClass])
1017ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner    return CI;
1018a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
1019a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson  throw TGError(Rec->getLoc(), "operand has no match class!");
1020338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar}
1021338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar
10221de88235781c45c0afc0c7500d65b59775196c4cChris Lattnervoid AsmMatcherInfo::
10238caecdea56c830f3fc80ed67fff121c83de0e364Jim GrosbachbuildRegisterClasses(SmallPtrSet<Record*, 16> &SingletonRegisters) {
1024abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen  const std::vector<CodeGenRegister*> &Registers =
1025abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen    Target.getRegBank().getRegisters();
102629f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen  ArrayRef<CodeGenRegisterClass*> RegClassList =
102729f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen    Target.getRegBank().getRegClasses();
1028338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar
1029ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  // The register sets used for matching.
1030ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  std::set< std::set<Record*> > RegisterSets;
1031ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
1032a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach  // Gather the defined sets.
103329f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen  for (ArrayRef<CodeGenRegisterClass*>::const_iterator it =
1034ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner       RegClassList.begin(), ie = RegClassList.end(); it != ie; ++it)
103529f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen    RegisterSets.insert(std::set<Record*>(
103629f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen        (*it)->getOrder().begin(), (*it)->getOrder().end()));
10371095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar
10381095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar  // Add any required singleton sets.
10391de88235781c45c0afc0c7500d65b59775196c4cChris Lattner  for (SmallPtrSet<Record*, 16>::iterator it = SingletonRegisters.begin(),
10401de88235781c45c0afc0c7500d65b59775196c4cChris Lattner       ie = SingletonRegisters.end(); it != ie; ++it) {
10411de88235781c45c0afc0c7500d65b59775196c4cChris Lattner    Record *Rec = *it;
10421de88235781c45c0afc0c7500d65b59775196c4cChris Lattner    RegisterSets.insert(std::set<Record*>(&Rec, &Rec + 1));
10431de88235781c45c0afc0c7500d65b59775196c4cChris Lattner  }
1044a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
1045ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  // Introduce derived sets where necessary (when a register does not determine
1046ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  // a unique register set class), and build the mapping of registers to the set
1047ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  // they should classify to.
1048ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  std::map<Record*, std::set<Record*> > RegisterMap;
1049abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen  for (std::vector<CodeGenRegister*>::const_iterator it = Registers.begin(),
1050ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar         ie = Registers.end(); it != ie; ++it) {
1051abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen    const CodeGenRegister &CGR = **it;
1052ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    // Compute the intersection of all sets containing this register.
1053ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    std::set<Record*> ContainingSet;
1054a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
1055ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    for (std::set< std::set<Record*> >::iterator it = RegisterSets.begin(),
1056ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar           ie = RegisterSets.end(); it != ie; ++it) {
1057ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar      if (!it->count(CGR.TheDef))
1058ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar        continue;
1059ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
1060ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar      if (ContainingSet.empty()) {
1061ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar        ContainingSet = *it;
1062ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner        continue;
1063ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar      }
1064828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
1065ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner      std::set<Record*> Tmp;
1066ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner      std::swap(Tmp, ContainingSet);
1067ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner      std::insert_iterator< std::set<Record*> > II(ContainingSet,
1068ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner                                                   ContainingSet.begin());
1069ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner      std::set_intersection(Tmp.begin(), Tmp.end(), it->begin(), it->end(), II);
1070ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    }
1071ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
1072ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    if (!ContainingSet.empty()) {
1073ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar      RegisterSets.insert(ContainingSet);
1074ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar      RegisterMap.insert(std::make_pair(CGR.TheDef, ContainingSet));
1075ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    }
1076ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  }
1077ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
1078ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  // Construct the register classes.
1079ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  std::map<std::set<Record*>, ClassInfo*> RegisterSetClasses;
1080ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  unsigned Index = 0;
1081ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  for (std::set< std::set<Record*> >::iterator it = RegisterSets.begin(),
1082ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar         ie = RegisterSets.end(); it != ie; ++it, ++Index) {
1083ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    ClassInfo *CI = new ClassInfo();
1084ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    CI->Kind = ClassInfo::RegisterClass0 + Index;
1085ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    CI->ClassName = "Reg" + utostr(Index);
1086ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    CI->Name = "MCK_Reg" + utostr(Index);
1087ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    CI->ValueName = "";
1088ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    CI->PredicateMethod = ""; // unused
1089ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    CI->RenderMethod = "addRegOperands";
10908409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar    CI->Registers = *it;
10914dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach    // FIXME: diagnostic type.
10924dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach    CI->DiagnosticType = "";
1093ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    Classes.push_back(CI);
1094ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    RegisterSetClasses.insert(std::make_pair(*it, CI));
1095ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  }
1096ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
1097ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  // Find the superclasses; we could compute only the subgroup lattice edges,
1098ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  // but there isn't really a point.
1099ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  for (std::set< std::set<Record*> >::iterator it = RegisterSets.begin(),
1100ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar         ie = RegisterSets.end(); it != ie; ++it) {
1101ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    ClassInfo *CI = RegisterSetClasses[*it];
1102ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    for (std::set< std::set<Record*> >::iterator it2 = RegisterSets.begin(),
1103ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar           ie2 = RegisterSets.end(); it2 != ie2; ++it2)
1104a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach      if (*it != *it2 &&
1105ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar          std::includes(it2->begin(), it2->end(), it->begin(), it->end()))
1106ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar        CI->SuperClasses.push_back(RegisterSetClasses[*it2]);
1107ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  }
1108ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
1109ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  // Name the register classes which correspond to a user defined RegisterClass.
111029f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen  for (ArrayRef<CodeGenRegisterClass*>::const_iterator
1111ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner       it = RegClassList.begin(), ie = RegClassList.end(); it != ie; ++it) {
111229f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen    const CodeGenRegisterClass &RC = **it;
11136fea31e7300fe012b0b2984d6bc0338d02b054d3Jakob Stoklund Olesen    // Def will be NULL for non-user defined register classes.
11146fea31e7300fe012b0b2984d6bc0338d02b054d3Jakob Stoklund Olesen    Record *Def = RC.getDef();
11156fea31e7300fe012b0b2984d6bc0338d02b054d3Jakob Stoklund Olesen    if (!Def)
11166fea31e7300fe012b0b2984d6bc0338d02b054d3Jakob Stoklund Olesen      continue;
111729f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen    ClassInfo *CI = RegisterSetClasses[std::set<Record*>(RC.getOrder().begin(),
111829f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen                                                         RC.getOrder().end())];
1119ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    if (CI->ValueName.empty()) {
112029f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen      CI->ClassName = RC.getName();
112129f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen      CI->Name = "MCK_" + RC.getName();
112229f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen      CI->ValueName = RC.getName();
1123ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    } else
112429f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen      CI->ValueName = CI->ValueName + "," + RC.getName();
1125ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
11266fea31e7300fe012b0b2984d6bc0338d02b054d3Jakob Stoklund Olesen    RegisterClassClasses.insert(std::make_pair(Def, CI));
1127ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  }
1128ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
1129ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  // Populate the map for individual registers.
1130ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  for (std::map<Record*, std::set<Record*> >::iterator it = RegisterMap.begin(),
1131ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar         ie = RegisterMap.end(); it != ie; ++it)
1132ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner    RegisterClasses[it->first] = RegisterSetClasses[it->second];
11331095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar
11341095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar  // Name the register classes which correspond to singleton registers.
11351de88235781c45c0afc0c7500d65b59775196c4cChris Lattner  for (SmallPtrSet<Record*, 16>::iterator it = SingletonRegisters.begin(),
11361de88235781c45c0afc0c7500d65b59775196c4cChris Lattner         ie = SingletonRegisters.end(); it != ie; ++it) {
11371de88235781c45c0afc0c7500d65b59775196c4cChris Lattner    Record *Rec = *it;
1138ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner    ClassInfo *CI = RegisterClasses[Rec];
11391de88235781c45c0afc0c7500d65b59775196c4cChris Lattner    assert(CI && "Missing singleton register class info!");
11401de88235781c45c0afc0c7500d65b59775196c4cChris Lattner
11411de88235781c45c0afc0c7500d65b59775196c4cChris Lattner    if (CI->ValueName.empty()) {
11421de88235781c45c0afc0c7500d65b59775196c4cChris Lattner      CI->ClassName = Rec->getName();
11431de88235781c45c0afc0c7500d65b59775196c4cChris Lattner      CI->Name = "MCK_" + Rec->getName();
11441de88235781c45c0afc0c7500d65b59775196c4cChris Lattner      CI->ValueName = Rec->getName();
11451de88235781c45c0afc0c7500d65b59775196c4cChris Lattner    } else
11461de88235781c45c0afc0c7500d65b59775196c4cChris Lattner      CI->ValueName = CI->ValueName + "," + Rec->getName();
11471095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar  }
1148ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar}
1149ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
11508caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachvoid AsmMatcherInfo::buildOperandClasses() {
1151e66b7ebfb426c7ed9bc911e9708321e2d8510b41Chris Lattner  std::vector<Record*> AsmOperands =
1152e66b7ebfb426c7ed9bc911e9708321e2d8510b41Chris Lattner    Records.getAllDerivedDefinitions("AsmOperandClass");
1153a2f5e00347641d1b46ce4f65bf9378fecce9be14Daniel Dunbar
1154a2f5e00347641d1b46ce4f65bf9378fecce9be14Daniel Dunbar  // Pre-populate AsmOperandClasses map.
1155a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach  for (std::vector<Record*>::iterator it = AsmOperands.begin(),
1156a2f5e00347641d1b46ce4f65bf9378fecce9be14Daniel Dunbar         ie = AsmOperands.end(); it != ie; ++it)
1157a2f5e00347641d1b46ce4f65bf9378fecce9be14Daniel Dunbar    AsmOperandClasses[*it] = new ClassInfo();
1158a2f5e00347641d1b46ce4f65bf9378fecce9be14Daniel Dunbar
1159338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar  unsigned Index = 0;
1160a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach  for (std::vector<Record*>::iterator it = AsmOperands.begin(),
1161338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar         ie = AsmOperands.end(); it != ie; ++it, ++Index) {
1162a2f5e00347641d1b46ce4f65bf9378fecce9be14Daniel Dunbar    ClassInfo *CI = AsmOperandClasses[*it];
1163338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar    CI->Kind = ClassInfo::UserClass0 + Index;
1164338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar
116505bce0beee87512e52428d4b80f5a8e79a949576David Greene    ListInit *Supers = (*it)->getValueAsListInit("SuperClasses");
116654ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar    for (unsigned i = 0, e = Supers->getSize(); i != e; ++i) {
116705bce0beee87512e52428d4b80f5a8e79a949576David Greene      DefInit *DI = dynamic_cast<DefInit*>(Supers->getElement(i));
116854ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar      if (!DI) {
116954ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar        PrintError((*it)->getLoc(), "Invalid super class reference!");
117054ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar        continue;
117154ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar      }
117254ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar
1173ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar      ClassInfo *SC = AsmOperandClasses[DI->getDef()];
1174ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar      if (!SC)
1175338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar        PrintError((*it)->getLoc(), "Invalid super class reference!");
1176ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar      else
1177ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar        CI->SuperClasses.push_back(SC);
1178a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    }
1179338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar    CI->ClassName = (*it)->getValueAsString("Name");
1180338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar    CI->Name = "MCK_" + CI->ClassName;
1181338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar    CI->ValueName = (*it)->getName();
11825c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar
11835c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar    // Get or construct the predicate method name.
118405bce0beee87512e52428d4b80f5a8e79a949576David Greene    Init *PMName = (*it)->getValueInit("PredicateMethod");
118505bce0beee87512e52428d4b80f5a8e79a949576David Greene    if (StringInit *SI = dynamic_cast<StringInit*>(PMName)) {
11865c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar      CI->PredicateMethod = SI->getValue();
11875c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar    } else {
118805bce0beee87512e52428d4b80f5a8e79a949576David Greene      assert(dynamic_cast<UnsetInit*>(PMName) &&
11895c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar             "Unexpected PredicateMethod field!");
11905c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar      CI->PredicateMethod = "is" + CI->ClassName;
11915c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar    }
11925c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar
11935c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar    // Get or construct the render method name.
119405bce0beee87512e52428d4b80f5a8e79a949576David Greene    Init *RMName = (*it)->getValueInit("RenderMethod");
119505bce0beee87512e52428d4b80f5a8e79a949576David Greene    if (StringInit *SI = dynamic_cast<StringInit*>(RMName)) {
11965c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar      CI->RenderMethod = SI->getValue();
11975c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar    } else {
119805bce0beee87512e52428d4b80f5a8e79a949576David Greene      assert(dynamic_cast<UnsetInit*>(RMName) &&
11995c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar             "Unexpected RenderMethod field!");
12005c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar      CI->RenderMethod = "add" + CI->ClassName + "Operands";
12015c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar    }
12025c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar
1203e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    // Get the parse method name or leave it as empty.
120405bce0beee87512e52428d4b80f5a8e79a949576David Greene    Init *PRMName = (*it)->getValueInit("ParserMethod");
120505bce0beee87512e52428d4b80f5a8e79a949576David Greene    if (StringInit *SI = dynamic_cast<StringInit*>(PRMName))
1206e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes      CI->ParserMethod = SI->getValue();
1207e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
12084dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach    // Get the diagnostic type or leave it as empty.
12094dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach    // Get the parse method name or leave it as empty.
12104dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach    Init *DiagnosticType = (*it)->getValueInit("DiagnosticType");
12114dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach    if (StringInit *SI = dynamic_cast<StringInit*>(DiagnosticType))
12124dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach      CI->DiagnosticType = SI->getValue();
12134dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach
1214338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar    AsmOperandClasses[*it] = CI;
1215338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar    Classes.push_back(CI);
1216a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  }
1217ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar}
1218ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
1219828295bb301d6cd3683751c2da1c2dd22ec6423fBob WilsonAsmMatcherInfo::AsmMatcherInfo(Record *asmParser,
1220828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson                               CodeGenTarget &target,
12219c6b60eb28d2717008f8d6ff52f7666ebc81113dChris Lattner                               RecordKeeper &records)
122263faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel  : Records(records), AsmParser(asmParser), Target(target) {
122359fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar}
122459fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar
12258caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach/// buildOperandMatchInfo - Build the necessary information to handle user
1226e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes/// defined operand parsing methods.
12278caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachvoid AsmMatcherInfo::buildOperandMatchInfo() {
1228e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
1229d4824fc8aa1df5501600dd2a73c6da823f3b02dbJim Grosbach  /// Map containing a mask with all operands indices that can be found for
1230e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  /// that class inside a instruction.
1231e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  std::map<ClassInfo*, unsigned> OpClassMask;
1232e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
1233e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  for (std::vector<MatchableInfo*>::const_iterator it =
1234e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes       Matchables.begin(), ie = Matchables.end();
1235e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes       it != ie; ++it) {
1236e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    MatchableInfo &II = **it;
1237e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    OpClassMask.clear();
1238e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
1239e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    // Keep track of all operands of this instructions which belong to the
1240e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    // same class.
1241e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    for (unsigned i = 0, e = II.AsmOperands.size(); i != e; ++i) {
1242e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes      MatchableInfo::AsmOperand &Op = II.AsmOperands[i];
1243e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes      if (Op.Class->ParserMethod.empty())
1244e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes        continue;
1245e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes      unsigned &OperandMask = OpClassMask[Op.Class];
1246e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes      OperandMask |= (1 << i);
1247e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    }
1248e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
1249e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    // Generate operand match info for each mnemonic/operand class pair.
1250e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    for (std::map<ClassInfo*, unsigned>::iterator iit = OpClassMask.begin(),
1251e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes         iie = OpClassMask.end(); iit != iie; ++iit) {
1252e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes      unsigned OpMask = iit->second;
1253e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes      ClassInfo *CI = iit->first;
12548caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach      OperandMatchInfo.push_back(OperandMatchEntry::create(&II, CI, OpMask));
1255e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    }
1256e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  }
1257e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes}
1258e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
12598caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachvoid AsmMatcherInfo::buildInfo() {
12600aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner  // Build information about all of the AssemblerPredicates.
12610aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner  std::vector<Record*> AllPredicates =
12620aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner    Records.getAllDerivedDefinitions("Predicate");
12630aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner  for (unsigned i = 0, e = AllPredicates.size(); i != e; ++i) {
12640aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner    Record *Pred = AllPredicates[i];
12650aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner    // Ignore predicates that are not intended for the assembler.
12660aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner    if (!Pred->getValueAsBit("AssemblerMatcherPredicate"))
12670aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner      continue;
1268828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
12694164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner    if (Pred->getName().empty())
12704164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner      throw TGError(Pred->getLoc(), "Predicate has no name!");
1271828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
12720aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner    unsigned FeatureNo = SubtargetFeatures.size();
12730aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner    SubtargetFeatures[Pred] = new SubtargetFeatureInfo(Pred, FeatureNo);
12740aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner    assert(FeatureNo < 32 && "Too many subtarget features!");
12750aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner  }
1276a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
127739ee036f407bd0c94cb993cf9b97348843cfafa4Chris Lattner  // Parse the instructions; we need to do this first so that we can gather the
127839ee036f407bd0c94cb993cf9b97348843cfafa4Chris Lattner  // singleton register classes.
12791de88235781c45c0afc0c7500d65b59775196c4cChris Lattner  SmallPtrSet<Record*, 16> SingletonRegisters;
12800dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel  unsigned VariantCount = Target.getAsmParserVariantCount();
12810dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel  for (unsigned VC = 0; VC != VariantCount; ++VC) {
12820dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel    Record *AsmVariant = Target.getAsmParserVariant(VC);
128365da6fc8af561e77620bd86b83be8ca50acfdd30Jim Grosbach    std::string CommentDelimiter =
128465da6fc8af561e77620bd86b83be8ca50acfdd30Jim Grosbach      AsmVariant->getValueAsString("CommentDelimiter");
12850dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel    std::string RegisterPrefix = AsmVariant->getValueAsString("RegisterPrefix");
12860dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel    int AsmVariantNo = AsmVariant->getValueAsInt("Variant");
1287f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach
12880dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel    for (CodeGenTarget::inst_iterator I = Target.inst_begin(),
128911fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach           E = Target.inst_end(); I != E; ++I) {
12900dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      const CodeGenInstruction &CGI = **I;
1291f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach
12920dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      // If the tblgen -match-prefix option is specified (for tblgen hackers),
12930dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      // filter the set of instructions we consider.
12940dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      if (!StringRef(CGI.TheDef->getName()).startswith(MatchPrefix))
129511fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach        continue;
1296f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach
12970dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      // Ignore "codegen only" instructions.
12980dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      if (CGI.TheDef->getValueAsBit("isCodeGenOnly"))
129911fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach        continue;
1300f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach
13010dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      // Validate the operand list to ensure we can handle this instruction.
13020dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      for (unsigned i = 0, e = CGI.Operands.size(); i != e; ++i) {
130311fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach        const CGIOperandList::OperandInfo &OI = CGI.Operands[i];
130411fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach
130511fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach        // Validate tied operands.
130611fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach        if (OI.getTiedRegister() != -1) {
130711fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach          // If we have a tied operand that consists of multiple MCOperands,
130811fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach          // reject it.  We reject aliases and ignore instructions for now.
130911fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach          if (OI.MINumOperands != 1) {
131011fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach            // FIXME: Should reject these.  The ARM backend hits this with $lane
131165da6fc8af561e77620bd86b83be8ca50acfdd30Jim Grosbach            // in a bunch of instructions. The right answer is unclear.
131211fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach            DEBUG({
131311fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach                errs() << "warning: '" << CGI.TheDef->getName() << "': "
131465da6fc8af561e77620bd86b83be8ca50acfdd30Jim Grosbach                     << "ignoring instruction with multi-operand tied operand '"
131565da6fc8af561e77620bd86b83be8ca50acfdd30Jim Grosbach                     << OI.Name << "'\n";
131611fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach              });
131711fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach            continue;
131811fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach          }
131911fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach        }
13201d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      }
1321f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach
13220dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      OwningPtr<MatchableInfo> II(new MatchableInfo(CGI));
1323f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach
13248caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach      II->initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix);
1325f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach
13260dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      // Ignore instructions which shouldn't be matched and diagnose invalid
13270dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      // instruction definitions with an error.
13288caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach      if (!II->validate(CommentDelimiter, true))
132911fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach        continue;
1330f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach
13310dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      // Ignore "Int_*" and "*_Int" instructions, which are internal aliases.
13320dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      //
13330dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      // FIXME: This is a total hack.
13340dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      if (StringRef(II->TheDef->getName()).startswith("Int_") ||
133511fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach          StringRef(II->TheDef->getName()).endswith("_Int"))
133611fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach        continue;
1337f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach
13380dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      Matchables.push_back(II.take());
13390dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel    }
1340f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach
13410dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel    // Parse all of the InstAlias definitions and stick them in the list of
13420dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel    // matchables.
13430dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel    std::vector<Record*> AllInstAliases =
13440dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      Records.getAllDerivedDefinitions("InstAlias");
13450dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel    for (unsigned i = 0, e = AllInstAliases.size(); i != e; ++i) {
13460dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      CodeGenInstAlias *Alias = new CodeGenInstAlias(AllInstAliases[i], Target);
1347f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach
13480dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      // If the tblgen -match-prefix option is specified (for tblgen hackers),
13490dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      // filter the set of instruction aliases we consider, based on the target
13500dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      // instruction.
135165da6fc8af561e77620bd86b83be8ca50acfdd30Jim Grosbach      if (!StringRef(Alias->ResultInst->TheDef->getName())
135265da6fc8af561e77620bd86b83be8ca50acfdd30Jim Grosbach            .startswith( MatchPrefix))
135311fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach        continue;
1354f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach
13550dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      OwningPtr<MatchableInfo> II(new MatchableInfo(Alias));
1356f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach
13578caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach      II->initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix);
1358f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach
13590dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      // Validate the alias definitions.
13608caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach      II->validate(CommentDelimiter, false);
1361f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach
13620dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      Matchables.push_back(II.take());
13631d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner    }
1364c76e80ded753b78a72be0db40fcdba543435d818Chris Lattner  }
1365c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner
13661095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar  // Build info for the register classes.
13678caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  buildRegisterClasses(SingletonRegisters);
13681095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar
13691095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar  // Build info for the user defined assembly operand classes.
13708caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  buildOperandClasses();
13711095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar
13720bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner  // Build the information about matchables, now that we have fully formed
13730bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner  // classes.
1374c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  std::vector<MatchableInfo*> NewMatchables;
137522bc5c4184a497353e33195dd12541a4f08b008aChris Lattner  for (std::vector<MatchableInfo*>::iterator it = Matchables.begin(),
137622bc5c4184a497353e33195dd12541a4f08b008aChris Lattner         ie = Matchables.end(); it != ie; ++it) {
137722bc5c4184a497353e33195dd12541a4f08b008aChris Lattner    MatchableInfo *II = *it;
1378a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
1379e206fcf0e9c7e79c7f42ff2151f3fb58cba70674Chris Lattner    // Parse the tokens after the mnemonic.
13808caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach    // Note: buildInstructionOperandReference may insert new AsmOperands, so
1381a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    // don't precompute the loop bound.
1382a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    for (unsigned i = 0; i != II->AsmOperands.size(); ++i) {
1383c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner      MatchableInfo::AsmOperand &Op = II->AsmOperands[i];
1384d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      StringRef Token = Op.Token;
138520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
13861095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar      // Check for singleton registers.
138763faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel      if (Record *RegRecord = II->AsmOperands[i].SingletonReg) {
1388d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner        Op.Class = RegisterClasses[RegRecord];
138902bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner        assert(Op.Class && Op.Class->Registers.size() == 1 &&
139002bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner               "Unexpected class for singleton register");
139102bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner        continue;
13921095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar      }
13931095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar
139420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar      // Check for simple tokens.
139520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar      if (Token[0] != '$') {
1396d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner        Op.Class = getTokenClass(Token);
139720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar        continue;
139820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar      }
1399a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
14007ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner      if (Token.size() > 1 && isdigit(Token[1])) {
14017ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner        Op.Class = getTokenClass(Token);
14027ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner        continue;
14037ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner      }
1404828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
1405c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner      // Otherwise this is an operand reference.
14065f4280cd2d2d1aeb527c8b161acaa1870cf6ee82Chris Lattner      StringRef OperandName;
14075f4280cd2d2d1aeb527c8b161acaa1870cf6ee82Chris Lattner      if (Token[1] == '{')
14085f4280cd2d2d1aeb527c8b161acaa1870cf6ee82Chris Lattner        OperandName = Token.substr(2, Token.size() - 3);
14095f4280cd2d2d1aeb527c8b161acaa1870cf6ee82Chris Lattner      else
14105f4280cd2d2d1aeb527c8b161acaa1870cf6ee82Chris Lattner        OperandName = Token.substr(1);
1411828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
1412c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner      if (II->DefRec.is<const CodeGenInstruction*>())
14138caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach        buildInstructionOperandReference(II, OperandName, i);
1414c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner      else
14158caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach        buildAliasOperandReference(II, OperandName, Op);
141653a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar    }
1417828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
1418c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach    if (II->DefRec.is<const CodeGenInstruction*>()) {
14198caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach      II->buildInstructionResultOperands();
1420c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach      // If the instruction has a two-operand alias, build up the
1421c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach      // matchable here. We'll add them in bulk at the end to avoid
1422c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach      // confusing this loop.
1423c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach      std::string Constraint =
1424c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach        II->TheDef->getValueAsString("TwoOperandAliasConstraint");
1425c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach      if (Constraint != "") {
1426c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach        // Start by making a copy of the original matchable.
1427c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach        OwningPtr<MatchableInfo> AliasII(new MatchableInfo(*II));
1428c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach
1429c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach        // Adjust it to be a two-operand alias.
1430c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach        AliasII->formTwoOperandAlias(Constraint);
1431c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach
1432c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach        // Add the alias to the matchables list.
1433c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach        NewMatchables.push_back(AliasII.take());
1434c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach      }
1435c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach    } else
14368caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach      II->buildAliasResultOperands();
143720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
1438c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  if (!NewMatchables.empty())
1439c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach    Matchables.insert(Matchables.end(), NewMatchables.begin(),
1440c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach                      NewMatchables.end());
14415fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar
1442a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach  // Process token alias definitions and set up the associated superclass
1443a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach  // information.
1444a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach  std::vector<Record*> AllTokenAliases =
1445a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach    Records.getAllDerivedDefinitions("TokenAlias");
1446a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach  for (unsigned i = 0, e = AllTokenAliases.size(); i != e; ++i) {
1447a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach    Record *Rec = AllTokenAliases[i];
1448a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach    ClassInfo *FromClass = getTokenClass(Rec->getValueAsString("FromToken"));
1449a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach    ClassInfo *ToClass = getTokenClass(Rec->getValueAsString("ToToken"));
145067cd20d0396a68e61858736b7943dd352f1b0d0bJim Grosbach    if (FromClass == ToClass)
145167cd20d0396a68e61858736b7943dd352f1b0d0bJim Grosbach      throw TGError(Rec->getLoc(),
145267cd20d0396a68e61858736b7943dd352f1b0d0bJim Grosbach                    "error: Destination value identical to source value.");
1453a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach    FromClass->SuperClasses.push_back(ToClass);
1454a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach  }
1455a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach
14567a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner  // Reorder classes so that classes precede super classes.
14575fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar  std::sort(Classes.begin(), Classes.end(), less_ptr<ClassInfo>());
145820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar}
1459a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
14608caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach/// buildInstructionOperandReference - The specified operand is a reference to a
14610bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner/// named operand such as $src.  Resolve the Class and OperandInfo pointers.
14620bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattnervoid AsmMatcherInfo::
14638caecdea56c830f3fc80ed67fff121c83de0e364Jim GrosbachbuildInstructionOperandReference(MatchableInfo *II,
14645f4280cd2d2d1aeb527c8b161acaa1870cf6ee82Chris Lattner                                 StringRef OperandName,
1465a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson                                 unsigned AsmOpIdx) {
1466c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner  const CodeGenInstruction &CGI = *II->DefRec.get<const CodeGenInstruction*>();
1467c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner  const CGIOperandList &Operands = CGI.Operands;
1468a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson  MatchableInfo::AsmOperand *Op = &II->AsmOperands[AsmOpIdx];
1469828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
1470662e5a30e864e71111b885d3da3cdd184772035dChris Lattner  // Map this token to an operand.
14710bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner  unsigned Idx;
14720bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner  if (!Operands.hasOperandNamed(OperandName, Idx))
14730bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner    throw TGError(II->TheDef->getLoc(), "error: unable to find operand: '" +
14740bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner                  OperandName.str() + "'");
1475ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner
1476a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson  // If the instruction operand has multiple suboperands, but the parser
1477a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson  // match class for the asm operand is still the default "ImmAsmOperand",
1478a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson  // then handle each suboperand separately.
1479a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson  if (Op->SubOpIdx == -1 && Operands[Idx].MINumOperands > 1) {
1480a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    Record *Rec = Operands[Idx].Rec;
1481a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    assert(Rec->isSubClassOf("Operand") && "Unexpected operand!");
1482a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    Record *MatchClass = Rec->getValueAsDef("ParserMatchClass");
1483a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    if (MatchClass && MatchClass->getValueAsString("Name") == "Imm") {
1484a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      // Insert remaining suboperands after AsmOpIdx in II->AsmOperands.
1485a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      StringRef Token = Op->Token; // save this in case Op gets moved
1486a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      for (unsigned SI = 1, SE = Operands[Idx].MINumOperands; SI != SE; ++SI) {
1487a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson        MatchableInfo::AsmOperand NewAsmOp(Token);
1488a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson        NewAsmOp.SubOpIdx = SI;
1489a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson        II->AsmOperands.insert(II->AsmOperands.begin()+AsmOpIdx+SI, NewAsmOp);
1490a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      }
1491a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      // Replace Op with first suboperand.
1492a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      Op = &II->AsmOperands[AsmOpIdx]; // update the pointer in case it moved
1493a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      Op->SubOpIdx = 0;
1494a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    }
1495a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson  }
1496a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson
1497ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner  // Set up the operand class.
1498a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson  Op->Class = getOperandClass(Operands[Idx], Op->SubOpIdx);
1499ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner
1500ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner  // If the named operand is tied, canonicalize it to the untied operand.
1501ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner  // For example, something like:
1502ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner  //   (outs GPR:$dst), (ins GPR:$src)
1503ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner  // with an asmstring of
1504ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner  //   "inc $src"
1505ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner  // we want to canonicalize to:
1506c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner  //   "inc $dst"
1507c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner  // so that we know how to provide the $dst operand when filling in the result.
1508c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner  int OITied = Operands[Idx].getTiedRegister();
1509c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner  if (OITied != -1) {
1510c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner    // The tied operand index is an MIOperand index, find the operand that
1511c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner    // contains it.
1512a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    std::pair<unsigned, unsigned> Idx = Operands.getSubOperandNumber(OITied);
1513a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    OperandName = Operands[Idx.first].Name;
1514a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    Op->SubOpIdx = Idx.second;
1515c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner  }
1516828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
1517a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson  Op->SrcOpName = OperandName;
1518c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner}
1519c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner
15208caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach/// buildAliasOperandReference - When parsing an operand reference out of the
15213f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner/// matching string (e.g. "movsx $src, $dst"), determine what the class of the
15223f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner/// operand reference is by looking it up in the result pattern definition.
15238caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachvoid AsmMatcherInfo::buildAliasOperandReference(MatchableInfo *II,
1524c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner                                                StringRef OperandName,
1525c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner                                                MatchableInfo::AsmOperand &Op) {
1526c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner  const CodeGenInstAlias &CGA = *II->DefRec.get<const CodeGenInstAlias*>();
1527828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
1528c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner  // Set up the operand class.
15293f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner  for (unsigned i = 0, e = CGA.ResultOperands.size(); i != e; ++i)
153098c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner    if (CGA.ResultOperands[i].isRecord() &&
153198c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner        CGA.ResultOperands[i].getName() == OperandName) {
1532662e5a30e864e71111b885d3da3cdd184772035dChris Lattner      // It's safe to go with the first one we find, because CodeGenInstAlias
1533662e5a30e864e71111b885d3da3cdd184772035dChris Lattner      // validates that all operands with the same name have the same record.
1534a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      Op.SubOpIdx = CGA.ResultInstOperandIndex[i].second;
153548c1f84b104fd32109d809a56f5ebbf461c0910cJim Grosbach      // Use the match class from the Alias definition, not the
153648c1f84b104fd32109d809a56f5ebbf461c0910cJim Grosbach      // destination instruction, as we may have an immediate that's
153748c1f84b104fd32109d809a56f5ebbf461c0910cJim Grosbach      // being munged by the match class.
153848c1f84b104fd32109d809a56f5ebbf461c0910cJim Grosbach      Op.Class = getOperandClass(CGA.ResultOperands[i].getRecord(),
1539a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson                                 Op.SubOpIdx);
15403f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner      Op.SrcOpName = OperandName;
15413f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner      return;
15420bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner    }
15433f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner
15443f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner  throw TGError(II->TheDef->getLoc(), "error: unable to find operand: '" +
15453f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner                OperandName.str() + "'");
15460bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner}
15470bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner
15488caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachvoid MatchableInfo::buildInstructionResultOperands() {
1549662e5a30e864e71111b885d3da3cdd184772035dChris Lattner  const CodeGenInstruction *ResultInst = getResultInst();
1550828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
1551662e5a30e864e71111b885d3da3cdd184772035dChris Lattner  // Loop over all operands of the result instruction, determining how to
1552662e5a30e864e71111b885d3da3cdd184772035dChris Lattner  // populate them.
1553662e5a30e864e71111b885d3da3cdd184772035dChris Lattner  for (unsigned i = 0, e = ResultInst->Operands.size(); i != e; ++i) {
1554662e5a30e864e71111b885d3da3cdd184772035dChris Lattner    const CGIOperandList::OperandInfo &OpInfo = ResultInst->Operands[i];
1555567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner
1556567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner    // If this is a tied operand, just copy from the previously handled operand.
1557567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner    int TiedOp = OpInfo.getTiedRegister();
1558567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner    if (TiedOp != -1) {
1559a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      ResOperands.push_back(ResOperand::getTiedOp(TiedOp));
1560567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner      continue;
1561567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner    }
1562828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
1563a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    // Find out what operand from the asmparser this MCInst operand comes from.
15648caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach    int SrcOperand = findAsmOperandNamed(OpInfo.Name);
1565a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    if (OpInfo.Name.empty() || SrcOperand == -1)
1566a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      throw TGError(TheDef->getLoc(), "Instruction '" +
1567a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson                    TheDef->getName() + "' has operand '" + OpInfo.Name +
1568a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson                    "' that doesn't appear in asm string!");
1569567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner
1570a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    // Check if the one AsmOperand populates the entire operand.
1571a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    unsigned NumOperands = OpInfo.MINumOperands;
1572a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    if (AsmOperands[SrcOperand].SubOpIdx == -1) {
1573a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      ResOperands.push_back(ResOperand::getRenderedOp(SrcOperand, NumOperands));
15741d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      continue;
15751d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner    }
1576a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson
1577a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    // Add a separate ResOperand for each suboperand.
1578a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    for (unsigned AI = 0; AI < NumOperands; ++AI) {
1579a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      assert(AsmOperands[SrcOperand+AI].SubOpIdx == (int)AI &&
1580a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson             AsmOperands[SrcOperand+AI].SrcOpName == OpInfo.Name &&
1581a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson             "unexpected AsmOperands for suboperands");
1582a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      ResOperands.push_back(ResOperand::getRenderedOp(SrcOperand + AI, 1));
1583a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    }
15841d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner  }
15851d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner}
15861d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner
15878caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachvoid MatchableInfo::buildAliasResultOperands() {
1588414098571b19fc248fda2be194082cfd012d2729Chris Lattner  const CodeGenInstAlias &CGA = *DefRec.get<const CodeGenInstAlias*>();
1589414098571b19fc248fda2be194082cfd012d2729Chris Lattner  const CodeGenInstruction *ResultInst = getResultInst();
1590828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
1591414098571b19fc248fda2be194082cfd012d2729Chris Lattner  // Loop over all operands of the result instruction, determining how to
1592414098571b19fc248fda2be194082cfd012d2729Chris Lattner  // populate them.
1593414098571b19fc248fda2be194082cfd012d2729Chris Lattner  unsigned AliasOpNo = 0;
1594a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson  unsigned LastOpNo = CGA.ResultInstOperandIndex.size();
1595414098571b19fc248fda2be194082cfd012d2729Chris Lattner  for (unsigned i = 0, e = ResultInst->Operands.size(); i != e; ++i) {
1596a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    const CGIOperandList::OperandInfo *OpInfo = &ResultInst->Operands[i];
1597828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
1598414098571b19fc248fda2be194082cfd012d2729Chris Lattner    // If this is a tied operand, just copy from the previously handled operand.
1599a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    int TiedOp = OpInfo->getTiedRegister();
1600414098571b19fc248fda2be194082cfd012d2729Chris Lattner    if (TiedOp != -1) {
1601a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      ResOperands.push_back(ResOperand::getTiedOp(TiedOp));
160290fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner      continue;
160390fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner    }
160490fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner
1605a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    // Handle all the suboperands for this operand.
1606a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    const std::string &OpName = OpInfo->Name;
1607a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    for ( ; AliasOpNo <  LastOpNo &&
1608a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson            CGA.ResultInstOperandIndex[AliasOpNo].first == i; ++AliasOpNo) {
1609a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      int SubIdx = CGA.ResultInstOperandIndex[AliasOpNo].second;
1610a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson
1611a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      // Find out what operand from the asmparser that this MCInst operand
1612a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      // comes from.
1613a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      switch (CGA.ResultOperands[AliasOpNo].Kind) {
1614a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      case CodeGenInstAlias::ResultOperand::K_Record: {
1615a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson        StringRef Name = CGA.ResultOperands[AliasOpNo].getName();
16168caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach        int SrcOperand = findAsmOperand(Name, SubIdx);
1617a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson        if (SrcOperand == -1)
1618a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson          throw TGError(TheDef->getLoc(), "Instruction '" +
1619a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson                        TheDef->getName() + "' has operand '" + OpName +
1620a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson                        "' that doesn't appear in asm string!");
1621a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson        unsigned NumOperands = (SubIdx == -1 ? OpInfo->MINumOperands : 1);
1622a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson        ResOperands.push_back(ResOperand::getRenderedOp(SrcOperand,
1623a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson                                                        NumOperands));
1624a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson        break;
1625a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      }
1626a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      case CodeGenInstAlias::ResultOperand::K_Imm: {
1627a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson        int64_t ImmVal = CGA.ResultOperands[AliasOpNo].getImm();
1628a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson        ResOperands.push_back(ResOperand::getImmOp(ImmVal));
1629a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson        break;
1630a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      }
1631a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      case CodeGenInstAlias::ResultOperand::K_Reg: {
1632a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson        Record *Reg = CGA.ResultOperands[AliasOpNo].getRegister();
1633a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson        ResOperands.push_back(ResOperand::getRegOp(Reg));
1634a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson        break;
1635a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      }
1636a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      }
163790fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner    }
1638414098571b19fc248fda2be194082cfd012d2729Chris Lattner  }
1639414098571b19fc248fda2be194082cfd012d2729Chris Lattner}
16401d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner
16418caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachstatic void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName,
164222bc5c4184a497353e33195dd12541a4f08b008aChris Lattner                                std::vector<MatchableInfo*> &Infos,
1643606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar                                raw_ostream &OS) {
1644b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar  // Write the convert function to a separate stream, so we can drop it after
1645b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar  // the enum.
1646b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar  std::string ConvertFnBody;
1647b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar  raw_string_ostream CvtOS(ConvertFnBody);
1648b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar
164920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  // Function we have already generated.
165020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  std::set<std::string> GeneratedFns;
165120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
1652b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar  // Start the unified conversion function.
16535c228a945fe3e25a12d0f7e2e9b26b548d6f29f5Daniel Dunbar  CvtOS << "bool " << Target.getName() << ClassName << "::\n";
16545c228a945fe3e25a12d0f7e2e9b26b548d6f29f5Daniel Dunbar  CvtOS << "ConvertToMCInst(unsigned Kind, MCInst &Inst, "
1655b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar        << "unsigned Opcode,\n"
16569898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner        << "                      const SmallVectorImpl<MCParsedAsmOperand*"
16579898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner        << "> &Operands) {\n";
1658b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar  CvtOS << "  Inst.setOpcode(Opcode);\n";
1659b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar  CvtOS << "  switch (Kind) {\n";
1660b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar  CvtOS << "  default:\n";
1661b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar
1662b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar  // Start the enum, which we will generate inline.
1663b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar
1664d51257a4368d52e2340073bc7ccd83f3c3f1c04dChris Lattner  OS << "// Unified function for converting operands to MCInst instances.\n\n";
1665b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar  OS << "enum ConversionKind {\n";
1666a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
16679898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner  // TargetOperandClass - This is the target's operand class, like X86Operand.
16689898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner  std::string TargetOperandClass = Target.getName() + "Operand";
1669a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
167022bc5c4184a497353e33195dd12541a4f08b008aChris Lattner  for (std::vector<MatchableInfo*>::const_iterator it = Infos.begin(),
167120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar         ie = Infos.end(); it != ie; ++it) {
167222bc5c4184a497353e33195dd12541a4f08b008aChris Lattner    MatchableInfo &II = **it;
167320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
1674cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar    // Check if we have a custom match function.
167527b83d4ff2264d9a0e2367d92543efe4c0148931Daniel Dunbar    std::string AsmMatchConverter =
167627b83d4ff2264d9a0e2367d92543efe4c0148931Daniel Dunbar      II.getResultInst()->TheDef->getValueAsString("AsmMatchConverter");
1677cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar    if (!AsmMatchConverter.empty()) {
167827b83d4ff2264d9a0e2367d92543efe4c0148931Daniel Dunbar      std::string Signature = "ConvertCustom_" + AsmMatchConverter;
1679cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar      II.ConversionFnKind = Signature;
1680cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar
1681cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar      // Check if we have already generated this signature.
1682cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar      if (!GeneratedFns.insert(Signature).second)
1683cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar        continue;
1684cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar
1685cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar      // If not, emit it now.  Add to the enum list.
1686cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar      OS << "  " << Signature << ",\n";
1687cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar
1688cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar      CvtOS << "  case " << Signature << ":\n";
1689b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar      CvtOS << "    return " << AsmMatchConverter
1690b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar            << "(Inst, Opcode, Operands);\n";
1691cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar      continue;
1692cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar    }
1693cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar
169420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    // Build the conversion function signature.
169520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    std::string Signature = "Convert";
1696dda855de8b3c60bce5d1d0d9eb11470c9710e30fChris Lattner    std::string CaseBody;
1697dda855de8b3c60bce5d1d0d9eb11470c9710e30fChris Lattner    raw_string_ostream CaseOS(CaseBody);
1698828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
1699dda855de8b3c60bce5d1d0d9eb11470c9710e30fChris Lattner    // Compute the convert enum and the case body.
17001d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner    for (unsigned i = 0, e = II.ResOperands.size(); i != e; ++i) {
17011d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      const MatchableInfo::ResOperand &OpInfo = II.ResOperands[i];
17021d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner
17031d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      // Generate code to populate each result operand.
17041d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      switch (OpInfo.Kind) {
17051d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      case MatchableInfo::ResOperand::RenderAsmOperand: {
17061d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner        // This comes from something we parsed.
17071d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner        MatchableInfo::AsmOperand &Op = II.AsmOperands[OpInfo.AsmOperandNum];
1708828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
17099b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner        // Registers are always converted the same, don't duplicate the
17109b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner        // conversion function based on them.
17119b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner        Signature += "__";
17129b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner        if (Op.Class->isRegisterClass())
17139b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner          Signature += "Reg";
17149b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner        else
17159b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner          Signature += Op.Class->ClassName;
1716a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson        Signature += utostr(OpInfo.MINumOperands);
17171d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner        Signature += "_" + itostr(OpInfo.AsmOperandNum);
1718828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
17199b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner        CaseOS << "    ((" << TargetOperandClass << "*)Operands["
17201d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner               << (OpInfo.AsmOperandNum+1) << "])->" << Op.Class->RenderMethod
1721a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson               << "(Inst, " << OpInfo.MINumOperands << ");\n";
17221d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner        break;
17231d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      }
1724828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
17251d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      case MatchableInfo::ResOperand::TiedOperand: {
17261d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner        // If this operand is tied to a previous one, just copy the MCInst
17271d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner        // operand from the earlier one.We can only tie single MCOperand values.
1728a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson        //assert(OpInfo.MINumOperands == 1 && "Not a singular MCOperand");
17291d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner        unsigned TiedOp = OpInfo.TiedOperandNum;
17307a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner        assert(i > TiedOp && "Tied operand precedes its target!");
17311d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner        CaseOS << "    Inst.addOperand(Inst.getOperand(" << TiedOp << "));\n";
17321d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner        Signature += "__Tie" + utostr(TiedOp);
17331d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner        break;
17341d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      }
173598c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      case MatchableInfo::ResOperand::ImmOperand: {
173698c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner        int64_t Val = OpInfo.ImmVal;
173798c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner        CaseOS << "    Inst.addOperand(MCOperand::CreateImm(" << Val << "));\n";
173898c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner        Signature += "__imm" + itostr(Val);
173998c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner        break;
174098c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      }
174190fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner      case MatchableInfo::ResOperand::RegOperand: {
1742dc1a2bd3aa199693413f39dd723cc14a77e9f131Bob Wilson        if (OpInfo.Register == 0) {
1743dc1a2bd3aa199693413f39dd723cc14a77e9f131Bob Wilson          CaseOS << "    Inst.addOperand(MCOperand::CreateReg(0));\n";
1744dc1a2bd3aa199693413f39dd723cc14a77e9f131Bob Wilson          Signature += "__reg0";
1745dc1a2bd3aa199693413f39dd723cc14a77e9f131Bob Wilson        } else {
1746dc1a2bd3aa199693413f39dd723cc14a77e9f131Bob Wilson          std::string N = getQualifiedName(OpInfo.Register);
1747dc1a2bd3aa199693413f39dd723cc14a77e9f131Bob Wilson          CaseOS << "    Inst.addOperand(MCOperand::CreateReg(" << N << "));\n";
1748dc1a2bd3aa199693413f39dd723cc14a77e9f131Bob Wilson          Signature += "__reg" + OpInfo.Register->getName();
1749dc1a2bd3aa199693413f39dd723cc14a77e9f131Bob Wilson        }
1750828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson      }
1751af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar      }
17529b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner    }
1753828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
1754b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar    II.ConversionFnKind = Signature;
1755a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
1756b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar    // Check if we have already generated this signature.
175720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    if (!GeneratedFns.insert(Signature).second)
175820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar      continue;
1759a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
1760dda855de8b3c60bce5d1d0d9eb11470c9710e30fChris Lattner    // If not, emit it now.  Add to the enum list.
1761b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar    OS << "  " << Signature << ",\n";
1762b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar
1763b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar    CvtOS << "  case " << Signature << ":\n";
1764dda855de8b3c60bce5d1d0d9eb11470c9710e30fChris Lattner    CvtOS << CaseOS.str();
1765b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar    CvtOS << "    return true;\n";
1766a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar  }
1767b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar
1768b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar  // Finish the convert function.
1769b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar
1770b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar  CvtOS << "  }\n";
1771b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar  CvtOS << "  return false;\n";
1772b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar  CvtOS << "}\n\n";
1773b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar
1774b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar  // Finish the enum, and drop the convert function after it.
1775b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar
1776b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar  OS << "  NumConversionVariants\n";
1777b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar  OS << "};\n\n";
1778a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
1779b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar  OS << CvtOS.str();
178020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar}
178120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
17828caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach/// emitMatchClassEnumeration - Emit the enumeration for match class kinds.
17838caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachstatic void emitMatchClassEnumeration(CodeGenTarget &Target,
1784a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar                                      std::vector<ClassInfo*> &Infos,
1785a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar                                      raw_ostream &OS) {
1786a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  OS << "namespace {\n\n";
1787a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
1788a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  OS << "/// MatchClassKind - The kinds of classes which participate in\n"
1789a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar     << "/// instruction matching.\n";
1790a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  OS << "enum MatchClassKind {\n";
1791a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  OS << "  InvalidMatchClass = 0,\n";
1792a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach  for (std::vector<ClassInfo*>::iterator it = Infos.begin(),
1793a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar         ie = Infos.end(); it != ie; ++it) {
1794a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    ClassInfo &CI = **it;
1795a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    OS << "  " << CI.Name << ", // ";
1796a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    if (CI.Kind == ClassInfo::Token) {
1797a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar      OS << "'" << CI.ValueName << "'\n";
1798ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    } else if (CI.isRegisterClass()) {
1799a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar      if (!CI.ValueName.empty())
1800a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar        OS << "register class '" << CI.ValueName << "'\n";
1801a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar      else
1802a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar        OS << "derived register class\n";
1803a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    } else {
1804a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar      OS << "user defined class '" << CI.ValueName << "'\n";
1805a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    }
1806a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  }
1807a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  OS << "  NumMatchClassKinds\n";
1808a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  OS << "};\n\n";
1809a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
1810a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  OS << "}\n\n";
1811a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar}
1812a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
18138caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach/// emitValidateOperandClass - Emit the function to validate an operand class.
18148caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachstatic void emitValidateOperandClass(AsmMatcherInfo &Info,
1815b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach                                     raw_ostream &OS) {
18164dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  OS << "static unsigned validateOperandClass(MCParsedAsmOperand *GOp, "
1817b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach     << "MatchClassKind Kind) {\n";
1818b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach  OS << "  " << Info.Target.getName() << "Operand &Operand = *("
181902bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner     << Info.Target.getName() << "Operand*)GOp;\n";
1820ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
1821893818347e9d7b34ea99ae9c984934c9b6bf92daKevin Enderby  // The InvalidMatchClass is not to match any operand.
1822893818347e9d7b34ea99ae9c984934c9b6bf92daKevin Enderby  OS << "  if (Kind == InvalidMatchClass)\n";
18234dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  OS << "    return MCTargetAsmParser::Match_InvalidOperand;\n\n";
1824893818347e9d7b34ea99ae9c984934c9b6bf92daKevin Enderby
1825b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach  // Check for Token operands first.
18264dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  // FIXME: Use a more specific diagnostic type.
1827a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  OS << "  if (Operand.isToken())\n";
18284dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  OS << "    return isSubclass(matchTokenString(Operand.getToken()), Kind) ?\n"
18294dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach     << "             MCTargetAsmParser::Match_Success :\n"
18304dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach     << "             MCTargetAsmParser::Match_InvalidOperand;\n\n";
1831ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
1832b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach  // Check the user classes. We don't care what order since we're only
1833b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach  // actually matching against one of them.
1834a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach  for (std::vector<ClassInfo*>::iterator it = Info.Classes.begin(),
1835ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar         ie = Info.Classes.end(); it != ie; ++it) {
1836a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    ClassInfo &CI = **it;
1837a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
1838ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    if (!CI.isUserClass())
1839ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar      continue;
1840828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
1841b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach    OS << "  // '" << CI.ClassName << "' class\n";
18424dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach    OS << "  if (Kind == " << CI.Name << ") {\n";
18434dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach    OS << "    if (Operand." << CI.PredicateMethod << "())\n";
18444dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach    OS << "      return MCTargetAsmParser::Match_Success;\n";
18454dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach    if (!CI.DiagnosticType.empty())
18464dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach      OS << "    return " << Info.Target.getName() << "AsmParser::Match_"
18474dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach         << CI.DiagnosticType << ";\n";
1848ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    OS << "  }\n\n";
1849a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  }
1850828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
1851b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson  // Check for register operands, including sub-classes.
1852b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson  OS << "  if (Operand.isReg()) {\n";
1853b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson  OS << "    MatchClassKind OpKind;\n";
1854b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson  OS << "    switch (Operand.getReg()) {\n";
1855b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson  OS << "    default: OpKind = InvalidMatchClass; break;\n";
1856b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson  for (std::map<Record*, ClassInfo*>::iterator
1857b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson         it = Info.RegisterClasses.begin(), ie = Info.RegisterClasses.end();
1858b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson       it != ie; ++it)
1859b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson    OS << "    case " << Info.Target.getName() << "::"
1860b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson       << it->first->getName() << ": OpKind = " << it->second->Name
1861b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson       << "; break;\n";
1862b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson  OS << "    }\n";
1863b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson  OS << "    return isSubclass(OpKind, Kind) ? "
1864b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson     << "MCTargetAsmParser::Match_Success :\n                             "
1865b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson     << "         MCTargetAsmParser::Match_InvalidOperand;\n  }\n\n";
1866b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson
18674dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  // Generic fallthrough match failure case for operands that don't have
18684dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  // specialized diagnostic types.
18694dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  OS << "  return MCTargetAsmParser::Match_InvalidOperand;\n";
1870a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  OS << "}\n\n";
1871a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar}
1872a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
18738caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach/// emitIsSubclass - Emit the subclass predicate function.
18748caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachstatic void emitIsSubclass(CodeGenTarget &Target,
1875fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar                           std::vector<ClassInfo*> &Infos,
1876fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar                           raw_ostream &OS) {
18773d5d8f6b768619ed65f79606d5c981c1e056c7e8Jim Grosbach  OS << "/// isSubclass - Compute whether \\arg A is a subclass of \\arg B.\n";
18783d5d8f6b768619ed65f79606d5c981c1e056c7e8Jim Grosbach  OS << "static bool isSubclass(MatchClassKind A, MatchClassKind B) {\n";
1879fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar  OS << "  if (A == B)\n";
1880fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar  OS << "    return true;\n\n";
1881fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar
1882fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar  OS << "  switch (A) {\n";
1883fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar  OS << "  default:\n";
1884fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar  OS << "    return false;\n";
1885a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach  for (std::vector<ClassInfo*>::iterator it = Infos.begin(),
1886fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar         ie = Infos.end(); it != ie; ++it) {
1887fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar    ClassInfo &A = **it;
1888fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar
1889a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach    std::vector<StringRef> SuperClasses;
1890a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach    for (std::vector<ClassInfo*>::iterator it = Infos.begin(),
1891a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach         ie = Infos.end(); it != ie; ++it) {
1892a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach      ClassInfo &B = **it;
1893fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar
1894a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach      if (&A != &B && A.isSubsetOf(B))
1895a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach        SuperClasses.push_back(B.Name);
1896a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach    }
1897fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar
1898a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach    if (SuperClasses.empty())
1899a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach      continue;
1900fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar
1901a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach    OS << "\n  case " << A.Name << ":\n";
1902fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar
1903a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach    if (SuperClasses.size() == 1) {
1904a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach      OS << "    return B == " << SuperClasses.back() << ";\n";
1905a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach      continue;
1906fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar    }
1907a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach
1908a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach    OS << "    switch (B) {\n";
1909a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach    OS << "    default: return false;\n";
1910a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach    for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i)
1911a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach      OS << "    case " << SuperClasses[i] << ": return true;\n";
1912a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach    OS << "    }\n";
1913fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar  }
1914fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar  OS << "  }\n";
1915fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar  OS << "}\n\n";
1916fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar}
1917fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar
19188caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach/// emitMatchTokenString - Emit the function to match a token string to the
1919245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar/// appropriate match class value.
19208caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachstatic void emitMatchTokenString(CodeGenTarget &Target,
1921245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar                                 std::vector<ClassInfo*> &Infos,
1922245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar                                 raw_ostream &OS) {
1923245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar  // Construct the match list.
19245845e5c62b42d025557765006515156691a6a8b1Chris Lattner  std::vector<StringMatcher::StringPair> Matches;
1925a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach  for (std::vector<ClassInfo*>::iterator it = Infos.begin(),
1926245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar         ie = Infos.end(); it != ie; ++it) {
1927245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar    ClassInfo &CI = **it;
1928245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar
1929245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar    if (CI.Kind == ClassInfo::Token)
19305845e5c62b42d025557765006515156691a6a8b1Chris Lattner      Matches.push_back(StringMatcher::StringPair(CI.ValueName,
19315845e5c62b42d025557765006515156691a6a8b1Chris Lattner                                                  "return " + CI.Name + ";"));
1932245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar  }
1933245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar
19343d5d8f6b768619ed65f79606d5c981c1e056c7e8Jim Grosbach  OS << "static MatchClassKind matchTokenString(StringRef Name) {\n";
1935245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar
19365845e5c62b42d025557765006515156691a6a8b1Chris Lattner  StringMatcher("Name", Matches, OS).Emit();
1937245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar
1938245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar  OS << "  return InvalidMatchClass;\n";
1939245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar  OS << "}\n\n";
1940245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar}
194170add884e4967f511e2cbb35c61534186b9b418aChris Lattner
19428caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach/// emitMatchRegisterName - Emit the function to match a string to the target
19432234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar/// specific register enum.
19448caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachstatic void emitMatchRegisterName(CodeGenTarget &Target, Record *AsmParser,
19452234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar                                  raw_ostream &OS) {
1946245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar  // Construct the match list.
19475845e5c62b42d025557765006515156691a6a8b1Chris Lattner  std::vector<StringMatcher::StringPair> Matches;
1948abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen  const std::vector<CodeGenRegister*> &Regs =
1949abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen    Target.getRegBank().getRegisters();
1950abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen  for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
1951abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen    const CodeGenRegister *Reg = Regs[i];
1952abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen    if (Reg->TheDef->getValueAsString("AsmName").empty())
195320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar      continue;
195420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
19555845e5c62b42d025557765006515156691a6a8b1Chris Lattner    Matches.push_back(StringMatcher::StringPair(
1956abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen                                     Reg->TheDef->getValueAsString("AsmName"),
1957abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen                                     "return " + utostr(Reg->EnumValue) + ";"));
195820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
1959a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
1960b8d6e98e566724f58344d275a4bd675249bb713aChris Lattner  OS << "static unsigned MatchRegisterName(StringRef Name) {\n";
1961245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar
19625845e5c62b42d025557765006515156691a6a8b1Chris Lattner  StringMatcher("Name", Matches, OS).Emit();
1963a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
1964245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar  OS << "  return 0;\n";
196520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  OS << "}\n\n";
19662234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar}
19672234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar
19688caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach/// emitSubtargetFeatureFlagEnumeration - Emit the subtarget feature flag
196954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar/// definitions.
19708caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachstatic void emitSubtargetFeatureFlagEnumeration(AsmMatcherInfo &Info,
197154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar                                                raw_ostream &OS) {
197254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  OS << "// Flags for subtarget features that participate in "
197354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar     << "instruction matching.\n";
197454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  OS << "enum SubtargetFeatureFlag {\n";
197554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  for (std::map<Record*, SubtargetFeatureInfo*>::const_iterator
197654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar         it = Info.SubtargetFeatures.begin(),
197754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar         ie = Info.SubtargetFeatures.end(); it != ie; ++it) {
197854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar    SubtargetFeatureInfo &SFI = *it->second;
19790aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner    OS << "  " << SFI.getEnumName() << " = (1 << " << SFI.Index << "),\n";
198054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  }
198154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  OS << "  Feature_None = 0\n";
198254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  OS << "};\n\n";
198354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar}
198454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar
19854dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach/// emitOperandDiagnosticTypes - Emit the operand matching diagnostic types.
19864dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbachstatic void emitOperandDiagnosticTypes(AsmMatcherInfo &Info, raw_ostream &OS) {
19874dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  // Get the set of diagnostic types from all of the operand classes.
19884dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  std::set<StringRef> Types;
19894dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  for (std::map<Record*, ClassInfo*>::const_iterator
19904dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach       I = Info.AsmOperandClasses.begin(),
19914dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach       E = Info.AsmOperandClasses.end(); I != E; ++I) {
19924dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach    if (!I->second->DiagnosticType.empty())
19934dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach      Types.insert(I->second->DiagnosticType);
19944dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  }
19954dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach
19964dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  if (Types.empty()) return;
19974dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach
19984dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  // Now emit the enum entries.
19994dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  for (std::set<StringRef>::const_iterator I = Types.begin(), E = Types.end();
20004dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach       I != E; ++I)
20014dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach    OS << "  Match_" << *I << ",\n";
20024dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  OS << "  END_OPERAND_DIAGNOSTIC_TYPES\n";
20034dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach}
20044dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach
200514ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach/// emitGetSubtargetFeatureName - Emit the helper function to get the
200614ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach/// user-level name for a subtarget feature.
200714ce6fac242228dacc5c08040e544141a96880e5Jim Grosbachstatic void emitGetSubtargetFeatureName(AsmMatcherInfo &Info, raw_ostream &OS) {
200814ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach  OS << "// User-level names for subtarget features that participate in\n"
200914ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach     << "// instruction matching.\n"
201014ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach     << "static const char *getSubtargetFeatureName(unsigned Val) {\n"
201114ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach     << "  switch(Val) {\n";
201214ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach  for (std::map<Record*, SubtargetFeatureInfo*>::const_iterator
201314ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach         it = Info.SubtargetFeatures.begin(),
201414ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach         ie = Info.SubtargetFeatures.end(); it != ie; ++it) {
201514ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach    SubtargetFeatureInfo &SFI = *it->second;
201614ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach    // FIXME: Totally just a placeholder name to get the algorithm working.
201714ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach    OS << "  case " << SFI.getEnumName() << ": return \""
201814ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach       << SFI.TheDef->getValueAsString("PredicateName") << "\";\n";
201914ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach  }
202014ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach  OS << "  default: return \"(unknown)\";\n";
202114ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach  OS << "  }\n}\n\n";
202214ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach}
202314ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach
20248caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach/// emitComputeAvailableFeatures - Emit the function to compute the list of
202554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar/// available features given a subtarget.
20268caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachstatic void emitComputeAvailableFeatures(AsmMatcherInfo &Info,
202754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar                                         raw_ostream &OS) {
202854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  std::string ClassName =
202954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar    Info.AsmParser->getValueAsString("AsmParserClassName");
203054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar
203102bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner  OS << "unsigned " << Info.Target.getName() << ClassName << "::\n"
2032ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng     << "ComputeAvailableFeatures(uint64_t FB) const {\n";
203354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  OS << "  unsigned Features = 0;\n";
203454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  for (std::map<Record*, SubtargetFeatureInfo*>::const_iterator
203554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar         it = Info.SubtargetFeatures.begin(),
203654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar         ie = Info.SubtargetFeatures.end(); it != ie; ++it) {
203754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar    SubtargetFeatureInfo &SFI = *it->second;
2038ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
2039ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    OS << "  if (";
204065da6fc8af561e77620bd86b83be8ca50acfdd30Jim Grosbach    std::string CondStorage =
204165da6fc8af561e77620bd86b83be8ca50acfdd30Jim Grosbach      SFI.TheDef->getValueAsString("AssemblerCondString");
2042fbc38d2c16bc2fb923efdbbd6035ec8233fb4856Evan Cheng    StringRef Conds = CondStorage;
2043ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    std::pair<StringRef,StringRef> Comma = Conds.split(',');
2044ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    bool First = true;
2045ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    do {
2046ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng      if (!First)
2047ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng        OS << " && ";
2048ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
2049ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng      bool Neg = false;
2050ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng      StringRef Cond = Comma.first;
2051ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng      if (Cond[0] == '!') {
2052ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng        Neg = true;
2053ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng        Cond = Cond.substr(1);
2054ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng      }
2055ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
2056ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng      OS << "((FB & " << Info.Target.getName() << "::" << Cond << ")";
2057ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng      if (Neg)
2058ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng        OS << " == 0";
2059ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng      else
2060ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng        OS << " != 0";
2061ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng      OS << ")";
2062ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
2063ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng      if (Comma.second.empty())
2064ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng        break;
2065ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
2066ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng      First = false;
2067ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng      Comma = Comma.second.split(',');
2068ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    } while (true);
2069ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
2070ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    OS << ")\n";
20710aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner    OS << "    Features |= " << SFI.getEnumName() << ";\n";
207254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  }
207354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  OS << "  return Features;\n";
207454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  OS << "}\n\n";
207554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar}
207654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar
20776fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattnerstatic std::string GetAliasRequiredFeatures(Record *R,
20786fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner                                            const AsmMatcherInfo &Info) {
2079693173feefaa326fad0e386470846fb3199ba381Chris Lattner  std::vector<Record*> ReqFeatures = R->getValueAsListOfDefs("Predicates");
2080693173feefaa326fad0e386470846fb3199ba381Chris Lattner  std::string Result;
2081693173feefaa326fad0e386470846fb3199ba381Chris Lattner  unsigned NumFeatures = 0;
2082693173feefaa326fad0e386470846fb3199ba381Chris Lattner  for (unsigned i = 0, e = ReqFeatures.size(); i != e; ++i) {
20834a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner    SubtargetFeatureInfo *F = Info.getSubtargetFeature(ReqFeatures[i]);
2084828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
20854a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner    if (F == 0)
20864a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner      throw TGError(R->getLoc(), "Predicate '" + ReqFeatures[i]->getName() +
20874a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner                    "' is not marked as an AssemblerPredicate!");
2088828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
20894a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner    if (NumFeatures)
20904a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner      Result += '|';
2091828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
20924a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner    Result += F->getEnumName();
20934a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner    ++NumFeatures;
2094693173feefaa326fad0e386470846fb3199ba381Chris Lattner  }
2095828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
2096693173feefaa326fad0e386470846fb3199ba381Chris Lattner  if (NumFeatures > 1)
2097693173feefaa326fad0e386470846fb3199ba381Chris Lattner    Result = '(' + Result + ')';
2098693173feefaa326fad0e386470846fb3199ba381Chris Lattner  return Result;
2099693173feefaa326fad0e386470846fb3199ba381Chris Lattner}
2100693173feefaa326fad0e386470846fb3199ba381Chris Lattner
21018caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach/// emitMnemonicAliases - If the target has any MnemonicAlias<> definitions,
21027fd4489de11bdf06f6c852d42abafea013b76f28Chris Lattner/// emit a function for them and return true, otherwise return false.
21038caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachstatic bool emitMnemonicAliases(raw_ostream &OS, const AsmMatcherInfo &Info) {
2104c0a7007d3a6a7bb31eec568b9dfdb8fb137702e5Daniel Dunbar  // Ignore aliases when match-prefix is set.
2105c0a7007d3a6a7bb31eec568b9dfdb8fb137702e5Daniel Dunbar  if (!MatchPrefix.empty())
2106c0a7007d3a6a7bb31eec568b9dfdb8fb137702e5Daniel Dunbar    return false;
2107c0a7007d3a6a7bb31eec568b9dfdb8fb137702e5Daniel Dunbar
2108674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner  std::vector<Record*> Aliases =
210967db883487fca3472fdde51e931657e22d4d0495Chris Lattner    Info.getRecords().getAllDerivedDefinitions("MnemonicAlias");
21107fd4489de11bdf06f6c852d42abafea013b76f28Chris Lattner  if (Aliases.empty()) return false;
2111674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner
21123d5d8f6b768619ed65f79606d5c981c1e056c7e8Jim Grosbach  OS << "static void applyMnemonicAliases(StringRef &Mnemonic, "
21138cc0a6b788a17b3afc779e9da90f5203c8b78436Chris Lattner        "unsigned Features) {\n";
2114828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
21154fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner  // Keep track of all the aliases from a mnemonic.  Use an std::map so that the
21164fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner  // iteration order of the map is stable.
21174fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner  std::map<std::string, std::vector<Record*> > AliasesFromMnemonic;
2118828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
2119674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner  for (unsigned i = 0, e = Aliases.size(); i != e; ++i) {
2120674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner    Record *R = Aliases[i];
21214fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner    AliasesFromMnemonic[R->getValueAsString("FromMnemonic")].push_back(R);
21224fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner  }
21234fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner
21244fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner  // Process each alias a "from" mnemonic at a time, building the code executed
21254fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner  // by the string remapper.
21264fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner  std::vector<StringMatcher::StringPair> Cases;
21274fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner  for (std::map<std::string, std::vector<Record*> >::iterator
21284fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner       I = AliasesFromMnemonic.begin(), E = AliasesFromMnemonic.end();
21294fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner       I != E; ++I) {
21304fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner    const std::vector<Record*> &ToVec = I->second;
2131693173feefaa326fad0e386470846fb3199ba381Chris Lattner
2132693173feefaa326fad0e386470846fb3199ba381Chris Lattner    // Loop through each alias and emit code that handles each case.  If there
2133693173feefaa326fad0e386470846fb3199ba381Chris Lattner    // are two instructions without predicates, emit an error.  If there is one,
2134693173feefaa326fad0e386470846fb3199ba381Chris Lattner    // emit it last.
2135693173feefaa326fad0e386470846fb3199ba381Chris Lattner    std::string MatchCode;
2136693173feefaa326fad0e386470846fb3199ba381Chris Lattner    int AliasWithNoPredicate = -1;
2137828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
2138693173feefaa326fad0e386470846fb3199ba381Chris Lattner    for (unsigned i = 0, e = ToVec.size(); i != e; ++i) {
2139693173feefaa326fad0e386470846fb3199ba381Chris Lattner      Record *R = ToVec[i];
21406fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner      std::string FeatureMask = GetAliasRequiredFeatures(R, Info);
2141828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
2142693173feefaa326fad0e386470846fb3199ba381Chris Lattner      // If this unconditionally matches, remember it for later and diagnose
2143693173feefaa326fad0e386470846fb3199ba381Chris Lattner      // duplicates.
2144693173feefaa326fad0e386470846fb3199ba381Chris Lattner      if (FeatureMask.empty()) {
2145693173feefaa326fad0e386470846fb3199ba381Chris Lattner        if (AliasWithNoPredicate != -1) {
2146693173feefaa326fad0e386470846fb3199ba381Chris Lattner          // We can't have two aliases from the same mnemonic with no predicate.
2147693173feefaa326fad0e386470846fb3199ba381Chris Lattner          PrintError(ToVec[AliasWithNoPredicate]->getLoc(),
2148693173feefaa326fad0e386470846fb3199ba381Chris Lattner                     "two MnemonicAliases with the same 'from' mnemonic!");
21494164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner          throw TGError(R->getLoc(), "this is the other MnemonicAlias.");
2150693173feefaa326fad0e386470846fb3199ba381Chris Lattner        }
2151828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
2152693173feefaa326fad0e386470846fb3199ba381Chris Lattner        AliasWithNoPredicate = i;
2153693173feefaa326fad0e386470846fb3199ba381Chris Lattner        continue;
2154693173feefaa326fad0e386470846fb3199ba381Chris Lattner      }
21556ef6ceda6883d0ee543d8da86d16b0fcdcecab96Joerg Sonnenberger      if (R->getValueAsString("ToMnemonic") == I->first)
21566ef6ceda6883d0ee543d8da86d16b0fcdcecab96Joerg Sonnenberger        throw TGError(R->getLoc(), "MnemonicAlias to the same string");
2157828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
21588cf8bcc40c977713e51fb85fb9f24a0ecfbde24bChris Lattner      if (!MatchCode.empty())
21598cf8bcc40c977713e51fb85fb9f24a0ecfbde24bChris Lattner        MatchCode += "else ";
2160693173feefaa326fad0e386470846fb3199ba381Chris Lattner      MatchCode += "if ((Features & " + FeatureMask + ") == "+FeatureMask+")\n";
2161693173feefaa326fad0e386470846fb3199ba381Chris Lattner      MatchCode += "  Mnemonic = \"" +R->getValueAsString("ToMnemonic")+"\";\n";
2162693173feefaa326fad0e386470846fb3199ba381Chris Lattner    }
2163828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
2164693173feefaa326fad0e386470846fb3199ba381Chris Lattner    if (AliasWithNoPredicate != -1) {
2165693173feefaa326fad0e386470846fb3199ba381Chris Lattner      Record *R = ToVec[AliasWithNoPredicate];
21668cf8bcc40c977713e51fb85fb9f24a0ecfbde24bChris Lattner      if (!MatchCode.empty())
21678cf8bcc40c977713e51fb85fb9f24a0ecfbde24bChris Lattner        MatchCode += "else\n  ";
21688cf8bcc40c977713e51fb85fb9f24a0ecfbde24bChris Lattner      MatchCode += "Mnemonic = \"" + R->getValueAsString("ToMnemonic")+"\";\n";
21694fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner    }
2170828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
2171693173feefaa326fad0e386470846fb3199ba381Chris Lattner    MatchCode += "return;";
2172693173feefaa326fad0e386470846fb3199ba381Chris Lattner
2173693173feefaa326fad0e386470846fb3199ba381Chris Lattner    Cases.push_back(std::make_pair(I->first, MatchCode));
2174674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner  }
2175828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
2176674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner  StringMatcher("Mnemonic", Cases, OS).Emit();
217755b5e85643b189636758188f11b598c45178407fDaniel Dunbar  OS << "}\n\n";
2178828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
21797fd4489de11bdf06f6c852d42abafea013b76f28Chris Lattner  return true;
2180674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner}
2181674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner
2182194f3fa9eadc7dfe9f1750c16e1c2a8ebe11c88cJim Grosbachstatic const char *getMinimalTypeForRange(uint64_t Range) {
2183194f3fa9eadc7dfe9f1750c16e1c2a8ebe11c88cJim Grosbach  assert(Range < 0xFFFFFFFFULL && "Enum too large");
2184194f3fa9eadc7dfe9f1750c16e1c2a8ebe11c88cJim Grosbach  if (Range > 0xFFFF)
2185194f3fa9eadc7dfe9f1750c16e1c2a8ebe11c88cJim Grosbach    return "uint32_t";
2186194f3fa9eadc7dfe9f1750c16e1c2a8ebe11c88cJim Grosbach  if (Range > 0xFF)
2187194f3fa9eadc7dfe9f1750c16e1c2a8ebe11c88cJim Grosbach    return "uint16_t";
2188194f3fa9eadc7dfe9f1750c16e1c2a8ebe11c88cJim Grosbach  return "uint8_t";
2189194f3fa9eadc7dfe9f1750c16e1c2a8ebe11c88cJim Grosbach}
2190194f3fa9eadc7dfe9f1750c16e1c2a8ebe11c88cJim Grosbach
21918caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachstatic void emitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target,
2192e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes                              const AsmMatcherInfo &Info, StringRef ClassName) {
2193e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  // Emit the static custom operand parsing table;
2194e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "namespace {\n";
2195e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "  struct OperandMatchEntry {\n";
21967044cce1a30539e2ec779f49546d13d7db5a33dfJakob Stoklund Olesen  OS << "    static const char *const MnemonicTable;\n";
2197fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper  OS << "    uint32_t OperandMask;\n";
2198fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper  OS << "    uint32_t Mnemonic;\n";
2199b08bb34a6f49c79e963aac52030c0cbeb0526f86Benjamin Kramer  OS << "    " << getMinimalTypeForRange(1ULL << Info.SubtargetFeatures.size())
2200fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper               << " RequiredFeatures;\n";
2201fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper  OS << "    " << getMinimalTypeForRange(Info.Classes.size())
2202fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper               << " Class;\n\n";
2203b08bb34a6f49c79e963aac52030c0cbeb0526f86Benjamin Kramer  OS << "    StringRef getMnemonic() const {\n";
2204b08bb34a6f49c79e963aac52030c0cbeb0526f86Benjamin Kramer  OS << "      return StringRef(MnemonicTable + Mnemonic + 1,\n";
2205b08bb34a6f49c79e963aac52030c0cbeb0526f86Benjamin Kramer  OS << "                       MnemonicTable[Mnemonic]);\n";
2206b08bb34a6f49c79e963aac52030c0cbeb0526f86Benjamin Kramer  OS << "    }\n";
2207e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "  };\n\n";
2208e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2209e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "  // Predicate for searching for an opcode.\n";
2210e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "  struct LessOpcodeOperand {\n";
2211e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "    bool operator()(const OperandMatchEntry &LHS, StringRef RHS) {\n";
2212b08bb34a6f49c79e963aac52030c0cbeb0526f86Benjamin Kramer  OS << "      return LHS.getMnemonic()  < RHS;\n";
2213e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "    }\n";
2214e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "    bool operator()(StringRef LHS, const OperandMatchEntry &RHS) {\n";
2215b08bb34a6f49c79e963aac52030c0cbeb0526f86Benjamin Kramer  OS << "      return LHS < RHS.getMnemonic();\n";
2216e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "    }\n";
2217e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "    bool operator()(const OperandMatchEntry &LHS,";
2218e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << " const OperandMatchEntry &RHS) {\n";
2219b08bb34a6f49c79e963aac52030c0cbeb0526f86Benjamin Kramer  OS << "      return LHS.getMnemonic() < RHS.getMnemonic();\n";
2220e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "    }\n";
2221e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "  };\n";
2222e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2223e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "} // end anonymous namespace.\n\n";
2224e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2225b08bb34a6f49c79e963aac52030c0cbeb0526f86Benjamin Kramer  StringToOffsetTable StringTable;
2226b08bb34a6f49c79e963aac52030c0cbeb0526f86Benjamin Kramer
2227e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "static const OperandMatchEntry OperandMatchTable["
2228e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes     << Info.OperandMatchInfo.size() << "] = {\n";
2229e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2230b08bb34a6f49c79e963aac52030c0cbeb0526f86Benjamin Kramer  OS << "  /* Operand List Mask, Mnemonic, Operand Class, Features */\n";
2231e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  for (std::vector<OperandMatchEntry>::const_iterator it =
2232e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes       Info.OperandMatchInfo.begin(), ie = Info.OperandMatchInfo.end();
2233e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes       it != ie; ++it) {
2234e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    const OperandMatchEntry &OMI = *it;
2235e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    const MatchableInfo &II = *OMI.MI;
2236e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2237b08bb34a6f49c79e963aac52030c0cbeb0526f86Benjamin Kramer    OS << "  { " << OMI.OperandMask;
2238e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2239e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    OS << " /* ";
2240e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    bool printComma = false;
2241e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    for (int i = 0, e = 31; i !=e; ++i)
2242e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes      if (OMI.OperandMask & (1 << i)) {
2243e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes        if (printComma)
2244e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes          OS << ", ";
2245e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes        OS << i;
2246e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes        printComma = true;
2247e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes      }
2248e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    OS << " */";
2249e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2250b08bb34a6f49c79e963aac52030c0cbeb0526f86Benjamin Kramer    // Store a pascal-style length byte in the mnemonic.
2251b08bb34a6f49c79e963aac52030c0cbeb0526f86Benjamin Kramer    std::string LenMnemonic = char(II.Mnemonic.size()) + II.Mnemonic.str();
2252bcfa982c4866fee5f86dca8c4bfc7425a9629f0dJakob Stoklund Olesen    OS << ", " << StringTable.GetOrAddStringOffset(LenMnemonic, false)
2253fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper       << " /* " << II.Mnemonic << " */, ";
2254e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2255e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    // Write the required features mask.
2256e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    if (!II.RequiredFeatures.empty()) {
2257e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes      for (unsigned i = 0, e = II.RequiredFeatures.size(); i != e; ++i) {
2258e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes        if (i) OS << "|";
2259e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes        OS << II.RequiredFeatures[i]->getEnumName();
2260e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes      }
2261e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    } else
2262e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes      OS << "0";
2263fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper
2264fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper    OS << ", " << OMI.CI->Name;
2265fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper
2266e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    OS << " },\n";
2267e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  }
2268e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "};\n\n";
2269e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
22707044cce1a30539e2ec779f49546d13d7db5a33dfJakob Stoklund Olesen  OS << "const char *const OperandMatchEntry::MnemonicTable =\n";
2271b08bb34a6f49c79e963aac52030c0cbeb0526f86Benjamin Kramer  StringTable.EmitString(OS);
2272b08bb34a6f49c79e963aac52030c0cbeb0526f86Benjamin Kramer  OS << ";\n\n";
2273b08bb34a6f49c79e963aac52030c0cbeb0526f86Benjamin Kramer
2274e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  // Emit the operand class switch to call the correct custom parser for
2275e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  // the found operand class.
2276f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OS << Target.getName() << ClassName << "::OperandMatchResultTy "
2277f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach     << Target.getName() << ClassName << "::\n"
22783d5d8f6b768619ed65f79606d5c981c1e056c7e8Jim Grosbach     << "tryCustomParseOperand(SmallVectorImpl<MCParsedAsmOperand*>"
2279e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes     << " &Operands,\n                      unsigned MCK) {\n\n"
2280e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes     << "  switch(MCK) {\n";
2281e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2282e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  for (std::vector<ClassInfo*>::const_iterator it = Info.Classes.begin(),
2283e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes       ie = Info.Classes.end(); it != ie; ++it) {
2284e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    ClassInfo *CI = *it;
2285e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    if (CI->ParserMethod.empty())
2286e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes      continue;
2287e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    OS << "  case " << CI->Name << ":\n"
2288e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes       << "    return " << CI->ParserMethod << "(Operands);\n";
2289e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  }
2290e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2291e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "  default:\n";
2292f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OS << "    return MatchOperand_NoMatch;\n";
2293e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "  }\n";
2294f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OS << "  return MatchOperand_NoMatch;\n";
2295e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "}\n\n";
2296e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2297e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  // Emit the static custom operand parser. This code is very similar with
2298e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  // the other matcher. Also use MatchResultTy here just in case we go for
2299e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  // a better error handling.
2300f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OS << Target.getName() << ClassName << "::OperandMatchResultTy "
2301e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes     << Target.getName() << ClassName << "::\n"
2302e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes     << "MatchOperandParserImpl(SmallVectorImpl<MCParsedAsmOperand*>"
2303e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes     << " &Operands,\n                       StringRef Mnemonic) {\n";
2304e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2305e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  // Emit code to get the available features.
2306e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "  // Get the current feature set.\n";
2307e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "  unsigned AvailableFeatures = getAvailableFeatures();\n\n";
2308e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2309e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "  // Get the next operand index.\n";
2310e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "  unsigned NextOpNum = Operands.size()-1;\n";
2311e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2312e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  // Emit code to search the table.
2313e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "  // Search the table.\n";
2314e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "  std::pair<const OperandMatchEntry*, const OperandMatchEntry*>";
2315e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << " MnemonicRange =\n";
2316e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "    std::equal_range(OperandMatchTable, OperandMatchTable+"
2317e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes     << Info.OperandMatchInfo.size() << ", Mnemonic,\n"
2318e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes     << "                     LessOpcodeOperand());\n\n";
2319e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2320e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "  if (MnemonicRange.first == MnemonicRange.second)\n";
2321f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OS << "    return MatchOperand_NoMatch;\n\n";
2322e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2323e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "  for (const OperandMatchEntry *it = MnemonicRange.first,\n"
2324e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes     << "       *ie = MnemonicRange.second; it != ie; ++it) {\n";
2325e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2326e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "    // equal_range guarantees that instruction mnemonic matches.\n";
2327b08bb34a6f49c79e963aac52030c0cbeb0526f86Benjamin Kramer  OS << "    assert(Mnemonic == it->getMnemonic());\n\n";
2328e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2329e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  // Emit check that the required features are available.
2330e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "    // check if the available features match\n";
2331e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "    if ((AvailableFeatures & it->RequiredFeatures) "
2332e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes     << "!= it->RequiredFeatures) {\n";
2333e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "      continue;\n";
2334e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "    }\n\n";
2335e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2336e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  // Emit check to ensure the operand number matches.
2337e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "    // check if the operand in question has a custom parser.\n";
2338e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "    if (!(it->OperandMask & (1 << NextOpNum)))\n";
2339e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "      continue;\n\n";
2340e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2341e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  // Emit call to the custom parser method
2342e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "    // call custom parse method to handle the operand\n";
2343f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OS << "    OperandMatchResultTy Result = ";
23443d5d8f6b768619ed65f79606d5c981c1e056c7e8Jim Grosbach  OS << "tryCustomParseOperand(Operands, it->Class);\n";
2345f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OS << "    if (Result != MatchOperand_NoMatch)\n";
2346f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OS << "      return Result;\n";
2347e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "  }\n\n";
2348e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2349f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OS << "  // Okay, we had no match.\n";
2350f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OS << "  return MatchOperand_NoMatch;\n";
2351e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "}\n\n";
2352e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes}
2353e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
23542234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbarvoid AsmMatcherEmitter::run(raw_ostream &OS) {
235567db883487fca3472fdde51e931657e22d4d0495Chris Lattner  CodeGenTarget Target(Records);
23562234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar  Record *AsmParser = Target.getAsmParser();
23572234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar  std::string ClassName = AsmParser->getValueAsString("AsmParserClassName");
23582234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar
2359a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  // Compute the information on the instructions to match.
236067db883487fca3472fdde51e931657e22d4d0495Chris Lattner  AsmMatcherInfo Info(AsmParser, Target, Records);
23618caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  Info.buildInfo();
236220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
2363e1f6de3fbd892ea3f918a26912660cf316866fc1Daniel Dunbar  // Sort the instruction table using the partial order on classes. We use
2364e1f6de3fbd892ea3f918a26912660cf316866fc1Daniel Dunbar  // stable_sort to ensure that ambiguous instructions are still
2365e1f6de3fbd892ea3f918a26912660cf316866fc1Daniel Dunbar  // deterministically ordered.
236622bc5c4184a497353e33195dd12541a4f08b008aChris Lattner  std::stable_sort(Info.Matchables.begin(), Info.Matchables.end(),
236722bc5c4184a497353e33195dd12541a4f08b008aChris Lattner                   less_ptr<MatchableInfo>());
2368a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
2369b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar  DEBUG_WITH_TYPE("instruction_info", {
237022bc5c4184a497353e33195dd12541a4f08b008aChris Lattner      for (std::vector<MatchableInfo*>::iterator
237122bc5c4184a497353e33195dd12541a4f08b008aChris Lattner             it = Info.Matchables.begin(), ie = Info.Matchables.end();
2372a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar           it != ie; ++it)
237320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar        (*it)->dump();
237420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    });
237520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
237622bc5c4184a497353e33195dd12541a4f08b008aChris Lattner  // Check for ambiguous matchables.
2377fa0d74d58e6c70ef032afb5f83680276dc4d7370Chris Lattner  DEBUG_WITH_TYPE("ambiguous_instrs", {
2378fa0d74d58e6c70ef032afb5f83680276dc4d7370Chris Lattner    unsigned NumAmbiguous = 0;
237922bc5c4184a497353e33195dd12541a4f08b008aChris Lattner    for (unsigned i = 0, e = Info.Matchables.size(); i != e; ++i) {
238087410368e1bd50408e787f6ece0e58d94c53c1e1Chris Lattner      for (unsigned j = i + 1; j != e; ++j) {
238122bc5c4184a497353e33195dd12541a4f08b008aChris Lattner        MatchableInfo &A = *Info.Matchables[i];
238222bc5c4184a497353e33195dd12541a4f08b008aChris Lattner        MatchableInfo &B = *Info.Matchables[j];
2383a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
23848caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach        if (A.couldMatchAmbiguouslyWith(B)) {
238522bc5c4184a497353e33195dd12541a4f08b008aChris Lattner          errs() << "warning: ambiguous matchables:\n";
2386fa0d74d58e6c70ef032afb5f83680276dc4d7370Chris Lattner          A.dump();
2387fa0d74d58e6c70ef032afb5f83680276dc4d7370Chris Lattner          errs() << "\nis incomparable with:\n";
2388fa0d74d58e6c70ef032afb5f83680276dc4d7370Chris Lattner          B.dump();
2389fa0d74d58e6c70ef032afb5f83680276dc4d7370Chris Lattner          errs() << "\n\n";
239087410368e1bd50408e787f6ece0e58d94c53c1e1Chris Lattner          ++NumAmbiguous;
239187410368e1bd50408e787f6ece0e58d94c53c1e1Chris Lattner        }
23922b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar      }
2393606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar    }
239487410368e1bd50408e787f6ece0e58d94c53c1e1Chris Lattner    if (NumAmbiguous)
2395a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach      errs() << "warning: " << NumAmbiguous
239622bc5c4184a497353e33195dd12541a4f08b008aChris Lattner             << " ambiguous matchables!\n";
2397fa0d74d58e6c70ef032afb5f83680276dc4d7370Chris Lattner  });
2398606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar
2399e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  // Compute the information on the custom operand parsing.
24008caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  Info.buildOperandMatchInfo();
2401e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
24021095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar  // Write the output.
24031095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar
24040692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner  // Information for the class declaration.
24050692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner  OS << "\n#ifdef GET_ASSEMBLER_HEADER\n";
24060692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner  OS << "#undef GET_ASSEMBLER_HEADER\n";
240784cb033bf30b6f93ae2fbea71513970147e08dc2Jim Grosbach  OS << "  // This should be included into the middle of the declaration of\n";
240894b9550a32d189704a8eae55505edf62662c0534Evan Cheng  OS << "  // your subclasses implementation of MCTargetAsmParser.\n";
2409ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  OS << "  unsigned ComputeAvailableFeatures(uint64_t FeatureBits) const;\n";
24105c228a945fe3e25a12d0f7e2e9b26b548d6f29f5Daniel Dunbar  OS << "  bool ConvertToMCInst(unsigned Kind, MCInst &Inst, "
24115c228a945fe3e25a12d0f7e2e9b26b548d6f29f5Daniel Dunbar     << "unsigned Opcode,\n"
24125c228a945fe3e25a12d0f7e2e9b26b548d6f29f5Daniel Dunbar     << "                       const SmallVectorImpl<MCParsedAsmOperand*> "
24135c228a945fe3e25a12d0f7e2e9b26b548d6f29f5Daniel Dunbar     << "&Operands);\n";
24141fe3aa15e9cdc4981d7a125d87eaf257c1d75af1Bob Wilson  OS << "  bool MnemonicIsValid(StringRef Mnemonic);\n";
241519cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  OS << "  unsigned MatchInstructionImpl(\n";
2416083203dde8bd50e1be47ac6509ae52f43abcd12aDaniel Dunbar  OS << "    const SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n";
241756315d319c104dc96187444e1e19711a1c801166Devang Patel  OS << "    MCInst &Inst, unsigned &ErrorInfo, unsigned VariantID = 0);\n";
2418e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2419e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  if (Info.OperandMatchInfo.size()) {
2420f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    OS << "\n  enum OperandMatchResultTy {\n";
2421f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    OS << "    MatchOperand_Success,    // operand matched successfully\n";
2422f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    OS << "    MatchOperand_NoMatch,    // operand did not match\n";
2423f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    OS << "    MatchOperand_ParseFail   // operand matched but had errors\n";
2424f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    OS << "  };\n";
2425f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    OS << "  OperandMatchResultTy MatchOperandParserImpl(\n";
2426e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    OS << "    SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n";
2427e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    OS << "    StringRef Mnemonic);\n";
2428e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
24293d5d8f6b768619ed65f79606d5c981c1e056c7e8Jim Grosbach    OS << "  OperandMatchResultTy tryCustomParseOperand(\n";
2430e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    OS << "    SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n";
2431e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    OS << "    unsigned MCK);\n\n";
2432e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  }
2433e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
24340692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner  OS << "#endif // GET_ASSEMBLER_HEADER_INFO\n\n";
24350692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner
24364dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  // Emit the operand match diagnostic enum names.
24374dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  OS << "\n#ifdef GET_OPERAND_DIAGNOSTIC_TYPES\n";
24384dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  OS << "#undef GET_OPERAND_DIAGNOSTIC_TYPES\n\n";
24394dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  emitOperandDiagnosticTypes(Info, OS);
24404dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  OS << "#endif // GET_OPERAND_DIAGNOSTIC_TYPES\n\n";
24414dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach
24424dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach
24430692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner  OS << "\n#ifdef GET_REGISTER_MATCHER\n";
24440692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner  OS << "#undef GET_REGISTER_MATCHER\n\n";
24450692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner
244654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  // Emit the subtarget feature enumeration.
24478caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  emitSubtargetFeatureFlagEnumeration(Info, OS);
244854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar
24491095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar  // Emit the function to match a register name to number.
245072e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  // This should be omitted for Mips target
245172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  if (AsmParser->getValueAsBit("ShouldEmitMatchRegisterName"))
245272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    emitMatchRegisterName(Target, AsmParser, OS);
24530692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner
24540692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner  OS << "#endif // GET_REGISTER_MATCHER\n\n";
2455a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
24568030e1a0df630ec6ed1cd5ec673f6472558a4dbeCraig Topper  OS << "\n#ifdef GET_SUBTARGET_FEATURE_NAME\n";
24578030e1a0df630ec6ed1cd5ec673f6472558a4dbeCraig Topper  OS << "#undef GET_SUBTARGET_FEATURE_NAME\n\n";
24581095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar
245914ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach  // Generate the helper function to get the names for subtarget features.
246014ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach  emitGetSubtargetFeatureName(Info, OS);
246114ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach
24628030e1a0df630ec6ed1cd5ec673f6472558a4dbeCraig Topper  OS << "#endif // GET_SUBTARGET_FEATURE_NAME\n\n";
24638030e1a0df630ec6ed1cd5ec673f6472558a4dbeCraig Topper
24648030e1a0df630ec6ed1cd5ec673f6472558a4dbeCraig Topper  OS << "\n#ifdef GET_MATCHER_IMPLEMENTATION\n";
24658030e1a0df630ec6ed1cd5ec673f6472558a4dbeCraig Topper  OS << "#undef GET_MATCHER_IMPLEMENTATION\n\n";
24668030e1a0df630ec6ed1cd5ec673f6472558a4dbeCraig Topper
24677fd4489de11bdf06f6c852d42abafea013b76f28Chris Lattner  // Generate the function that remaps for mnemonic aliases.
24688caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  bool HasMnemonicAliases = emitMnemonicAliases(OS, Info);
2469828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
2470606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar  // Generate the unified function to convert operands into an MCInst.
24718caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  emitConvertToMCInst(Target, ClassName, Info.Matchables, OS);
2472a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
2473a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  // Emit the enumeration for classes which participate in matching.
24748caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  emitMatchClassEnumeration(Target, Info.Classes, OS);
247520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
2476a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  // Emit the routine to match token strings to their match class.
24778caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  emitMatchTokenString(Target, Info.Classes, OS);
247820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
2479fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar  // Emit the subclass predicate routine.
24808caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  emitIsSubclass(Target, Info.Classes, OS);
2481fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar
2482b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach  // Emit the routine to validate an operand against a match class.
24838caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  emitValidateOperandClass(Info, OS);
2484b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach
248554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  // Emit the available features compute function.
24868caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  emitComputeAvailableFeatures(Info, OS);
248754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar
2488a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
2489a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  size_t MaxNumOperands = 0;
249022bc5c4184a497353e33195dd12541a4f08b008aChris Lattner  for (std::vector<MatchableInfo*>::const_iterator it =
249122bc5c4184a497353e33195dd12541a4f08b008aChris Lattner         Info.Matchables.begin(), ie = Info.Matchables.end();
2492a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar       it != ie; ++it)
24933116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner    MaxNumOperands = std::max(MaxNumOperands, (*it)->AsmOperands.size());
2494a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
2495a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  // Emit the static match table; unused classes get initalized to 0 which is
2496a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  // guaranteed to be InvalidMatchClass.
2497a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  //
2498a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  // FIXME: We can reduce the size of this table very easily. First, we change
2499a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  // it so that store the kinds in separate bit-fields for each index, which
2500a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  // only needs to be the max width used for classes at that index (we also need
2501a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  // to reject based on this during classification). If we then make sure to
2502a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  // order the match kinds appropriately (putting mnemonics last), then we
2503a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  // should only end up using a few bits for each class, especially the ones
2504a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  // following the mnemonic.
250596352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner  OS << "namespace {\n";
250696352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner  OS << "  struct MatchEntry {\n";
25077044cce1a30539e2ec779f49546d13d7db5a33dfJakob Stoklund Olesen  OS << "    static const char *const MnemonicTable;\n";
2508fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper  OS << "    uint32_t Mnemonic;\n";
2509a4c5ecfb1bc0101c1b42a4d81bb427482b52cecfBenjamin Kramer  OS << "    uint16_t Opcode;\n";
2510af482cf301cf35eebb3a67a3540e16b102b92246Benjamin Kramer  OS << "    " << getMinimalTypeForRange(Info.Matchables.size())
2511af482cf301cf35eebb3a67a3540e16b102b92246Benjamin Kramer               << " ConvertFn;\n";
2512af482cf301cf35eebb3a67a3540e16b102b92246Benjamin Kramer  OS << "    " << getMinimalTypeForRange(1ULL << Info.SubtargetFeatures.size())
2513af482cf301cf35eebb3a67a3540e16b102b92246Benjamin Kramer               << " RequiredFeatures;\n";
2514fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper  OS << "    " << getMinimalTypeForRange(Info.Classes.size())
2515fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper               << " Classes[" << MaxNumOperands << "];\n";
2516a4c5ecfb1bc0101c1b42a4d81bb427482b52cecfBenjamin Kramer  OS << "    uint8_t AsmVariantID;\n\n";
2517a4c5ecfb1bc0101c1b42a4d81bb427482b52cecfBenjamin Kramer  OS << "    StringRef getMnemonic() const {\n";
2518a4c5ecfb1bc0101c1b42a4d81bb427482b52cecfBenjamin Kramer  OS << "      return StringRef(MnemonicTable + Mnemonic + 1,\n";
2519a4c5ecfb1bc0101c1b42a4d81bb427482b52cecfBenjamin Kramer  OS << "                       MnemonicTable[Mnemonic]);\n";
2520a4c5ecfb1bc0101c1b42a4d81bb427482b52cecfBenjamin Kramer  OS << "    }\n";
25212b1f943444d1853204725c7b45b1e1032be39958Chris Lattner  OS << "  };\n\n";
2522a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
2523e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "  // Predicate for searching for an opcode.\n";
25242b1f943444d1853204725c7b45b1e1032be39958Chris Lattner  OS << "  struct LessOpcode {\n";
25252b1f943444d1853204725c7b45b1e1032be39958Chris Lattner  OS << "    bool operator()(const MatchEntry &LHS, StringRef RHS) {\n";
2526a4c5ecfb1bc0101c1b42a4d81bb427482b52cecfBenjamin Kramer  OS << "      return LHS.getMnemonic() < RHS;\n";
25272b1f943444d1853204725c7b45b1e1032be39958Chris Lattner  OS << "    }\n";
25282b1f943444d1853204725c7b45b1e1032be39958Chris Lattner  OS << "    bool operator()(StringRef LHS, const MatchEntry &RHS) {\n";
2529a4c5ecfb1bc0101c1b42a4d81bb427482b52cecfBenjamin Kramer  OS << "      return LHS < RHS.getMnemonic();\n";
25302b1f943444d1853204725c7b45b1e1032be39958Chris Lattner  OS << "    }\n";
253132c685cb67ff7701f4970ef61765cae7a50f255cChris Lattner  OS << "    bool operator()(const MatchEntry &LHS, const MatchEntry &RHS) {\n";
2532a4c5ecfb1bc0101c1b42a4d81bb427482b52cecfBenjamin Kramer  OS << "      return LHS.getMnemonic() < RHS.getMnemonic();\n";
253332c685cb67ff7701f4970ef61765cae7a50f255cChris Lattner  OS << "    }\n";
253496352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner  OS << "  };\n";
2535a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
253696352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner  OS << "} // end anonymous namespace.\n\n";
2537a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
2538a4c5ecfb1bc0101c1b42a4d81bb427482b52cecfBenjamin Kramer  StringToOffsetTable StringTable;
2539a4c5ecfb1bc0101c1b42a4d81bb427482b52cecfBenjamin Kramer
254096352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner  OS << "static const MatchEntry MatchTable["
254122bc5c4184a497353e33195dd12541a4f08b008aChris Lattner     << Info.Matchables.size() << "] = {\n";
2542a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
254322bc5c4184a497353e33195dd12541a4f08b008aChris Lattner  for (std::vector<MatchableInfo*>::const_iterator it =
254422bc5c4184a497353e33195dd12541a4f08b008aChris Lattner       Info.Matchables.begin(), ie = Info.Matchables.end();
2545a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar       it != ie; ++it) {
254622bc5c4184a497353e33195dd12541a4f08b008aChris Lattner    MatchableInfo &II = **it;
2547a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
2548a4c5ecfb1bc0101c1b42a4d81bb427482b52cecfBenjamin Kramer    // Store a pascal-style length byte in the mnemonic.
2549a4c5ecfb1bc0101c1b42a4d81bb427482b52cecfBenjamin Kramer    std::string LenMnemonic = char(II.Mnemonic.size()) + II.Mnemonic.str();
2550fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper    OS << "  { " << StringTable.GetOrAddStringOffset(LenMnemonic, false)
2551fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper       << " /* " << II.Mnemonic << " */, "
2552fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper       << Target.getName() << "::"
2553a4c5ecfb1bc0101c1b42a4d81bb427482b52cecfBenjamin Kramer       << II.getResultInst()->TheDef->getName() << ", "
2554fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper       << II.ConversionFnKind << ", ";
2555a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
255654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar    // Write the required features mask.
255754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar    if (!II.RequiredFeatures.empty()) {
255854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar      for (unsigned i = 0, e = II.RequiredFeatures.size(); i != e; ++i) {
255954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar        if (i) OS << "|";
25600aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner        OS << II.RequiredFeatures[i]->getEnumName();
256154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar      }
256254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar    } else
256354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar      OS << "0";
2564fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper
2565fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper    OS << ", { ";
2566fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper    for (unsigned i = 0, e = II.AsmOperands.size(); i != e; ++i) {
2567fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper      MatchableInfo::AsmOperand &Op = II.AsmOperands[i];
2568fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper
2569fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper      if (i) OS << ", ";
2570fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper      OS << Op.Class->Name;
2571fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper    }
2572fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper    OS << " }, " << II.AsmVariantID;
257354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar    OS << "},\n";
2574a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  }
2575a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
257696352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner  OS << "};\n\n";
2577a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
25787044cce1a30539e2ec779f49546d13d7db5a33dfJakob Stoklund Olesen  OS << "const char *const MatchEntry::MnemonicTable =\n";
2579a4c5ecfb1bc0101c1b42a4d81bb427482b52cecfBenjamin Kramer  StringTable.EmitString(OS);
2580a4c5ecfb1bc0101c1b42a4d81bb427482b52cecfBenjamin Kramer  OS << ";\n\n";
2581a4c5ecfb1bc0101c1b42a4d81bb427482b52cecfBenjamin Kramer
25821fe3aa15e9cdc4981d7a125d87eaf257c1d75af1Bob Wilson  // A method to determine if a mnemonic is in the list.
25831fe3aa15e9cdc4981d7a125d87eaf257c1d75af1Bob Wilson  OS << "bool " << Target.getName() << ClassName << "::\n"
25841fe3aa15e9cdc4981d7a125d87eaf257c1d75af1Bob Wilson     << "MnemonicIsValid(StringRef Mnemonic) {\n";
25851fe3aa15e9cdc4981d7a125d87eaf257c1d75af1Bob Wilson  OS << "  // Search the table.\n";
25861fe3aa15e9cdc4981d7a125d87eaf257c1d75af1Bob Wilson  OS << "  std::pair<const MatchEntry*, const MatchEntry*> MnemonicRange =\n";
25871fe3aa15e9cdc4981d7a125d87eaf257c1d75af1Bob Wilson  OS << "    std::equal_range(MatchTable, MatchTable+"
25881fe3aa15e9cdc4981d7a125d87eaf257c1d75af1Bob Wilson     << Info.Matchables.size() << ", Mnemonic, LessOpcode());\n";
25891fe3aa15e9cdc4981d7a125d87eaf257c1d75af1Bob Wilson  OS << "  return MnemonicRange.first != MnemonicRange.second;\n";
25901fe3aa15e9cdc4981d7a125d87eaf257c1d75af1Bob Wilson  OS << "}\n\n";
25911fe3aa15e9cdc4981d7a125d87eaf257c1d75af1Bob Wilson
259296352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner  // Finally, build the match function.
259319cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  OS << "unsigned "
259496352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner     << Target.getName() << ClassName << "::\n"
259596352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner     << "MatchInstructionImpl(const SmallVectorImpl<MCParsedAsmOperand*>"
259696352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner     << " &Operands,\n";
259714ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach  OS << "                     MCInst &Inst, unsigned &ErrorInfo, ";
259814ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach  OS << "unsigned VariantID) {\n";
259954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar
260054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  // Emit code to get the available features.
260154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  OS << "  // Get the current feature set.\n";
260254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  OS << "  unsigned AvailableFeatures = getAvailableFeatures();\n\n";
260354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar
2604674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner  OS << "  // Get the instruction mnemonic, which is the first token.\n";
2605674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner  OS << "  StringRef Mnemonic = ((" << Target.getName()
2606674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner     << "Operand*)Operands[0])->getToken();\n\n";
2607674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner
26087fd4489de11bdf06f6c852d42abafea013b76f28Chris Lattner  if (HasMnemonicAliases) {
26097fd4489de11bdf06f6c852d42abafea013b76f28Chris Lattner    OS << "  // Process all MnemonicAliases to remap the mnemonic.\n";
261040bced0306e953c3d0fec19db4c4770b0e3c787eDevang Patel    OS << "  // FIXME : Add an entry in AsmParserVariant to check this.\n";
261140bced0306e953c3d0fec19db4c4770b0e3c787eDevang Patel    OS << "  if (!VariantID)\n";
261240bced0306e953c3d0fec19db4c4770b0e3c787eDevang Patel    OS << "    applyMnemonicAliases(Mnemonic, AvailableFeatures);\n\n";
26137fd4489de11bdf06f6c852d42abafea013b76f28Chris Lattner  }
2614828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
2615a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  // Emit code to compute the class list for this operand vector.
2616a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  OS << "  // Eliminate obvious mismatches.\n";
2617ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  OS << "  if (Operands.size() > " << (MaxNumOperands+1) << ") {\n";
2618ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  OS << "    ErrorInfo = " << (MaxNumOperands+1) << ";\n";
2619ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  OS << "    return Match_InvalidOperand;\n";
2620ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  OS << "  }\n\n";
2621a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
26229bb9fa19a5e121b83866867ad1d8f7bf2618c1a0Chris Lattner  OS << "  // Some state to try to produce better error messages.\n";
262319cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  OS << "  bool HadMatchOtherThanFeatures = false;\n";
2624578071a08734a4eb76484ba0a8d9f10b6e322184Jim Grosbach  OS << "  bool HadMatchOtherThanPredicate = false;\n";
262519cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  OS << "  unsigned RetCode = Match_InvalidOperand;\n";
2626325bd661ff57787efddc6b302230f22e9c187655Jim Grosbach  OS << "  unsigned MissingFeatures = ~0U;\n";
262784cb033bf30b6f93ae2fbea71513970147e08dc2Jim Grosbach  OS << "  // Set ErrorInfo to the operand that mismatches if it is\n";
26289bb9fa19a5e121b83866867ad1d8f7bf2618c1a0Chris Lattner  OS << "  // wrong for all instances of the instruction.\n";
26299bb9fa19a5e121b83866867ad1d8f7bf2618c1a0Chris Lattner  OS << "  ErrorInfo = ~0U;\n";
26302b1f943444d1853204725c7b45b1e1032be39958Chris Lattner
2631a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  // Emit code to search the table.
2632a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  OS << "  // Search the table.\n";
26332b1f943444d1853204725c7b45b1e1032be39958Chris Lattner  OS << "  std::pair<const MatchEntry*, const MatchEntry*> MnemonicRange =\n";
26342b1f943444d1853204725c7b45b1e1032be39958Chris Lattner  OS << "    std::equal_range(MatchTable, MatchTable+"
263522bc5c4184a497353e33195dd12541a4f08b008aChris Lattner     << Info.Matchables.size() << ", Mnemonic, LessOpcode());\n\n";
2636a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
2637a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  OS << "  // Return a more specific error code if no mnemonics match.\n";
2638a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  OS << "  if (MnemonicRange.first == MnemonicRange.second)\n";
2639a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  OS << "    return Match_MnemonicFail;\n\n";
2640a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
26412b1f943444d1853204725c7b45b1e1032be39958Chris Lattner  OS << "  for (const MatchEntry *it = MnemonicRange.first, "
264280db4e51d2a44bc623b5892bed2351406890b9aaChris Lattner     << "*ie = MnemonicRange.second;\n";
26432b1f943444d1853204725c7b45b1e1032be39958Chris Lattner  OS << "       it != ie; ++it) {\n";
264454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar
2645e53ee3b112810068b8ca229aff211fc497069273Gabor Greif  OS << "    // equal_range guarantees that instruction mnemonic matches.\n";
2646a4c5ecfb1bc0101c1b42a4d81bb427482b52cecfBenjamin Kramer  OS << "    assert(Mnemonic == it->getMnemonic());\n";
2647a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
264854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  // Emit check that the subclasses match.
264956315d319c104dc96187444e1e19711a1c801166Devang Patel  OS << "    if (VariantID != it->AsmVariantID) continue;\n";
2650ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  OS << "    bool OperandsValid = true;\n";
2651ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  OS << "    for (unsigned i = 0; i != " << MaxNumOperands << "; ++i) {\n";
2652b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach  OS << "      if (i + 1 >= Operands.size()) {\n";
2653b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach  OS << "        OperandsValid = (it->Classes[i] == " <<"InvalidMatchClass);\n";
2654087642f8638b08bf236b2cf8f0feb4df34c568f4Bill Wendling  OS << "        if (!OperandsValid) ErrorInfo = i + 1;\n";
2655b9d5af05fdc0867ed772c4bbfe3f3acc9fb3d628Jim Grosbach  OS << "        break;\n";
2656b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach  OS << "      }\n";
26574dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  OS << "      unsigned Diag = validateOperandClass(Operands[i+1],\n";
26584dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  OS.indent(43);
26594dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  OS << "(MatchClassKind)it->Classes[i]);\n";
26604dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  OS << "      if (Diag == Match_Success)\n";
2661ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  OS << "        continue;\n";
26629bb9fa19a5e121b83866867ad1d8f7bf2618c1a0Chris Lattner  OS << "      // If this operand is broken for all of the instances of this\n";
26639bb9fa19a5e121b83866867ad1d8f7bf2618c1a0Chris Lattner  OS << "      // mnemonic, keep track of it so we can report loc info.\n";
26644dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  OS << "      // If we already had a match that only failed due to a\n";
26654dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  OS << "      // target predicate, that diagnostic is preferred.\n";
26664dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  OS << "      if (!HadMatchOtherThanPredicate &&\n";
26674dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  OS << "          (it == MnemonicRange.first || ErrorInfo <= i+1)) {\n";
2668ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  OS << "        ErrorInfo = i+1;\n";
2669ef970c10918dde1e84b8e14a28dc7cf0a93c7c95Jim Grosbach  OS << "        // InvalidOperand is the default. Prefer specificity.\n";
2670ef970c10918dde1e84b8e14a28dc7cf0a93c7c95Jim Grosbach  OS << "        if (Diag != Match_InvalidOperand)\n";
2671ef970c10918dde1e84b8e14a28dc7cf0a93c7c95Jim Grosbach  OS << "          RetCode = Diag;\n";
26724dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  OS << "      }\n";
2673ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  OS << "      // Otherwise, just reject this instance of the mnemonic.\n";
2674ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  OS << "      OperandsValid = false;\n";
2675ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  OS << "      break;\n";
2676ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  OS << "    }\n\n";
2677a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
2678ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  OS << "    if (!OperandsValid) continue;\n";
2679ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner
2680ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  // Emit check that the required features are available.
2681ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  OS << "    if ((AvailableFeatures & it->RequiredFeatures) "
2682ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner     << "!= it->RequiredFeatures) {\n";
2683ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  OS << "      HadMatchOtherThanFeatures = true;\n";
2684325bd661ff57787efddc6b302230f22e9c187655Jim Grosbach  OS << "      unsigned NewMissingFeatures = it->RequiredFeatures & "
2685325bd661ff57787efddc6b302230f22e9c187655Jim Grosbach        "~AvailableFeatures;\n";
2686325bd661ff57787efddc6b302230f22e9c187655Jim Grosbach  OS << "      if (CountPopulation_32(NewMissingFeatures) <= "
2687325bd661ff57787efddc6b302230f22e9c187655Jim Grosbach        "CountPopulation_32(MissingFeatures))\n";
2688325bd661ff57787efddc6b302230f22e9c187655Jim Grosbach  OS << "        MissingFeatures = NewMissingFeatures;\n";
2689ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  OS << "      continue;\n";
2690ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  OS << "    }\n";
2691a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  OS << "\n";
2692b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar  OS << "    // We have selected a definite instruction, convert the parsed\n"
2693b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar     << "    // operands into the appropriate MCInst.\n";
2694b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar  OS << "    if (!ConvertToMCInst(it->ConvertFn, Inst,\n"
2695b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar     << "                         it->Opcode, Operands))\n";
2696b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar  OS << "      return Match_ConversionFail;\n";
2697b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar  OS << "\n";
26988cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar
269919cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  // Verify the instruction with the target-specific match predicate function.
270019cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  OS << "    // We have a potential match. Check the target predicate to\n"
270119cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach     << "    // handle any context sensitive constraints.\n"
270219cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach     << "    unsigned MatchResult;\n"
270319cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach     << "    if ((MatchResult = checkTargetMatchPredicate(Inst)) !="
270419cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach     << " Match_Success) {\n"
270519cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach     << "      Inst.clear();\n"
270619cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach     << "      RetCode = MatchResult;\n"
2707578071a08734a4eb76484ba0a8d9f10b6e322184Jim Grosbach     << "      HadMatchOtherThanPredicate = true;\n"
270819cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach     << "      continue;\n"
270919cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach     << "    }\n\n";
271019cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach
27118cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar  // Call the post-processing function, if used.
27128cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar  std::string InsnCleanupFn =
27138cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar    AsmParser->getValueAsString("AsmParserInstCleanup");
27148cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar  if (!InsnCleanupFn.empty())
27158cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar    OS << "    " << InsnCleanupFn << "(Inst);\n";
27168cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar
271779ed3f77e8b87615b80054ca6e4e3ba5e07445bdChris Lattner  OS << "    return Match_Success;\n";
2718a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  OS << "  }\n\n";
2719a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
2720ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  OS << "  // Okay, we had no match.  Try to return a useful error code.\n";
27214c1d2baa7c3303302fec9a15ebc4021bd5d45002Chad Rosier  OS << "  if (HadMatchOtherThanPredicate || !HadMatchOtherThanFeatures)\n";
27224c1d2baa7c3303302fec9a15ebc4021bd5d45002Chad Rosier  OS << "    return RetCode;\n\n";
2723325bd661ff57787efddc6b302230f22e9c187655Jim Grosbach  OS << "  // Missing feature matches return which features were missing\n";
2724325bd661ff57787efddc6b302230f22e9c187655Jim Grosbach  OS << "  ErrorInfo = MissingFeatures;\n";
2725578071a08734a4eb76484ba0a8d9f10b6e322184Jim Grosbach  OS << "  return Match_MissingFeature;\n";
2726a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar  OS << "}\n\n";
2727a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
2728e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  if (Info.OperandMatchInfo.size())
27298caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach    emitCustomOperandParsing(OS, Target, Info, ClassName);
2730e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
27310692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner  OS << "#endif // GET_MATCHER_IMPLEMENTATION\n\n";
2732d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar}
27336f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
27346f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesennamespace llvm {
27356f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
27366f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenvoid EmitAsmMatcher(RecordKeeper &RK, raw_ostream &OS) {
27376f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  emitSourceFileHeader("Assembly Matcher Source Fragment", OS);
27386f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  AsmMatcherEmitter(RK).run(OS);
27396f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen}
27406f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
27416f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End llvm namespace
2742