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
80be480ff607285157361a100e72ac5ed84ccce328Craig Topper//  identifiers that need to be mapped to specific values 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"
1034ffd89fa4d2788611187d1a534d2ed46adf1702cChandler Carruth#include "llvm/ADT/STLExtras.h"
1041de88235781c45c0afc0c7500d65b59775196c4cChris Lattner#include "llvm/ADT/SmallPtrSet.h"
105a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar#include "llvm/ADT/SmallVector.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>
11754911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman#include <sstream>
118d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbarusing namespace llvm;
119d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar
1202724915c171b08fa9f7f9e54a46ea81708d9c5b2Daniel Dunbarstatic cl::opt<std::string>
121606e8ad796f72824f5509e2657c44eca025d4bafDaniel DunbarMatchPrefix("match-prefix", cl::init(""),
122606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar            cl::desc("Only match instructions with the given prefix"));
12320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
12420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbarnamespace {
125828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilsonclass AsmMatcherInfo;
12654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbarstruct SubtargetFeatureInfo;
12754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar
1286f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenclass AsmMatcherEmitter {
1296f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  RecordKeeper &Records;
1306f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenpublic:
1316f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  AsmMatcherEmitter(RecordKeeper &R) : Records(R) {}
1326f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
1336f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  void run(raw_ostream &o);
1346f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen};
1356f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
136a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar/// ClassInfo - Helper class for storing the information about a particular
137a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar/// class of operands which can be matched.
138a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarstruct ClassInfo {
139606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar  enum ClassInfoKind {
140ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    /// Invalid kind, for use as a sentinel value.
141ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    Invalid = 0,
142ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
143ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    /// The class for a particular token.
144ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    Token,
145ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
146ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    /// The (first) register class, subsequent register classes are
147ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    /// RegisterClass0+1, and so on.
148ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    RegisterClass0,
149ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
150ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    /// The (first) user defined class, subsequent user defined classes are
151ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    /// UserClass0+1, and so on.
152ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    UserClass0 = 1<<16
153606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar  };
154606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar
155606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar  /// Kind - The class kind, which is either a predefined kind, or (UserClass0 +
156606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar  /// N) for the Nth user defined class.
157606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar  unsigned Kind;
158a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
159ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  /// SuperClasses - The super classes of this class. Note that for simplicities
160ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  /// sake user operands only record their immediate super class, while register
161ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  /// operands include all superclasses.
162ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  std::vector<ClassInfo*> SuperClasses;
1635fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar
1646745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar  /// Name - The full class name, suitable for use in an enum.
165a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  std::string Name;
166a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
1676745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar  /// ClassName - The unadorned generic name for this class (e.g., Token).
1686745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar  std::string ClassName;
1696745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar
170a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  /// ValueName - The name of the value this class represents; for a token this
171a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  /// is the literal token string, for an operand it is the TableGen class (or
172a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  /// empty if this is a derived class).
173a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  std::string ValueName;
174a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
175a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  /// PredicateMethod - The name of the operand method to test whether the
176ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  /// operand matches this class; this is not valid for Token or register kinds.
177a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  std::string PredicateMethod;
178a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
179a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  /// RenderMethod - The name of the operand method to add this operand to an
180ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  /// MCInst; this is not valid for Token or register kinds.
181a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  std::string RenderMethod;
182606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar
183e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  /// ParserMethod - The name of the operand method to do a target specific
184e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  /// parsing on the operand.
185e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  std::string ParserMethod;
186e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
1878409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar  /// For register classes, the records for all the registers in this class.
1888409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar  std::set<Record*> Registers;
1898409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar
1904dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  /// For custom match classes, he diagnostic kind for when the predicate fails.
1914dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  std::string DiagnosticType;
1928409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbarpublic:
193ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  /// isRegisterClass() - Check if this is a register class.
194ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  bool isRegisterClass() const {
195ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    return Kind >= RegisterClass0 && Kind < UserClass0;
196ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  }
197ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
1985fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar  /// isUserClass() - Check if this is a user defined class.
1995fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar  bool isUserClass() const {
2005fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar    return Kind >= UserClass0;
2015fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar  }
2025fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar
2034e0ae44b3a1b5f7157351764fd125c7c85959797Dmitri Gribenko  /// isRelatedTo - Check whether this class is "related" to \p RHS. Classes
204ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  /// are related if they are in the same class hierarchy.
205ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  bool isRelatedTo(const ClassInfo &RHS) const {
206ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    // Tokens are only related to tokens.
207ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    if (Kind == Token || RHS.Kind == Token)
208ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar      return Kind == Token && RHS.Kind == Token;
209ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
2108409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar    // Registers classes are only related to registers classes, and only if
2118409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar    // their intersection is non-empty.
2128409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar    if (isRegisterClass() || RHS.isRegisterClass()) {
2138409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar      if (!isRegisterClass() || !RHS.isRegisterClass())
2148409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar        return false;
2158409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar
2168409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar      std::set<Record*> Tmp;
2178409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar      std::insert_iterator< std::set<Record*> > II(Tmp, Tmp.begin());
218a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach      std::set_intersection(Registers.begin(), Registers.end(),
2198409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar                            RHS.Registers.begin(), RHS.Registers.end(),
2208409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar                            II);
2218409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar
2228409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar      return !Tmp.empty();
2238409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar    }
224ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
225ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    // Otherwise we have two users operands; they are related if they are in the
226ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    // same class hierarchy.
2278409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar    //
2288409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar    // FIXME: This is an oversimplification, they should only be related if they
2298409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar    // intersect, however we don't have that information.
230ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    assert(isUserClass() && RHS.isUserClass() && "Unexpected class!");
231ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    const ClassInfo *Root = this;
232ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    while (!Root->SuperClasses.empty())
233ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar      Root = Root->SuperClasses.front();
234ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
2358409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar    const ClassInfo *RHSRoot = &RHS;
236ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    while (!RHSRoot->SuperClasses.empty())
237ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar      RHSRoot = RHSRoot->SuperClasses.front();
238a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
239ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    return Root == RHSRoot;
240ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  }
241ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
2424e0ae44b3a1b5f7157351764fd125c7c85959797Dmitri Gribenko  /// isSubsetOf - Test whether this class is a subset of \p RHS.
243ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  bool isSubsetOf(const ClassInfo &RHS) const {
244ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    // This is a subset of RHS if it is the same class...
245ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    if (this == &RHS)
246ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar      return true;
247ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
248ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    // ... or if any of its super classes are a subset of RHS.
249ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    for (std::vector<ClassInfo*>::const_iterator it = SuperClasses.begin(),
250ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar           ie = SuperClasses.end(); it != ie; ++it)
251ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar      if ((*it)->isSubsetOf(RHS))
252ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar        return true;
253ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
254ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    return false;
2555fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar  }
2565fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar
257606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar  /// operator< - Compare two classes.
258606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar  bool operator<(const ClassInfo &RHS) const {
259368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar    if (this == &RHS)
260368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar      return false;
261368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar
262ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    // Unrelated classes can be ordered by kind.
263ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    if (!isRelatedTo(RHS))
264606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar      return Kind < RHS.Kind;
265606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar
266606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar    switch (Kind) {
2676745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar    case Invalid:
268655b8de7b2ab773a977e0c524307e71354d8af29Craig Topper      llvm_unreachable("Invalid kind!");
269606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar
270606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar    default:
2717a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner      // This class precedes the RHS if it is a proper subset of the RHS.
272368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar      if (isSubsetOf(RHS))
2733472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands        return true;
274368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar      if (RHS.isSubsetOf(*this))
2753472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands        return false;
276368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar
277368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar      // Otherwise, order by name to ensure we have a total ordering.
278368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar      return ValueName < RHS.ValueName;
279606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar    }
280606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar  }
281a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar};
282a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
283b2df610b44902124c22f3661a39bffd5341da62dSean Silvanamespace {
284b2df610b44902124c22f3661a39bffd5341da62dSean Silva/// Sort ClassInfo pointers independently of pointer value.
285b2df610b44902124c22f3661a39bffd5341da62dSean Silvastruct LessClassInfoPtr {
286b2df610b44902124c22f3661a39bffd5341da62dSean Silva  bool operator()(const ClassInfo *LHS, const ClassInfo *RHS) const {
287b2df610b44902124c22f3661a39bffd5341da62dSean Silva    return *LHS < *RHS;
288b2df610b44902124c22f3661a39bffd5341da62dSean Silva  }
289b2df610b44902124c22f3661a39bffd5341da62dSean Silva};
290b2df610b44902124c22f3661a39bffd5341da62dSean Silva}
291b2df610b44902124c22f3661a39bffd5341da62dSean Silva
29222bc5c4184a497353e33195dd12541a4f08b008aChris Lattner/// MatchableInfo - Helper class for storing the necessary information for an
29322bc5c4184a497353e33195dd12541a4f08b008aChris Lattner/// instruction or alias which is capable of being matched.
29422bc5c4184a497353e33195dd12541a4f08b008aChris Lattnerstruct MatchableInfo {
295c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner  struct AsmOperand {
296d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    /// Token - This is the token that the operand came from.
297d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    StringRef Token;
298828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
299a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    /// The unique class instance this operand should match.
300a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    ClassInfo *Class;
301a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
302567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner    /// The operand name this is, if anything.
303567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner    StringRef SrcOpName;
304a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson
305a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    /// The suboperand index within SrcOpName, or -1 for the entire operand.
306a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    int SubOpIdx;
307828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
30863faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel    /// Register record if this token is singleton register.
30963faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel    Record *SingletonReg;
31063faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel
311f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach    explicit AsmOperand(StringRef T) : Token(T), Class(0), SubOpIdx(-1),
31211fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach                                       SingletonReg(0) {}
31320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  };
314828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
3151d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner  /// ResOperand - This represents a single operand in the result instruction
3161d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner  /// generated by the match.  In cases (like addressing modes) where a single
3171d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner  /// assembler operand expands to multiple MCOperands, this represents the
3181d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner  /// single assembler operand, not the MCOperand.
3191d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner  struct ResOperand {
3201d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner    enum {
3211d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      /// RenderAsmOperand - This represents an operand result that is
3221d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      /// generated by calling the render method on the assembly operand.  The
3231d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      /// corresponding AsmOperand is specified by AsmOperandNum.
3241d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      RenderAsmOperand,
325828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
3261d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      /// TiedOperand - This represents a result operand that is a duplicate of
3271d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      /// a previous result operand.
32898c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      TiedOperand,
329828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
33098c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      /// ImmOperand - This represents an immediate value that is dumped into
33198c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      /// the operand.
33290fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner      ImmOperand,
333828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
33490fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner      /// RegOperand - This represents a fixed register that is dumped in.
33590fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner      RegOperand
3361d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner    } Kind;
337828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
3381d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner    union {
3391d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      /// This is the operand # in the AsmOperands list that this should be
3401d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      /// copied from.
3411d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      unsigned AsmOperandNum;
342828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
3431d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      /// TiedOperandNum - This is the (earlier) result operand that should be
3441d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      /// copied from.
3451d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      unsigned TiedOperandNum;
346828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
34798c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      /// ImmVal - This is the immediate value added to the instruction.
34898c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      int64_t ImmVal;
349828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
35090fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner      /// Register - This is the register record.
35190fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner      Record *Register;
3521d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner    };
353828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
354a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    /// MINumOperands - The number of MCInst operands populated by this
355a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    /// operand.
356a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    unsigned MINumOperands;
357828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
358a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    static ResOperand getRenderedOp(unsigned AsmOpNum, unsigned NumOperands) {
3591d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      ResOperand X;
3601d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      X.Kind = RenderAsmOperand;
3611d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      X.AsmOperandNum = AsmOpNum;
362a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      X.MINumOperands = NumOperands;
3631d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      return X;
3641d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner    }
365828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
366a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    static ResOperand getTiedOp(unsigned TiedOperandNum) {
3671d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      ResOperand X;
3681d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      X.Kind = TiedOperand;
3691d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      X.TiedOperandNum = TiedOperandNum;
370a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      X.MINumOperands = 1;
3711d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      return X;
3721d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner    }
373828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
374a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    static ResOperand getImmOp(int64_t Val) {
37598c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      ResOperand X;
37698c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      X.Kind = ImmOperand;
37798c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      X.ImmVal = Val;
378a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      X.MINumOperands = 1;
37998c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      return X;
38098c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner    }
381828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
382a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    static ResOperand getRegOp(Record *Reg) {
38390fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner      ResOperand X;
38490fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner      X.Kind = RegOperand;
38590fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner      X.Register = Reg;
386a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      X.MINumOperands = 1;
38790fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner      return X;
38890fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner    }
3891d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner  };
39020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
39156315d319c104dc96187444e1e19711a1c801166Devang Patel  /// AsmVariantID - Target's assembly syntax variant no.
39256315d319c104dc96187444e1e19711a1c801166Devang Patel  int AsmVariantID;
39356315d319c104dc96187444e1e19711a1c801166Devang Patel
3943b5aec67ef174c74ff6620ddd71ad3b0cb39030cChris Lattner  /// TheDef - This is the definition of the instruction or InstAlias that this
3953b5aec67ef174c74ff6620ddd71ad3b0cb39030cChris Lattner  /// matchable came from.
3965bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner  Record *const TheDef;
397828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
398c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner  /// DefRec - This is the definition that it came from.
399c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner  PointerUnion<const CodeGenInstruction*, const CodeGenInstAlias*> DefRec;
400828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
401662e5a30e864e71111b885d3da3cdd184772035dChris Lattner  const CodeGenInstruction *getResultInst() const {
402662e5a30e864e71111b885d3da3cdd184772035dChris Lattner    if (DefRec.is<const CodeGenInstruction*>())
403662e5a30e864e71111b885d3da3cdd184772035dChris Lattner      return DefRec.get<const CodeGenInstruction*>();
404662e5a30e864e71111b885d3da3cdd184772035dChris Lattner    return DefRec.get<const CodeGenInstAlias*>()->ResultInst;
405662e5a30e864e71111b885d3da3cdd184772035dChris Lattner  }
406828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
4071d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner  /// ResOperands - This is the operand list that should be built for the result
4081d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner  /// MCInst.
409b423d18a00eed4968d6df7415449259b09b7d67eJim Grosbach  SmallVector<ResOperand, 8> ResOperands;
41020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
41120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  /// AsmString - The assembly string for this instruction (with variants
4123b5aec67ef174c74ff6620ddd71ad3b0cb39030cChris Lattner  /// removed), e.g. "movsx $src, $dst".
41320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  std::string AsmString;
41420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
415d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner  /// Mnemonic - This is the first token of the matched instruction, its
416d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner  /// mnemonic.
417d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner  StringRef Mnemonic;
418828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
4193116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner  /// AsmOperands - The textual operands that this instruction matches,
4203b5aec67ef174c74ff6620ddd71ad3b0cb39030cChris Lattner  /// annotated with a class and where in the OperandList they were defined.
4213b5aec67ef174c74ff6620ddd71ad3b0cb39030cChris Lattner  /// This directly corresponds to the tokenized AsmString after the mnemonic is
4223b5aec67ef174c74ff6620ddd71ad3b0cb39030cChris Lattner  /// removed.
423b423d18a00eed4968d6df7415449259b09b7d67eJim Grosbach  SmallVector<AsmOperand, 8> AsmOperands;
42420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
42554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  /// Predicates - The required subtarget features to match this instruction.
42654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  SmallVector<SubtargetFeatureInfo*, 4> RequiredFeatures;
42754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar
428b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar  /// ConversionFnKind - The enum value which is passed to the generated
42990e11f8c95146c2d3718e9b3de71ee6628347b05Chad Rosier  /// convertToMCInst to convert parsed operands into an MCInst for this
430b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar  /// function.
431b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar  std::string ConversionFnKind;
432828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
43322bc5c4184a497353e33195dd12541a4f08b008aChris Lattner  MatchableInfo(const CodeGenInstruction &CGI)
434f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach    : AsmVariantID(0), TheDef(CGI.TheDef), DefRec(&CGI),
43556315d319c104dc96187444e1e19711a1c801166Devang Patel      AsmString(CGI.AsmString) {
4365bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner  }
4375bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner
43822bc5c4184a497353e33195dd12541a4f08b008aChris Lattner  MatchableInfo(const CodeGenInstAlias *Alias)
439f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach    : AsmVariantID(0), TheDef(Alias->TheDef), DefRec(Alias),
44056315d319c104dc96187444e1e19711a1c801166Devang Patel      AsmString(Alias->AsmString) {
441c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner  }
442828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
443c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  // Two-operand aliases clone from the main matchable, but mark the second
444c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  // operand as a tied operand of the first for purposes of the assembler.
445c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  void formTwoOperandAlias(StringRef Constraint);
446c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach
4478caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  void initialize(const AsmMatcherInfo &Info,
448f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach                  SmallPtrSet<Record*, 16> &SingletonRegisters,
44911fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach                  int AsmVariantNo, std::string &RegisterPrefix);
450828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
4518caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  /// validate - Return true if this matchable is a valid thing to match against
45222bc5c4184a497353e33195dd12541a4f08b008aChris Lattner  /// and perform a bunch of validity checking.
4538caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  bool validate(StringRef CommentDelimiter, bool Hack) const;
454828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
455f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach  /// extractSingletonRegisterForAsmOperand - Extract singleton register,
45663faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel  /// if present, from specified token.
45763faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel  void
45863faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel  extractSingletonRegisterForAsmOperand(unsigned i, const AsmMatcherInfo &Info,
45963faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel                                        std::string &RegisterPrefix);
46020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
4618caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  /// findAsmOperand - Find the AsmOperand with the specified name and
462a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson  /// suboperand index.
4638caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  int findAsmOperand(StringRef N, int SubOpIdx) const {
464a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i)
465a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      if (N == AsmOperands[i].SrcOpName &&
466a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson          SubOpIdx == AsmOperands[i].SubOpIdx)
467a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson        return i;
468a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    return -1;
469a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson  }
470828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
4718caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  /// findAsmOperandNamed - Find the first AsmOperand with the specified name.
472a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson  /// This does not check the suboperand index.
4738caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  int findAsmOperandNamed(StringRef N) const {
474ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner    for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i)
475ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner      if (N == AsmOperands[i].SrcOpName)
476ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner        return i;
477ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner    return -1;
478ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner  }
479828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
4808caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  void buildInstructionResultOperands();
4818caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  void buildAliasResultOperands();
4821d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner
48322bc5c4184a497353e33195dd12541a4f08b008aChris Lattner  /// operator< - Compare two matchables.
48422bc5c4184a497353e33195dd12541a4f08b008aChris Lattner  bool operator<(const MatchableInfo &RHS) const {
485e206fcf0e9c7e79c7f42ff2151f3fb58cba70674Chris Lattner    // The primary comparator is the instruction mnemonic.
486d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    if (Mnemonic != RHS.Mnemonic)
487d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      return Mnemonic < RHS.Mnemonic;
488a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
4893116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner    if (AsmOperands.size() != RHS.AsmOperands.size())
4903116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner      return AsmOperands.size() < RHS.AsmOperands.size();
4912b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar
492db2ddb5dc57319eff249144f1d9a553a3278d2e0Daniel Dunbar    // Compare lexicographically by operand. The matcher validates that other
4938caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach    // orderings wouldn't be ambiguous using \see couldMatchAmbiguouslyWith().
4943116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner    for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) {
4953116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner      if (*AsmOperands[i].Class < *RHS.AsmOperands[i].Class)
4962b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar        return true;
4973116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner      if (*RHS.AsmOperands[i].Class < *AsmOperands[i].Class)
498db2ddb5dc57319eff249144f1d9a553a3278d2e0Daniel Dunbar        return false;
499db2ddb5dc57319eff249144f1d9a553a3278d2e0Daniel Dunbar    }
500db2ddb5dc57319eff249144f1d9a553a3278d2e0Daniel Dunbar
5012b70dfaaebcc436c53b2c86cd8a9574baba47253Andrew Trick    // Give matches that require more features higher precedence. This is useful
5022b70dfaaebcc436c53b2c86cd8a9574baba47253Andrew Trick    // because we cannot define AssemblerPredicates with the negation of
5032b70dfaaebcc436c53b2c86cd8a9574baba47253Andrew Trick    // processor features. For example, ARM v6 "nop" may be either a HINT or
5042b70dfaaebcc436c53b2c86cd8a9574baba47253Andrew Trick    // MOV. With v6, we want to match HINT. The assembler has no way to
5052b70dfaaebcc436c53b2c86cd8a9574baba47253Andrew Trick    // predicate MOV under "NoV6", but HINT will always match first because it
5062b70dfaaebcc436c53b2c86cd8a9574baba47253Andrew Trick    // requires V6 while MOV does not.
5072b70dfaaebcc436c53b2c86cd8a9574baba47253Andrew Trick    if (RequiredFeatures.size() != RHS.RequiredFeatures.size())
5082b70dfaaebcc436c53b2c86cd8a9574baba47253Andrew Trick      return RequiredFeatures.size() > RHS.RequiredFeatures.size();
5092b70dfaaebcc436c53b2c86cd8a9574baba47253Andrew Trick
5102b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar    return false;
5112b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar  }
512606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar
5138caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  /// couldMatchAmbiguouslyWith - Check whether this matchable could
5144e0ae44b3a1b5f7157351764fd125c7c85959797Dmitri Gribenko  /// ambiguously match the same set of operands as \p RHS (without being a
5152b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar  /// strictly superior match).
5168caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  bool couldMatchAmbiguouslyWith(const MatchableInfo &RHS) {
517e66b7ebfb426c7ed9bc911e9708321e2d8510b41Chris Lattner    // The primary comparator is the instruction mnemonic.
518d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    if (Mnemonic != RHS.Mnemonic)
519e66b7ebfb426c7ed9bc911e9708321e2d8510b41Chris Lattner      return false;
520828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
5212b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar    // The number of operands is unambiguous.
5223116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner    if (AsmOperands.size() != RHS.AsmOperands.size())
5232b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar      return false;
524606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar
5251402f0b2cac017ab997f71ab4909a2ccfea7be4bDaniel Dunbar    // Otherwise, make sure the ordering of the two instructions is unambiguous
5261402f0b2cac017ab997f71ab4909a2ccfea7be4bDaniel Dunbar    // by checking that either (a) a token or operand kind discriminates them,
5271402f0b2cac017ab997f71ab4909a2ccfea7be4bDaniel Dunbar    // or (b) the ordering among equivalent kinds is consistent.
5281402f0b2cac017ab997f71ab4909a2ccfea7be4bDaniel Dunbar
5292b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar    // Tokens and operand kinds are unambiguous (assuming a correct target
5302b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar    // specific parser).
5313116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner    for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i)
5323116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner      if (AsmOperands[i].Class->Kind != RHS.AsmOperands[i].Class->Kind ||
5333116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner          AsmOperands[i].Class->Kind == ClassInfo::Token)
5343116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner        if (*AsmOperands[i].Class < *RHS.AsmOperands[i].Class ||
5353116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner            *RHS.AsmOperands[i].Class < *AsmOperands[i].Class)
5362b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar          return false;
537a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
5382b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar    // Otherwise, this operand could commute if all operands are equivalent, or
5392b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar    // there is a pair of operands that compare less than and a pair that
5402b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar    // compare greater than.
5412b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar    bool HasLT = false, HasGT = false;
5423116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner    for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) {
5433116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner      if (*AsmOperands[i].Class < *RHS.AsmOperands[i].Class)
5442b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar        HasLT = true;
5453116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner      if (*RHS.AsmOperands[i].Class < *AsmOperands[i].Class)
5462b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar        HasGT = true;
5472b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar    }
548606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar
5492b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar    return !(HasLT ^ HasGT);
550606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar  }
551606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar
55220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  void dump();
553828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
554d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattnerprivate:
5558caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  void tokenizeAsmString(const AsmMatcherInfo &Info);
55620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar};
55720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
55854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar/// SubtargetFeatureInfo - Helper class for storing information on a subtarget
55954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar/// feature which participates in instruction matching.
56054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbarstruct SubtargetFeatureInfo {
56154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  /// \brief The predicate record for this feature.
56254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  Record *TheDef;
56354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar
56454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  /// \brief An unique index assigned to represent this feature.
56554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  unsigned Index;
56654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar
5670aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner  SubtargetFeatureInfo(Record *D, unsigned Idx) : TheDef(D), Index(Idx) {}
568828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
56954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  /// \brief The name of the enumerated constant identifying this feature.
5700aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner  std::string getEnumName() const {
5710aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner    return "Feature_" + TheDef->getName();
5720aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner  }
57354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar};
57454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar
575e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopesstruct OperandMatchEntry {
576e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  unsigned OperandMask;
577e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  MatchableInfo* MI;
578e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  ClassInfo *CI;
579e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
5808caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  static OperandMatchEntry create(MatchableInfo* mi, ClassInfo *ci,
581e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes                                  unsigned opMask) {
582e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    OperandMatchEntry X;
583e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    X.OperandMask = opMask;
584e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    X.CI = ci;
585e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    X.MI = mi;
586e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    return X;
587e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  }
588e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes};
589e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
590e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
591a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarclass AsmMatcherInfo {
592a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarpublic:
59367db883487fca3472fdde51e931657e22d4d0495Chris Lattner  /// Tracked Records
5949c6b60eb28d2717008f8d6ff52f7666ebc81113dChris Lattner  RecordKeeper &Records;
59567db883487fca3472fdde51e931657e22d4d0495Chris Lattner
59659fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar  /// The tablegen AsmParser record.
59759fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar  Record *AsmParser;
59859fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar
59902bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner  /// Target - The target information.
60002bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner  CodeGenTarget &Target;
60102bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner
602a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  /// The classes which are needed for matching.
603a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  std::vector<ClassInfo*> Classes;
604a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
60522bc5c4184a497353e33195dd12541a4f08b008aChris Lattner  /// The information on the matchables to match.
60622bc5c4184a497353e33195dd12541a4f08b008aChris Lattner  std::vector<MatchableInfo*> Matchables;
607a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
608e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  /// Info for custom matching operands by user defined methods.
609e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  std::vector<OperandMatchEntry> OperandMatchInfo;
610e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
611ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  /// Map of Register records to their class information.
612decfdf548b43c80c3dd81ff1cc3639b80ed33a3eSean Silva  typedef std::map<Record*, ClassInfo*, LessRecordByID> RegisterClassesTy;
613decfdf548b43c80c3dd81ff1cc3639b80ed33a3eSean Silva  RegisterClassesTy RegisterClasses;
614ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
61554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  /// Map of Predicate records to their subtarget information.
61654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  std::map<Record*, SubtargetFeatureInfo*> SubtargetFeatures;
617828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
6184dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  /// Map of AsmOperandClass records to their class information.
6194dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  std::map<Record*, ClassInfo*> AsmOperandClasses;
6204dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach
621a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarprivate:
622a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  /// Map of token to class information which has already been constructed.
623a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  std::map<std::string, ClassInfo*> TokenClasses;
624a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
625ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  /// Map of RegisterClass records to their class information.
626ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  std::map<Record*, ClassInfo*> RegisterClassClasses;
627a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
628a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarprivate:
629a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  /// getTokenClass - Lookup or create the class for the given token.
630b8d6e98e566724f58344d275a4bd675249bb713aChris Lattner  ClassInfo *getTokenClass(StringRef Token);
631a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
632a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  /// getOperandClass - Lookup or create the class for the given operand.
633a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson  ClassInfo *getOperandClass(const CGIOperandList::OperandInfo &OI,
63448c1f84b104fd32109d809a56f5ebbf461c0910cJim Grosbach                             int SubOpIdx);
63548c1f84b104fd32109d809a56f5ebbf461c0910cJim Grosbach  ClassInfo *getOperandClass(Record *Rec, int SubOpIdx);
636a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
6378caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  /// buildRegisterClasses - Build the ClassInfo* instances for register
638ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  /// classes.
6398caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  void buildRegisterClasses(SmallPtrSet<Record*, 16> &SingletonRegisters);
640ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
6418caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  /// buildOperandClasses - Build the ClassInfo* instances for user defined
642ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  /// operand classes.
6438caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  void buildOperandClasses();
644ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
6458caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  void buildInstructionOperandReference(MatchableInfo *II, StringRef OpName,
646a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson                                        unsigned AsmOpIdx);
6478caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  void buildAliasOperandReference(MatchableInfo *II, StringRef OpName,
648c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner                                  MatchableInfo::AsmOperand &Op);
649828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
650a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarpublic:
651828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson  AsmMatcherInfo(Record *AsmParser,
652828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson                 CodeGenTarget &Target,
6539c6b60eb28d2717008f8d6ff52f7666ebc81113dChris Lattner                 RecordKeeper &Records);
65459fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar
6558caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  /// buildInfo - Construct the various tables used during matching.
6568caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  void buildInfo();
657828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
6588caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  /// buildOperandMatchInfo - Build the necessary information to handle user
659e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  /// defined operand parsing methods.
6608caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  void buildOperandMatchInfo();
661e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
6626fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner  /// getSubtargetFeature - Lookup or create the subtarget feature info for the
6636fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner  /// given operand.
6646fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner  SubtargetFeatureInfo *getSubtargetFeature(Record *Def) const {
6656fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner    assert(Def->isSubClassOf("Predicate") && "Invalid predicate type!");
6666fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner    std::map<Record*, SubtargetFeatureInfo*>::const_iterator I =
6676fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner      SubtargetFeatures.find(Def);
6686fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner    return I == SubtargetFeatures.end() ? 0 : I->second;
6696fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner  }
67067db883487fca3472fdde51e931657e22d4d0495Chris Lattner
6719c6b60eb28d2717008f8d6ff52f7666ebc81113dChris Lattner  RecordKeeper &getRecords() const {
6729c6b60eb28d2717008f8d6ff52f7666ebc81113dChris Lattner    return Records;
67367db883487fca3472fdde51e931657e22d4d0495Chris Lattner  }
674a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar};
675a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
6766f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End anonymous namespace
67720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
67822bc5c4184a497353e33195dd12541a4f08b008aChris Lattnervoid MatchableInfo::dump() {
6795abd1ebcb380664ae5010395b217e01f7190046cChris Lattner  errs() << TheDef->getName() << " -- " << "flattened:\"" << AsmString <<"\"\n";
680a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
6813116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner  for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) {
682c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner    AsmOperand &Op = AsmOperands[i];
6836745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar    errs() << "  op[" << i << "] = " << Op.Class->ClassName << " - ";
6840bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner    errs() << '\"' << Op.Token << "\"\n";
68520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
68620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar}
687a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
688c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbachstatic std::pair<StringRef, StringRef>
689376a8a773e38fdcd9102a40e08ab1e0661d645d9Jakob Stoklund OlesenparseTwoOperandConstraint(StringRef S, ArrayRef<SMLoc> Loc) {
690c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  // Split via the '='.
691c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  std::pair<StringRef, StringRef> Ops = S.split('=');
692c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  if (Ops.second == "")
69361131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger    PrintFatalError(Loc, "missing '=' in two-operand alias constraint");
694c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  // Trim whitespace and the leading '$' on the operand names.
695c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  size_t start = Ops.first.find_first_of('$');
696c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  if (start == std::string::npos)
69761131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger    PrintFatalError(Loc, "expected '$' prefix on asm operand name");
698c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  Ops.first = Ops.first.slice(start + 1, std::string::npos);
699c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  size_t end = Ops.first.find_last_of(" \t");
700c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  Ops.first = Ops.first.slice(0, end);
701c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  // Now the second operand.
702c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  start = Ops.second.find_first_of('$');
703c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  if (start == std::string::npos)
70461131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger    PrintFatalError(Loc, "expected '$' prefix on asm operand name");
705c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  Ops.second = Ops.second.slice(start + 1, std::string::npos);
706c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  end = Ops.second.find_last_of(" \t");
707c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  Ops.first = Ops.first.slice(0, end);
708c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  return Ops;
709c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach}
710c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach
711c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbachvoid MatchableInfo::formTwoOperandAlias(StringRef Constraint) {
712c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  // Figure out which operands are aliased and mark them as tied.
713c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  std::pair<StringRef, StringRef> Ops =
714c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach    parseTwoOperandConstraint(Constraint, TheDef->getLoc());
715c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach
716c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  // Find the AsmOperands that refer to the operands we're aliasing.
717c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  int SrcAsmOperand = findAsmOperandNamed(Ops.first);
718c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  int DstAsmOperand = findAsmOperandNamed(Ops.second);
719c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  if (SrcAsmOperand == -1)
72061131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger    PrintFatalError(TheDef->getLoc(),
721c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach                  "unknown source two-operand alias operand '" +
722c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach                  Ops.first.str() + "'.");
723c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  if (DstAsmOperand == -1)
72461131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger    PrintFatalError(TheDef->getLoc(),
725c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach                  "unknown destination two-operand alias operand '" +
726c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach                  Ops.second.str() + "'.");
727c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach
728c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  // Find the ResOperand that refers to the operand we're aliasing away
729c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  // and update it to refer to the combined operand instead.
730c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  for (unsigned i = 0, e = ResOperands.size(); i != e; ++i) {
731c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach    ResOperand &Op = ResOperands[i];
732c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach    if (Op.Kind == ResOperand::RenderAsmOperand &&
733c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach        Op.AsmOperandNum == (unsigned)SrcAsmOperand) {
734c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach      Op.AsmOperandNum = DstAsmOperand;
735c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach      break;
736c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach    }
737c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  }
738c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  // Remove the AsmOperand for the alias operand.
739c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  AsmOperands.erase(AsmOperands.begin() + SrcAsmOperand);
740c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  // Adjust the ResOperand references to any AsmOperands that followed
741c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  // the one we just deleted.
742c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  for (unsigned i = 0, e = ResOperands.size(); i != e; ++i) {
743c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach    ResOperand &Op = ResOperands[i];
744c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach    switch(Op.Kind) {
745c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach    default:
746c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach      // Nothing to do for operands that don't reference AsmOperands.
747c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach      break;
748c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach    case ResOperand::RenderAsmOperand:
749c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach      if (Op.AsmOperandNum > (unsigned)SrcAsmOperand)
750c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach        --Op.AsmOperandNum;
751c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach      break;
752c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach    case ResOperand::TiedOperand:
753c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach      if (Op.TiedOperandNum > (unsigned)SrcAsmOperand)
754c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach        --Op.TiedOperandNum;
755c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach      break;
756c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach    }
757c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  }
758c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach}
759c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach
7608caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachvoid MatchableInfo::initialize(const AsmMatcherInfo &Info,
76163faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel                               SmallPtrSet<Record*, 16> &SingletonRegisters,
76263faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel                               int AsmVariantNo, std::string &RegisterPrefix) {
76356315d319c104dc96187444e1e19711a1c801166Devang Patel  AsmVariantID = AsmVariantNo;
764f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach  AsmString =
76563faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel    CodeGenInstruction::FlattenAsmStringVariants(AsmString, AsmVariantNo);
766828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
7678caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  tokenizeAsmString(Info);
768828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
769c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner  // Compute the require features.
770c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner  std::vector<Record*> Predicates =TheDef->getValueAsListOfDefs("Predicates");
771c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner  for (unsigned i = 0, e = Predicates.size(); i != e; ++i)
772c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner    if (SubtargetFeatureInfo *Feature =
773c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner        Info.getSubtargetFeature(Predicates[i]))
774c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner      RequiredFeatures.push_back(Feature);
775828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
776c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner  // Collect singleton registers, if used.
777d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner  for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) {
77863faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel    extractSingletonRegisterForAsmOperand(i, Info, RegisterPrefix);
77963faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel    if (Record *Reg = AsmOperands[i].SingletonReg)
780c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner      SingletonRegisters.insert(Reg);
781c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner  }
782c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner}
783c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner
7848caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach/// tokenizeAsmString - Tokenize a simplified assembly string.
7858caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachvoid MatchableInfo::tokenizeAsmString(const AsmMatcherInfo &Info) {
786d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner  StringRef String = AsmString;
787d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner  unsigned Prev = 0;
788d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner  bool InTok = true;
789d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner  for (unsigned i = 0, e = String.size(); i != e; ++i) {
790d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    switch (String[i]) {
791d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    case '[':
792d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    case ']':
793d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    case '*':
794d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    case '!':
795d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    case ' ':
796d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    case '\t':
797d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    case ',':
798d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      if (InTok) {
799c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner        AsmOperands.push_back(AsmOperand(String.slice(Prev, i)));
800d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner        InTok = false;
801d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      }
802d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      if (!isspace(String[i]) && String[i] != ',')
803c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner        AsmOperands.push_back(AsmOperand(String.substr(i, 1)));
804d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      Prev = i + 1;
805d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      break;
806d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner
807d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    case '\\':
808d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      if (InTok) {
809c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner        AsmOperands.push_back(AsmOperand(String.slice(Prev, i)));
810d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner        InTok = false;
811d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      }
812d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      ++i;
813d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      assert(i != String.size() && "Invalid quoted character");
814c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner      AsmOperands.push_back(AsmOperand(String.substr(i, 1)));
815d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      Prev = i + 1;
816d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      break;
817d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner
818d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    case '$': {
8197ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner      if (InTok) {
8207ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner        AsmOperands.push_back(AsmOperand(String.slice(Prev, i)));
8217ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner        InTok = false;
8227ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner      }
823828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
824d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      // If this isn't "${", treat like a normal token.
825d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      if (i + 1 == String.size() || String[i + 1] != '{') {
826d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner        Prev = i;
827d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner        break;
828d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      }
829d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner
830d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      StringRef::iterator End = std::find(String.begin() + i, String.end(),'}');
831d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      assert(End != String.end() && "Missing brace in operand reference!");
832d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      size_t EndPos = End - String.begin();
833c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner      AsmOperands.push_back(AsmOperand(String.slice(i, EndPos+1)));
834d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      Prev = EndPos + 1;
835d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      i = EndPos;
836d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      break;
837d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    }
838d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner
839d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    case '.':
840588f408b95c83e9b59c0777925d2ae70ac445faeVladimir Medic      if (!Info.AsmParser->getValueAsBit("MnemonicContainsDot")) {
8419273151c3bbc96c9b2911caffe3e1a724261cd06Vladimir Medic        if (InTok)
8429273151c3bbc96c9b2911caffe3e1a724261cd06Vladimir Medic          AsmOperands.push_back(AsmOperand(String.slice(Prev, i)));
8439273151c3bbc96c9b2911caffe3e1a724261cd06Vladimir Medic        Prev = i;
8449273151c3bbc96c9b2911caffe3e1a724261cd06Vladimir Medic      }
845d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      InTok = true;
846d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      break;
847d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner
848d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    default:
849d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      InTok = true;
850d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    }
851d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner  }
852d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner  if (InTok && Prev != String.size())
853c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner    AsmOperands.push_back(AsmOperand(String.substr(Prev)));
854828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
855d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner  // The first token of the instruction is the mnemonic, which must be a
856d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner  // simple string, not a $foo variable or a singleton register.
8574a2242cea0e9fdb36276807b1d4ddd7cd1a15bd4Jim Grosbach  if (AsmOperands.empty())
85861131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger    PrintFatalError(TheDef->getLoc(),
8594a2242cea0e9fdb36276807b1d4ddd7cd1a15bd4Jim Grosbach                  "Instruction '" + TheDef->getName() + "' has no tokens");
860d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner  Mnemonic = AsmOperands[0].Token;
8618e27c9615938298bd03a7884964a0f5e0e80542dJim Grosbach  if (Mnemonic.empty())
86261131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger    PrintFatalError(TheDef->getLoc(),
8638e27c9615938298bd03a7884964a0f5e0e80542dJim Grosbach                  "Missing instruction mnemonic");
86463faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel  // FIXME : Check and raise an error if it is a register.
865b78307fc58025713fd98c8414fa8f29720f37a76Devang Patel  if (Mnemonic[0] == '$')
86661131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger    PrintFatalError(TheDef->getLoc(),
867d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner                  "Invalid instruction mnemonic '" + Mnemonic.str() + "'!");
868828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
869d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner  // Remove the first operand, it is tracked in the mnemonic field.
870d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner  AsmOperands.erase(AsmOperands.begin());
871d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner}
872d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner
8738caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachbool MatchableInfo::validate(StringRef CommentDelimiter, bool Hack) const {
87422bc5c4184a497353e33195dd12541a4f08b008aChris Lattner  // Reject matchables with no .s string.
8755bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner  if (AsmString.empty())
87661131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger    PrintFatalError(TheDef->getLoc(), "instruction with empty asm string");
877828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
87822bc5c4184a497353e33195dd12541a4f08b008aChris Lattner  // Reject any matchables with a newline in them, they should be marked
8795bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner  // isCodeGenOnly if they are pseudo instructions.
8805bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner  if (AsmString.find('\n') != std::string::npos)
88161131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger    PrintFatalError(TheDef->getLoc(),
8825bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner                  "multiline instruction is not valid for the asmparser, "
8835bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner                  "mark it isCodeGenOnly");
884828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
8854164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner  // Remove comments from the asm string.  We know that the asmstring only
8864164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner  // has one line.
8874164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner  if (!CommentDelimiter.empty() &&
8884164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner      StringRef(AsmString).find(CommentDelimiter) != StringRef::npos)
88961131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger    PrintFatalError(TheDef->getLoc(),
8904164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner                  "asmstring for instruction has comment character in it, "
8914164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner                  "mark it isCodeGenOnly");
892828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
89322bc5c4184a497353e33195dd12541a4f08b008aChris Lattner  // Reject matchables with operand modifiers, these aren't something we can
894906bc368bc0fe18682edc0743ada41f62e436383Bob Wilson  // handle, the target should be refactored to use operands instead of
895906bc368bc0fe18682edc0743ada41f62e436383Bob Wilson  // modifiers.
8965bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner  //
8975bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner  // Also, check for instructions which reference the operand multiple times;
8985bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner  // this implies a constraint we would not honor.
8995bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner  std::set<std::string> OperandNames;
900d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner  for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) {
901d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    StringRef Tok = AsmOperands[i].Token;
902d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    if (Tok[0] == '$' && Tok.find(':') != StringRef::npos)
90361131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger      PrintFatalError(TheDef->getLoc(),
904d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner                    "matchable with operand modifier '" + Tok.str() +
9055bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner                    "' not supported by asm matcher.  Mark isCodeGenOnly!");
906828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
90722bc5c4184a497353e33195dd12541a4f08b008aChris Lattner    // Verify that any operand is only mentioned once.
908d51257a4368d52e2340073bc7ccd83f3c3f1c04dChris Lattner    // We reject aliases and ignore instructions for now.
909d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner    if (Tok[0] == '$' && !OperandNames.insert(Tok).second) {
91022bc5c4184a497353e33195dd12541a4f08b008aChris Lattner      if (!Hack)
91161131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger        PrintFatalError(TheDef->getLoc(),
912d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner                      "ERROR: matchable with tied operand '" + Tok.str() +
91322bc5c4184a497353e33195dd12541a4f08b008aChris Lattner                      "' can never be matched!");
91422bc5c4184a497353e33195dd12541a4f08b008aChris Lattner      // FIXME: Should reject these.  The ARM backend hits this with $lane in a
91522bc5c4184a497353e33195dd12541a4f08b008aChris Lattner      // bunch of instructions.  It is unclear what the right answer is.
9165bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner      DEBUG({
9175abd1ebcb380664ae5010395b217e01f7190046cChris Lattner        errs() << "warning: '" << TheDef->getName() << "': "
91822bc5c4184a497353e33195dd12541a4f08b008aChris Lattner               << "ignoring instruction with tied operand '"
919d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner               << Tok.str() << "'\n";
9205bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner      });
9215bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner      return false;
9225bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner    }
9235bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner  }
924828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
9255bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner  return true;
9265bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner}
9275bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner
928f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach/// extractSingletonRegisterForAsmOperand - Extract singleton register,
929d06b01c038e00f6af50a1b6d4c71389037e00212Devang Patel/// if present, from specified token.
93063faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patelvoid MatchableInfo::
931f35307ceac57194094f207f0920fbd22231f5331Jim GrosbachextractSingletonRegisterForAsmOperand(unsigned OperandNo,
932d06b01c038e00f6af50a1b6d4c71389037e00212Devang Patel                                      const AsmMatcherInfo &Info,
93311fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach                                      std::string &RegisterPrefix) {
934d06b01c038e00f6af50a1b6d4c71389037e00212Devang Patel  StringRef Tok = AsmOperands[OperandNo].Token;
93563faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel  if (RegisterPrefix.empty()) {
936d06b01c038e00f6af50a1b6d4c71389037e00212Devang Patel    std::string LoweredTok = Tok.lower();
937d06b01c038e00f6af50a1b6d4c71389037e00212Devang Patel    if (const CodeGenRegister *Reg = Info.Target.getRegisterByName(LoweredTok))
938d06b01c038e00f6af50a1b6d4c71389037e00212Devang Patel      AsmOperands[OperandNo].SingletonReg = Reg->TheDef;
93963faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel    return;
940f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach  }
94163faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel
94263faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel  if (!Tok.startswith(RegisterPrefix))
94363faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel    return;
944828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
94563faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel  StringRef RegName = Tok.substr(RegisterPrefix.size());
946ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner  if (const CodeGenRegister *Reg = Info.Target.getRegisterByName(RegName))
947d06b01c038e00f6af50a1b6d4c71389037e00212Devang Patel    AsmOperands[OperandNo].SingletonReg = Reg->TheDef;
948828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
9491de88235781c45c0afc0c7500d65b59775196c4cChris Lattner  // If there is no register prefix (i.e. "%" in "%eax"), then this may
9501de88235781c45c0afc0c7500d65b59775196c4cChris Lattner  // be some random non-register token, just ignore it.
95163faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel  return;
95202bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner}
95302bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner
954b8d6e98e566724f58344d275a4bd675249bb713aChris Lattnerstatic std::string getEnumNameForToken(StringRef Str) {
955a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  std::string Res;
956a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
957a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  for (StringRef::iterator it = Str.begin(), ie = Str.end(); it != ie; ++it) {
958a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    switch (*it) {
959a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    case '*': Res += "_STAR_"; break;
960a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    case '%': Res += "_PCT_"; break;
961a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    case ':': Res += "_COLON_"; break;
962bd9c77bc9ad384d046a7967d160ad96f61916d9dBill Wendling    case '!': Res += "_EXCLAIM_"; break;
9630ef755d9051a79680326d6144a2401660fc93e57Bill Wendling    case '.': Res += "_DOT_"; break;
96412da505d938ecfbc49b203e454bada99eda950e3Tim Northover    case '<': Res += "_LT_"; break;
96512da505d938ecfbc49b203e454bada99eda950e3Tim Northover    case '>': Res += "_GT_"; break;
966a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    default:
96712da505d938ecfbc49b203e454bada99eda950e3Tim Northover      if ((*it >= 'A' && *it <= 'Z') ||
96812da505d938ecfbc49b203e454bada99eda950e3Tim Northover          (*it >= 'a' && *it <= 'z') ||
96912da505d938ecfbc49b203e454bada99eda950e3Tim Northover          (*it >= '0' && *it <= '9'))
970a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar        Res += *it;
97139ee036f407bd0c94cb993cf9b97348843cfafa4Chris Lattner      else
972a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar        Res += "_" + utostr((unsigned) *it) + "_";
973a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    }
974a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  }
97520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
976a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  return Res;
977a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar}
978a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
979b8d6e98e566724f58344d275a4bd675249bb713aChris LattnerClassInfo *AsmMatcherInfo::getTokenClass(StringRef Token) {
980a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  ClassInfo *&Entry = TokenClasses[Token];
981a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
982a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  if (!Entry) {
983a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    Entry = new ClassInfo();
984a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    Entry->Kind = ClassInfo::Token;
9856745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar    Entry->ClassName = "Token";
986a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    Entry->Name = "MCK_" + getEnumNameForToken(Token);
987a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    Entry->ValueName = Token;
988a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    Entry->PredicateMethod = "<invalid>";
989a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    Entry->RenderMethod = "<invalid>";
990e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    Entry->ParserMethod = "";
9914dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach    Entry->DiagnosticType = "";
992a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    Classes.push_back(Entry);
993a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  }
994a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
995a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  return Entry;
996a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar}
997a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
998a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel DunbarClassInfo *
999a49c7dfb360154070c08b8eb94ad31711d1babaeBob WilsonAsmMatcherInfo::getOperandClass(const CGIOperandList::OperandInfo &OI,
1000a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson                                int SubOpIdx) {
1001a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson  Record *Rec = OI.Rec;
1002a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson  if (SubOpIdx != -1)
10033f7b7f8ce0b050fc6a0100839d9c5a84198b2aedSean Silva    Rec = cast<DefInit>(OI.MIOperandInfo->getArg(SubOpIdx))->getDef();
100448c1f84b104fd32109d809a56f5ebbf461c0910cJim Grosbach  return getOperandClass(Rec, SubOpIdx);
100548c1f84b104fd32109d809a56f5ebbf461c0910cJim Grosbach}
1006a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson
100748c1f84b104fd32109d809a56f5ebbf461c0910cJim GrosbachClassInfo *
100848c1f84b104fd32109d809a56f5ebbf461c0910cJim GrosbachAsmMatcherInfo::getOperandClass(Record *Rec, int SubOpIdx) {
1009bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson  if (Rec->isSubClassOf("RegisterOperand")) {
1010bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson    // RegisterOperand may have an associated ParserMatchClass. If it does,
1011bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson    // use it, else just fall back to the underlying register class.
1012bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson    const RecordVal *R = Rec->getValue("ParserMatchClass");
1013bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson    if (R == 0 || R->getValue() == 0)
101461131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger      PrintFatalError("Record `" + Rec->getName() +
101561131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger        "' does not have a ParserMatchClass!\n");
1016bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson
10176cfc806a6b82b60a3e923b6b89f2b4da62cdb50bSean Silva    if (DefInit *DI= dyn_cast<DefInit>(R->getValue())) {
1018bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson      Record *MatchClass = DI->getDef();
1019bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson      if (ClassInfo *CI = AsmOperandClasses[MatchClass])
1020bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson        return CI;
1021bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson    }
1022bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson
1023bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson    // No custom match class. Just use the register class.
1024bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson    Record *ClassRec = Rec->getValueAsDef("RegClass");
1025bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson    if (!ClassRec)
102661131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger      PrintFatalError(Rec->getLoc(), "RegisterOperand `" + Rec->getName() +
1027bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson                    "' has no associated register class!\n");
1028bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson    if (ClassInfo *CI = RegisterClassClasses[ClassRec])
1029bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson      return CI;
103061131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger    PrintFatalError(Rec->getLoc(), "register class has no class info!");
1031bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson  }
1032bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson
1033bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson
1034a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson  if (Rec->isSubClassOf("RegisterClass")) {
1035a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    if (ClassInfo *CI = RegisterClassClasses[Rec])
1036ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner      return CI;
103761131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger    PrintFatalError(Rec->getLoc(), "register class has no class info!");
1038ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  }
1039338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar
1040a562dc7228990797a259f4fef4acb95a83b23e0dJim Grosbach  if (!Rec->isSubClassOf("Operand"))
104161131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger    PrintFatalError(Rec->getLoc(), "Operand `" + Rec->getName() +
1042a562dc7228990797a259f4fef4acb95a83b23e0dJim Grosbach                  "' does not derive from class Operand!\n");
1043a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson  Record *MatchClass = Rec->getValueAsDef("ParserMatchClass");
1044ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner  if (ClassInfo *CI = AsmOperandClasses[MatchClass])
1045ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner    return CI;
1046a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
104761131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger  PrintFatalError(Rec->getLoc(), "operand has no match class!");
1048338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar}
1049338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar
10501de88235781c45c0afc0c7500d65b59775196c4cChris Lattnervoid AsmMatcherInfo::
10518caecdea56c830f3fc80ed67fff121c83de0e364Jim GrosbachbuildRegisterClasses(SmallPtrSet<Record*, 16> &SingletonRegisters) {
1052abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen  const std::vector<CodeGenRegister*> &Registers =
1053abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen    Target.getRegBank().getRegisters();
105429f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen  ArrayRef<CodeGenRegisterClass*> RegClassList =
105529f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen    Target.getRegBank().getRegClasses();
1056338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar
1057ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  // The register sets used for matching.
1058ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  std::set< std::set<Record*> > RegisterSets;
1059ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
1060a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach  // Gather the defined sets.
106129f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen  for (ArrayRef<CodeGenRegisterClass*>::const_iterator it =
1062ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner       RegClassList.begin(), ie = RegClassList.end(); it != ie; ++it)
106329f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen    RegisterSets.insert(std::set<Record*>(
106429f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen        (*it)->getOrder().begin(), (*it)->getOrder().end()));
10651095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar
10661095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar  // Add any required singleton sets.
10671de88235781c45c0afc0c7500d65b59775196c4cChris Lattner  for (SmallPtrSet<Record*, 16>::iterator it = SingletonRegisters.begin(),
10681de88235781c45c0afc0c7500d65b59775196c4cChris Lattner       ie = SingletonRegisters.end(); it != ie; ++it) {
10691de88235781c45c0afc0c7500d65b59775196c4cChris Lattner    Record *Rec = *it;
10701de88235781c45c0afc0c7500d65b59775196c4cChris Lattner    RegisterSets.insert(std::set<Record*>(&Rec, &Rec + 1));
10711de88235781c45c0afc0c7500d65b59775196c4cChris Lattner  }
1072a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
1073ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  // Introduce derived sets where necessary (when a register does not determine
1074ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  // a unique register set class), and build the mapping of registers to the set
1075ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  // they should classify to.
1076ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  std::map<Record*, std::set<Record*> > RegisterMap;
1077abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen  for (std::vector<CodeGenRegister*>::const_iterator it = Registers.begin(),
1078ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar         ie = Registers.end(); it != ie; ++it) {
1079abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen    const CodeGenRegister &CGR = **it;
1080ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    // Compute the intersection of all sets containing this register.
1081ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    std::set<Record*> ContainingSet;
1082a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
1083ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    for (std::set< std::set<Record*> >::iterator it = RegisterSets.begin(),
1084ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar           ie = RegisterSets.end(); it != ie; ++it) {
1085ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar      if (!it->count(CGR.TheDef))
1086ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar        continue;
1087ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
1088ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar      if (ContainingSet.empty()) {
1089ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar        ContainingSet = *it;
1090ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner        continue;
1091ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar      }
1092828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
1093ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner      std::set<Record*> Tmp;
1094ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner      std::swap(Tmp, ContainingSet);
1095ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner      std::insert_iterator< std::set<Record*> > II(ContainingSet,
1096ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner                                                   ContainingSet.begin());
1097ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner      std::set_intersection(Tmp.begin(), Tmp.end(), it->begin(), it->end(), II);
1098ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    }
1099ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
1100ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    if (!ContainingSet.empty()) {
1101ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar      RegisterSets.insert(ContainingSet);
1102ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar      RegisterMap.insert(std::make_pair(CGR.TheDef, ContainingSet));
1103ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    }
1104ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  }
1105ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
1106ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  // Construct the register classes.
1107ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  std::map<std::set<Record*>, ClassInfo*> RegisterSetClasses;
1108ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  unsigned Index = 0;
1109ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  for (std::set< std::set<Record*> >::iterator it = RegisterSets.begin(),
1110ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar         ie = RegisterSets.end(); it != ie; ++it, ++Index) {
1111ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    ClassInfo *CI = new ClassInfo();
1112ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    CI->Kind = ClassInfo::RegisterClass0 + Index;
1113ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    CI->ClassName = "Reg" + utostr(Index);
1114ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    CI->Name = "MCK_Reg" + utostr(Index);
1115ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    CI->ValueName = "";
1116ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    CI->PredicateMethod = ""; // unused
1117ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    CI->RenderMethod = "addRegOperands";
11188409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar    CI->Registers = *it;
11194dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach    // FIXME: diagnostic type.
11204dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach    CI->DiagnosticType = "";
1121ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    Classes.push_back(CI);
1122ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    RegisterSetClasses.insert(std::make_pair(*it, CI));
1123ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  }
1124ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
1125ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  // Find the superclasses; we could compute only the subgroup lattice edges,
1126ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  // but there isn't really a point.
1127ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  for (std::set< std::set<Record*> >::iterator it = RegisterSets.begin(),
1128ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar         ie = RegisterSets.end(); it != ie; ++it) {
1129ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    ClassInfo *CI = RegisterSetClasses[*it];
1130ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    for (std::set< std::set<Record*> >::iterator it2 = RegisterSets.begin(),
1131ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar           ie2 = RegisterSets.end(); it2 != ie2; ++it2)
1132a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach      if (*it != *it2 &&
1133ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar          std::includes(it2->begin(), it2->end(), it->begin(), it->end()))
1134ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar        CI->SuperClasses.push_back(RegisterSetClasses[*it2]);
1135ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  }
1136ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
1137ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  // Name the register classes which correspond to a user defined RegisterClass.
113829f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen  for (ArrayRef<CodeGenRegisterClass*>::const_iterator
1139ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner       it = RegClassList.begin(), ie = RegClassList.end(); it != ie; ++it) {
114029f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen    const CodeGenRegisterClass &RC = **it;
11416fea31e7300fe012b0b2984d6bc0338d02b054d3Jakob Stoklund Olesen    // Def will be NULL for non-user defined register classes.
11426fea31e7300fe012b0b2984d6bc0338d02b054d3Jakob Stoklund Olesen    Record *Def = RC.getDef();
11436fea31e7300fe012b0b2984d6bc0338d02b054d3Jakob Stoklund Olesen    if (!Def)
11446fea31e7300fe012b0b2984d6bc0338d02b054d3Jakob Stoklund Olesen      continue;
114529f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen    ClassInfo *CI = RegisterSetClasses[std::set<Record*>(RC.getOrder().begin(),
114629f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen                                                         RC.getOrder().end())];
1147ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    if (CI->ValueName.empty()) {
114829f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen      CI->ClassName = RC.getName();
114929f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen      CI->Name = "MCK_" + RC.getName();
115029f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen      CI->ValueName = RC.getName();
1151ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    } else
115229f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen      CI->ValueName = CI->ValueName + "," + RC.getName();
1153ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
11546fea31e7300fe012b0b2984d6bc0338d02b054d3Jakob Stoklund Olesen    RegisterClassClasses.insert(std::make_pair(Def, CI));
1155ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  }
1156ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
1157ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  // Populate the map for individual registers.
1158ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar  for (std::map<Record*, std::set<Record*> >::iterator it = RegisterMap.begin(),
1159ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar         ie = RegisterMap.end(); it != ie; ++it)
1160ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner    RegisterClasses[it->first] = RegisterSetClasses[it->second];
11611095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar
11621095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar  // Name the register classes which correspond to singleton registers.
11631de88235781c45c0afc0c7500d65b59775196c4cChris Lattner  for (SmallPtrSet<Record*, 16>::iterator it = SingletonRegisters.begin(),
11641de88235781c45c0afc0c7500d65b59775196c4cChris Lattner         ie = SingletonRegisters.end(); it != ie; ++it) {
11651de88235781c45c0afc0c7500d65b59775196c4cChris Lattner    Record *Rec = *it;
1166ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner    ClassInfo *CI = RegisterClasses[Rec];
11671de88235781c45c0afc0c7500d65b59775196c4cChris Lattner    assert(CI && "Missing singleton register class info!");
11681de88235781c45c0afc0c7500d65b59775196c4cChris Lattner
11691de88235781c45c0afc0c7500d65b59775196c4cChris Lattner    if (CI->ValueName.empty()) {
11701de88235781c45c0afc0c7500d65b59775196c4cChris Lattner      CI->ClassName = Rec->getName();
11711de88235781c45c0afc0c7500d65b59775196c4cChris Lattner      CI->Name = "MCK_" + Rec->getName();
11721de88235781c45c0afc0c7500d65b59775196c4cChris Lattner      CI->ValueName = Rec->getName();
11731de88235781c45c0afc0c7500d65b59775196c4cChris Lattner    } else
11741de88235781c45c0afc0c7500d65b59775196c4cChris Lattner      CI->ValueName = CI->ValueName + "," + Rec->getName();
11751095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar  }
1176ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar}
1177ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
11788caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachvoid AsmMatcherInfo::buildOperandClasses() {
1179e66b7ebfb426c7ed9bc911e9708321e2d8510b41Chris Lattner  std::vector<Record*> AsmOperands =
1180e66b7ebfb426c7ed9bc911e9708321e2d8510b41Chris Lattner    Records.getAllDerivedDefinitions("AsmOperandClass");
1181a2f5e00347641d1b46ce4f65bf9378fecce9be14Daniel Dunbar
1182a2f5e00347641d1b46ce4f65bf9378fecce9be14Daniel Dunbar  // Pre-populate AsmOperandClasses map.
1183a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach  for (std::vector<Record*>::iterator it = AsmOperands.begin(),
1184a2f5e00347641d1b46ce4f65bf9378fecce9be14Daniel Dunbar         ie = AsmOperands.end(); it != ie; ++it)
1185a2f5e00347641d1b46ce4f65bf9378fecce9be14Daniel Dunbar    AsmOperandClasses[*it] = new ClassInfo();
1186a2f5e00347641d1b46ce4f65bf9378fecce9be14Daniel Dunbar
1187338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar  unsigned Index = 0;
1188a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach  for (std::vector<Record*>::iterator it = AsmOperands.begin(),
1189338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar         ie = AsmOperands.end(); it != ie; ++it, ++Index) {
1190a2f5e00347641d1b46ce4f65bf9378fecce9be14Daniel Dunbar    ClassInfo *CI = AsmOperandClasses[*it];
1191338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar    CI->Kind = ClassInfo::UserClass0 + Index;
1192338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar
119305bce0beee87512e52428d4b80f5a8e79a949576David Greene    ListInit *Supers = (*it)->getValueAsListInit("SuperClasses");
119454ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar    for (unsigned i = 0, e = Supers->getSize(); i != e; ++i) {
11956cfc806a6b82b60a3e923b6b89f2b4da62cdb50bSean Silva      DefInit *DI = dyn_cast<DefInit>(Supers->getElement(i));
119654ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar      if (!DI) {
119754ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar        PrintError((*it)->getLoc(), "Invalid super class reference!");
119854ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar        continue;
119954ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar      }
120054ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar
1201ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar      ClassInfo *SC = AsmOperandClasses[DI->getDef()];
1202ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar      if (!SC)
1203338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar        PrintError((*it)->getLoc(), "Invalid super class reference!");
1204ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar      else
1205ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar        CI->SuperClasses.push_back(SC);
1206a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    }
1207338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar    CI->ClassName = (*it)->getValueAsString("Name");
1208338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar    CI->Name = "MCK_" + CI->ClassName;
1209338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar    CI->ValueName = (*it)->getName();
12105c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar
12115c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar    // Get or construct the predicate method name.
121205bce0beee87512e52428d4b80f5a8e79a949576David Greene    Init *PMName = (*it)->getValueInit("PredicateMethod");
12136cfc806a6b82b60a3e923b6b89f2b4da62cdb50bSean Silva    if (StringInit *SI = dyn_cast<StringInit>(PMName)) {
12145c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar      CI->PredicateMethod = SI->getValue();
12155c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar    } else {
12163f7b7f8ce0b050fc6a0100839d9c5a84198b2aedSean Silva      assert(isa<UnsetInit>(PMName) && "Unexpected PredicateMethod field!");
12175c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar      CI->PredicateMethod = "is" + CI->ClassName;
12185c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar    }
12195c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar
12205c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar    // Get or construct the render method name.
122105bce0beee87512e52428d4b80f5a8e79a949576David Greene    Init *RMName = (*it)->getValueInit("RenderMethod");
12226cfc806a6b82b60a3e923b6b89f2b4da62cdb50bSean Silva    if (StringInit *SI = dyn_cast<StringInit>(RMName)) {
12235c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar      CI->RenderMethod = SI->getValue();
12245c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar    } else {
12253f7b7f8ce0b050fc6a0100839d9c5a84198b2aedSean Silva      assert(isa<UnsetInit>(RMName) && "Unexpected RenderMethod field!");
12265c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar      CI->RenderMethod = "add" + CI->ClassName + "Operands";
12275c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar    }
12285c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar
1229e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    // Get the parse method name or leave it as empty.
123005bce0beee87512e52428d4b80f5a8e79a949576David Greene    Init *PRMName = (*it)->getValueInit("ParserMethod");
12316cfc806a6b82b60a3e923b6b89f2b4da62cdb50bSean Silva    if (StringInit *SI = dyn_cast<StringInit>(PRMName))
1232e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes      CI->ParserMethod = SI->getValue();
1233e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
12344dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach    // Get the diagnostic type or leave it as empty.
12354dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach    // Get the parse method name or leave it as empty.
12364dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach    Init *DiagnosticType = (*it)->getValueInit("DiagnosticType");
12376cfc806a6b82b60a3e923b6b89f2b4da62cdb50bSean Silva    if (StringInit *SI = dyn_cast<StringInit>(DiagnosticType))
12384dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach      CI->DiagnosticType = SI->getValue();
12394dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach
1240338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar    AsmOperandClasses[*it] = CI;
1241338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar    Classes.push_back(CI);
1242a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  }
1243ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar}
1244ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
1245828295bb301d6cd3683751c2da1c2dd22ec6423fBob WilsonAsmMatcherInfo::AsmMatcherInfo(Record *asmParser,
1246828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson                               CodeGenTarget &target,
12479c6b60eb28d2717008f8d6ff52f7666ebc81113dChris Lattner                               RecordKeeper &records)
124863faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel  : Records(records), AsmParser(asmParser), Target(target) {
124959fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar}
125059fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar
12518caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach/// buildOperandMatchInfo - Build the necessary information to handle user
1252e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes/// defined operand parsing methods.
12538caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachvoid AsmMatcherInfo::buildOperandMatchInfo() {
1254e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
1255d4824fc8aa1df5501600dd2a73c6da823f3b02dbJim Grosbach  /// Map containing a mask with all operands indices that can be found for
1256e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  /// that class inside a instruction.
1257b2df610b44902124c22f3661a39bffd5341da62dSean Silva  typedef std::map<ClassInfo*, unsigned, LessClassInfoPtr> OpClassMaskTy;
1258b2df610b44902124c22f3661a39bffd5341da62dSean Silva  OpClassMaskTy OpClassMask;
1259e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
1260e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  for (std::vector<MatchableInfo*>::const_iterator it =
1261e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes       Matchables.begin(), ie = Matchables.end();
1262e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes       it != ie; ++it) {
1263e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    MatchableInfo &II = **it;
1264e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    OpClassMask.clear();
1265e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
1266e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    // Keep track of all operands of this instructions which belong to the
1267e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    // same class.
1268e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    for (unsigned i = 0, e = II.AsmOperands.size(); i != e; ++i) {
1269e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes      MatchableInfo::AsmOperand &Op = II.AsmOperands[i];
1270e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes      if (Op.Class->ParserMethod.empty())
1271e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes        continue;
1272e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes      unsigned &OperandMask = OpClassMask[Op.Class];
1273e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes      OperandMask |= (1 << i);
1274e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    }
1275e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
1276e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    // Generate operand match info for each mnemonic/operand class pair.
1277b2df610b44902124c22f3661a39bffd5341da62dSean Silva    for (OpClassMaskTy::iterator iit = OpClassMask.begin(),
1278e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes         iie = OpClassMask.end(); iit != iie; ++iit) {
1279e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes      unsigned OpMask = iit->second;
1280e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes      ClassInfo *CI = iit->first;
12818caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach      OperandMatchInfo.push_back(OperandMatchEntry::create(&II, CI, OpMask));
1282e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    }
1283e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  }
1284e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes}
1285e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
12868caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachvoid AsmMatcherInfo::buildInfo() {
12870aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner  // Build information about all of the AssemblerPredicates.
12880aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner  std::vector<Record*> AllPredicates =
12890aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner    Records.getAllDerivedDefinitions("Predicate");
12900aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner  for (unsigned i = 0, e = AllPredicates.size(); i != e; ++i) {
12910aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner    Record *Pred = AllPredicates[i];
12920aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner    // Ignore predicates that are not intended for the assembler.
12930aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner    if (!Pred->getValueAsBit("AssemblerMatcherPredicate"))
12940aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner      continue;
1295828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
12964164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner    if (Pred->getName().empty())
129761131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger      PrintFatalError(Pred->getLoc(), "Predicate has no name!");
1298828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
12990aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner    unsigned FeatureNo = SubtargetFeatures.size();
13000aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner    SubtargetFeatures[Pred] = new SubtargetFeatureInfo(Pred, FeatureNo);
13010aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner    assert(FeatureNo < 32 && "Too many subtarget features!");
13020aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner  }
1303a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
130439ee036f407bd0c94cb993cf9b97348843cfafa4Chris Lattner  // Parse the instructions; we need to do this first so that we can gather the
130539ee036f407bd0c94cb993cf9b97348843cfafa4Chris Lattner  // singleton register classes.
13061de88235781c45c0afc0c7500d65b59775196c4cChris Lattner  SmallPtrSet<Record*, 16> SingletonRegisters;
13070dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel  unsigned VariantCount = Target.getAsmParserVariantCount();
13080dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel  for (unsigned VC = 0; VC != VariantCount; ++VC) {
13090dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel    Record *AsmVariant = Target.getAsmParserVariant(VC);
131065da6fc8af561e77620bd86b83be8ca50acfdd30Jim Grosbach    std::string CommentDelimiter =
131165da6fc8af561e77620bd86b83be8ca50acfdd30Jim Grosbach      AsmVariant->getValueAsString("CommentDelimiter");
13120dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel    std::string RegisterPrefix = AsmVariant->getValueAsString("RegisterPrefix");
13130dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel    int AsmVariantNo = AsmVariant->getValueAsInt("Variant");
1314f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach
13150dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel    for (CodeGenTarget::inst_iterator I = Target.inst_begin(),
131611fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach           E = Target.inst_end(); I != E; ++I) {
13170dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      const CodeGenInstruction &CGI = **I;
1318f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach
13190dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      // If the tblgen -match-prefix option is specified (for tblgen hackers),
13200dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      // filter the set of instructions we consider.
13210dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      if (!StringRef(CGI.TheDef->getName()).startswith(MatchPrefix))
132211fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach        continue;
1323f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach
13240dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      // Ignore "codegen only" instructions.
13250dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      if (CGI.TheDef->getValueAsBit("isCodeGenOnly"))
132611fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach        continue;
1327f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach
13280dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      OwningPtr<MatchableInfo> II(new MatchableInfo(CGI));
1329f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach
13308caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach      II->initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix);
1331f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach
13320dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      // Ignore instructions which shouldn't be matched and diagnose invalid
13330dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      // instruction definitions with an error.
13348caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach      if (!II->validate(CommentDelimiter, true))
133511fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach        continue;
1336f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach
13370dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      // Ignore "Int_*" and "*_Int" instructions, which are internal aliases.
13380dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      //
13390dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      // FIXME: This is a total hack.
13400dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      if (StringRef(II->TheDef->getName()).startswith("Int_") ||
134111fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach          StringRef(II->TheDef->getName()).endswith("_Int"))
134211fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach        continue;
1343f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach
13440dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      Matchables.push_back(II.take());
13450dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel    }
1346f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach
13470dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel    // Parse all of the InstAlias definitions and stick them in the list of
13480dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel    // matchables.
13490dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel    std::vector<Record*> AllInstAliases =
13500dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      Records.getAllDerivedDefinitions("InstAlias");
13510dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel    for (unsigned i = 0, e = AllInstAliases.size(); i != e; ++i) {
13520dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      CodeGenInstAlias *Alias = new CodeGenInstAlias(AllInstAliases[i], Target);
1353f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach
13540dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      // If the tblgen -match-prefix option is specified (for tblgen hackers),
13550dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      // filter the set of instruction aliases we consider, based on the target
13560dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      // instruction.
135765da6fc8af561e77620bd86b83be8ca50acfdd30Jim Grosbach      if (!StringRef(Alias->ResultInst->TheDef->getName())
135865da6fc8af561e77620bd86b83be8ca50acfdd30Jim Grosbach            .startswith( MatchPrefix))
135911fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach        continue;
1360f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach
13610dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      OwningPtr<MatchableInfo> II(new MatchableInfo(Alias));
1362f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach
13638caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach      II->initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix);
1364f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach
13650dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      // Validate the alias definitions.
13668caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach      II->validate(CommentDelimiter, false);
1367f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach
13680dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel      Matchables.push_back(II.take());
13691d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner    }
1370c76e80ded753b78a72be0db40fcdba543435d818Chris Lattner  }
1371c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner
13721095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar  // Build info for the register classes.
13738caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  buildRegisterClasses(SingletonRegisters);
13741095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar
13751095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar  // Build info for the user defined assembly operand classes.
13768caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  buildOperandClasses();
13771095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar
13780bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner  // Build the information about matchables, now that we have fully formed
13790bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner  // classes.
1380c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  std::vector<MatchableInfo*> NewMatchables;
138122bc5c4184a497353e33195dd12541a4f08b008aChris Lattner  for (std::vector<MatchableInfo*>::iterator it = Matchables.begin(),
138222bc5c4184a497353e33195dd12541a4f08b008aChris Lattner         ie = Matchables.end(); it != ie; ++it) {
138322bc5c4184a497353e33195dd12541a4f08b008aChris Lattner    MatchableInfo *II = *it;
1384a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
1385e206fcf0e9c7e79c7f42ff2151f3fb58cba70674Chris Lattner    // Parse the tokens after the mnemonic.
13868caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach    // Note: buildInstructionOperandReference may insert new AsmOperands, so
1387a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    // don't precompute the loop bound.
1388a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    for (unsigned i = 0; i != II->AsmOperands.size(); ++i) {
1389c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner      MatchableInfo::AsmOperand &Op = II->AsmOperands[i];
1390d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner      StringRef Token = Op.Token;
139120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
13921095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar      // Check for singleton registers.
139363faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel      if (Record *RegRecord = II->AsmOperands[i].SingletonReg) {
1394d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner        Op.Class = RegisterClasses[RegRecord];
139502bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner        assert(Op.Class && Op.Class->Registers.size() == 1 &&
139602bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner               "Unexpected class for singleton register");
139702bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner        continue;
13981095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar      }
13991095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar
140020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar      // Check for simple tokens.
140120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar      if (Token[0] != '$') {
1402d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner        Op.Class = getTokenClass(Token);
140320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar        continue;
140420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar      }
1405a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
14067ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner      if (Token.size() > 1 && isdigit(Token[1])) {
14077ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner        Op.Class = getTokenClass(Token);
14087ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner        continue;
14097ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner      }
1410828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
1411c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner      // Otherwise this is an operand reference.
14125f4280cd2d2d1aeb527c8b161acaa1870cf6ee82Chris Lattner      StringRef OperandName;
14135f4280cd2d2d1aeb527c8b161acaa1870cf6ee82Chris Lattner      if (Token[1] == '{')
14145f4280cd2d2d1aeb527c8b161acaa1870cf6ee82Chris Lattner        OperandName = Token.substr(2, Token.size() - 3);
14155f4280cd2d2d1aeb527c8b161acaa1870cf6ee82Chris Lattner      else
14165f4280cd2d2d1aeb527c8b161acaa1870cf6ee82Chris Lattner        OperandName = Token.substr(1);
1417828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
1418c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner      if (II->DefRec.is<const CodeGenInstruction*>())
14198caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach        buildInstructionOperandReference(II, OperandName, i);
1420c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner      else
14218caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach        buildAliasOperandReference(II, OperandName, Op);
142253a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar    }
1423828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
1424c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach    if (II->DefRec.is<const CodeGenInstruction*>()) {
14258caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach      II->buildInstructionResultOperands();
1426c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach      // If the instruction has a two-operand alias, build up the
1427c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach      // matchable here. We'll add them in bulk at the end to avoid
1428c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach      // confusing this loop.
1429c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach      std::string Constraint =
1430c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach        II->TheDef->getValueAsString("TwoOperandAliasConstraint");
1431c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach      if (Constraint != "") {
1432c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach        // Start by making a copy of the original matchable.
1433c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach        OwningPtr<MatchableInfo> AliasII(new MatchableInfo(*II));
1434c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach
1435c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach        // Adjust it to be a two-operand alias.
1436c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach        AliasII->formTwoOperandAlias(Constraint);
1437c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach
1438c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach        // Add the alias to the matchables list.
1439c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach        NewMatchables.push_back(AliasII.take());
1440c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach      }
1441c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach    } else
14428caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach      II->buildAliasResultOperands();
144320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
1444c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach  if (!NewMatchables.empty())
1445c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach    Matchables.insert(Matchables.end(), NewMatchables.begin(),
1446c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach                      NewMatchables.end());
14475fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar
1448a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach  // Process token alias definitions and set up the associated superclass
1449a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach  // information.
1450a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach  std::vector<Record*> AllTokenAliases =
1451a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach    Records.getAllDerivedDefinitions("TokenAlias");
1452a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach  for (unsigned i = 0, e = AllTokenAliases.size(); i != e; ++i) {
1453a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach    Record *Rec = AllTokenAliases[i];
1454a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach    ClassInfo *FromClass = getTokenClass(Rec->getValueAsString("FromToken"));
1455a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach    ClassInfo *ToClass = getTokenClass(Rec->getValueAsString("ToToken"));
145667cd20d0396a68e61858736b7943dd352f1b0d0bJim Grosbach    if (FromClass == ToClass)
145761131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger      PrintFatalError(Rec->getLoc(),
145867cd20d0396a68e61858736b7943dd352f1b0d0bJim Grosbach                    "error: Destination value identical to source value.");
1459a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach    FromClass->SuperClasses.push_back(ToClass);
1460a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach  }
1461a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach
14627a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner  // Reorder classes so that classes precede super classes.
14635fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar  std::sort(Classes.begin(), Classes.end(), less_ptr<ClassInfo>());
146420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar}
1465a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
14668caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach/// buildInstructionOperandReference - The specified operand is a reference to a
14670bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner/// named operand such as $src.  Resolve the Class and OperandInfo pointers.
14680bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattnervoid AsmMatcherInfo::
14698caecdea56c830f3fc80ed67fff121c83de0e364Jim GrosbachbuildInstructionOperandReference(MatchableInfo *II,
14705f4280cd2d2d1aeb527c8b161acaa1870cf6ee82Chris Lattner                                 StringRef OperandName,
1471a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson                                 unsigned AsmOpIdx) {
1472c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner  const CodeGenInstruction &CGI = *II->DefRec.get<const CodeGenInstruction*>();
1473c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner  const CGIOperandList &Operands = CGI.Operands;
1474a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson  MatchableInfo::AsmOperand *Op = &II->AsmOperands[AsmOpIdx];
1475828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
1476662e5a30e864e71111b885d3da3cdd184772035dChris Lattner  // Map this token to an operand.
14770bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner  unsigned Idx;
14780bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner  if (!Operands.hasOperandNamed(OperandName, Idx))
147961131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger    PrintFatalError(II->TheDef->getLoc(), "error: unable to find operand: '" +
14800bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner                  OperandName.str() + "'");
1481ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner
1482a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson  // If the instruction operand has multiple suboperands, but the parser
1483a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson  // match class for the asm operand is still the default "ImmAsmOperand",
1484a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson  // then handle each suboperand separately.
1485a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson  if (Op->SubOpIdx == -1 && Operands[Idx].MINumOperands > 1) {
1486a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    Record *Rec = Operands[Idx].Rec;
1487a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    assert(Rec->isSubClassOf("Operand") && "Unexpected operand!");
1488a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    Record *MatchClass = Rec->getValueAsDef("ParserMatchClass");
1489a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    if (MatchClass && MatchClass->getValueAsString("Name") == "Imm") {
1490a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      // Insert remaining suboperands after AsmOpIdx in II->AsmOperands.
1491a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      StringRef Token = Op->Token; // save this in case Op gets moved
1492a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      for (unsigned SI = 1, SE = Operands[Idx].MINumOperands; SI != SE; ++SI) {
1493a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson        MatchableInfo::AsmOperand NewAsmOp(Token);
1494a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson        NewAsmOp.SubOpIdx = SI;
1495a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson        II->AsmOperands.insert(II->AsmOperands.begin()+AsmOpIdx+SI, NewAsmOp);
1496a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      }
1497a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      // Replace Op with first suboperand.
1498a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      Op = &II->AsmOperands[AsmOpIdx]; // update the pointer in case it moved
1499a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      Op->SubOpIdx = 0;
1500a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    }
1501a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson  }
1502a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson
1503ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner  // Set up the operand class.
1504a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson  Op->Class = getOperandClass(Operands[Idx], Op->SubOpIdx);
1505ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner
1506ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner  // If the named operand is tied, canonicalize it to the untied operand.
1507ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner  // For example, something like:
1508ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner  //   (outs GPR:$dst), (ins GPR:$src)
1509ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner  // with an asmstring of
1510ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner  //   "inc $src"
1511ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner  // we want to canonicalize to:
1512c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner  //   "inc $dst"
1513c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner  // so that we know how to provide the $dst operand when filling in the result.
1514d999062f31b5e0a2f12d70a54ffdb02be8363657Ulrich Weigand  int OITied = -1;
1515d999062f31b5e0a2f12d70a54ffdb02be8363657Ulrich Weigand  if (Operands[Idx].MINumOperands == 1)
1516d999062f31b5e0a2f12d70a54ffdb02be8363657Ulrich Weigand    OITied = Operands[Idx].getTiedRegister();
1517c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner  if (OITied != -1) {
1518c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner    // The tied operand index is an MIOperand index, find the operand that
1519c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner    // contains it.
1520a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    std::pair<unsigned, unsigned> Idx = Operands.getSubOperandNumber(OITied);
1521a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    OperandName = Operands[Idx.first].Name;
1522a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    Op->SubOpIdx = Idx.second;
1523c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner  }
1524828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
1525a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson  Op->SrcOpName = OperandName;
1526c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner}
1527c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner
15288caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach/// buildAliasOperandReference - When parsing an operand reference out of the
15293f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner/// matching string (e.g. "movsx $src, $dst"), determine what the class of the
15303f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner/// operand reference is by looking it up in the result pattern definition.
15318caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachvoid AsmMatcherInfo::buildAliasOperandReference(MatchableInfo *II,
1532c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner                                                StringRef OperandName,
1533c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner                                                MatchableInfo::AsmOperand &Op) {
1534c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner  const CodeGenInstAlias &CGA = *II->DefRec.get<const CodeGenInstAlias*>();
1535828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
1536c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner  // Set up the operand class.
15373f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner  for (unsigned i = 0, e = CGA.ResultOperands.size(); i != e; ++i)
153898c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner    if (CGA.ResultOperands[i].isRecord() &&
153998c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner        CGA.ResultOperands[i].getName() == OperandName) {
1540662e5a30e864e71111b885d3da3cdd184772035dChris Lattner      // It's safe to go with the first one we find, because CodeGenInstAlias
1541662e5a30e864e71111b885d3da3cdd184772035dChris Lattner      // validates that all operands with the same name have the same record.
1542a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      Op.SubOpIdx = CGA.ResultInstOperandIndex[i].second;
154348c1f84b104fd32109d809a56f5ebbf461c0910cJim Grosbach      // Use the match class from the Alias definition, not the
154448c1f84b104fd32109d809a56f5ebbf461c0910cJim Grosbach      // destination instruction, as we may have an immediate that's
154548c1f84b104fd32109d809a56f5ebbf461c0910cJim Grosbach      // being munged by the match class.
154648c1f84b104fd32109d809a56f5ebbf461c0910cJim Grosbach      Op.Class = getOperandClass(CGA.ResultOperands[i].getRecord(),
1547a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson                                 Op.SubOpIdx);
15483f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner      Op.SrcOpName = OperandName;
15493f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner      return;
15500bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner    }
15513f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner
155261131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger  PrintFatalError(II->TheDef->getLoc(), "error: unable to find operand: '" +
15533f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner                OperandName.str() + "'");
15540bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner}
15550bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner
15568caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachvoid MatchableInfo::buildInstructionResultOperands() {
1557662e5a30e864e71111b885d3da3cdd184772035dChris Lattner  const CodeGenInstruction *ResultInst = getResultInst();
1558828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
1559662e5a30e864e71111b885d3da3cdd184772035dChris Lattner  // Loop over all operands of the result instruction, determining how to
1560662e5a30e864e71111b885d3da3cdd184772035dChris Lattner  // populate them.
1561662e5a30e864e71111b885d3da3cdd184772035dChris Lattner  for (unsigned i = 0, e = ResultInst->Operands.size(); i != e; ++i) {
1562662e5a30e864e71111b885d3da3cdd184772035dChris Lattner    const CGIOperandList::OperandInfo &OpInfo = ResultInst->Operands[i];
1563567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner
1564567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner    // If this is a tied operand, just copy from the previously handled operand.
1565d999062f31b5e0a2f12d70a54ffdb02be8363657Ulrich Weigand    int TiedOp = -1;
1566d999062f31b5e0a2f12d70a54ffdb02be8363657Ulrich Weigand    if (OpInfo.MINumOperands == 1)
1567d999062f31b5e0a2f12d70a54ffdb02be8363657Ulrich Weigand      TiedOp = OpInfo.getTiedRegister();
1568567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner    if (TiedOp != -1) {
1569a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      ResOperands.push_back(ResOperand::getTiedOp(TiedOp));
1570567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner      continue;
1571567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner    }
1572828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
1573a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    // Find out what operand from the asmparser this MCInst operand comes from.
15748caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach    int SrcOperand = findAsmOperandNamed(OpInfo.Name);
1575d999062f31b5e0a2f12d70a54ffdb02be8363657Ulrich Weigand    if (OpInfo.Name.empty() || SrcOperand == -1) {
1576d999062f31b5e0a2f12d70a54ffdb02be8363657Ulrich Weigand      // This may happen for operands that are tied to a suboperand of a
1577d999062f31b5e0a2f12d70a54ffdb02be8363657Ulrich Weigand      // complex operand.  Simply use a dummy value here; nobody should
1578d999062f31b5e0a2f12d70a54ffdb02be8363657Ulrich Weigand      // use this operand slot.
1579d999062f31b5e0a2f12d70a54ffdb02be8363657Ulrich Weigand      // FIXME: The long term goal is for the MCOperand list to not contain
1580d999062f31b5e0a2f12d70a54ffdb02be8363657Ulrich Weigand      // tied operands at all.
1581d999062f31b5e0a2f12d70a54ffdb02be8363657Ulrich Weigand      ResOperands.push_back(ResOperand::getImmOp(0));
1582d999062f31b5e0a2f12d70a54ffdb02be8363657Ulrich Weigand      continue;
1583d999062f31b5e0a2f12d70a54ffdb02be8363657Ulrich Weigand    }
1584567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner
1585a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    // Check if the one AsmOperand populates the entire operand.
1586a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    unsigned NumOperands = OpInfo.MINumOperands;
1587a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    if (AsmOperands[SrcOperand].SubOpIdx == -1) {
1588a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      ResOperands.push_back(ResOperand::getRenderedOp(SrcOperand, NumOperands));
15891d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      continue;
15901d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner    }
1591a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson
1592a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    // Add a separate ResOperand for each suboperand.
1593a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    for (unsigned AI = 0; AI < NumOperands; ++AI) {
1594a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      assert(AsmOperands[SrcOperand+AI].SubOpIdx == (int)AI &&
1595a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson             AsmOperands[SrcOperand+AI].SrcOpName == OpInfo.Name &&
1596a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson             "unexpected AsmOperands for suboperands");
1597a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      ResOperands.push_back(ResOperand::getRenderedOp(SrcOperand + AI, 1));
1598a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    }
15991d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner  }
16001d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner}
16011d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner
16028caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachvoid MatchableInfo::buildAliasResultOperands() {
1603414098571b19fc248fda2be194082cfd012d2729Chris Lattner  const CodeGenInstAlias &CGA = *DefRec.get<const CodeGenInstAlias*>();
1604414098571b19fc248fda2be194082cfd012d2729Chris Lattner  const CodeGenInstruction *ResultInst = getResultInst();
1605828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
1606414098571b19fc248fda2be194082cfd012d2729Chris Lattner  // Loop over all operands of the result instruction, determining how to
1607414098571b19fc248fda2be194082cfd012d2729Chris Lattner  // populate them.
1608414098571b19fc248fda2be194082cfd012d2729Chris Lattner  unsigned AliasOpNo = 0;
1609a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson  unsigned LastOpNo = CGA.ResultInstOperandIndex.size();
1610414098571b19fc248fda2be194082cfd012d2729Chris Lattner  for (unsigned i = 0, e = ResultInst->Operands.size(); i != e; ++i) {
1611a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    const CGIOperandList::OperandInfo *OpInfo = &ResultInst->Operands[i];
1612828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
1613414098571b19fc248fda2be194082cfd012d2729Chris Lattner    // If this is a tied operand, just copy from the previously handled operand.
1614d999062f31b5e0a2f12d70a54ffdb02be8363657Ulrich Weigand    int TiedOp = -1;
1615d999062f31b5e0a2f12d70a54ffdb02be8363657Ulrich Weigand    if (OpInfo->MINumOperands == 1)
1616d999062f31b5e0a2f12d70a54ffdb02be8363657Ulrich Weigand      TiedOp = OpInfo->getTiedRegister();
1617414098571b19fc248fda2be194082cfd012d2729Chris Lattner    if (TiedOp != -1) {
1618a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      ResOperands.push_back(ResOperand::getTiedOp(TiedOp));
161990fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner      continue;
162090fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner    }
162190fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner
1622a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    // Handle all the suboperands for this operand.
1623a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    const std::string &OpName = OpInfo->Name;
1624a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    for ( ; AliasOpNo <  LastOpNo &&
1625a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson            CGA.ResultInstOperandIndex[AliasOpNo].first == i; ++AliasOpNo) {
1626a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      int SubIdx = CGA.ResultInstOperandIndex[AliasOpNo].second;
1627a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson
1628a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      // Find out what operand from the asmparser that this MCInst operand
1629a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      // comes from.
1630a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      switch (CGA.ResultOperands[AliasOpNo].Kind) {
1631a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      case CodeGenInstAlias::ResultOperand::K_Record: {
1632a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson        StringRef Name = CGA.ResultOperands[AliasOpNo].getName();
16338caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach        int SrcOperand = findAsmOperand(Name, SubIdx);
1634a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson        if (SrcOperand == -1)
163561131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger          PrintFatalError(TheDef->getLoc(), "Instruction '" +
1636a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson                        TheDef->getName() + "' has operand '" + OpName +
1637a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson                        "' that doesn't appear in asm string!");
1638a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson        unsigned NumOperands = (SubIdx == -1 ? OpInfo->MINumOperands : 1);
1639a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson        ResOperands.push_back(ResOperand::getRenderedOp(SrcOperand,
1640a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson                                                        NumOperands));
1641a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson        break;
1642a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      }
1643a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      case CodeGenInstAlias::ResultOperand::K_Imm: {
1644a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson        int64_t ImmVal = CGA.ResultOperands[AliasOpNo].getImm();
1645a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson        ResOperands.push_back(ResOperand::getImmOp(ImmVal));
1646a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson        break;
1647a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      }
1648a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      case CodeGenInstAlias::ResultOperand::K_Reg: {
1649a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson        Record *Reg = CGA.ResultOperands[AliasOpNo].getRegister();
1650a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson        ResOperands.push_back(ResOperand::getRegOp(Reg));
1651a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson        break;
1652a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      }
1653a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson      }
165490fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner    }
1655414098571b19fc248fda2be194082cfd012d2729Chris Lattner  }
1656414098571b19fc248fda2be194082cfd012d2729Chris Lattner}
16571d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner
1658c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbachstatic unsigned getConverterOperandID(const std::string &Name,
1659c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach                                      SetVector<std::string> &Table,
1660c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach                                      bool &IsNew) {
1661c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach  IsNew = Table.insert(Name);
1662c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach
1663c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach  unsigned ID = IsNew ? Table.size() - 1 :
1664c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach    std::find(Table.begin(), Table.end(), Name) - Table.begin();
1665c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach
1666c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach  assert(ID < Table.size());
1667c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach
1668c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach  return ID;
1669c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach}
1670c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach
1671c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach
167222685876ed7231f32f7d1698c00acab22825b74cChad Rosierstatic void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
167322685876ed7231f32f7d1698c00acab22825b74cChad Rosier                             std::vector<MatchableInfo*> &Infos,
167422685876ed7231f32f7d1698c00acab22825b74cChad Rosier                             raw_ostream &OS) {
1675c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach  SetVector<std::string> OperandConversionKinds;
1676c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach  SetVector<std::string> InstructionConversionKinds;
1677c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach  std::vector<std::vector<uint8_t> > ConversionTable;
1678c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach  size_t MaxRowLength = 2; // minimum is custom converter plus terminator.
1679c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach
1680c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach  // TargetOperandClass - This is the target's operand class, like X86Operand.
1681c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach  std::string TargetOperandClass = Target.getName() + "Operand";
1682c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach
1683b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar  // Write the convert function to a separate stream, so we can drop it after
1684c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach  // the enum. We'll build up the conversion handlers for the individual
1685c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach  // operand types opportunistically as we encounter them.
1686b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar  std::string ConvertFnBody;
1687b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar  raw_string_ostream CvtOS(ConvertFnBody);
1688b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar  // Start the unified conversion function.
1689359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosier  CvtOS << "void " << Target.getName() << ClassName << "::\n"
169090e11f8c95146c2d3718e9b3de71ee6628347b05Chad Rosier        << "convertToMCInst(unsigned Kind, MCInst &Inst, "
1691b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar        << "unsigned Opcode,\n"
169204508c6cb734ab1119a076f94b1c9fe8c4240b7dChad Rosier        << "                const SmallVectorImpl<MCParsedAsmOperand*"
1693c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        << "> &Operands) {\n"
1694359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosier        << "  assert(Kind < CVT_NUM_SIGNATURES && \"Invalid signature!\");\n"
1695b198f5c8979d46d75a08c1710a160f8e102b9ba8Craig Topper        << "  const uint8_t *Converter = ConversionTable[Kind];\n"
1696c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        << "  Inst.setOpcode(Opcode);\n"
1697b198f5c8979d46d75a08c1710a160f8e102b9ba8Craig Topper        << "  for (const uint8_t *p = Converter; *p; p+= 2) {\n"
1698c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        << "    switch (*p) {\n"
1699c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        << "    default: llvm_unreachable(\"invalid conversion entry!\");\n"
1700c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        << "    case CVT_Reg:\n"
1701c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        << "      static_cast<" << TargetOperandClass
1702c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        << "*>(Operands[*(p + 1)])->addRegOperands(Inst, 1);\n"
1703c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        << "      break;\n"
1704c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        << "    case CVT_Tied:\n"
1705c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        << "      Inst.addOperand(Inst.getOperand(*(p + 1)));\n"
1706c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        << "      break;\n";
1707c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach
170862316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier  std::string OperandFnBody;
170962316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier  raw_string_ostream OpOS(OperandFnBody);
171062316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier  // Start the operand number lookup function.
171122685876ed7231f32f7d1698c00acab22825b74cChad Rosier  OpOS << "void " << Target.getName() << ClassName << "::\n"
171222685876ed7231f32f7d1698c00acab22825b74cChad Rosier       << "convertToMapAndConstraints(unsigned Kind,\n";
1713c69bb70deb5b596941bb1de180d1554f9a411062Chad Rosier  OpOS.indent(27);
17146e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier  OpOS << "const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {\n"
1715359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosier       << "  assert(Kind < CVT_NUM_SIGNATURES && \"Invalid signature!\");\n"
171622685876ed7231f32f7d1698c00acab22825b74cChad Rosier       << "  unsigned NumMCOperands = 0;\n"
1717b198f5c8979d46d75a08c1710a160f8e102b9ba8Craig Topper       << "  const uint8_t *Converter = ConversionTable[Kind];\n"
1718b198f5c8979d46d75a08c1710a160f8e102b9ba8Craig Topper       << "  for (const uint8_t *p = Converter; *p; p+= 2) {\n"
171962316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier       << "    switch (*p) {\n"
172062316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier       << "    default: llvm_unreachable(\"invalid conversion entry!\");\n"
172162316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier       << "    case CVT_Reg:\n"
17226e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier       << "      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);\n"
17231c99a7f4892a24eb227802e042917d05d8cd415fChad Rosier       << "      Operands[*(p + 1)]->setConstraint(\"r\");\n"
17246e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier       << "      ++NumMCOperands;\n"
17256e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier       << "      break;\n"
172662316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier       << "    case CVT_Tied:\n"
172722685876ed7231f32f7d1698c00acab22825b74cChad Rosier       << "      ++NumMCOperands;\n"
172862316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier       << "      break;\n";
1729c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach
1730c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach  // Pre-populate the operand conversion kinds with the standard always
1731c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach  // available entries.
1732c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach  OperandConversionKinds.insert("CVT_Done");
1733c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach  OperandConversionKinds.insert("CVT_Reg");
1734c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach  OperandConversionKinds.insert("CVT_Tied");
1735c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach  enum { CVT_Done, CVT_Reg, CVT_Tied };
1736a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
173722bc5c4184a497353e33195dd12541a4f08b008aChris Lattner  for (std::vector<MatchableInfo*>::const_iterator it = Infos.begin(),
173820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar         ie = Infos.end(); it != ie; ++it) {
173922bc5c4184a497353e33195dd12541a4f08b008aChris Lattner    MatchableInfo &II = **it;
174020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
1741cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar    // Check if we have a custom match function.
174227b83d4ff2264d9a0e2367d92543efe4c0148931Daniel Dunbar    std::string AsmMatchConverter =
174327b83d4ff2264d9a0e2367d92543efe4c0148931Daniel Dunbar      II.getResultInst()->TheDef->getValueAsString("AsmMatchConverter");
1744cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar    if (!AsmMatchConverter.empty()) {
174527b83d4ff2264d9a0e2367d92543efe4c0148931Daniel Dunbar      std::string Signature = "ConvertCustom_" + AsmMatchConverter;
1746cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar      II.ConversionFnKind = Signature;
1747cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar
1748cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar      // Check if we have already generated this signature.
1749c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach      if (!InstructionConversionKinds.insert(Signature))
1750cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar        continue;
1751cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar
1752c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach      // Remember this converter for the kind enum.
1753c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach      unsigned KindID = OperandConversionKinds.size();
175412da505d938ecfbc49b203e454bada99eda950e3Tim Northover      OperandConversionKinds.insert("CVT_" +
175512da505d938ecfbc49b203e454bada99eda950e3Tim Northover                                    getEnumNameForToken(AsmMatchConverter));
1756c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach
1757c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach      // Add the converter row for this instruction.
1758c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach      ConversionTable.push_back(std::vector<uint8_t>());
1759c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach      ConversionTable.back().push_back(KindID);
1760c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach      ConversionTable.back().push_back(CVT_Done);
1761cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar
1762c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach      // Add the handler to the conversion driver function.
176312da505d938ecfbc49b203e454bada99eda950e3Tim Northover      CvtOS << "    case CVT_"
176412da505d938ecfbc49b203e454bada99eda950e3Tim Northover            << getEnumNameForToken(AsmMatchConverter) << ":\n"
1765756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad Rosier            << "      " << AsmMatchConverter << "(Inst, Operands);\n"
1766359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosier            << "      break;\n";
1767c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach
176862316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier      // FIXME: Handle the operand number lookup for custom match functions.
1769cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar      continue;
1770cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar    }
1771cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar
177220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    // Build the conversion function signature.
177320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    std::string Signature = "Convert";
1774c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach
1775c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach    std::vector<uint8_t> ConversionRow;
1776828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
1777dda855de8b3c60bce5d1d0d9eb11470c9710e30fChris Lattner    // Compute the convert enum and the case body.
1778c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach    MaxRowLength = std::max(MaxRowLength, II.ResOperands.size()*2 + 1 );
1779c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach
17801d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner    for (unsigned i = 0, e = II.ResOperands.size(); i != e; ++i) {
17811d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      const MatchableInfo::ResOperand &OpInfo = II.ResOperands[i];
17821d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner
17831d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      // Generate code to populate each result operand.
17841d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      switch (OpInfo.Kind) {
17851d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      case MatchableInfo::ResOperand::RenderAsmOperand: {
17861d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner        // This comes from something we parsed.
17871d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner        MatchableInfo::AsmOperand &Op = II.AsmOperands[OpInfo.AsmOperandNum];
1788828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
17899b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner        // Registers are always converted the same, don't duplicate the
17909b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner        // conversion function based on them.
17919b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner        Signature += "__";
1792c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        std::string Class;
1793c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        Class = Op.Class->isRegisterClass() ? "Reg" : Op.Class->ClassName;
1794c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        Signature += Class;
1795a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson        Signature += utostr(OpInfo.MINumOperands);
17961d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner        Signature += "_" + itostr(OpInfo.AsmOperandNum);
1797828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
1798c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        // Add the conversion kind, if necessary, and get the associated ID
1799c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        // the index of its entry in the vector).
1800c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        std::string Name = "CVT_" + (Op.Class->isRegisterClass() ? "Reg" :
1801c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach                                     Op.Class->RenderMethod);
180212da505d938ecfbc49b203e454bada99eda950e3Tim Northover        Name = getEnumNameForToken(Name);
1803c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach
1804c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        bool IsNewConverter = false;
1805c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        unsigned ID = getConverterOperandID(Name, OperandConversionKinds,
1806c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach                                            IsNewConverter);
1807c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach
1808c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        // Add the operand entry to the instruction kind conversion row.
1809c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        ConversionRow.push_back(ID);
1810c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        ConversionRow.push_back(OpInfo.AsmOperandNum + 1);
1811c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach
1812c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        if (!IsNewConverter)
1813c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach          break;
1814c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach
1815c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        // This is a new operand kind. Add a handler for it to the
1816c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        // converter driver.
1817c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        CvtOS << "    case " << Name << ":\n"
1818c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach              << "      static_cast<" << TargetOperandClass
1819c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach              << "*>(Operands[*(p + 1)])->"
1820c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach              << Op.Class->RenderMethod << "(Inst, " << OpInfo.MINumOperands
1821c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach              << ");\n"
1822c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach              << "      break;\n";
182362316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier
182462316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier        // Add a handler for the operand number lookup.
182562316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier        OpOS << "    case " << Name << ":\n"
18261c99a7f4892a24eb227802e042917d05d8cd415fChad Rosier             << "      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);\n";
18271c99a7f4892a24eb227802e042917d05d8cd415fChad Rosier
18281c99a7f4892a24eb227802e042917d05d8cd415fChad Rosier        if (Op.Class->isRegisterClass())
18291c99a7f4892a24eb227802e042917d05d8cd415fChad Rosier          OpOS << "      Operands[*(p + 1)]->setConstraint(\"r\");\n";
18301c99a7f4892a24eb227802e042917d05d8cd415fChad Rosier        else
18311c99a7f4892a24eb227802e042917d05d8cd415fChad Rosier          OpOS << "      Operands[*(p + 1)]->setConstraint(\"m\");\n";
18321c99a7f4892a24eb227802e042917d05d8cd415fChad Rosier        OpOS << "      NumMCOperands += " << OpInfo.MINumOperands << ";\n"
183362316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier             << "      break;\n";
18341d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner        break;
18351d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      }
18361d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      case MatchableInfo::ResOperand::TiedOperand: {
18371d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner        // If this operand is tied to a previous one, just copy the MCInst
18381d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner        // operand from the earlier one.We can only tie single MCOperand values.
1839d999062f31b5e0a2f12d70a54ffdb02be8363657Ulrich Weigand        assert(OpInfo.MINumOperands == 1 && "Not a singular MCOperand");
18401d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner        unsigned TiedOp = OpInfo.TiedOperandNum;
18417a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner        assert(i > TiedOp && "Tied operand precedes its target!");
18421d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner        Signature += "__Tie" + utostr(TiedOp);
1843c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        ConversionRow.push_back(CVT_Tied);
1844c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        ConversionRow.push_back(TiedOp);
18451d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner        break;
18461d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner      }
184798c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      case MatchableInfo::ResOperand::ImmOperand: {
184898c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner        int64_t Val = OpInfo.ImmVal;
1849c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        std::string Ty = "imm_" + itostr(Val);
1850c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        Signature += "__" + Ty;
1851c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach
1852c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        std::string Name = "CVT_" + Ty;
1853c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        bool IsNewConverter = false;
1854c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        unsigned ID = getConverterOperandID(Name, OperandConversionKinds,
1855c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach                                            IsNewConverter);
1856c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        // Add the operand entry to the instruction kind conversion row.
1857c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        ConversionRow.push_back(ID);
1858c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        ConversionRow.push_back(0);
1859c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach
1860c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        if (!IsNewConverter)
1861c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach          break;
1862c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach
1863c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        CvtOS << "    case " << Name << ":\n"
1864c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach              << "      Inst.addOperand(MCOperand::CreateImm(" << Val << "));\n"
1865c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach              << "      break;\n";
1866c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach
186762316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier        OpOS << "    case " << Name << ":\n"
18686e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier             << "      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);\n"
18696e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier             << "      Operands[*(p + 1)]->setConstraint(\"\");\n"
187022685876ed7231f32f7d1698c00acab22825b74cChad Rosier             << "      ++NumMCOperands;\n"
187162316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier             << "      break;\n";
187298c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner        break;
187398c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      }
187490fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner      case MatchableInfo::ResOperand::RegOperand: {
1875c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        std::string Reg, Name;
1876dc1a2bd3aa199693413f39dd723cc14a77e9f131Bob Wilson        if (OpInfo.Register == 0) {
1877c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach          Name = "reg0";
1878c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach          Reg = "0";
1879dc1a2bd3aa199693413f39dd723cc14a77e9f131Bob Wilson        } else {
1880c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach          Reg = getQualifiedName(OpInfo.Register);
1881c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach          Name = "reg" + OpInfo.Register->getName();
1882dc1a2bd3aa199693413f39dd723cc14a77e9f131Bob Wilson        }
1883c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        Signature += "__" + Name;
1884c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        Name = "CVT_" + Name;
1885c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        bool IsNewConverter = false;
1886c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        unsigned ID = getConverterOperandID(Name, OperandConversionKinds,
1887c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach                                            IsNewConverter);
1888c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        // Add the operand entry to the instruction kind conversion row.
1889c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        ConversionRow.push_back(ID);
1890c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        ConversionRow.push_back(0);
1891c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach
1892c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        if (!IsNewConverter)
1893c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach          break;
1894c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach        CvtOS << "    case " << Name << ":\n"
1895c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach              << "      Inst.addOperand(MCOperand::CreateReg(" << Reg << "));\n"
1896c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach              << "      break;\n";
189762316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier
189862316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier        OpOS << "    case " << Name << ":\n"
18996e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier             << "      Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);\n"
19006e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier             << "      Operands[*(p + 1)]->setConstraint(\"m\");\n"
190122685876ed7231f32f7d1698c00acab22825b74cChad Rosier             << "      ++NumMCOperands;\n"
190262316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier             << "      break;\n";
1903828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson      }
1904af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar      }
19059b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner    }
1906828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
1907c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach    // If there were no operands, add to the signature to that effect
1908c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach    if (Signature == "Convert")
1909c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach      Signature += "_NoOperands";
1910c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach
1911b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar    II.ConversionFnKind = Signature;
1912a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
1913c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach    // Save the signature. If we already have it, don't add a new row
1914c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach    // to the table.
1915c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach    if (!InstructionConversionKinds.insert(Signature))
191620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar      continue;
1917a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
1918c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach    // Add the row to the table.
1919c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach    ConversionTable.push_back(ConversionRow);
1920a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar  }
1921b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar
1922c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach  // Finish up the converter driver function.
1923ad2d3e637a3a9eb368e71a1672331ee5e7809fe8Chad Rosier  CvtOS << "    }\n  }\n}\n\n";
1924b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar
192562316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier  // Finish up the operand number lookup function.
192622685876ed7231f32f7d1698c00acab22825b74cChad Rosier  OpOS << "    }\n  }\n}\n\n";
192762316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier
1928c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach  OS << "namespace {\n";
1929b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar
1930c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach  // Output the operand conversion kind enum.
1931c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach  OS << "enum OperatorConversionKind {\n";
1932c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach  for (unsigned i = 0, e = OperandConversionKinds.size(); i != e; ++i)
1933c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach    OS << "  " << OperandConversionKinds[i] << ",\n";
1934c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach  OS << "  CVT_NUM_CONVERTERS\n";
1935c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach  OS << "};\n\n";
1936b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar
1937c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach  // Output the instruction conversion kind enum.
1938c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach  OS << "enum InstructionConversionKind {\n";
1939c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach  for (SetVector<std::string>::const_iterator
1940c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach         i = InstructionConversionKinds.begin(),
1941c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach         e = InstructionConversionKinds.end(); i != e; ++i)
1942c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach    OS << "  " << *i << ",\n";
1943c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach  OS << "  CVT_NUM_SIGNATURES\n";
1944b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar  OS << "};\n\n";
1945a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
1946c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach
1947c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach  OS << "} // end anonymous namespace\n\n";
1948c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach
1949c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach  // Output the conversion table.
1950b198f5c8979d46d75a08c1710a160f8e102b9ba8Craig Topper  OS << "static const uint8_t ConversionTable[CVT_NUM_SIGNATURES]["
1951c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach     << MaxRowLength << "] = {\n";
1952c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach
1953c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach  for (unsigned Row = 0, ERow = ConversionTable.size(); Row != ERow; ++Row) {
1954c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach    assert(ConversionTable[Row].size() % 2 == 0 && "bad conversion row!");
1955c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach    OS << "  // " << InstructionConversionKinds[Row] << "\n";
1956c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach    OS << "  { ";
1957c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach    for (unsigned i = 0, e = ConversionTable[Row].size(); i != e; i += 2)
1958c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach      OS << OperandConversionKinds[ConversionTable[Row][i]] << ", "
1959c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach         << (unsigned)(ConversionTable[Row][i + 1]) << ", ";
1960c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach    OS << "CVT_Done },\n";
1961c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach  }
1962c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach
1963c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach  OS << "};\n\n";
1964c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach
1965c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach  // Spit out the conversion driver function.
1966b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar  OS << CvtOS.str();
1967c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach
196862316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier  // Spit out the operand number lookup function.
196962316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier  OS << OpOS.str();
197020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar}
197120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
19728caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach/// emitMatchClassEnumeration - Emit the enumeration for match class kinds.
19738caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachstatic void emitMatchClassEnumeration(CodeGenTarget &Target,
1974a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar                                      std::vector<ClassInfo*> &Infos,
1975a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar                                      raw_ostream &OS) {
1976a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  OS << "namespace {\n\n";
1977a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
1978a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  OS << "/// MatchClassKind - The kinds of classes which participate in\n"
1979a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar     << "/// instruction matching.\n";
1980a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  OS << "enum MatchClassKind {\n";
1981a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  OS << "  InvalidMatchClass = 0,\n";
1982a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach  for (std::vector<ClassInfo*>::iterator it = Infos.begin(),
1983a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar         ie = Infos.end(); it != ie; ++it) {
1984a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    ClassInfo &CI = **it;
1985a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    OS << "  " << CI.Name << ", // ";
1986a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    if (CI.Kind == ClassInfo::Token) {
1987a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar      OS << "'" << CI.ValueName << "'\n";
1988ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    } else if (CI.isRegisterClass()) {
1989a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar      if (!CI.ValueName.empty())
1990a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar        OS << "register class '" << CI.ValueName << "'\n";
1991a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar      else
1992a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar        OS << "derived register class\n";
1993a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    } else {
1994a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar      OS << "user defined class '" << CI.ValueName << "'\n";
1995a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    }
1996a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  }
1997a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  OS << "  NumMatchClassKinds\n";
1998a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  OS << "};\n\n";
1999a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
2000a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  OS << "}\n\n";
2001a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar}
2002a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
20038caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach/// emitValidateOperandClass - Emit the function to validate an operand class.
20048caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachstatic void emitValidateOperandClass(AsmMatcherInfo &Info,
2005b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach                                     raw_ostream &OS) {
20064dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  OS << "static unsigned validateOperandClass(MCParsedAsmOperand *GOp, "
2007b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach     << "MatchClassKind Kind) {\n";
2008b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach  OS << "  " << Info.Target.getName() << "Operand &Operand = *("
200902bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner     << Info.Target.getName() << "Operand*)GOp;\n";
2010ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
2011893818347e9d7b34ea99ae9c984934c9b6bf92daKevin Enderby  // The InvalidMatchClass is not to match any operand.
2012893818347e9d7b34ea99ae9c984934c9b6bf92daKevin Enderby  OS << "  if (Kind == InvalidMatchClass)\n";
20134dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  OS << "    return MCTargetAsmParser::Match_InvalidOperand;\n\n";
2014893818347e9d7b34ea99ae9c984934c9b6bf92daKevin Enderby
2015b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach  // Check for Token operands first.
20164dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  // FIXME: Use a more specific diagnostic type.
2017a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  OS << "  if (Operand.isToken())\n";
20184dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  OS << "    return isSubclass(matchTokenString(Operand.getToken()), Kind) ?\n"
20194dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach     << "             MCTargetAsmParser::Match_Success :\n"
20204dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach     << "             MCTargetAsmParser::Match_InvalidOperand;\n\n";
2021ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar
2022b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach  // Check the user classes. We don't care what order since we're only
2023b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach  // actually matching against one of them.
2024a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach  for (std::vector<ClassInfo*>::iterator it = Info.Classes.begin(),
2025ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar         ie = Info.Classes.end(); it != ie; ++it) {
2026a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar    ClassInfo &CI = **it;
2027a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
2028ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    if (!CI.isUserClass())
2029ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar      continue;
2030828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
2031b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach    OS << "  // '" << CI.ClassName << "' class\n";
20324dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach    OS << "  if (Kind == " << CI.Name << ") {\n";
20334dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach    OS << "    if (Operand." << CI.PredicateMethod << "())\n";
20344dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach    OS << "      return MCTargetAsmParser::Match_Success;\n";
20354dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach    if (!CI.DiagnosticType.empty())
20364dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach      OS << "    return " << Info.Target.getName() << "AsmParser::Match_"
20374dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach         << CI.DiagnosticType << ";\n";
2038ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar    OS << "  }\n\n";
2039a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  }
2040828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
2041b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson  // Check for register operands, including sub-classes.
2042b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson  OS << "  if (Operand.isReg()) {\n";
2043b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson  OS << "    MatchClassKind OpKind;\n";
2044b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson  OS << "    switch (Operand.getReg()) {\n";
2045b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson  OS << "    default: OpKind = InvalidMatchClass; break;\n";
2046decfdf548b43c80c3dd81ff1cc3639b80ed33a3eSean Silva  for (AsmMatcherInfo::RegisterClassesTy::iterator
2047b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson         it = Info.RegisterClasses.begin(), ie = Info.RegisterClasses.end();
2048b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson       it != ie; ++it)
2049b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson    OS << "    case " << Info.Target.getName() << "::"
2050b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson       << it->first->getName() << ": OpKind = " << it->second->Name
2051b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson       << "; break;\n";
2052b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson  OS << "    }\n";
2053b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson  OS << "    return isSubclass(OpKind, Kind) ? "
2054b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson     << "MCTargetAsmParser::Match_Success :\n                             "
2055b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson     << "         MCTargetAsmParser::Match_InvalidOperand;\n  }\n\n";
2056b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson
20574dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  // Generic fallthrough match failure case for operands that don't have
20584dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  // specialized diagnostic types.
20594dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  OS << "  return MCTargetAsmParser::Match_InvalidOperand;\n";
2060a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  OS << "}\n\n";
2061a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar}
2062a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
20638caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach/// emitIsSubclass - Emit the subclass predicate function.
20648caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachstatic void emitIsSubclass(CodeGenTarget &Target,
2065fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar                           std::vector<ClassInfo*> &Infos,
2066fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar                           raw_ostream &OS) {
20674e0ae44b3a1b5f7157351764fd125c7c85959797Dmitri Gribenko  OS << "/// isSubclass - Compute whether \\p A is a subclass of \\p B.\n";
20683d5d8f6b768619ed65f79606d5c981c1e056c7e8Jim Grosbach  OS << "static bool isSubclass(MatchClassKind A, MatchClassKind B) {\n";
2069fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar  OS << "  if (A == B)\n";
2070fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar  OS << "    return true;\n\n";
2071fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar
207247cfec02842f885b46ea0d3c812793e660691640Reid Kleckner  std::string OStr;
207347cfec02842f885b46ea0d3c812793e660691640Reid Kleckner  raw_string_ostream SS(OStr);
207454911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman  unsigned Count = 0;
207554911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman  SS << "  switch (A) {\n";
207654911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman  SS << "  default:\n";
207754911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman  SS << "    return false;\n";
2078a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach  for (std::vector<ClassInfo*>::iterator it = Infos.begin(),
2079fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar         ie = Infos.end(); it != ie; ++it) {
2080fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar    ClassInfo &A = **it;
2081fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar
2082a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach    std::vector<StringRef> SuperClasses;
2083a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach    for (std::vector<ClassInfo*>::iterator it = Infos.begin(),
2084a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach         ie = Infos.end(); it != ie; ++it) {
2085a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach      ClassInfo &B = **it;
2086fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar
2087a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach      if (&A != &B && A.isSubsetOf(B))
2088a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach        SuperClasses.push_back(B.Name);
2089a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach    }
2090fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar
2091a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach    if (SuperClasses.empty())
2092a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach      continue;
209354911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman    ++Count;
2094fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar
209554911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman    SS << "\n  case " << A.Name << ":\n";
2096fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar
2097a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach    if (SuperClasses.size() == 1) {
209854911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman      SS << "    return B == " << SuperClasses.back().str() << ";\n";
2099a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach      continue;
2100fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar    }
2101a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach
210254911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman    if (!SuperClasses.empty()) {
210354911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman      SS << "    switch (B) {\n";
210454911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman      SS << "    default: return false;\n";
210554911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman      for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i)
210654911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman        SS << "    case " << SuperClasses[i].str() << ": return true;\n";
210754911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman      SS << "    }\n";
210854911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman    } else {
210954911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman      // No case statement to emit
211054911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman      SS << "    return false;\n";
211154911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman    }
2112fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar  }
211354911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman  SS << "  }\n";
211454911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman
211554911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman  // If there were case statements emitted into the string stream, write them
211654911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman  // to the output stream, otherwise write the default.
211754911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman  if (Count)
211854911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman    OS << SS.str();
211954911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman  else
212054911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman    OS << "  return false;\n";
212154911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman
2122fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar  OS << "}\n\n";
2123fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar}
2124fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar
21258caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach/// emitMatchTokenString - Emit the function to match a token string to the
2126245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar/// appropriate match class value.
21278caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachstatic void emitMatchTokenString(CodeGenTarget &Target,
2128245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar                                 std::vector<ClassInfo*> &Infos,
2129245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar                                 raw_ostream &OS) {
2130245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar  // Construct the match list.
21315845e5c62b42d025557765006515156691a6a8b1Chris Lattner  std::vector<StringMatcher::StringPair> Matches;
2132a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach  for (std::vector<ClassInfo*>::iterator it = Infos.begin(),
2133245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar         ie = Infos.end(); it != ie; ++it) {
2134245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar    ClassInfo &CI = **it;
2135245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar
2136245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar    if (CI.Kind == ClassInfo::Token)
21375845e5c62b42d025557765006515156691a6a8b1Chris Lattner      Matches.push_back(StringMatcher::StringPair(CI.ValueName,
21385845e5c62b42d025557765006515156691a6a8b1Chris Lattner                                                  "return " + CI.Name + ";"));
2139245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar  }
2140245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar
21413d5d8f6b768619ed65f79606d5c981c1e056c7e8Jim Grosbach  OS << "static MatchClassKind matchTokenString(StringRef Name) {\n";
2142245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar
21435845e5c62b42d025557765006515156691a6a8b1Chris Lattner  StringMatcher("Name", Matches, OS).Emit();
2144245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar
2145245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar  OS << "  return InvalidMatchClass;\n";
2146245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar  OS << "}\n\n";
2147245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar}
214870add884e4967f511e2cbb35c61534186b9b418aChris Lattner
21498caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach/// emitMatchRegisterName - Emit the function to match a string to the target
21502234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar/// specific register enum.
21518caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachstatic void emitMatchRegisterName(CodeGenTarget &Target, Record *AsmParser,
21522234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar                                  raw_ostream &OS) {
2153245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar  // Construct the match list.
21545845e5c62b42d025557765006515156691a6a8b1Chris Lattner  std::vector<StringMatcher::StringPair> Matches;
2155abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen  const std::vector<CodeGenRegister*> &Regs =
2156abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen    Target.getRegBank().getRegisters();
2157abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen  for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
2158abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen    const CodeGenRegister *Reg = Regs[i];
2159abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen    if (Reg->TheDef->getValueAsString("AsmName").empty())
216020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar      continue;
216120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
21625845e5c62b42d025557765006515156691a6a8b1Chris Lattner    Matches.push_back(StringMatcher::StringPair(
2163abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen                                     Reg->TheDef->getValueAsString("AsmName"),
2164abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen                                     "return " + utostr(Reg->EnumValue) + ";"));
216520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
2166a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
2167b8d6e98e566724f58344d275a4bd675249bb713aChris Lattner  OS << "static unsigned MatchRegisterName(StringRef Name) {\n";
2168245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar
21695845e5c62b42d025557765006515156691a6a8b1Chris Lattner  StringMatcher("Name", Matches, OS).Emit();
2170a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
2171245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar  OS << "  return 0;\n";
217220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  OS << "}\n\n";
21732234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar}
21742234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar
21758caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach/// emitSubtargetFeatureFlagEnumeration - Emit the subtarget feature flag
217654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar/// definitions.
21778caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachstatic void emitSubtargetFeatureFlagEnumeration(AsmMatcherInfo &Info,
217854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar                                                raw_ostream &OS) {
217954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  OS << "// Flags for subtarget features that participate in "
218054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar     << "instruction matching.\n";
218154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  OS << "enum SubtargetFeatureFlag {\n";
218254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  for (std::map<Record*, SubtargetFeatureInfo*>::const_iterator
218354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar         it = Info.SubtargetFeatures.begin(),
218454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar         ie = Info.SubtargetFeatures.end(); it != ie; ++it) {
218554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar    SubtargetFeatureInfo &SFI = *it->second;
21860aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner    OS << "  " << SFI.getEnumName() << " = (1 << " << SFI.Index << "),\n";
218754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  }
218854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  OS << "  Feature_None = 0\n";
218954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  OS << "};\n\n";
219054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar}
219154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar
21924dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach/// emitOperandDiagnosticTypes - Emit the operand matching diagnostic types.
21934dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbachstatic void emitOperandDiagnosticTypes(AsmMatcherInfo &Info, raw_ostream &OS) {
21944dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  // Get the set of diagnostic types from all of the operand classes.
21954dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  std::set<StringRef> Types;
21964dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  for (std::map<Record*, ClassInfo*>::const_iterator
21974dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach       I = Info.AsmOperandClasses.begin(),
21984dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach       E = Info.AsmOperandClasses.end(); I != E; ++I) {
21994dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach    if (!I->second->DiagnosticType.empty())
22004dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach      Types.insert(I->second->DiagnosticType);
22014dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  }
22024dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach
22034dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  if (Types.empty()) return;
22044dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach
22054dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  // Now emit the enum entries.
22064dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  for (std::set<StringRef>::const_iterator I = Types.begin(), E = Types.end();
22074dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach       I != E; ++I)
22084dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach    OS << "  Match_" << *I << ",\n";
22094dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  OS << "  END_OPERAND_DIAGNOSTIC_TYPES\n";
22104dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach}
22114dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach
221214ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach/// emitGetSubtargetFeatureName - Emit the helper function to get the
221314ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach/// user-level name for a subtarget feature.
221414ce6fac242228dacc5c08040e544141a96880e5Jim Grosbachstatic void emitGetSubtargetFeatureName(AsmMatcherInfo &Info, raw_ostream &OS) {
221514ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach  OS << "// User-level names for subtarget features that participate in\n"
221614ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach     << "// instruction matching.\n"
221754911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman     << "static const char *getSubtargetFeatureName(unsigned Val) {\n";
221854911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman  if (!Info.SubtargetFeatures.empty()) {
221954911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman    OS << "  switch(Val) {\n";
222054911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman    for (std::map<Record*, SubtargetFeatureInfo*>::const_iterator
222154911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman           it = Info.SubtargetFeatures.begin(),
222254911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman           ie = Info.SubtargetFeatures.end(); it != ie; ++it) {
222354911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman      SubtargetFeatureInfo &SFI = *it->second;
222454911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman      // FIXME: Totally just a placeholder name to get the algorithm working.
222554911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman      OS << "  case " << SFI.getEnumName() << ": return \""
222654911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman         << SFI.TheDef->getValueAsString("PredicateName") << "\";\n";
222754911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman    }
222854911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman    OS << "  default: return \"(unknown)\";\n";
222954911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman    OS << "  }\n";
223054911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman  } else {
223154911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman    // Nothing to emit, so skip the switch
223254911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman    OS << "  return \"(unknown)\";\n";
223314ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach  }
223454911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman  OS << "}\n\n";
223514ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach}
223614ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach
22378caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach/// emitComputeAvailableFeatures - Emit the function to compute the list of
223854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar/// available features given a subtarget.
22398caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachstatic void emitComputeAvailableFeatures(AsmMatcherInfo &Info,
224054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar                                         raw_ostream &OS) {
224154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  std::string ClassName =
224254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar    Info.AsmParser->getValueAsString("AsmParserClassName");
224354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar
224402bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner  OS << "unsigned " << Info.Target.getName() << ClassName << "::\n"
2245ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng     << "ComputeAvailableFeatures(uint64_t FB) const {\n";
224654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  OS << "  unsigned Features = 0;\n";
224754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  for (std::map<Record*, SubtargetFeatureInfo*>::const_iterator
224854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar         it = Info.SubtargetFeatures.begin(),
224954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar         ie = Info.SubtargetFeatures.end(); it != ie; ++it) {
225054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar    SubtargetFeatureInfo &SFI = *it->second;
2251ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
2252ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    OS << "  if (";
225365da6fc8af561e77620bd86b83be8ca50acfdd30Jim Grosbach    std::string CondStorage =
225465da6fc8af561e77620bd86b83be8ca50acfdd30Jim Grosbach      SFI.TheDef->getValueAsString("AssemblerCondString");
2255fbc38d2c16bc2fb923efdbbd6035ec8233fb4856Evan Cheng    StringRef Conds = CondStorage;
2256ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    std::pair<StringRef,StringRef> Comma = Conds.split(',');
2257ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    bool First = true;
2258ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    do {
2259ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng      if (!First)
2260ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng        OS << " && ";
2261ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
2262ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng      bool Neg = false;
2263ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng      StringRef Cond = Comma.first;
2264ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng      if (Cond[0] == '!') {
2265ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng        Neg = true;
2266ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng        Cond = Cond.substr(1);
2267ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng      }
2268ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
2269ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng      OS << "((FB & " << Info.Target.getName() << "::" << Cond << ")";
2270ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng      if (Neg)
2271ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng        OS << " == 0";
2272ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng      else
2273ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng        OS << " != 0";
2274ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng      OS << ")";
2275ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
2276ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng      if (Comma.second.empty())
2277ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng        break;
2278ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
2279ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng      First = false;
2280ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng      Comma = Comma.second.split(',');
2281ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    } while (true);
2282ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
2283ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    OS << ")\n";
22840aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner    OS << "    Features |= " << SFI.getEnumName() << ";\n";
228554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  }
228654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  OS << "  return Features;\n";
228754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  OS << "}\n\n";
228854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar}
228954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar
22906fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattnerstatic std::string GetAliasRequiredFeatures(Record *R,
22916fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner                                            const AsmMatcherInfo &Info) {
2292693173feefaa326fad0e386470846fb3199ba381Chris Lattner  std::vector<Record*> ReqFeatures = R->getValueAsListOfDefs("Predicates");
2293693173feefaa326fad0e386470846fb3199ba381Chris Lattner  std::string Result;
2294693173feefaa326fad0e386470846fb3199ba381Chris Lattner  unsigned NumFeatures = 0;
2295693173feefaa326fad0e386470846fb3199ba381Chris Lattner  for (unsigned i = 0, e = ReqFeatures.size(); i != e; ++i) {
22964a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner    SubtargetFeatureInfo *F = Info.getSubtargetFeature(ReqFeatures[i]);
2297828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
22984a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner    if (F == 0)
229961131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger      PrintFatalError(R->getLoc(), "Predicate '" + ReqFeatures[i]->getName() +
23004a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner                    "' is not marked as an AssemblerPredicate!");
2301828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
23024a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner    if (NumFeatures)
23034a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner      Result += '|';
2304828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
23054a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner    Result += F->getEnumName();
23064a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner    ++NumFeatures;
2307693173feefaa326fad0e386470846fb3199ba381Chris Lattner  }
2308828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
2309693173feefaa326fad0e386470846fb3199ba381Chris Lattner  if (NumFeatures > 1)
2310693173feefaa326fad0e386470846fb3199ba381Chris Lattner    Result = '(' + Result + ')';
2311693173feefaa326fad0e386470846fb3199ba381Chris Lattner  return Result;
2312693173feefaa326fad0e386470846fb3199ba381Chris Lattner}
2313693173feefaa326fad0e386470846fb3199ba381Chris Lattner
231488eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosierstatic void emitMnemonicAliasVariant(raw_ostream &OS,const AsmMatcherInfo &Info,
231588eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier                                     std::vector<Record*> &Aliases,
231688eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier                                     unsigned Indent = 0,
231788eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier                                  StringRef AsmParserVariantName = StringRef()){
23184fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner  // Keep track of all the aliases from a mnemonic.  Use an std::map so that the
23194fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner  // iteration order of the map is stable.
23204fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner  std::map<std::string, std::vector<Record*> > AliasesFromMnemonic;
2321828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
2322674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner  for (unsigned i = 0, e = Aliases.size(); i != e; ++i) {
2323674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner    Record *R = Aliases[i];
232488eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier    // FIXME: Allow AssemblerVariantName to be a comma separated list.
232588eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier    std::string AsmVariantName = R->getValueAsString("AsmVariantName");
232688eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier    if (AsmVariantName != AsmParserVariantName)
232788eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier      continue;
23284fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner    AliasesFromMnemonic[R->getValueAsString("FromMnemonic")].push_back(R);
23294fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner  }
233088eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier  if (AliasesFromMnemonic.empty())
233188eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier    return;
23329273151c3bbc96c9b2911caffe3e1a724261cd06Vladimir Medic
23334fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner  // Process each alias a "from" mnemonic at a time, building the code executed
23344fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner  // by the string remapper.
23354fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner  std::vector<StringMatcher::StringPair> Cases;
23364fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner  for (std::map<std::string, std::vector<Record*> >::iterator
23374fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner       I = AliasesFromMnemonic.begin(), E = AliasesFromMnemonic.end();
23384fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner       I != E; ++I) {
23394fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner    const std::vector<Record*> &ToVec = I->second;
2340693173feefaa326fad0e386470846fb3199ba381Chris Lattner
2341693173feefaa326fad0e386470846fb3199ba381Chris Lattner    // Loop through each alias and emit code that handles each case.  If there
2342693173feefaa326fad0e386470846fb3199ba381Chris Lattner    // are two instructions without predicates, emit an error.  If there is one,
2343693173feefaa326fad0e386470846fb3199ba381Chris Lattner    // emit it last.
2344693173feefaa326fad0e386470846fb3199ba381Chris Lattner    std::string MatchCode;
2345693173feefaa326fad0e386470846fb3199ba381Chris Lattner    int AliasWithNoPredicate = -1;
2346828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
2347693173feefaa326fad0e386470846fb3199ba381Chris Lattner    for (unsigned i = 0, e = ToVec.size(); i != e; ++i) {
2348693173feefaa326fad0e386470846fb3199ba381Chris Lattner      Record *R = ToVec[i];
23496fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner      std::string FeatureMask = GetAliasRequiredFeatures(R, Info);
2350828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
2351693173feefaa326fad0e386470846fb3199ba381Chris Lattner      // If this unconditionally matches, remember it for later and diagnose
2352693173feefaa326fad0e386470846fb3199ba381Chris Lattner      // duplicates.
2353693173feefaa326fad0e386470846fb3199ba381Chris Lattner      if (FeatureMask.empty()) {
2354693173feefaa326fad0e386470846fb3199ba381Chris Lattner        if (AliasWithNoPredicate != -1) {
2355693173feefaa326fad0e386470846fb3199ba381Chris Lattner          // We can't have two aliases from the same mnemonic with no predicate.
2356693173feefaa326fad0e386470846fb3199ba381Chris Lattner          PrintError(ToVec[AliasWithNoPredicate]->getLoc(),
2357693173feefaa326fad0e386470846fb3199ba381Chris Lattner                     "two MnemonicAliases with the same 'from' mnemonic!");
235861131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger          PrintFatalError(R->getLoc(), "this is the other MnemonicAlias.");
2359693173feefaa326fad0e386470846fb3199ba381Chris Lattner        }
2360828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
2361693173feefaa326fad0e386470846fb3199ba381Chris Lattner        AliasWithNoPredicate = i;
2362693173feefaa326fad0e386470846fb3199ba381Chris Lattner        continue;
2363693173feefaa326fad0e386470846fb3199ba381Chris Lattner      }
23646ef6ceda6883d0ee543d8da86d16b0fcdcecab96Joerg Sonnenberger      if (R->getValueAsString("ToMnemonic") == I->first)
236561131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger        PrintFatalError(R->getLoc(), "MnemonicAlias to the same string");
2366828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
23678cf8bcc40c977713e51fb85fb9f24a0ecfbde24bChris Lattner      if (!MatchCode.empty())
23688cf8bcc40c977713e51fb85fb9f24a0ecfbde24bChris Lattner        MatchCode += "else ";
2369693173feefaa326fad0e386470846fb3199ba381Chris Lattner      MatchCode += "if ((Features & " + FeatureMask + ") == "+FeatureMask+")\n";
2370693173feefaa326fad0e386470846fb3199ba381Chris Lattner      MatchCode += "  Mnemonic = \"" +R->getValueAsString("ToMnemonic")+"\";\n";
2371693173feefaa326fad0e386470846fb3199ba381Chris Lattner    }
2372828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
2373693173feefaa326fad0e386470846fb3199ba381Chris Lattner    if (AliasWithNoPredicate != -1) {
2374693173feefaa326fad0e386470846fb3199ba381Chris Lattner      Record *R = ToVec[AliasWithNoPredicate];
23758cf8bcc40c977713e51fb85fb9f24a0ecfbde24bChris Lattner      if (!MatchCode.empty())
23768cf8bcc40c977713e51fb85fb9f24a0ecfbde24bChris Lattner        MatchCode += "else\n  ";
23778cf8bcc40c977713e51fb85fb9f24a0ecfbde24bChris Lattner      MatchCode += "Mnemonic = \"" + R->getValueAsString("ToMnemonic")+"\";\n";
23784fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner    }
2379828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
2380693173feefaa326fad0e386470846fb3199ba381Chris Lattner    MatchCode += "return;";
2381693173feefaa326fad0e386470846fb3199ba381Chris Lattner
2382693173feefaa326fad0e386470846fb3199ba381Chris Lattner    Cases.push_back(std::make_pair(I->first, MatchCode));
2383674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner  }
238488eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier  StringMatcher("Mnemonic", Cases, OS).Emit(Indent);
238588eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier}
238688eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier
238788eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier/// emitMnemonicAliases - If the target has any MnemonicAlias<> definitions,
238888eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier/// emit a function for them and return true, otherwise return false.
238988eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosierstatic bool emitMnemonicAliases(raw_ostream &OS, const AsmMatcherInfo &Info,
239088eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier                                CodeGenTarget &Target) {
239188eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier  // Ignore aliases when match-prefix is set.
239288eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier  if (!MatchPrefix.empty())
239388eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier    return false;
239488eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier
239588eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier  std::vector<Record*> Aliases =
239688eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier    Info.getRecords().getAllDerivedDefinitions("MnemonicAlias");
239788eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier  if (Aliases.empty()) return false;
239888eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier
239988eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier  OS << "static void applyMnemonicAliases(StringRef &Mnemonic, "
240088eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier    "unsigned Features, unsigned VariantID) {\n";
240188eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier  OS << "  switch (VariantID) {\n";
240288eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier  unsigned VariantCount = Target.getAsmParserVariantCount();
240388eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier  for (unsigned VC = 0; VC != VariantCount; ++VC) {
240488eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier    Record *AsmVariant = Target.getAsmParserVariant(VC);
240588eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier    int AsmParserVariantNo = AsmVariant->getValueAsInt("Variant");
240688eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier    std::string AsmParserVariantName = AsmVariant->getValueAsString("Name");
240788eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier    OS << "    case " << AsmParserVariantNo << ":\n";
240888eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier    emitMnemonicAliasVariant(OS, Info, Aliases, /*Indent=*/2,
240988eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier                             AsmParserVariantName);
241088eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier    OS << "    break;\n";
241188eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier  }
241288eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier  OS << "  }\n";
241388eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier
241488eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier  // Emit aliases that apply to all variants.
241588eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier  emitMnemonicAliasVariant(OS, Info, Aliases);
2416828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
241755b5e85643b189636758188f11b598c45178407fDaniel Dunbar  OS << "}\n\n";
2418828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
24197fd4489de11bdf06f6c852d42abafea013b76f28Chris Lattner  return true;
2420674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner}
2421674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner
2422194f3fa9eadc7dfe9f1750c16e1c2a8ebe11c88cJim Grosbachstatic const char *getMinimalTypeForRange(uint64_t Range) {
2423194f3fa9eadc7dfe9f1750c16e1c2a8ebe11c88cJim Grosbach  assert(Range < 0xFFFFFFFFULL && "Enum too large");
2424194f3fa9eadc7dfe9f1750c16e1c2a8ebe11c88cJim Grosbach  if (Range > 0xFFFF)
2425194f3fa9eadc7dfe9f1750c16e1c2a8ebe11c88cJim Grosbach    return "uint32_t";
2426194f3fa9eadc7dfe9f1750c16e1c2a8ebe11c88cJim Grosbach  if (Range > 0xFF)
2427194f3fa9eadc7dfe9f1750c16e1c2a8ebe11c88cJim Grosbach    return "uint16_t";
2428194f3fa9eadc7dfe9f1750c16e1c2a8ebe11c88cJim Grosbach  return "uint8_t";
2429194f3fa9eadc7dfe9f1750c16e1c2a8ebe11c88cJim Grosbach}
2430194f3fa9eadc7dfe9f1750c16e1c2a8ebe11c88cJim Grosbach
24318caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachstatic void emitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target,
24323a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper                              const AsmMatcherInfo &Info, StringRef ClassName,
24333a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper                              StringToOffsetTable &StringTable,
24343a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper                              unsigned MaxMnemonicIndex) {
24353a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper  unsigned MaxMask = 0;
24363a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper  for (std::vector<OperandMatchEntry>::const_iterator it =
24373a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper       Info.OperandMatchInfo.begin(), ie = Info.OperandMatchInfo.end();
24383a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper       it != ie; ++it) {
24393a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper    MaxMask |= it->OperandMask;
24403a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper  }
24413a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper
2442e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  // Emit the static custom operand parsing table;
2443e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "namespace {\n";
2444e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "  struct OperandMatchEntry {\n";
2445b08bb34a6f49c79e963aac52030c0cbeb0526f86Benjamin Kramer  OS << "    " << getMinimalTypeForRange(1ULL << Info.SubtargetFeatures.size())
2446fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper               << " RequiredFeatures;\n";
24473a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper  OS << "    " << getMinimalTypeForRange(MaxMnemonicIndex)
24483a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper               << " Mnemonic;\n";
2449fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper  OS << "    " << getMinimalTypeForRange(Info.Classes.size())
24503a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper               << " Class;\n";
24513a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper  OS << "    " << getMinimalTypeForRange(MaxMask)
24523a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper               << " OperandMask;\n\n";
2453b08bb34a6f49c79e963aac52030c0cbeb0526f86Benjamin Kramer  OS << "    StringRef getMnemonic() const {\n";
2454b08bb34a6f49c79e963aac52030c0cbeb0526f86Benjamin Kramer  OS << "      return StringRef(MnemonicTable + Mnemonic + 1,\n";
2455b08bb34a6f49c79e963aac52030c0cbeb0526f86Benjamin Kramer  OS << "                       MnemonicTable[Mnemonic]);\n";
2456b08bb34a6f49c79e963aac52030c0cbeb0526f86Benjamin Kramer  OS << "    }\n";
2457e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "  };\n\n";
2458e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2459e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "  // Predicate for searching for an opcode.\n";
2460e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "  struct LessOpcodeOperand {\n";
2461e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "    bool operator()(const OperandMatchEntry &LHS, StringRef RHS) {\n";
2462b08bb34a6f49c79e963aac52030c0cbeb0526f86Benjamin Kramer  OS << "      return LHS.getMnemonic()  < RHS;\n";
2463e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "    }\n";
2464e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "    bool operator()(StringRef LHS, const OperandMatchEntry &RHS) {\n";
2465b08bb34a6f49c79e963aac52030c0cbeb0526f86Benjamin Kramer  OS << "      return LHS < RHS.getMnemonic();\n";
2466e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "    }\n";
2467e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "    bool operator()(const OperandMatchEntry &LHS,";
2468e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << " const OperandMatchEntry &RHS) {\n";
2469b08bb34a6f49c79e963aac52030c0cbeb0526f86Benjamin Kramer  OS << "      return LHS.getMnemonic() < RHS.getMnemonic();\n";
2470e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "    }\n";
2471e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "  };\n";
2472e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2473e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "} // end anonymous namespace.\n\n";
2474e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2475e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "static const OperandMatchEntry OperandMatchTable["
2476e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes     << Info.OperandMatchInfo.size() << "] = {\n";
2477e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2478b08bb34a6f49c79e963aac52030c0cbeb0526f86Benjamin Kramer  OS << "  /* Operand List Mask, Mnemonic, Operand Class, Features */\n";
2479e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  for (std::vector<OperandMatchEntry>::const_iterator it =
2480e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes       Info.OperandMatchInfo.begin(), ie = Info.OperandMatchInfo.end();
2481e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes       it != ie; ++it) {
2482e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    const OperandMatchEntry &OMI = *it;
2483e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    const MatchableInfo &II = *OMI.MI;
2484e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
24853a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper    OS << "  { ";
24863a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper
24873a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper    // Write the required features mask.
24883a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper    if (!II.RequiredFeatures.empty()) {
24893a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper      for (unsigned i = 0, e = II.RequiredFeatures.size(); i != e; ++i) {
24903a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper        if (i) OS << "|";
24913a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper        OS << II.RequiredFeatures[i]->getEnumName();
24923a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper      }
24933a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper    } else
24943a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper      OS << "0";
24953a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper
24963a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper    // Store a pascal-style length byte in the mnemonic.
24973a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper    std::string LenMnemonic = char(II.Mnemonic.size()) + II.Mnemonic.str();
24983a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper    OS << ", " << StringTable.GetOrAddStringOffset(LenMnemonic, false)
24993a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper       << " /* " << II.Mnemonic << " */, ";
25003a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper
25013a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper    OS << OMI.CI->Name;
2502e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
25033a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper    OS << ", " << OMI.OperandMask;
2504e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    OS << " /* ";
2505e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    bool printComma = false;
2506e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    for (int i = 0, e = 31; i !=e; ++i)
2507e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes      if (OMI.OperandMask & (1 << i)) {
2508e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes        if (printComma)
2509e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes          OS << ", ";
2510e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes        OS << i;
2511e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes        printComma = true;
2512e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes      }
2513e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    OS << " */";
2514e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2515e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    OS << " },\n";
2516e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  }
2517e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "};\n\n";
2518e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2519e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  // Emit the operand class switch to call the correct custom parser for
2520e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  // the found operand class.
2521f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OS << Target.getName() << ClassName << "::OperandMatchResultTy "
2522f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach     << Target.getName() << ClassName << "::\n"
25233d5d8f6b768619ed65f79606d5c981c1e056c7e8Jim Grosbach     << "tryCustomParseOperand(SmallVectorImpl<MCParsedAsmOperand*>"
2524e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes     << " &Operands,\n                      unsigned MCK) {\n\n"
2525e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes     << "  switch(MCK) {\n";
2526e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2527e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  for (std::vector<ClassInfo*>::const_iterator it = Info.Classes.begin(),
2528e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes       ie = Info.Classes.end(); it != ie; ++it) {
2529e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    ClassInfo *CI = *it;
2530e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    if (CI->ParserMethod.empty())
2531e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes      continue;
2532e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    OS << "  case " << CI->Name << ":\n"
2533e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes       << "    return " << CI->ParserMethod << "(Operands);\n";
2534e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  }
2535e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2536e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "  default:\n";
2537f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OS << "    return MatchOperand_NoMatch;\n";
2538e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "  }\n";
2539f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OS << "  return MatchOperand_NoMatch;\n";
2540e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "}\n\n";
2541e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2542e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  // Emit the static custom operand parser. This code is very similar with
2543e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  // the other matcher. Also use MatchResultTy here just in case we go for
2544e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  // a better error handling.
2545f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OS << Target.getName() << ClassName << "::OperandMatchResultTy "
2546e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes     << Target.getName() << ClassName << "::\n"
2547e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes     << "MatchOperandParserImpl(SmallVectorImpl<MCParsedAsmOperand*>"
2548e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes     << " &Operands,\n                       StringRef Mnemonic) {\n";
2549e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2550e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  // Emit code to get the available features.
2551e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "  // Get the current feature set.\n";
2552e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "  unsigned AvailableFeatures = getAvailableFeatures();\n\n";
2553e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2554e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "  // Get the next operand index.\n";
2555e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "  unsigned NextOpNum = Operands.size()-1;\n";
2556e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2557e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  // Emit code to search the table.
2558e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "  // Search the table.\n";
2559e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "  std::pair<const OperandMatchEntry*, const OperandMatchEntry*>";
2560e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << " MnemonicRange =\n";
2561e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "    std::equal_range(OperandMatchTable, OperandMatchTable+"
2562e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes     << Info.OperandMatchInfo.size() << ", Mnemonic,\n"
2563e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes     << "                     LessOpcodeOperand());\n\n";
2564e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2565e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "  if (MnemonicRange.first == MnemonicRange.second)\n";
2566f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OS << "    return MatchOperand_NoMatch;\n\n";
2567e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2568e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "  for (const OperandMatchEntry *it = MnemonicRange.first,\n"
2569e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes     << "       *ie = MnemonicRange.second; it != ie; ++it) {\n";
2570e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2571e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "    // equal_range guarantees that instruction mnemonic matches.\n";
2572b08bb34a6f49c79e963aac52030c0cbeb0526f86Benjamin Kramer  OS << "    assert(Mnemonic == it->getMnemonic());\n\n";
2573e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2574e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  // Emit check that the required features are available.
2575e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "    // check if the available features match\n";
2576e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "    if ((AvailableFeatures & it->RequiredFeatures) "
2577e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes     << "!= it->RequiredFeatures) {\n";
2578e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "      continue;\n";
2579e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "    }\n\n";
2580e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2581e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  // Emit check to ensure the operand number matches.
2582e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "    // check if the operand in question has a custom parser.\n";
2583e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "    if (!(it->OperandMask & (1 << NextOpNum)))\n";
2584e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "      continue;\n\n";
2585e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2586e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  // Emit call to the custom parser method
2587e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "    // call custom parse method to handle the operand\n";
2588f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OS << "    OperandMatchResultTy Result = ";
25893d5d8f6b768619ed65f79606d5c981c1e056c7e8Jim Grosbach  OS << "tryCustomParseOperand(Operands, it->Class);\n";
2590f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OS << "    if (Result != MatchOperand_NoMatch)\n";
2591f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OS << "      return Result;\n";
2592e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "  }\n\n";
2593e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2594f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OS << "  // Okay, we had no match.\n";
2595f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OS << "  return MatchOperand_NoMatch;\n";
2596e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "}\n\n";
2597e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes}
2598e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
25992234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbarvoid AsmMatcherEmitter::run(raw_ostream &OS) {
260067db883487fca3472fdde51e931657e22d4d0495Chris Lattner  CodeGenTarget Target(Records);
26012234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar  Record *AsmParser = Target.getAsmParser();
26022234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar  std::string ClassName = AsmParser->getValueAsString("AsmParserClassName");
26032234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar
2604a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  // Compute the information on the instructions to match.
260567db883487fca3472fdde51e931657e22d4d0495Chris Lattner  AsmMatcherInfo Info(AsmParser, Target, Records);
26068caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  Info.buildInfo();
260720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
2608e1f6de3fbd892ea3f918a26912660cf316866fc1Daniel Dunbar  // Sort the instruction table using the partial order on classes. We use
2609e1f6de3fbd892ea3f918a26912660cf316866fc1Daniel Dunbar  // stable_sort to ensure that ambiguous instructions are still
2610e1f6de3fbd892ea3f918a26912660cf316866fc1Daniel Dunbar  // deterministically ordered.
261122bc5c4184a497353e33195dd12541a4f08b008aChris Lattner  std::stable_sort(Info.Matchables.begin(), Info.Matchables.end(),
261222bc5c4184a497353e33195dd12541a4f08b008aChris Lattner                   less_ptr<MatchableInfo>());
2613a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
2614b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar  DEBUG_WITH_TYPE("instruction_info", {
261522bc5c4184a497353e33195dd12541a4f08b008aChris Lattner      for (std::vector<MatchableInfo*>::iterator
261622bc5c4184a497353e33195dd12541a4f08b008aChris Lattner             it = Info.Matchables.begin(), ie = Info.Matchables.end();
2617a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar           it != ie; ++it)
261820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar        (*it)->dump();
261920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    });
262020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
262122bc5c4184a497353e33195dd12541a4f08b008aChris Lattner  // Check for ambiguous matchables.
2622fa0d74d58e6c70ef032afb5f83680276dc4d7370Chris Lattner  DEBUG_WITH_TYPE("ambiguous_instrs", {
2623fa0d74d58e6c70ef032afb5f83680276dc4d7370Chris Lattner    unsigned NumAmbiguous = 0;
262422bc5c4184a497353e33195dd12541a4f08b008aChris Lattner    for (unsigned i = 0, e = Info.Matchables.size(); i != e; ++i) {
262587410368e1bd50408e787f6ece0e58d94c53c1e1Chris Lattner      for (unsigned j = i + 1; j != e; ++j) {
262622bc5c4184a497353e33195dd12541a4f08b008aChris Lattner        MatchableInfo &A = *Info.Matchables[i];
262722bc5c4184a497353e33195dd12541a4f08b008aChris Lattner        MatchableInfo &B = *Info.Matchables[j];
2628a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
26298caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach        if (A.couldMatchAmbiguouslyWith(B)) {
263022bc5c4184a497353e33195dd12541a4f08b008aChris Lattner          errs() << "warning: ambiguous matchables:\n";
2631fa0d74d58e6c70ef032afb5f83680276dc4d7370Chris Lattner          A.dump();
2632fa0d74d58e6c70ef032afb5f83680276dc4d7370Chris Lattner          errs() << "\nis incomparable with:\n";
2633fa0d74d58e6c70ef032afb5f83680276dc4d7370Chris Lattner          B.dump();
2634fa0d74d58e6c70ef032afb5f83680276dc4d7370Chris Lattner          errs() << "\n\n";
263587410368e1bd50408e787f6ece0e58d94c53c1e1Chris Lattner          ++NumAmbiguous;
263687410368e1bd50408e787f6ece0e58d94c53c1e1Chris Lattner        }
26372b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar      }
2638606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar    }
263987410368e1bd50408e787f6ece0e58d94c53c1e1Chris Lattner    if (NumAmbiguous)
2640a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach      errs() << "warning: " << NumAmbiguous
264122bc5c4184a497353e33195dd12541a4f08b008aChris Lattner             << " ambiguous matchables!\n";
2642fa0d74d58e6c70ef032afb5f83680276dc4d7370Chris Lattner  });
2643606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar
2644e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  // Compute the information on the custom operand parsing.
26458caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  Info.buildOperandMatchInfo();
2646e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
26471095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar  // Write the output.
26481095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar
26490692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner  // Information for the class declaration.
26500692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner  OS << "\n#ifdef GET_ASSEMBLER_HEADER\n";
26510692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner  OS << "#undef GET_ASSEMBLER_HEADER\n";
265284cb033bf30b6f93ae2fbea71513970147e08dc2Jim Grosbach  OS << "  // This should be included into the middle of the declaration of\n";
265394b9550a32d189704a8eae55505edf62662c0534Evan Cheng  OS << "  // your subclasses implementation of MCTargetAsmParser.\n";
2654ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  OS << "  unsigned ComputeAvailableFeatures(uint64_t FeatureBits) const;\n";
265590e11f8c95146c2d3718e9b3de71ee6628347b05Chad Rosier  OS << "  void convertToMCInst(unsigned Kind, MCInst &Inst, "
26565c228a945fe3e25a12d0f7e2e9b26b548d6f29f5Daniel Dunbar     << "unsigned Opcode,\n"
2657c69bb70deb5b596941bb1de180d1554f9a411062Chad Rosier     << "                       const SmallVectorImpl<MCParsedAsmOperand*> "
26585c228a945fe3e25a12d0f7e2e9b26b548d6f29f5Daniel Dunbar     << "&Operands);\n";
2659c69bb70deb5b596941bb1de180d1554f9a411062Chad Rosier  OS << "  void convertToMapAndConstraints(unsigned Kind,\n                ";
26606e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier  OS << "           const SmallVectorImpl<MCParsedAsmOperand*> &Operands);\n";
2661f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper  OS << "  bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID);\n";
26629ba9d4d76bfa8de2b05cbce02a5a3ff7d46cb331Chad Rosier  OS << "  unsigned MatchInstructionImpl(\n";
26639ba9d4d76bfa8de2b05cbce02a5a3ff7d46cb331Chad Rosier  OS.indent(27);
26649ba9d4d76bfa8de2b05cbce02a5a3ff7d46cb331Chad Rosier  OS << "const SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n"
26656e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier     << "                                MCInst &Inst,\n"
2666c69bb70deb5b596941bb1de180d1554f9a411062Chad Rosier     << "                                unsigned &ErrorInfo,"
2667c69bb70deb5b596941bb1de180d1554f9a411062Chad Rosier     << " bool matchingInlineAsm,\n"
2668c69bb70deb5b596941bb1de180d1554f9a411062Chad Rosier     << "                                unsigned VariantID = 0);\n";
2669e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
2670e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  if (Info.OperandMatchInfo.size()) {
2671f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    OS << "\n  enum OperandMatchResultTy {\n";
2672f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    OS << "    MatchOperand_Success,    // operand matched successfully\n";
2673f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    OS << "    MatchOperand_NoMatch,    // operand did not match\n";
2674f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    OS << "    MatchOperand_ParseFail   // operand matched but had errors\n";
2675f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    OS << "  };\n";
2676f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    OS << "  OperandMatchResultTy MatchOperandParserImpl(\n";
2677e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    OS << "    SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n";
2678e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    OS << "    StringRef Mnemonic);\n";
2679e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
26803d5d8f6b768619ed65f79606d5c981c1e056c7e8Jim Grosbach    OS << "  OperandMatchResultTy tryCustomParseOperand(\n";
2681e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    OS << "    SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n";
2682e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes    OS << "    unsigned MCK);\n\n";
2683e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  }
2684e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
26850692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner  OS << "#endif // GET_ASSEMBLER_HEADER_INFO\n\n";
26860692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner
26874dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  // Emit the operand match diagnostic enum names.
26884dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  OS << "\n#ifdef GET_OPERAND_DIAGNOSTIC_TYPES\n";
26894dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  OS << "#undef GET_OPERAND_DIAGNOSTIC_TYPES\n\n";
26904dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  emitOperandDiagnosticTypes(Info, OS);
26914dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  OS << "#endif // GET_OPERAND_DIAGNOSTIC_TYPES\n\n";
26924dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach
26934dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach
26940692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner  OS << "\n#ifdef GET_REGISTER_MATCHER\n";
26950692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner  OS << "#undef GET_REGISTER_MATCHER\n\n";
26960692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner
269754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  // Emit the subtarget feature enumeration.
26988caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  emitSubtargetFeatureFlagEnumeration(Info, OS);
269954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar
27001095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar  // Emit the function to match a register name to number.
270172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  // This should be omitted for Mips target
270272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  if (AsmParser->getValueAsBit("ShouldEmitMatchRegisterName"))
270372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    emitMatchRegisterName(Target, AsmParser, OS);
27040692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner
27050692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner  OS << "#endif // GET_REGISTER_MATCHER\n\n";
2706a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
27078030e1a0df630ec6ed1cd5ec673f6472558a4dbeCraig Topper  OS << "\n#ifdef GET_SUBTARGET_FEATURE_NAME\n";
27088030e1a0df630ec6ed1cd5ec673f6472558a4dbeCraig Topper  OS << "#undef GET_SUBTARGET_FEATURE_NAME\n\n";
27091095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar
271014ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach  // Generate the helper function to get the names for subtarget features.
271114ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach  emitGetSubtargetFeatureName(Info, OS);
271214ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach
27138030e1a0df630ec6ed1cd5ec673f6472558a4dbeCraig Topper  OS << "#endif // GET_SUBTARGET_FEATURE_NAME\n\n";
27148030e1a0df630ec6ed1cd5ec673f6472558a4dbeCraig Topper
27158030e1a0df630ec6ed1cd5ec673f6472558a4dbeCraig Topper  OS << "\n#ifdef GET_MATCHER_IMPLEMENTATION\n";
27168030e1a0df630ec6ed1cd5ec673f6472558a4dbeCraig Topper  OS << "#undef GET_MATCHER_IMPLEMENTATION\n\n";
27178030e1a0df630ec6ed1cd5ec673f6472558a4dbeCraig Topper
27187fd4489de11bdf06f6c852d42abafea013b76f28Chris Lattner  // Generate the function that remaps for mnemonic aliases.
271988eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier  bool HasMnemonicAliases = emitMnemonicAliases(OS, Info, Target);
2720828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
272122685876ed7231f32f7d1698c00acab22825b74cChad Rosier  // Generate the convertToMCInst function to convert operands into an MCInst.
272222685876ed7231f32f7d1698c00acab22825b74cChad Rosier  // Also, generate the convertToMapAndConstraints function for MS-style inline
272322685876ed7231f32f7d1698c00acab22825b74cChad Rosier  // assembly.  The latter doesn't actually generate a MCInst.
272422685876ed7231f32f7d1698c00acab22825b74cChad Rosier  emitConvertFuncs(Target, ClassName, Info.Matchables, OS);
2725a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
2726a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  // Emit the enumeration for classes which participate in matching.
27278caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  emitMatchClassEnumeration(Target, Info.Classes, OS);
272820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
2729a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  // Emit the routine to match token strings to their match class.
27308caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  emitMatchTokenString(Target, Info.Classes, OS);
273120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
2732fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar  // Emit the subclass predicate routine.
27338caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  emitIsSubclass(Target, Info.Classes, OS);
2734fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar
2735b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach  // Emit the routine to validate an operand against a match class.
27368caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  emitValidateOperandClass(Info, OS);
2737b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach
273854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  // Emit the available features compute function.
27398caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach  emitComputeAvailableFeatures(Info, OS);
274054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar
2741a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
2742fee7f01d1e193266b9ca88ef6b5466d543e4cec4Craig Topper  StringToOffsetTable StringTable;
2743fee7f01d1e193266b9ca88ef6b5466d543e4cec4Craig Topper
2744a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  size_t MaxNumOperands = 0;
2745fee7f01d1e193266b9ca88ef6b5466d543e4cec4Craig Topper  unsigned MaxMnemonicIndex = 0;
274622bc5c4184a497353e33195dd12541a4f08b008aChris Lattner  for (std::vector<MatchableInfo*>::const_iterator it =
274722bc5c4184a497353e33195dd12541a4f08b008aChris Lattner         Info.Matchables.begin(), ie = Info.Matchables.end();
2748fee7f01d1e193266b9ca88ef6b5466d543e4cec4Craig Topper       it != ie; ++it) {
2749fee7f01d1e193266b9ca88ef6b5466d543e4cec4Craig Topper    MatchableInfo &II = **it;
2750fee7f01d1e193266b9ca88ef6b5466d543e4cec4Craig Topper    MaxNumOperands = std::max(MaxNumOperands, II.AsmOperands.size());
2751fee7f01d1e193266b9ca88ef6b5466d543e4cec4Craig Topper
2752fee7f01d1e193266b9ca88ef6b5466d543e4cec4Craig Topper    // Store a pascal-style length byte in the mnemonic.
2753fee7f01d1e193266b9ca88ef6b5466d543e4cec4Craig Topper    std::string LenMnemonic = char(II.Mnemonic.size()) + II.Mnemonic.str();
2754fee7f01d1e193266b9ca88ef6b5466d543e4cec4Craig Topper    MaxMnemonicIndex = std::max(MaxMnemonicIndex,
2755fee7f01d1e193266b9ca88ef6b5466d543e4cec4Craig Topper                        StringTable.GetOrAddStringOffset(LenMnemonic, false));
2756fee7f01d1e193266b9ca88ef6b5466d543e4cec4Craig Topper  }
2757a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
27583a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper  OS << "static const char *const MnemonicTable =\n";
27593a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper  StringTable.EmitString(OS);
27603a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper  OS << ";\n\n";
27613a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper
2762a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  // Emit the static match table; unused classes get initalized to 0 which is
2763a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  // guaranteed to be InvalidMatchClass.
2764a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  //
2765a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  // FIXME: We can reduce the size of this table very easily. First, we change
2766a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  // it so that store the kinds in separate bit-fields for each index, which
2767a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  // only needs to be the max width used for classes at that index (we also need
2768a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  // to reject based on this during classification). If we then make sure to
2769a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  // order the match kinds appropriately (putting mnemonics last), then we
2770a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  // should only end up using a few bits for each class, especially the ones
2771a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  // following the mnemonic.
277296352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner  OS << "namespace {\n";
277396352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner  OS << "  struct MatchEntry {\n";
2774fee7f01d1e193266b9ca88ef6b5466d543e4cec4Craig Topper  OS << "    " << getMinimalTypeForRange(MaxMnemonicIndex)
2775fee7f01d1e193266b9ca88ef6b5466d543e4cec4Craig Topper               << " Mnemonic;\n";
2776a4c5ecfb1bc0101c1b42a4d81bb427482b52cecfBenjamin Kramer  OS << "    uint16_t Opcode;\n";
2777af482cf301cf35eebb3a67a3540e16b102b92246Benjamin Kramer  OS << "    " << getMinimalTypeForRange(Info.Matchables.size())
2778af482cf301cf35eebb3a67a3540e16b102b92246Benjamin Kramer               << " ConvertFn;\n";
2779af482cf301cf35eebb3a67a3540e16b102b92246Benjamin Kramer  OS << "    " << getMinimalTypeForRange(1ULL << Info.SubtargetFeatures.size())
2780af482cf301cf35eebb3a67a3540e16b102b92246Benjamin Kramer               << " RequiredFeatures;\n";
2781fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper  OS << "    " << getMinimalTypeForRange(Info.Classes.size())
2782fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper               << " Classes[" << MaxNumOperands << "];\n";
2783a4c5ecfb1bc0101c1b42a4d81bb427482b52cecfBenjamin Kramer  OS << "    StringRef getMnemonic() const {\n";
2784a4c5ecfb1bc0101c1b42a4d81bb427482b52cecfBenjamin Kramer  OS << "      return StringRef(MnemonicTable + Mnemonic + 1,\n";
2785a4c5ecfb1bc0101c1b42a4d81bb427482b52cecfBenjamin Kramer  OS << "                       MnemonicTable[Mnemonic]);\n";
2786a4c5ecfb1bc0101c1b42a4d81bb427482b52cecfBenjamin Kramer  OS << "    }\n";
27872b1f943444d1853204725c7b45b1e1032be39958Chris Lattner  OS << "  };\n\n";
2788a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
2789e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  OS << "  // Predicate for searching for an opcode.\n";
27902b1f943444d1853204725c7b45b1e1032be39958Chris Lattner  OS << "  struct LessOpcode {\n";
27912b1f943444d1853204725c7b45b1e1032be39958Chris Lattner  OS << "    bool operator()(const MatchEntry &LHS, StringRef RHS) {\n";
2792a4c5ecfb1bc0101c1b42a4d81bb427482b52cecfBenjamin Kramer  OS << "      return LHS.getMnemonic() < RHS;\n";
27932b1f943444d1853204725c7b45b1e1032be39958Chris Lattner  OS << "    }\n";
27942b1f943444d1853204725c7b45b1e1032be39958Chris Lattner  OS << "    bool operator()(StringRef LHS, const MatchEntry &RHS) {\n";
2795a4c5ecfb1bc0101c1b42a4d81bb427482b52cecfBenjamin Kramer  OS << "      return LHS < RHS.getMnemonic();\n";
27962b1f943444d1853204725c7b45b1e1032be39958Chris Lattner  OS << "    }\n";
279732c685cb67ff7701f4970ef61765cae7a50f255cChris Lattner  OS << "    bool operator()(const MatchEntry &LHS, const MatchEntry &RHS) {\n";
2798a4c5ecfb1bc0101c1b42a4d81bb427482b52cecfBenjamin Kramer  OS << "      return LHS.getMnemonic() < RHS.getMnemonic();\n";
279932c685cb67ff7701f4970ef61765cae7a50f255cChris Lattner  OS << "    }\n";
280096352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner  OS << "  };\n";
2801a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
280296352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner  OS << "} // end anonymous namespace.\n\n";
2803a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
2804f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper  unsigned VariantCount = Target.getAsmParserVariantCount();
2805f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper  for (unsigned VC = 0; VC != VariantCount; ++VC) {
2806f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper    Record *AsmVariant = Target.getAsmParserVariant(VC);
2807f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper    std::string CommentDelimiter =
2808f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper      AsmVariant->getValueAsString("CommentDelimiter");
2809f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper    std::string RegisterPrefix = AsmVariant->getValueAsString("RegisterPrefix");
2810f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper    int AsmVariantNo = AsmVariant->getValueAsInt("Variant");
2811a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
2812f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper    OS << "static const MatchEntry MatchTable" << VC << "[] = {\n";
2813a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
2814f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper    for (std::vector<MatchableInfo*>::const_iterator it =
2815f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper         Info.Matchables.begin(), ie = Info.Matchables.end();
2816f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper         it != ie; ++it) {
2817f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper      MatchableInfo &II = **it;
2818f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper      if (II.AsmVariantID != AsmVariantNo)
2819f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper        continue;
2820a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
2821f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper      // Store a pascal-style length byte in the mnemonic.
2822f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper      std::string LenMnemonic = char(II.Mnemonic.size()) + II.Mnemonic.str();
2823f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper      OS << "  { " << StringTable.GetOrAddStringOffset(LenMnemonic, false)
2824f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper         << " /* " << II.Mnemonic << " */, "
2825f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper         << Target.getName() << "::"
2826f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper         << II.getResultInst()->TheDef->getName() << ", "
2827f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper         << II.ConversionFnKind << ", ";
2828f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper
2829f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper      // Write the required features mask.
2830f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper      if (!II.RequiredFeatures.empty()) {
2831f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper        for (unsigned i = 0, e = II.RequiredFeatures.size(); i != e; ++i) {
2832f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper          if (i) OS << "|";
2833f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper          OS << II.RequiredFeatures[i]->getEnumName();
2834f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper        }
2835f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper      } else
2836f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper        OS << "0";
2837fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper
2838f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper      OS << ", { ";
2839f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper      for (unsigned i = 0, e = II.AsmOperands.size(); i != e; ++i) {
2840f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper        MatchableInfo::AsmOperand &Op = II.AsmOperands[i];
2841fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper
2842f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper        if (i) OS << ", ";
2843f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper        OS << Op.Class->Name;
2844f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper      }
2845f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper      OS << " }, },\n";
2846fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper    }
2847a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
2848f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper    OS << "};\n\n";
2849f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper  }
2850a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar
28511fe3aa15e9cdc4981d7a125d87eaf257c1d75af1Bob Wilson  // A method to determine if a mnemonic is in the list.
28521fe3aa15e9cdc4981d7a125d87eaf257c1d75af1Bob Wilson  OS << "bool " << Target.getName() << ClassName << "::\n"
2853f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper     << "mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) {\n";
2854f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper  OS << "  // Find the appropriate table for this asm variant.\n";
2855f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper  OS << "  const MatchEntry *Start, *End;\n";
2856f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper  OS << "  switch (VariantID) {\n";
2857f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper  OS << "  default: // unreachable\n";
2858f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper  for (unsigned VC = 0; VC != VariantCount; ++VC) {
2859f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper    Record *AsmVariant = Target.getAsmParserVariant(VC);
2860f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper    std::string CommentDelimiter =
2861f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper      AsmVariant->getValueAsString("CommentDelimiter");
2862f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper    std::string RegisterPrefix = AsmVariant->getValueAsString("RegisterPrefix");
2863f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper    int AsmVariantNo = AsmVariant->getValueAsInt("Variant");
2864f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper    OS << "  case " << AsmVariantNo << ": Start = MatchTable" << VC
2865f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper       << "; End = array_endof(MatchTable" << VC << "); break;\n";
2866f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper  }
2867f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper  OS << "  }\n";
28681fe3aa15e9cdc4981d7a125d87eaf257c1d75af1Bob Wilson  OS << "  // Search the table.\n";
28691fe3aa15e9cdc4981d7a125d87eaf257c1d75af1Bob Wilson  OS << "  std::pair<const MatchEntry*, const MatchEntry*> MnemonicRange =\n";
2870f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper  OS << "    std::equal_range(Start, End, Mnemonic, LessOpcode());\n";
28711fe3aa15e9cdc4981d7a125d87eaf257c1d75af1Bob Wilson  OS << "  return MnemonicRange.first != MnemonicRange.second;\n";
28721fe3aa15e9cdc4981d7a125d87eaf257c1d75af1Bob Wilson  OS << "}\n\n";
28731fe3aa15e9cdc4981d7a125d87eaf257c1d75af1Bob Wilson
287496352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner  // Finally, build the match function.
287519cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  OS << "unsigned "
287696352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner     << Target.getName() << ClassName << "::\n"
287796352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner     << "MatchInstructionImpl(const SmallVectorImpl<MCParsedAsmOperand*>"
287896352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner     << " &Operands,\n";
28796e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier  OS << "                     MCInst &Inst,\n"
288022685876ed7231f32f7d1698c00acab22825b74cChad Rosier     << "unsigned &ErrorInfo, bool matchingInlineAsm, unsigned VariantID) {\n";
288154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar
28820bad086d6dd2ee2d4ab8269ace959f7fb9cb3b9dChad Rosier  OS << "  // Eliminate obvious mismatches.\n";
28830bad086d6dd2ee2d4ab8269ace959f7fb9cb3b9dChad Rosier  OS << "  if (Operands.size() > " << (MaxNumOperands+1) << ") {\n";
28840bad086d6dd2ee2d4ab8269ace959f7fb9cb3b9dChad Rosier  OS << "    ErrorInfo = " << (MaxNumOperands+1) << ";\n";
28850bad086d6dd2ee2d4ab8269ace959f7fb9cb3b9dChad Rosier  OS << "    return Match_InvalidOperand;\n";
28860bad086d6dd2ee2d4ab8269ace959f7fb9cb3b9dChad Rosier  OS << "  }\n\n";
28870bad086d6dd2ee2d4ab8269ace959f7fb9cb3b9dChad Rosier
288854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  // Emit code to get the available features.
288954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  OS << "  // Get the current feature set.\n";
289054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  OS << "  unsigned AvailableFeatures = getAvailableFeatures();\n\n";
289154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar
2892674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner  OS << "  // Get the instruction mnemonic, which is the first token.\n";
2893674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner  OS << "  StringRef Mnemonic = ((" << Target.getName()
2894674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner     << "Operand*)Operands[0])->getToken();\n\n";
2895674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner
28967fd4489de11bdf06f6c852d42abafea013b76f28Chris Lattner  if (HasMnemonicAliases) {
28977fd4489de11bdf06f6c852d42abafea013b76f28Chris Lattner    OS << "  // Process all MnemonicAliases to remap the mnemonic.\n";
289888eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier    OS << "  applyMnemonicAliases(Mnemonic, AvailableFeatures, VariantID);\n\n";
28997fd4489de11bdf06f6c852d42abafea013b76f28Chris Lattner  }
2900828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson
2901a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  // Emit code to compute the class list for this operand vector.
29029bb9fa19a5e121b83866867ad1d8f7bf2618c1a0Chris Lattner  OS << "  // Some state to try to produce better error messages.\n";
290319cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  OS << "  bool HadMatchOtherThanFeatures = false;\n";
2904578071a08734a4eb76484ba0a8d9f10b6e322184Jim Grosbach  OS << "  bool HadMatchOtherThanPredicate = false;\n";
290519cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  OS << "  unsigned RetCode = Match_InvalidOperand;\n";
2906325bd661ff57787efddc6b302230f22e9c187655Jim Grosbach  OS << "  unsigned MissingFeatures = ~0U;\n";
290784cb033bf30b6f93ae2fbea71513970147e08dc2Jim Grosbach  OS << "  // Set ErrorInfo to the operand that mismatches if it is\n";
29089bb9fa19a5e121b83866867ad1d8f7bf2618c1a0Chris Lattner  OS << "  // wrong for all instances of the instruction.\n";
29099bb9fa19a5e121b83866867ad1d8f7bf2618c1a0Chris Lattner  OS << "  ErrorInfo = ~0U;\n";
29102b1f943444d1853204725c7b45b1e1032be39958Chris Lattner
2911a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  // Emit code to search the table.
2912f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper  OS << "  // Find the appropriate table for this asm variant.\n";
2913f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper  OS << "  const MatchEntry *Start, *End;\n";
2914f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper  OS << "  switch (VariantID) {\n";
2915f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper  OS << "  default: // unreachable\n";
2916f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper  for (unsigned VC = 0; VC != VariantCount; ++VC) {
2917f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper    Record *AsmVariant = Target.getAsmParserVariant(VC);
2918f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper    std::string CommentDelimiter =
2919f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper      AsmVariant->getValueAsString("CommentDelimiter");
2920f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper    std::string RegisterPrefix = AsmVariant->getValueAsString("RegisterPrefix");
2921f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper    int AsmVariantNo = AsmVariant->getValueAsInt("Variant");
2922f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper    OS << "  case " << AsmVariantNo << ": Start = MatchTable" << VC
2923f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper       << "; End = array_endof(MatchTable" << VC << "); break;\n";
2924f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper  }
2925f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper  OS << "  }\n";
2926a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  OS << "  // Search the table.\n";
29272b1f943444d1853204725c7b45b1e1032be39958Chris Lattner  OS << "  std::pair<const MatchEntry*, const MatchEntry*> MnemonicRange =\n";
2928f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper  OS << "    std::equal_range(Start, End, Mnemonic, LessOpcode());\n\n";
2929a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
2930a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  OS << "  // Return a more specific error code if no mnemonics match.\n";
2931a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  OS << "  if (MnemonicRange.first == MnemonicRange.second)\n";
2932a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  OS << "    return Match_MnemonicFail;\n\n";
2933a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
29342b1f943444d1853204725c7b45b1e1032be39958Chris Lattner  OS << "  for (const MatchEntry *it = MnemonicRange.first, "
293580db4e51d2a44bc623b5892bed2351406890b9aaChris Lattner     << "*ie = MnemonicRange.second;\n";
29362b1f943444d1853204725c7b45b1e1032be39958Chris Lattner  OS << "       it != ie; ++it) {\n";
293754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar
2938e53ee3b112810068b8ca229aff211fc497069273Gabor Greif  OS << "    // equal_range guarantees that instruction mnemonic matches.\n";
2939a4c5ecfb1bc0101c1b42a4d81bb427482b52cecfBenjamin Kramer  OS << "    assert(Mnemonic == it->getMnemonic());\n";
2940a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
294154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  // Emit check that the subclasses match.
2942ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  OS << "    bool OperandsValid = true;\n";
2943ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  OS << "    for (unsigned i = 0; i != " << MaxNumOperands << "; ++i) {\n";
2944b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach  OS << "      if (i + 1 >= Operands.size()) {\n";
2945b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach  OS << "        OperandsValid = (it->Classes[i] == " <<"InvalidMatchClass);\n";
2946087642f8638b08bf236b2cf8f0feb4df34c568f4Bill Wendling  OS << "        if (!OperandsValid) ErrorInfo = i + 1;\n";
2947b9d5af05fdc0867ed772c4bbfe3f3acc9fb3d628Jim Grosbach  OS << "        break;\n";
2948b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach  OS << "      }\n";
29494dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  OS << "      unsigned Diag = validateOperandClass(Operands[i+1],\n";
29504dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  OS.indent(43);
29514dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  OS << "(MatchClassKind)it->Classes[i]);\n";
29524dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  OS << "      if (Diag == Match_Success)\n";
2953ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  OS << "        continue;\n";
2954fa05def52c6bb8266d856a9af2de6fa066d93d44Jim Grosbach  OS << "      // If the generic handler indicates an invalid operand\n";
2955fa05def52c6bb8266d856a9af2de6fa066d93d44Jim Grosbach  OS << "      // failure, check for a special case.\n";
2956fa05def52c6bb8266d856a9af2de6fa066d93d44Jim Grosbach  OS << "      if (Diag == Match_InvalidOperand) {\n";
2957fa05def52c6bb8266d856a9af2de6fa066d93d44Jim Grosbach  OS << "        Diag = validateTargetOperandClass(Operands[i+1],\n";
2958fa05def52c6bb8266d856a9af2de6fa066d93d44Jim Grosbach  OS.indent(43);
2959fa05def52c6bb8266d856a9af2de6fa066d93d44Jim Grosbach  OS << "(MatchClassKind)it->Classes[i]);\n";
2960fa05def52c6bb8266d856a9af2de6fa066d93d44Jim Grosbach  OS << "        if (Diag == Match_Success)\n";
2961fa05def52c6bb8266d856a9af2de6fa066d93d44Jim Grosbach  OS << "          continue;\n";
2962fa05def52c6bb8266d856a9af2de6fa066d93d44Jim Grosbach  OS << "      }\n";
29639bb9fa19a5e121b83866867ad1d8f7bf2618c1a0Chris Lattner  OS << "      // If this operand is broken for all of the instances of this\n";
29649bb9fa19a5e121b83866867ad1d8f7bf2618c1a0Chris Lattner  OS << "      // mnemonic, keep track of it so we can report loc info.\n";
29654dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  OS << "      // If we already had a match that only failed due to a\n";
29664dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  OS << "      // target predicate, that diagnostic is preferred.\n";
29674dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  OS << "      if (!HadMatchOtherThanPredicate &&\n";
29684dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  OS << "          (it == MnemonicRange.first || ErrorInfo <= i+1)) {\n";
2969ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  OS << "        ErrorInfo = i+1;\n";
2970ef970c10918dde1e84b8e14a28dc7cf0a93c7c95Jim Grosbach  OS << "        // InvalidOperand is the default. Prefer specificity.\n";
2971ef970c10918dde1e84b8e14a28dc7cf0a93c7c95Jim Grosbach  OS << "        if (Diag != Match_InvalidOperand)\n";
2972ef970c10918dde1e84b8e14a28dc7cf0a93c7c95Jim Grosbach  OS << "          RetCode = Diag;\n";
29734dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach  OS << "      }\n";
2974ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  OS << "      // Otherwise, just reject this instance of the mnemonic.\n";
2975ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  OS << "      OperandsValid = false;\n";
2976ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  OS << "      break;\n";
2977ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  OS << "    }\n\n";
2978a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
2979ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  OS << "    if (!OperandsValid) continue;\n";
2980ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner
2981ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  // Emit check that the required features are available.
2982ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  OS << "    if ((AvailableFeatures & it->RequiredFeatures) "
2983ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner     << "!= it->RequiredFeatures) {\n";
2984ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  OS << "      HadMatchOtherThanFeatures = true;\n";
2985325bd661ff57787efddc6b302230f22e9c187655Jim Grosbach  OS << "      unsigned NewMissingFeatures = it->RequiredFeatures & "
2986325bd661ff57787efddc6b302230f22e9c187655Jim Grosbach        "~AvailableFeatures;\n";
29870bad086d6dd2ee2d4ab8269ace959f7fb9cb3b9dChad Rosier  OS << "      if (CountPopulation_32(NewMissingFeatures) <=\n"
29880bad086d6dd2ee2d4ab8269ace959f7fb9cb3b9dChad Rosier        "          CountPopulation_32(MissingFeatures))\n";
2989325bd661ff57787efddc6b302230f22e9c187655Jim Grosbach  OS << "        MissingFeatures = NewMissingFeatures;\n";
2990ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  OS << "      continue;\n";
2991ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  OS << "    }\n";
2992a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  OS << "\n";
299322685876ed7231f32f7d1698c00acab22825b74cChad Rosier  OS << "    if (matchingInlineAsm) {\n";
299422685876ed7231f32f7d1698c00acab22825b74cChad Rosier  OS << "      Inst.setOpcode(it->Opcode);\n";
29956e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier  OS << "      convertToMapAndConstraints(it->ConvertFn, Operands);\n";
299622685876ed7231f32f7d1698c00acab22825b74cChad Rosier  OS << "      return Match_Success;\n";
299722685876ed7231f32f7d1698c00acab22825b74cChad Rosier  OS << "    }\n\n";
2998b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar  OS << "    // We have selected a definite instruction, convert the parsed\n"
2999b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar     << "    // operands into the appropriate MCInst.\n";
300090e11f8c95146c2d3718e9b3de71ee6628347b05Chad Rosier  OS << "    convertToMCInst(it->ConvertFn, Inst, it->Opcode, Operands);\n";
3001b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar  OS << "\n";
30028cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar
300319cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  // Verify the instruction with the target-specific match predicate function.
300419cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  OS << "    // We have a potential match. Check the target predicate to\n"
300519cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach     << "    // handle any context sensitive constraints.\n"
300619cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach     << "    unsigned MatchResult;\n"
300719cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach     << "    if ((MatchResult = checkTargetMatchPredicate(Inst)) !="
300819cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach     << " Match_Success) {\n"
300919cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach     << "      Inst.clear();\n"
301019cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach     << "      RetCode = MatchResult;\n"
3011578071a08734a4eb76484ba0a8d9f10b6e322184Jim Grosbach     << "      HadMatchOtherThanPredicate = true;\n"
301219cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach     << "      continue;\n"
301319cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach     << "    }\n\n";
301419cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach
30158cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar  // Call the post-processing function, if used.
30168cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar  std::string InsnCleanupFn =
30178cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar    AsmParser->getValueAsString("AsmParserInstCleanup");
30188cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar  if (!InsnCleanupFn.empty())
30198cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar    OS << "    " << InsnCleanupFn << "(Inst);\n";
30208cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar
302179ed3f77e8b87615b80054ca6e4e3ba5e07445bdChris Lattner  OS << "    return Match_Success;\n";
3022a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  OS << "  }\n\n";
3023a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
3024ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  OS << "  // Okay, we had no match.  Try to return a useful error code.\n";
30254c1d2baa7c3303302fec9a15ebc4021bd5d45002Chad Rosier  OS << "  if (HadMatchOtherThanPredicate || !HadMatchOtherThanFeatures)\n";
30264c1d2baa7c3303302fec9a15ebc4021bd5d45002Chad Rosier  OS << "    return RetCode;\n\n";
3027325bd661ff57787efddc6b302230f22e9c187655Jim Grosbach  OS << "  // Missing feature matches return which features were missing\n";
3028325bd661ff57787efddc6b302230f22e9c187655Jim Grosbach  OS << "  ErrorInfo = MissingFeatures;\n";
3029578071a08734a4eb76484ba0a8d9f10b6e322184Jim Grosbach  OS << "  return Match_MissingFeature;\n";
3030a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar  OS << "}\n\n";
3031a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach
3032e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes  if (Info.OperandMatchInfo.size())
30333a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper    emitCustomOperandParsing(OS, Target, Info, ClassName, StringTable,
30343a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper                             MaxMnemonicIndex);
3035e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes
30360692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner  OS << "#endif // GET_MATCHER_IMPLEMENTATION\n\n";
3037d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar}
30386f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
30396f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesennamespace llvm {
30406f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
30416f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenvoid EmitAsmMatcher(RecordKeeper &RK, raw_ostream &OS) {
30426f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  emitSourceFileHeader("Assembly Matcher Source Fragment", OS);
30436f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  AsmMatcherEmitter(RK).run(OS);
30446f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen}
30456f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
30466f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End llvm namespace
3047