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