AsmMatcherEmitter.cpp revision 906bc368bc0fe18682edc0743ada41f62e436383
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 11d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar// assembly operands in the MCInst structures. 12d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar// 1320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// The input to the target specific matcher is a list of literal tokens and 1420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// operands. The target specific parser should generally eliminate any syntax 1520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// which is not relevant for matching; for example, comma tokens should have 1620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// already been consumed and eliminated by the parser. Most instructions will 1720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// end up with a single literal token (the instruction name) and some number of 1820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// operands. 1920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 2020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// Some example inputs, for X86: 2120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 'addl' (immediate ...) (register ...) 2220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 'add' (immediate ...) (memory ...) 23a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach// 'call' '*' %epc 2420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 2520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// The assembly matcher is responsible for converting this input into a precise 2620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// machine instruction (i.e., an instruction with a well defined encoding). This 2720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// mapping has several properties which complicate matching: 2820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 2920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// - It may be ambiguous; many architectures can legally encode particular 3020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// variants of an instruction in different ways (for example, using a smaller 3120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// encoding for small immediates). Such ambiguities should never be 3220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// arbitrarily resolved by the assembler, the assembler is always responsible 3320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// for choosing the "best" available instruction. 3420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 3520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// - It may depend on the subtarget or the assembler context. Instructions 3620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// which are invalid for the current mode, but otherwise unambiguous (e.g., 3720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// an SSE instruction in a file being assembled for i486) should be accepted 3820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// and rejected by the assembler front end. However, if the proper encoding 3920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// for an instruction is dependent on the assembler context then the matcher 4020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// is responsible for selecting the correct machine instruction for the 4120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// current mode. 4220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 4320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// The core matching algorithm attempts to exploit the regularity in most 4420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// instruction sets to quickly determine the set of possibly matching 4520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// instructions, and the simplify the generated code. Additionally, this helps 4620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// to ensure that the ambiguities are intentionally resolved by the user. 4720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 4820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// The matching is divided into two distinct phases: 4920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 5020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 1. Classification: Each operand is mapped to the unique set which (a) 5120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// contains it, and (b) is the largest such subset for which a single 5220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// instruction could match all members. 5320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 5420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// For register classes, we can generate these subgroups automatically. For 5520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// arbitrary operands, we expect the user to define the classes and their 5620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// relations to one another (for example, 8-bit signed immediates as a 5720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// subset of 32-bit immediates). 5820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 5920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// By partitioning the operands in this way, we guarantee that for any 6020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// tuple of classes, any single instruction must match either all or none 6120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// of the sets of operands which could classify to that tuple. 6220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 6320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// In addition, the subset relation amongst classes induces a partial order 6420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// on such tuples, which we use to resolve ambiguities. 6520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 6620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 2. The input can now be treated as a tuple of classes (static tokens are 6720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// simple singleton sets). Each such tuple should generally map to a single 6820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// instruction (we currently ignore cases where this isn't true, whee!!!), 6920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// which we can emit a simple matcher for. 7020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 71d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar//===----------------------------------------------------------------------===// 72d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar 73d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar#include "AsmMatcherEmitter.h" 74d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar#include "CodeGenTarget.h" 75d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar#include "Record.h" 765845e5c62b42d025557765006515156691a6a8b1Chris Lattner#include "StringMatcher.h" 7720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar#include "llvm/ADT/OwningPtr.h" 78c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner#include "llvm/ADT/PointerUnion.h" 791de88235781c45c0afc0c7500d65b59775196c4cChris Lattner#include "llvm/ADT/SmallPtrSet.h" 80a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar#include "llvm/ADT/SmallVector.h" 81606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar#include "llvm/ADT/STLExtras.h" 8220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar#include "llvm/ADT/StringExtras.h" 8320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar#include "llvm/Support/CommandLine.h" 84a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar#include "llvm/Support/Debug.h" 85b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar#include <map> 86b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar#include <set> 87d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbarusing namespace llvm; 88d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar 892724915c171b08fa9f7f9e54a46ea81708d9c5b2Daniel Dunbarstatic cl::opt<std::string> 90606e8ad796f72824f5509e2657c44eca025d4bafDaniel DunbarMatchPrefix("match-prefix", cl::init(""), 91606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar cl::desc("Only match instructions with the given prefix")); 9220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 9322be5225ff88ffaab83c36fa133e70586b91166dDaniel Dunbar 9420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbarnamespace { 9502bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner class AsmMatcherInfo; 9654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbarstruct SubtargetFeatureInfo; 9754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 98a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar/// ClassInfo - Helper class for storing the information about a particular 99a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar/// class of operands which can be matched. 100a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarstruct ClassInfo { 101606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar enum ClassInfoKind { 102ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// Invalid kind, for use as a sentinel value. 103ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar Invalid = 0, 104ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 105ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// The class for a particular token. 106ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar Token, 107ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 108ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// The (first) register class, subsequent register classes are 109ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// RegisterClass0+1, and so on. 110ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar RegisterClass0, 111ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 112ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// The (first) user defined class, subsequent user defined classes are 113ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// UserClass0+1, and so on. 114ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar UserClass0 = 1<<16 115606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar }; 116606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 117606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar /// Kind - The class kind, which is either a predefined kind, or (UserClass0 + 118606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar /// N) for the Nth user defined class. 119606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar unsigned Kind; 120a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 121ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// SuperClasses - The super classes of this class. Note that for simplicities 122ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// sake user operands only record their immediate super class, while register 123ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// operands include all superclasses. 124ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar std::vector<ClassInfo*> SuperClasses; 1255fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar 1266745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar /// Name - The full class name, suitable for use in an enum. 127a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::string Name; 128a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1296745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar /// ClassName - The unadorned generic name for this class (e.g., Token). 1306745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar std::string ClassName; 1316745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar 132a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// ValueName - The name of the value this class represents; for a token this 133a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// is the literal token string, for an operand it is the TableGen class (or 134a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// empty if this is a derived class). 135a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::string ValueName; 136a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 137a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// PredicateMethod - The name of the operand method to test whether the 138ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// operand matches this class; this is not valid for Token or register kinds. 139a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::string PredicateMethod; 140a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 141a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// RenderMethod - The name of the operand method to add this operand to an 142ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// MCInst; this is not valid for Token or register kinds. 143a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::string RenderMethod; 144606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 1458409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar /// For register classes, the records for all the registers in this class. 1468409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar std::set<Record*> Registers; 1478409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar 1488409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbarpublic: 149ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// isRegisterClass() - Check if this is a register class. 150ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar bool isRegisterClass() const { 151ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar return Kind >= RegisterClass0 && Kind < UserClass0; 152ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 153ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 1545fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar /// isUserClass() - Check if this is a user defined class. 1555fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar bool isUserClass() const { 1565fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar return Kind >= UserClass0; 1575fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar } 1585fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar 159ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// isRelatedTo - Check whether this class is "related" to \arg RHS. Classes 160ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// are related if they are in the same class hierarchy. 161ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar bool isRelatedTo(const ClassInfo &RHS) const { 162ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Tokens are only related to tokens. 163ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (Kind == Token || RHS.Kind == Token) 164ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar return Kind == Token && RHS.Kind == Token; 165ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 1668409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar // Registers classes are only related to registers classes, and only if 1678409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar // their intersection is non-empty. 1688409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar if (isRegisterClass() || RHS.isRegisterClass()) { 1698409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar if (!isRegisterClass() || !RHS.isRegisterClass()) 1708409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar return false; 1718409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar 1728409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar std::set<Record*> Tmp; 1738409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar std::insert_iterator< std::set<Record*> > II(Tmp, Tmp.begin()); 174a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach std::set_intersection(Registers.begin(), Registers.end(), 1758409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar RHS.Registers.begin(), RHS.Registers.end(), 1768409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar II); 1778409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar 1788409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar return !Tmp.empty(); 1798409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar } 180ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 181ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Otherwise we have two users operands; they are related if they are in the 182ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // same class hierarchy. 1838409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar // 1848409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar // FIXME: This is an oversimplification, they should only be related if they 1858409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar // intersect, however we don't have that information. 186ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar assert(isUserClass() && RHS.isUserClass() && "Unexpected class!"); 187ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar const ClassInfo *Root = this; 188ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar while (!Root->SuperClasses.empty()) 189ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar Root = Root->SuperClasses.front(); 190ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 1918409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar const ClassInfo *RHSRoot = &RHS; 192ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar while (!RHSRoot->SuperClasses.empty()) 193ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar RHSRoot = RHSRoot->SuperClasses.front(); 194a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 195ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar return Root == RHSRoot; 196ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 197ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 198a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach /// isSubsetOf - Test whether this class is a subset of \arg RHS; 199ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar bool isSubsetOf(const ClassInfo &RHS) const { 200ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // This is a subset of RHS if it is the same class... 201ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (this == &RHS) 202ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar return true; 203ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 204ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // ... or if any of its super classes are a subset of RHS. 205ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar for (std::vector<ClassInfo*>::const_iterator it = SuperClasses.begin(), 206ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ie = SuperClasses.end(); it != ie; ++it) 207ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if ((*it)->isSubsetOf(RHS)) 208ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar return true; 209ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 210ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar return false; 2115fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar } 2125fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar 213606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar /// operator< - Compare two classes. 214606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar bool operator<(const ClassInfo &RHS) const { 215368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar if (this == &RHS) 216368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar return false; 217368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar 218ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Unrelated classes can be ordered by kind. 219ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (!isRelatedTo(RHS)) 220606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar return Kind < RHS.Kind; 221606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 222606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar switch (Kind) { 2236745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar case Invalid: 2246745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar assert(0 && "Invalid kind!"); 225606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar case Token: 2265fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar // Tokens are comparable by value. 227606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar // 228606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar // FIXME: Compare by enum value. 229606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar return ValueName < RHS.ValueName; 230606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 231606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar default: 232ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // This class preceeds the RHS if it is a proper subset of the RHS. 233368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar if (isSubsetOf(RHS)) 2343472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands return true; 235368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar if (RHS.isSubsetOf(*this)) 2363472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands return false; 237368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar 238368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar // Otherwise, order by name to ensure we have a total ordering. 239368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar return ValueName < RHS.ValueName; 240606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar } 241606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar } 242a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar}; 243a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 24422bc5c4184a497353e33195dd12541a4f08b008aChris Lattner/// MatchableInfo - Helper class for storing the necessary information for an 24522bc5c4184a497353e33195dd12541a4f08b008aChris Lattner/// instruction or alias which is capable of being matched. 24622bc5c4184a497353e33195dd12541a4f08b008aChris Lattnerstruct MatchableInfo { 247c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner struct AsmOperand { 248d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner /// Token - This is the token that the operand came from. 249d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner StringRef Token; 250d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner 251a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// The unique class instance this operand should match. 252a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar ClassInfo *Class; 253a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 254567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner /// The operand name this is, if anything. 255567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner StringRef SrcOpName; 2564c9f4e4002bfdb059684a8dafef8993a5ec27a23Chris Lattner 257567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner explicit AsmOperand(StringRef T) : Token(T), Class(0) {} 25820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar }; 2591d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner 2601d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// ResOperand - This represents a single operand in the result instruction 2611d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// generated by the match. In cases (like addressing modes) where a single 2621d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// assembler operand expands to multiple MCOperands, this represents the 2631d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// single assembler operand, not the MCOperand. 2641d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner struct ResOperand { 2651d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner enum { 2661d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// RenderAsmOperand - This represents an operand result that is 2671d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// generated by calling the render method on the assembly operand. The 2681d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// corresponding AsmOperand is specified by AsmOperandNum. 2691d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner RenderAsmOperand, 2701d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner 2711d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// TiedOperand - This represents a result operand that is a duplicate of 2721d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// a previous result operand. 27398c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner TiedOperand, 27498c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner 27598c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner /// ImmOperand - This represents an immediate value that is dumped into 27698c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner /// the operand. 27790fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner ImmOperand, 27890fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner 27990fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner /// RegOperand - This represents a fixed register that is dumped in. 28090fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner RegOperand 2811d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner } Kind; 2821d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner 2831d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner union { 2841d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// This is the operand # in the AsmOperands list that this should be 2851d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// copied from. 2861d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner unsigned AsmOperandNum; 2871d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner 2881d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// TiedOperandNum - This is the (earlier) result operand that should be 2891d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// copied from. 2901d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner unsigned TiedOperandNum; 29198c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner 29298c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner /// ImmVal - This is the immediate value added to the instruction. 29398c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner int64_t ImmVal; 29490fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner 29590fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner /// Register - This is the register record. 29690fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner Record *Register; 2971d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner }; 2981d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner 2991d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// OpInfo - This is the information about the instruction operand that is 3001d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// being populated. 3011d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner const CGIOperandList::OperandInfo *OpInfo; 3021d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner 3031d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner static ResOperand getRenderedOp(unsigned AsmOpNum, 3041d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner const CGIOperandList::OperandInfo *Op) { 3051d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner ResOperand X; 3061d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner X.Kind = RenderAsmOperand; 3071d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner X.AsmOperandNum = AsmOpNum; 3081d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner X.OpInfo = Op; 3091d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner return X; 3101d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner } 3111d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner 3121d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner static ResOperand getTiedOp(unsigned TiedOperandNum, 3131d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner const CGIOperandList::OperandInfo *Op) { 3141d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner ResOperand X; 3151d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner X.Kind = TiedOperand; 3161d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner X.TiedOperandNum = TiedOperandNum; 3171d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner X.OpInfo = Op; 3181d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner return X; 3191d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner } 32098c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner 32198c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner static ResOperand getImmOp(int64_t Val, 32298c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner const CGIOperandList::OperandInfo *Op) { 32398c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner ResOperand X; 32498c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner X.Kind = ImmOperand; 32598c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner X.ImmVal = Val; 32698c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner X.OpInfo = Op; 32798c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner return X; 32898c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner } 32990fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner 33090fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner static ResOperand getRegOp(Record *Reg, 33190fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner const CGIOperandList::OperandInfo *Op) { 33290fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner ResOperand X; 33390fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner X.Kind = RegOperand; 33490fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner X.Register = Reg; 33590fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner X.OpInfo = Op; 33690fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner return X; 33790fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner } 33890fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner 3391d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner }; 34020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 3413b5aec67ef174c74ff6620ddd71ad3b0cb39030cChris Lattner /// TheDef - This is the definition of the instruction or InstAlias that this 3423b5aec67ef174c74ff6620ddd71ad3b0cb39030cChris Lattner /// matchable came from. 3435bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner Record *const TheDef; 3443b5aec67ef174c74ff6620ddd71ad3b0cb39030cChris Lattner 345c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner /// DefRec - This is the definition that it came from. 346c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner PointerUnion<const CodeGenInstruction*, const CodeGenInstAlias*> DefRec; 347c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner 348662e5a30e864e71111b885d3da3cdd184772035dChris Lattner const CodeGenInstruction *getResultInst() const { 349662e5a30e864e71111b885d3da3cdd184772035dChris Lattner if (DefRec.is<const CodeGenInstruction*>()) 350662e5a30e864e71111b885d3da3cdd184772035dChris Lattner return DefRec.get<const CodeGenInstruction*>(); 351662e5a30e864e71111b885d3da3cdd184772035dChris Lattner return DefRec.get<const CodeGenInstAlias*>()->ResultInst; 352662e5a30e864e71111b885d3da3cdd184772035dChris Lattner } 3531d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner 3541d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// ResOperands - This is the operand list that should be built for the result 3551d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// MCInst. 3561d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner std::vector<ResOperand> ResOperands; 35720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 35820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar /// AsmString - The assembly string for this instruction (with variants 3593b5aec67ef174c74ff6620ddd71ad3b0cb39030cChris Lattner /// removed), e.g. "movsx $src, $dst". 36020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar std::string AsmString; 36120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 362d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner /// Mnemonic - This is the first token of the matched instruction, its 363d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner /// mnemonic. 364d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner StringRef Mnemonic; 365d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner 3663116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner /// AsmOperands - The textual operands that this instruction matches, 3673b5aec67ef174c74ff6620ddd71ad3b0cb39030cChris Lattner /// annotated with a class and where in the OperandList they were defined. 3683b5aec67ef174c74ff6620ddd71ad3b0cb39030cChris Lattner /// This directly corresponds to the tokenized AsmString after the mnemonic is 3693b5aec67ef174c74ff6620ddd71ad3b0cb39030cChris Lattner /// removed. 370c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner SmallVector<AsmOperand, 4> AsmOperands; 37120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 37254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar /// Predicates - The required subtarget features to match this instruction. 37354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar SmallVector<SubtargetFeatureInfo*, 4> RequiredFeatures; 37454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 375b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar /// ConversionFnKind - The enum value which is passed to the generated 376b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar /// ConvertToMCInst to convert parsed operands into an MCInst for this 377b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar /// function. 378b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar std::string ConversionFnKind; 37902bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner 38022bc5c4184a497353e33195dd12541a4f08b008aChris Lattner MatchableInfo(const CodeGenInstruction &CGI) 381662e5a30e864e71111b885d3da3cdd184772035dChris Lattner : TheDef(CGI.TheDef), DefRec(&CGI), AsmString(CGI.AsmString) { 3825bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner } 3835bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner 38422bc5c4184a497353e33195dd12541a4f08b008aChris Lattner MatchableInfo(const CodeGenInstAlias *Alias) 385662e5a30e864e71111b885d3da3cdd184772035dChris Lattner : TheDef(Alias->TheDef), DefRec(Alias), AsmString(Alias->AsmString) { 386c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner } 387c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner 388c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner void Initialize(const AsmMatcherInfo &Info, 389c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner SmallPtrSet<Record*, 16> &SingletonRegisters); 390c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner 39122bc5c4184a497353e33195dd12541a4f08b008aChris Lattner /// Validate - Return true if this matchable is a valid thing to match against 39222bc5c4184a497353e33195dd12541a4f08b008aChris Lattner /// and perform a bunch of validity checking. 39322bc5c4184a497353e33195dd12541a4f08b008aChris Lattner bool Validate(StringRef CommentDelimiter, bool Hack) const; 3945bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner 395d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner /// getSingletonRegisterForAsmOperand - If the specified token is a singleton 3961de88235781c45c0afc0c7500d65b59775196c4cChris Lattner /// register, return the Record for it, otherwise return null. 397d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner Record *getSingletonRegisterForAsmOperand(unsigned i, 398d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner const AsmMatcherInfo &Info) const; 39920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 400ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner int FindAsmOperandNamed(StringRef N) const { 401ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) 402ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner if (N == AsmOperands[i].SrcOpName) 403ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner return i; 404ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner return -1; 405ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner } 406ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner 407414098571b19fc248fda2be194082cfd012d2729Chris Lattner void BuildInstructionResultOperands(); 408414098571b19fc248fda2be194082cfd012d2729Chris Lattner void BuildAliasResultOperands(); 4091d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner 41022bc5c4184a497353e33195dd12541a4f08b008aChris Lattner /// operator< - Compare two matchables. 41122bc5c4184a497353e33195dd12541a4f08b008aChris Lattner bool operator<(const MatchableInfo &RHS) const { 412e206fcf0e9c7e79c7f42ff2151f3fb58cba70674Chris Lattner // The primary comparator is the instruction mnemonic. 413d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner if (Mnemonic != RHS.Mnemonic) 414d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner return Mnemonic < RHS.Mnemonic; 415a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 4163116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner if (AsmOperands.size() != RHS.AsmOperands.size()) 4173116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner return AsmOperands.size() < RHS.AsmOperands.size(); 4182b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar 419db2ddb5dc57319eff249144f1d9a553a3278d2e0Daniel Dunbar // Compare lexicographically by operand. The matcher validates that other 420db2ddb5dc57319eff249144f1d9a553a3278d2e0Daniel Dunbar // orderings wouldn't be ambiguous using \see CouldMatchAmiguouslyWith(). 4213116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) { 4223116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner if (*AsmOperands[i].Class < *RHS.AsmOperands[i].Class) 4232b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar return true; 4243116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner if (*RHS.AsmOperands[i].Class < *AsmOperands[i].Class) 425db2ddb5dc57319eff249144f1d9a553a3278d2e0Daniel Dunbar return false; 426db2ddb5dc57319eff249144f1d9a553a3278d2e0Daniel Dunbar } 427db2ddb5dc57319eff249144f1d9a553a3278d2e0Daniel Dunbar 4282b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar return false; 4292b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar } 430606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 43122bc5c4184a497353e33195dd12541a4f08b008aChris Lattner /// CouldMatchAmiguouslyWith - Check whether this matchable could 4322b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar /// ambiguously match the same set of operands as \arg RHS (without being a 4332b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar /// strictly superior match). 43422bc5c4184a497353e33195dd12541a4f08b008aChris Lattner bool CouldMatchAmiguouslyWith(const MatchableInfo &RHS) { 435e66b7ebfb426c7ed9bc911e9708321e2d8510b41Chris Lattner // The primary comparator is the instruction mnemonic. 436d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner if (Mnemonic != RHS.Mnemonic) 437e66b7ebfb426c7ed9bc911e9708321e2d8510b41Chris Lattner return false; 438e66b7ebfb426c7ed9bc911e9708321e2d8510b41Chris Lattner 4392b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar // The number of operands is unambiguous. 4403116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner if (AsmOperands.size() != RHS.AsmOperands.size()) 4412b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar return false; 442606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 4431402f0b2cac017ab997f71ab4909a2ccfea7be4bDaniel Dunbar // Otherwise, make sure the ordering of the two instructions is unambiguous 4441402f0b2cac017ab997f71ab4909a2ccfea7be4bDaniel Dunbar // by checking that either (a) a token or operand kind discriminates them, 4451402f0b2cac017ab997f71ab4909a2ccfea7be4bDaniel Dunbar // or (b) the ordering among equivalent kinds is consistent. 4461402f0b2cac017ab997f71ab4909a2ccfea7be4bDaniel Dunbar 4472b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar // Tokens and operand kinds are unambiguous (assuming a correct target 4482b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar // specific parser). 4493116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) 4503116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner if (AsmOperands[i].Class->Kind != RHS.AsmOperands[i].Class->Kind || 4513116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner AsmOperands[i].Class->Kind == ClassInfo::Token) 4523116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner if (*AsmOperands[i].Class < *RHS.AsmOperands[i].Class || 4533116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner *RHS.AsmOperands[i].Class < *AsmOperands[i].Class) 4542b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar return false; 455a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 4562b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar // Otherwise, this operand could commute if all operands are equivalent, or 4572b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar // there is a pair of operands that compare less than and a pair that 4582b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar // compare greater than. 4592b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar bool HasLT = false, HasGT = false; 4603116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) { 4613116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner if (*AsmOperands[i].Class < *RHS.AsmOperands[i].Class) 4622b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar HasLT = true; 4633116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner if (*RHS.AsmOperands[i].Class < *AsmOperands[i].Class) 4642b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar HasGT = true; 4652b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar } 466606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 4672b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar return !(HasLT ^ HasGT); 468606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar } 469606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 47020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar void dump(); 471d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner 472d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattnerprivate: 473d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner void TokenizeAsmString(const AsmMatcherInfo &Info); 47420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar}; 47520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 47654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar/// SubtargetFeatureInfo - Helper class for storing information on a subtarget 47754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar/// feature which participates in instruction matching. 47854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbarstruct SubtargetFeatureInfo { 47954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar /// \brief The predicate record for this feature. 48054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar Record *TheDef; 48154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 48254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar /// \brief An unique index assigned to represent this feature. 48354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar unsigned Index; 48454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 4850aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner SubtargetFeatureInfo(Record *D, unsigned Idx) : TheDef(D), Index(Idx) {} 4860aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner 48754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar /// \brief The name of the enumerated constant identifying this feature. 4880aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner std::string getEnumName() const { 4890aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner return "Feature_" + TheDef->getName(); 4900aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner } 49154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar}; 49254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 493a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarclass AsmMatcherInfo { 494a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarpublic: 49567db883487fca3472fdde51e931657e22d4d0495Chris Lattner /// Tracked Records 4969c6b60eb28d2717008f8d6ff52f7666ebc81113dChris Lattner RecordKeeper &Records; 49767db883487fca3472fdde51e931657e22d4d0495Chris Lattner 49859fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar /// The tablegen AsmParser record. 49959fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar Record *AsmParser; 50059fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar 50102bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner /// Target - The target information. 50202bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner CodeGenTarget &Target; 50302bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner 50459fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar /// The AsmParser "RegisterPrefix" value. 50559fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar std::string RegisterPrefix; 50659fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar 507a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// The classes which are needed for matching. 508a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::vector<ClassInfo*> Classes; 509a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 51022bc5c4184a497353e33195dd12541a4f08b008aChris Lattner /// The information on the matchables to match. 51122bc5c4184a497353e33195dd12541a4f08b008aChris Lattner std::vector<MatchableInfo*> Matchables; 512a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 513ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// Map of Register records to their class information. 514ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar std::map<Record*, ClassInfo*> RegisterClasses; 515ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 51654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar /// Map of Predicate records to their subtarget information. 51754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar std::map<Record*, SubtargetFeatureInfo*> SubtargetFeatures; 5186fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner 519a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarprivate: 520a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// Map of token to class information which has already been constructed. 521a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::map<std::string, ClassInfo*> TokenClasses; 522a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 523ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// Map of RegisterClass records to their class information. 524ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar std::map<Record*, ClassInfo*> RegisterClassClasses; 525a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 526338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar /// Map of AsmOperandClass records to their class information. 527338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar std::map<Record*, ClassInfo*> AsmOperandClasses; 5286745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar 529a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarprivate: 530a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// getTokenClass - Lookup or create the class for the given token. 531b8d6e98e566724f58344d275a4bd675249bb713aChris Lattner ClassInfo *getTokenClass(StringRef Token); 532a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 533a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// getOperandClass - Lookup or create the class for the given operand. 5345f4280cd2d2d1aeb527c8b161acaa1870cf6ee82Chris Lattner ClassInfo *getOperandClass(const CGIOperandList::OperandInfo &OI); 535a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 536ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// BuildRegisterClasses - Build the ClassInfo* instances for register 537ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// classes. 5381de88235781c45c0afc0c7500d65b59775196c4cChris Lattner void BuildRegisterClasses(SmallPtrSet<Record*, 16> &SingletonRegisters); 539ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 540ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// BuildOperandClasses - Build the ClassInfo* instances for user defined 541ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// operand classes. 54202bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner void BuildOperandClasses(); 543ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 544c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner void BuildInstructionOperandReference(MatchableInfo *II, 545c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner StringRef OpName, 5461d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner MatchableInfo::AsmOperand &Op); 547c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner void BuildAliasOperandReference(MatchableInfo *II, 548c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner StringRef OpName, 549c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner MatchableInfo::AsmOperand &Op); 550c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner 551a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarpublic: 55267db883487fca3472fdde51e931657e22d4d0495Chris Lattner AsmMatcherInfo(Record *AsmParser, 55367db883487fca3472fdde51e931657e22d4d0495Chris Lattner CodeGenTarget &Target, 5549c6b60eb28d2717008f8d6ff52f7666ebc81113dChris Lattner RecordKeeper &Records); 55559fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar 556a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// BuildInfo - Construct the various tables used during matching. 55702bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner void BuildInfo(); 5586fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner 5596fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner /// getSubtargetFeature - Lookup or create the subtarget feature info for the 5606fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner /// given operand. 5616fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner SubtargetFeatureInfo *getSubtargetFeature(Record *Def) const { 5626fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner assert(Def->isSubClassOf("Predicate") && "Invalid predicate type!"); 5636fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner std::map<Record*, SubtargetFeatureInfo*>::const_iterator I = 5646fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner SubtargetFeatures.find(Def); 5656fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner return I == SubtargetFeatures.end() ? 0 : I->second; 5666fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner } 56767db883487fca3472fdde51e931657e22d4d0495Chris Lattner 5689c6b60eb28d2717008f8d6ff52f7666ebc81113dChris Lattner RecordKeeper &getRecords() const { 5699c6b60eb28d2717008f8d6ff52f7666ebc81113dChris Lattner return Records; 57067db883487fca3472fdde51e931657e22d4d0495Chris Lattner } 571a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar}; 572a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 57320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar} 57420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 57522bc5c4184a497353e33195dd12541a4f08b008aChris Lattnervoid MatchableInfo::dump() { 5765abd1ebcb380664ae5010395b217e01f7190046cChris Lattner errs() << TheDef->getName() << " -- " << "flattened:\"" << AsmString <<"\"\n"; 577a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 5783116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) { 579c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner AsmOperand &Op = AsmOperands[i]; 5806745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar errs() << " op[" << i << "] = " << Op.Class->ClassName << " - "; 5810bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner errs() << '\"' << Op.Token << "\"\n"; 58220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 58320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar} 584a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 58522bc5c4184a497353e33195dd12541a4f08b008aChris Lattnervoid MatchableInfo::Initialize(const AsmMatcherInfo &Info, 58622bc5c4184a497353e33195dd12541a4f08b008aChris Lattner SmallPtrSet<Record*, 16> &SingletonRegisters) { 587c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner // TODO: Eventually support asmparser for Variant != 0. 588c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner AsmString = CodeGenInstruction::FlattenAsmStringVariants(AsmString, 0); 589c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner 590d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner TokenizeAsmString(Info); 591c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner 592c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner // Compute the require features. 593c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner std::vector<Record*> Predicates =TheDef->getValueAsListOfDefs("Predicates"); 594c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner for (unsigned i = 0, e = Predicates.size(); i != e; ++i) 595c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner if (SubtargetFeatureInfo *Feature = 596c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner Info.getSubtargetFeature(Predicates[i])) 597c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner RequiredFeatures.push_back(Feature); 598c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner 599c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner // Collect singleton registers, if used. 600d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) { 601d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner if (Record *Reg = getSingletonRegisterForAsmOperand(i, Info)) 602c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner SingletonRegisters.insert(Reg); 603c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner } 604c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner} 605c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner 606d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner/// TokenizeAsmString - Tokenize a simplified assembly string. 607d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattnervoid MatchableInfo::TokenizeAsmString(const AsmMatcherInfo &Info) { 608d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner StringRef String = AsmString; 609d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner unsigned Prev = 0; 610d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner bool InTok = true; 611d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner for (unsigned i = 0, e = String.size(); i != e; ++i) { 612d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner switch (String[i]) { 613d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner case '[': 614d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner case ']': 615d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner case '*': 616d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner case '!': 617d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner case ' ': 618d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner case '\t': 619d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner case ',': 620d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner if (InTok) { 621c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner AsmOperands.push_back(AsmOperand(String.slice(Prev, i))); 622d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner InTok = false; 623d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner } 624d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner if (!isspace(String[i]) && String[i] != ',') 625c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner AsmOperands.push_back(AsmOperand(String.substr(i, 1))); 626d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner Prev = i + 1; 627d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner break; 628d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner 629d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner case '\\': 630d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner if (InTok) { 631c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner AsmOperands.push_back(AsmOperand(String.slice(Prev, i))); 632d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner InTok = false; 633d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner } 634d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner ++i; 635d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner assert(i != String.size() && "Invalid quoted character"); 636c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner AsmOperands.push_back(AsmOperand(String.substr(i, 1))); 637d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner Prev = i + 1; 638d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner break; 639d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner 640d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner case '$': { 6417ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner if (InTok) { 6427ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner AsmOperands.push_back(AsmOperand(String.slice(Prev, i))); 6437ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner InTok = false; 6447ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner } 6457ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner 646d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner // If this isn't "${", treat like a normal token. 647d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner if (i + 1 == String.size() || String[i + 1] != '{') { 648d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner Prev = i; 649d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner break; 650d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner } 651d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner 652d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner StringRef::iterator End = std::find(String.begin() + i, String.end(),'}'); 653d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner assert(End != String.end() && "Missing brace in operand reference!"); 654d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner size_t EndPos = End - String.begin(); 655c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner AsmOperands.push_back(AsmOperand(String.slice(i, EndPos+1))); 656d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner Prev = EndPos + 1; 657d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner i = EndPos; 658d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner break; 659d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner } 660d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner 661d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner case '.': 662d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner if (InTok) 663c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner AsmOperands.push_back(AsmOperand(String.slice(Prev, i))); 664d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner Prev = i; 665d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner InTok = true; 666d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner break; 667d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner 668d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner default: 669d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner InTok = true; 670d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner } 671d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner } 672d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner if (InTok && Prev != String.size()) 673c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner AsmOperands.push_back(AsmOperand(String.substr(Prev))); 674d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner 675d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner // The first token of the instruction is the mnemonic, which must be a 676d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner // simple string, not a $foo variable or a singleton register. 677d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner assert(!AsmOperands.empty() && "Instruction has no tokens?"); 678d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner Mnemonic = AsmOperands[0].Token; 679d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner if (Mnemonic[0] == '$' || getSingletonRegisterForAsmOperand(0, Info)) 680d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner throw TGError(TheDef->getLoc(), 681d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner "Invalid instruction mnemonic '" + Mnemonic.str() + "'!"); 682d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner 683d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner // Remove the first operand, it is tracked in the mnemonic field. 684d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner AsmOperands.erase(AsmOperands.begin()); 685d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner} 686d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner 687d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner 688c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner 68922bc5c4184a497353e33195dd12541a4f08b008aChris Lattnerbool MatchableInfo::Validate(StringRef CommentDelimiter, bool Hack) const { 69022bc5c4184a497353e33195dd12541a4f08b008aChris Lattner // Reject matchables with no .s string. 6915bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner if (AsmString.empty()) 6925bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner throw TGError(TheDef->getLoc(), "instruction with empty asm string"); 6935bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner 69422bc5c4184a497353e33195dd12541a4f08b008aChris Lattner // Reject any matchables with a newline in them, they should be marked 6955bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner // isCodeGenOnly if they are pseudo instructions. 6965bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner if (AsmString.find('\n') != std::string::npos) 6975bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner throw TGError(TheDef->getLoc(), 6985bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner "multiline instruction is not valid for the asmparser, " 6995bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner "mark it isCodeGenOnly"); 7005bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner 7014164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner // Remove comments from the asm string. We know that the asmstring only 7024164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner // has one line. 7034164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner if (!CommentDelimiter.empty() && 7044164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner StringRef(AsmString).find(CommentDelimiter) != StringRef::npos) 7054164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner throw TGError(TheDef->getLoc(), 7064164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner "asmstring for instruction has comment character in it, " 7074164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner "mark it isCodeGenOnly"); 7084164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner 70922bc5c4184a497353e33195dd12541a4f08b008aChris Lattner // Reject matchables with operand modifiers, these aren't something we can 710906bc368bc0fe18682edc0743ada41f62e436383Bob Wilson // handle, the target should be refactored to use operands instead of 711906bc368bc0fe18682edc0743ada41f62e436383Bob Wilson // modifiers. 7125bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner // 7135bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner // Also, check for instructions which reference the operand multiple times; 7145bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner // this implies a constraint we would not honor. 7155bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner std::set<std::string> OperandNames; 716d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) { 717d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner StringRef Tok = AsmOperands[i].Token; 718d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner if (Tok[0] == '$' && Tok.find(':') != StringRef::npos) 7195bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner throw TGError(TheDef->getLoc(), 720d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner "matchable with operand modifier '" + Tok.str() + 7215bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner "' not supported by asm matcher. Mark isCodeGenOnly!"); 7225bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner 72322bc5c4184a497353e33195dd12541a4f08b008aChris Lattner // Verify that any operand is only mentioned once. 724d51257a4368d52e2340073bc7ccd83f3c3f1c04dChris Lattner // We reject aliases and ignore instructions for now. 725d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner if (Tok[0] == '$' && !OperandNames.insert(Tok).second) { 72622bc5c4184a497353e33195dd12541a4f08b008aChris Lattner if (!Hack) 72722bc5c4184a497353e33195dd12541a4f08b008aChris Lattner throw TGError(TheDef->getLoc(), 728d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner "ERROR: matchable with tied operand '" + Tok.str() + 72922bc5c4184a497353e33195dd12541a4f08b008aChris Lattner "' can never be matched!"); 73022bc5c4184a497353e33195dd12541a4f08b008aChris Lattner // FIXME: Should reject these. The ARM backend hits this with $lane in a 73122bc5c4184a497353e33195dd12541a4f08b008aChris Lattner // bunch of instructions. It is unclear what the right answer is. 7325bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner DEBUG({ 7335abd1ebcb380664ae5010395b217e01f7190046cChris Lattner errs() << "warning: '" << TheDef->getName() << "': " 73422bc5c4184a497353e33195dd12541a4f08b008aChris Lattner << "ignoring instruction with tied operand '" 735d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner << Tok.str() << "'\n"; 7365bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner }); 7375bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner return false; 7385bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner } 7395bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner } 7405bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner 7415bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner return true; 7425bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner} 7435bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner 7445bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner 745d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner/// getSingletonRegisterForAsmOperand - If the specified token is a singleton 74602bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner/// register, return the register name, otherwise return a null StringRef. 74722bc5c4184a497353e33195dd12541a4f08b008aChris LattnerRecord *MatchableInfo:: 748d19ec05e0785152e7a520ffd4a88da4459a380aaChris LattnergetSingletonRegisterForAsmOperand(unsigned i, const AsmMatcherInfo &Info) const{ 749d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner StringRef Tok = AsmOperands[i].Token; 75002bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner if (!Tok.startswith(Info.RegisterPrefix)) 7511de88235781c45c0afc0c7500d65b59775196c4cChris Lattner return 0; 75202bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner 75302bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner StringRef RegName = Tok.substr(Info.RegisterPrefix.size()); 754ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner if (const CodeGenRegister *Reg = Info.Target.getRegisterByName(RegName)) 755ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner return Reg->TheDef; 75602bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner 7571de88235781c45c0afc0c7500d65b59775196c4cChris Lattner // If there is no register prefix (i.e. "%" in "%eax"), then this may 7581de88235781c45c0afc0c7500d65b59775196c4cChris Lattner // be some random non-register token, just ignore it. 7591de88235781c45c0afc0c7500d65b59775196c4cChris Lattner if (Info.RegisterPrefix.empty()) 7601de88235781c45c0afc0c7500d65b59775196c4cChris Lattner return 0; 76102bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner 762ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner // Otherwise, we have something invalid prefixed with the register prefix, 763ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner // such as %foo. 7641de88235781c45c0afc0c7500d65b59775196c4cChris Lattner std::string Err = "unable to find register for '" + RegName.str() + 7651de88235781c45c0afc0c7500d65b59775196c4cChris Lattner "' (which matches register prefix)"; 7665bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner throw TGError(TheDef->getLoc(), Err); 76702bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner} 76802bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner 76902bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner 770b8d6e98e566724f58344d275a4bd675249bb713aChris Lattnerstatic std::string getEnumNameForToken(StringRef Str) { 771a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::string Res; 772a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 773a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar for (StringRef::iterator it = Str.begin(), ie = Str.end(); it != ie; ++it) { 774a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar switch (*it) { 775a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar case '*': Res += "_STAR_"; break; 776a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar case '%': Res += "_PCT_"; break; 777a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar case ':': Res += "_COLON_"; break; 778bd9c77bc9ad384d046a7967d160ad96f61916d9dBill Wendling case '!': Res += "_EXCLAIM_"; break; 779a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar default: 78039ee036f407bd0c94cb993cf9b97348843cfafa4Chris Lattner if (isalnum(*it)) 781a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Res += *it; 78239ee036f407bd0c94cb993cf9b97348843cfafa4Chris Lattner else 783a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Res += "_" + utostr((unsigned) *it) + "_"; 784a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 785a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 78620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 787a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar return Res; 788a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar} 789a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 790b8d6e98e566724f58344d275a4bd675249bb713aChris LattnerClassInfo *AsmMatcherInfo::getTokenClass(StringRef Token) { 791a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar ClassInfo *&Entry = TokenClasses[Token]; 792a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 793a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar if (!Entry) { 794a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Entry = new ClassInfo(); 795a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Entry->Kind = ClassInfo::Token; 7966745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar Entry->ClassName = "Token"; 797a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Entry->Name = "MCK_" + getEnumNameForToken(Token); 798a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Entry->ValueName = Token; 799a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Entry->PredicateMethod = "<invalid>"; 800a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Entry->RenderMethod = "<invalid>"; 801a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Classes.push_back(Entry); 802a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 803a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 804a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar return Entry; 805a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar} 806a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 807a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel DunbarClassInfo * 8085f4280cd2d2d1aeb527c8b161acaa1870cf6ee82Chris LattnerAsmMatcherInfo::getOperandClass(const CGIOperandList::OperandInfo &OI) { 809ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (OI.Rec->isSubClassOf("RegisterClass")) { 810ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner if (ClassInfo *CI = RegisterClassClasses[OI.Rec]) 811ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner return CI; 812ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner throw TGError(OI.Rec->getLoc(), "register class has no class info!"); 813ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 814338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar 815338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar assert(OI.Rec->isSubClassOf("Operand") && "Unexpected operand!"); 816338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar Record *MatchClass = OI.Rec->getValueAsDef("ParserMatchClass"); 817ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner if (ClassInfo *CI = AsmOperandClasses[MatchClass]) 818ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner return CI; 819a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 820ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner throw TGError(OI.Rec->getLoc(), "operand has no match class!"); 821338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar} 822338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar 8231de88235781c45c0afc0c7500d65b59775196c4cChris Lattnervoid AsmMatcherInfo:: 8241de88235781c45c0afc0c7500d65b59775196c4cChris LattnerBuildRegisterClasses(SmallPtrSet<Record*, 16> &SingletonRegisters) { 825ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner const std::vector<CodeGenRegister> &Registers = Target.getRegisters(); 826ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner const std::vector<CodeGenRegisterClass> &RegClassList = 827ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner Target.getRegisterClasses(); 828338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar 829ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // The register sets used for matching. 830ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar std::set< std::set<Record*> > RegisterSets; 831ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 832a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach // Gather the defined sets. 833ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner for (std::vector<CodeGenRegisterClass>::const_iterator it = 834ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner RegClassList.begin(), ie = RegClassList.end(); it != ie; ++it) 835ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar RegisterSets.insert(std::set<Record*>(it->Elements.begin(), 836ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar it->Elements.end())); 8371095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 8381095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar // Add any required singleton sets. 8391de88235781c45c0afc0c7500d65b59775196c4cChris Lattner for (SmallPtrSet<Record*, 16>::iterator it = SingletonRegisters.begin(), 8401de88235781c45c0afc0c7500d65b59775196c4cChris Lattner ie = SingletonRegisters.end(); it != ie; ++it) { 8411de88235781c45c0afc0c7500d65b59775196c4cChris Lattner Record *Rec = *it; 8421de88235781c45c0afc0c7500d65b59775196c4cChris Lattner RegisterSets.insert(std::set<Record*>(&Rec, &Rec + 1)); 8431de88235781c45c0afc0c7500d65b59775196c4cChris Lattner } 844a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 845ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Introduce derived sets where necessary (when a register does not determine 846ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // a unique register set class), and build the mapping of registers to the set 847ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // they should classify to. 848ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar std::map<Record*, std::set<Record*> > RegisterMap; 849ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner for (std::vector<CodeGenRegister>::const_iterator it = Registers.begin(), 850ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ie = Registers.end(); it != ie; ++it) { 851ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner const CodeGenRegister &CGR = *it; 852ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Compute the intersection of all sets containing this register. 853ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar std::set<Record*> ContainingSet; 854a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 855ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar for (std::set< std::set<Record*> >::iterator it = RegisterSets.begin(), 856ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ie = RegisterSets.end(); it != ie; ++it) { 857ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (!it->count(CGR.TheDef)) 858ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar continue; 859ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 860ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (ContainingSet.empty()) { 861ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ContainingSet = *it; 862ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner continue; 863ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 864ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner 865ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner std::set<Record*> Tmp; 866ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner std::swap(Tmp, ContainingSet); 867ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner std::insert_iterator< std::set<Record*> > II(ContainingSet, 868ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner ContainingSet.begin()); 869ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner std::set_intersection(Tmp.begin(), Tmp.end(), it->begin(), it->end(), II); 870ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 871ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 872ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (!ContainingSet.empty()) { 873ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar RegisterSets.insert(ContainingSet); 874ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar RegisterMap.insert(std::make_pair(CGR.TheDef, ContainingSet)); 875ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 876ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 877ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 878ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Construct the register classes. 879ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar std::map<std::set<Record*>, ClassInfo*> RegisterSetClasses; 880ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar unsigned Index = 0; 881ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar for (std::set< std::set<Record*> >::iterator it = RegisterSets.begin(), 882ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ie = RegisterSets.end(); it != ie; ++it, ++Index) { 883ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ClassInfo *CI = new ClassInfo(); 884ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->Kind = ClassInfo::RegisterClass0 + Index; 885ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->ClassName = "Reg" + utostr(Index); 886ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->Name = "MCK_Reg" + utostr(Index); 887ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->ValueName = ""; 888ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->PredicateMethod = ""; // unused 889ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->RenderMethod = "addRegOperands"; 8908409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar CI->Registers = *it; 891ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar Classes.push_back(CI); 892ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar RegisterSetClasses.insert(std::make_pair(*it, CI)); 893ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 894ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 895ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Find the superclasses; we could compute only the subgroup lattice edges, 896ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // but there isn't really a point. 897ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar for (std::set< std::set<Record*> >::iterator it = RegisterSets.begin(), 898ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ie = RegisterSets.end(); it != ie; ++it) { 899ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ClassInfo *CI = RegisterSetClasses[*it]; 900ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar for (std::set< std::set<Record*> >::iterator it2 = RegisterSets.begin(), 901ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ie2 = RegisterSets.end(); it2 != ie2; ++it2) 902a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach if (*it != *it2 && 903ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar std::includes(it2->begin(), it2->end(), it->begin(), it->end())) 904ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->SuperClasses.push_back(RegisterSetClasses[*it2]); 905ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 906ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 907ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Name the register classes which correspond to a user defined RegisterClass. 908ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner for (std::vector<CodeGenRegisterClass>::const_iterator 909ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner it = RegClassList.begin(), ie = RegClassList.end(); it != ie; ++it) { 910ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ClassInfo *CI = RegisterSetClasses[std::set<Record*>(it->Elements.begin(), 911ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar it->Elements.end())]; 912ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (CI->ValueName.empty()) { 913ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->ClassName = it->getName(); 914ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->Name = "MCK_" + it->getName(); 915ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->ValueName = it->getName(); 916ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } else 917ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->ValueName = CI->ValueName + "," + it->getName(); 918ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 919ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar RegisterClassClasses.insert(std::make_pair(it->TheDef, CI)); 920ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 921ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 922ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Populate the map for individual registers. 923ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar for (std::map<Record*, std::set<Record*> >::iterator it = RegisterMap.begin(), 924ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ie = RegisterMap.end(); it != ie; ++it) 925ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner RegisterClasses[it->first] = RegisterSetClasses[it->second]; 9261095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 9271095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar // Name the register classes which correspond to singleton registers. 9281de88235781c45c0afc0c7500d65b59775196c4cChris Lattner for (SmallPtrSet<Record*, 16>::iterator it = SingletonRegisters.begin(), 9291de88235781c45c0afc0c7500d65b59775196c4cChris Lattner ie = SingletonRegisters.end(); it != ie; ++it) { 9301de88235781c45c0afc0c7500d65b59775196c4cChris Lattner Record *Rec = *it; 931ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner ClassInfo *CI = RegisterClasses[Rec]; 9321de88235781c45c0afc0c7500d65b59775196c4cChris Lattner assert(CI && "Missing singleton register class info!"); 9331de88235781c45c0afc0c7500d65b59775196c4cChris Lattner 9341de88235781c45c0afc0c7500d65b59775196c4cChris Lattner if (CI->ValueName.empty()) { 9351de88235781c45c0afc0c7500d65b59775196c4cChris Lattner CI->ClassName = Rec->getName(); 9361de88235781c45c0afc0c7500d65b59775196c4cChris Lattner CI->Name = "MCK_" + Rec->getName(); 9371de88235781c45c0afc0c7500d65b59775196c4cChris Lattner CI->ValueName = Rec->getName(); 9381de88235781c45c0afc0c7500d65b59775196c4cChris Lattner } else 9391de88235781c45c0afc0c7500d65b59775196c4cChris Lattner CI->ValueName = CI->ValueName + "," + Rec->getName(); 9401095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar } 941ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar} 942ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 94302bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattnervoid AsmMatcherInfo::BuildOperandClasses() { 944e66b7ebfb426c7ed9bc911e9708321e2d8510b41Chris Lattner std::vector<Record*> AsmOperands = 945e66b7ebfb426c7ed9bc911e9708321e2d8510b41Chris Lattner Records.getAllDerivedDefinitions("AsmOperandClass"); 946a2f5e00347641d1b46ce4f65bf9378fecce9be14Daniel Dunbar 947a2f5e00347641d1b46ce4f65bf9378fecce9be14Daniel Dunbar // Pre-populate AsmOperandClasses map. 948a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach for (std::vector<Record*>::iterator it = AsmOperands.begin(), 949a2f5e00347641d1b46ce4f65bf9378fecce9be14Daniel Dunbar ie = AsmOperands.end(); it != ie; ++it) 950a2f5e00347641d1b46ce4f65bf9378fecce9be14Daniel Dunbar AsmOperandClasses[*it] = new ClassInfo(); 951a2f5e00347641d1b46ce4f65bf9378fecce9be14Daniel Dunbar 952338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar unsigned Index = 0; 953a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach for (std::vector<Record*>::iterator it = AsmOperands.begin(), 954338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar ie = AsmOperands.end(); it != ie; ++it, ++Index) { 955a2f5e00347641d1b46ce4f65bf9378fecce9be14Daniel Dunbar ClassInfo *CI = AsmOperandClasses[*it]; 956338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar CI->Kind = ClassInfo::UserClass0 + Index; 957338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar 95854ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar ListInit *Supers = (*it)->getValueAsListInit("SuperClasses"); 95954ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar for (unsigned i = 0, e = Supers->getSize(); i != e; ++i) { 96054ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar DefInit *DI = dynamic_cast<DefInit*>(Supers->getElement(i)); 96154ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar if (!DI) { 96254ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar PrintError((*it)->getLoc(), "Invalid super class reference!"); 96354ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar continue; 96454ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar } 96554ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar 966ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ClassInfo *SC = AsmOperandClasses[DI->getDef()]; 967ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (!SC) 968338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar PrintError((*it)->getLoc(), "Invalid super class reference!"); 969ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar else 970ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->SuperClasses.push_back(SC); 971a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 972338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar CI->ClassName = (*it)->getValueAsString("Name"); 973338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar CI->Name = "MCK_" + CI->ClassName; 974338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar CI->ValueName = (*it)->getName(); 9755c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar 9765c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar // Get or construct the predicate method name. 9775c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar Init *PMName = (*it)->getValueInit("PredicateMethod"); 9785c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar if (StringInit *SI = dynamic_cast<StringInit*>(PMName)) { 9795c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar CI->PredicateMethod = SI->getValue(); 9805c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar } else { 981a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach assert(dynamic_cast<UnsetInit*>(PMName) && 9825c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar "Unexpected PredicateMethod field!"); 9835c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar CI->PredicateMethod = "is" + CI->ClassName; 9845c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar } 9855c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar 9865c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar // Get or construct the render method name. 9875c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar Init *RMName = (*it)->getValueInit("RenderMethod"); 9885c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar if (StringInit *SI = dynamic_cast<StringInit*>(RMName)) { 9895c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar CI->RenderMethod = SI->getValue(); 9905c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar } else { 9915c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar assert(dynamic_cast<UnsetInit*>(RMName) && 9925c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar "Unexpected RenderMethod field!"); 9935c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar CI->RenderMethod = "add" + CI->ClassName + "Operands"; 9945c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar } 9955c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar 996338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar AsmOperandClasses[*it] = CI; 997338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar Classes.push_back(CI); 998a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 999ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar} 1000ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 100167db883487fca3472fdde51e931657e22d4d0495Chris LattnerAsmMatcherInfo::AsmMatcherInfo(Record *asmParser, 100267db883487fca3472fdde51e931657e22d4d0495Chris Lattner CodeGenTarget &target, 10039c6b60eb28d2717008f8d6ff52f7666ebc81113dChris Lattner RecordKeeper &records) 100467db883487fca3472fdde51e931657e22d4d0495Chris Lattner : Records(records), AsmParser(asmParser), Target(target), 1005c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner RegisterPrefix(AsmParser->getValueAsString("RegisterPrefix")) { 100659fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar} 100759fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar 1008c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner 100902bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattnervoid AsmMatcherInfo::BuildInfo() { 10100aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner // Build information about all of the AssemblerPredicates. 10110aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner std::vector<Record*> AllPredicates = 10120aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner Records.getAllDerivedDefinitions("Predicate"); 10130aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner for (unsigned i = 0, e = AllPredicates.size(); i != e; ++i) { 10140aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner Record *Pred = AllPredicates[i]; 10150aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner // Ignore predicates that are not intended for the assembler. 10160aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner if (!Pred->getValueAsBit("AssemblerMatcherPredicate")) 10170aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner continue; 10180aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner 10194164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner if (Pred->getName().empty()) 10204164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner throw TGError(Pred->getLoc(), "Predicate has no name!"); 10210aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner 10220aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner unsigned FeatureNo = SubtargetFeatures.size(); 10230aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner SubtargetFeatures[Pred] = new SubtargetFeatureInfo(Pred, FeatureNo); 10240aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner assert(FeatureNo < 32 && "Too many subtarget features!"); 10250aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner } 1026a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 10274164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner StringRef CommentDelimiter = AsmParser->getValueAsString("CommentDelimiter"); 10284164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner 102939ee036f407bd0c94cb993cf9b97348843cfafa4Chris Lattner // Parse the instructions; we need to do this first so that we can gather the 103039ee036f407bd0c94cb993cf9b97348843cfafa4Chris Lattner // singleton register classes. 10311de88235781c45c0afc0c7500d65b59775196c4cChris Lattner SmallPtrSet<Record*, 16> SingletonRegisters; 103202bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner for (CodeGenTarget::inst_iterator I = Target.inst_begin(), 103302bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner E = Target.inst_end(); I != E; ++I) { 103402bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner const CodeGenInstruction &CGI = **I; 1035a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 103639ee036f407bd0c94cb993cf9b97348843cfafa4Chris Lattner // If the tblgen -match-prefix option is specified (for tblgen hackers), 103739ee036f407bd0c94cb993cf9b97348843cfafa4Chris Lattner // filter the set of instructions we consider. 1038b61e09de6d0cd7241ddc6dee3efef416552eec3bChris Lattner if (!StringRef(CGI.TheDef->getName()).startswith(MatchPrefix)) 103953a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar continue; 104053a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar 10415bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner // Ignore "codegen only" instructions. 10425bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner if (CGI.TheDef->getValueAsBit("isCodeGenOnly")) 10435bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner continue; 10445bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner 10451d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner // Validate the operand list to ensure we can handle this instruction. 10461d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner for (unsigned i = 0, e = CGI.Operands.size(); i != e; ++i) { 10471d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner const CGIOperandList::OperandInfo &OI = CGI.Operands[i]; 10481d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner 10491d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner // Validate tied operands. 10501d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner if (OI.getTiedRegister() != -1) { 10511d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner // If we have a tied operand that consists of multiple MCOperands, reject 10521d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner // it. We reject aliases and ignore instructions for now. 10531d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner if (OI.MINumOperands != 1) { 10541d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner // FIXME: Should reject these. The ARM backend hits this with $lane 10551d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner // in a bunch of instructions. It is unclear what the right answer is. 10561d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner DEBUG({ 10571d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner errs() << "warning: '" << CGI.TheDef->getName() << "': " 10581d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner << "ignoring instruction with multi-operand tied operand '" 10591d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner << OI.Name << "'\n"; 10601d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner }); 10611d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner continue; 10621d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner } 10631d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner } 10641d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner } 10651d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner 106622bc5c4184a497353e33195dd12541a4f08b008aChris Lattner OwningPtr<MatchableInfo> II(new MatchableInfo(CGI)); 1067a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 1068c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner II->Initialize(*this, SingletonRegisters); 1069c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner 10704d43d0fd996a01c2cd21fd51082bc1bba783ef3cChris Lattner // Ignore instructions which shouldn't be matched and diagnose invalid 10714d43d0fd996a01c2cd21fd51082bc1bba783ef3cChris Lattner // instruction definitions with an error. 107222bc5c4184a497353e33195dd12541a4f08b008aChris Lattner if (!II->Validate(CommentDelimiter, true)) 10735bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner continue; 10745bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner 10755bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner // Ignore "Int_*" and "*_Int" instructions, which are internal aliases. 10765bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner // 10775bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner // FIXME: This is a total hack. 10785abd1ebcb380664ae5010395b217e01f7190046cChris Lattner if (StringRef(II->TheDef->getName()).startswith("Int_") || 10795abd1ebcb380664ae5010395b217e01f7190046cChris Lattner StringRef(II->TheDef->getName()).endswith("_Int")) 1080a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar continue; 108139ee036f407bd0c94cb993cf9b97348843cfafa4Chris Lattner 108222bc5c4184a497353e33195dd12541a4f08b008aChris Lattner Matchables.push_back(II.take()); 10831095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar } 1084c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner 1085c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner // Parse all of the InstAlias definitions and stick them in the list of 1086c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner // matchables. 1087c76e80ded753b78a72be0db40fcdba543435d818Chris Lattner std::vector<Record*> AllInstAliases = 1088c76e80ded753b78a72be0db40fcdba543435d818Chris Lattner Records.getAllDerivedDefinitions("InstAlias"); 1089c76e80ded753b78a72be0db40fcdba543435d818Chris Lattner for (unsigned i = 0, e = AllInstAliases.size(); i != e; ++i) { 1090225549f775db61c5dba10e14758f4b43c53ef593Chris Lattner CodeGenInstAlias *Alias = new CodeGenInstAlias(AllInstAliases[i], Target); 1091c76e80ded753b78a72be0db40fcdba543435d818Chris Lattner 109222bc5c4184a497353e33195dd12541a4f08b008aChris Lattner OwningPtr<MatchableInfo> II(new MatchableInfo(Alias)); 1093c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner 1094c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner II->Initialize(*this, SingletonRegisters); 1095c76e80ded753b78a72be0db40fcdba543435d818Chris Lattner 109622bc5c4184a497353e33195dd12541a4f08b008aChris Lattner // Validate the alias definitions. 109722bc5c4184a497353e33195dd12541a4f08b008aChris Lattner II->Validate(CommentDelimiter, false); 109822bc5c4184a497353e33195dd12541a4f08b008aChris Lattner 1099b501d4f673c0db267a76800339f9943f2ce6fe33Chris Lattner Matchables.push_back(II.take()); 1100c76e80ded753b78a72be0db40fcdba543435d818Chris Lattner } 1101c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner 11021095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar // Build info for the register classes. 11031de88235781c45c0afc0c7500d65b59775196c4cChris Lattner BuildRegisterClasses(SingletonRegisters); 11041095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 11051095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar // Build info for the user defined assembly operand classes. 110602bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner BuildOperandClasses(); 11071095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 11080bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner // Build the information about matchables, now that we have fully formed 11090bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner // classes. 111022bc5c4184a497353e33195dd12541a4f08b008aChris Lattner for (std::vector<MatchableInfo*>::iterator it = Matchables.begin(), 111122bc5c4184a497353e33195dd12541a4f08b008aChris Lattner ie = Matchables.end(); it != ie; ++it) { 111222bc5c4184a497353e33195dd12541a4f08b008aChris Lattner MatchableInfo *II = *it; 1113a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 1114e206fcf0e9c7e79c7f42ff2151f3fb58cba70674Chris Lattner // Parse the tokens after the mnemonic. 1115d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner for (unsigned i = 0, e = II->AsmOperands.size(); i != e; ++i) { 1116c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner MatchableInfo::AsmOperand &Op = II->AsmOperands[i]; 1117d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner StringRef Token = Op.Token; 111820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 11191095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar // Check for singleton registers. 1120d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner if (Record *RegRecord = II->getSingletonRegisterForAsmOperand(i, *this)) { 1121d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner Op.Class = RegisterClasses[RegRecord]; 112202bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner assert(Op.Class && Op.Class->Registers.size() == 1 && 112302bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner "Unexpected class for singleton register"); 112402bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner continue; 11251095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar } 11261095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 112720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // Check for simple tokens. 112820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (Token[0] != '$') { 1129d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner Op.Class = getTokenClass(Token); 113020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar continue; 113120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 1132a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 11337ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner if (Token.size() > 1 && isdigit(Token[1])) { 11347ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner Op.Class = getTokenClass(Token); 11357ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner continue; 11367ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner } 11377ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner 1138c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner // Otherwise this is an operand reference. 11395f4280cd2d2d1aeb527c8b161acaa1870cf6ee82Chris Lattner StringRef OperandName; 11405f4280cd2d2d1aeb527c8b161acaa1870cf6ee82Chris Lattner if (Token[1] == '{') 11415f4280cd2d2d1aeb527c8b161acaa1870cf6ee82Chris Lattner OperandName = Token.substr(2, Token.size() - 3); 11425f4280cd2d2d1aeb527c8b161acaa1870cf6ee82Chris Lattner else 11435f4280cd2d2d1aeb527c8b161acaa1870cf6ee82Chris Lattner OperandName = Token.substr(1); 11445f4280cd2d2d1aeb527c8b161acaa1870cf6ee82Chris Lattner 1145c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner if (II->DefRec.is<const CodeGenInstruction*>()) 1146225549f775db61c5dba10e14758f4b43c53ef593Chris Lattner BuildInstructionOperandReference(II, OperandName, Op); 1147c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner else 1148225549f775db61c5dba10e14758f4b43c53ef593Chris Lattner BuildAliasOperandReference(II, OperandName, Op); 114953a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar } 11501d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner 1151414098571b19fc248fda2be194082cfd012d2729Chris Lattner if (II->DefRec.is<const CodeGenInstruction*>()) 1152414098571b19fc248fda2be194082cfd012d2729Chris Lattner II->BuildInstructionResultOperands(); 1153414098571b19fc248fda2be194082cfd012d2729Chris Lattner else 1154414098571b19fc248fda2be194082cfd012d2729Chris Lattner II->BuildAliasResultOperands(); 115520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 11565fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar 11575fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar // Reorder classes so that classes preceed super classes. 11585fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar std::sort(Classes.begin(), Classes.end(), less_ptr<ClassInfo>()); 115920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar} 1160a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 11610bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner/// BuildInstructionOperandReference - The specified operand is a reference to a 11620bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner/// named operand such as $src. Resolve the Class and OperandInfo pointers. 11630bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattnervoid AsmMatcherInfo:: 11640bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris LattnerBuildInstructionOperandReference(MatchableInfo *II, 11655f4280cd2d2d1aeb527c8b161acaa1870cf6ee82Chris Lattner StringRef OperandName, 11660bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner MatchableInfo::AsmOperand &Op) { 1167c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner const CodeGenInstruction &CGI = *II->DefRec.get<const CodeGenInstruction*>(); 1168c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner const CGIOperandList &Operands = CGI.Operands; 11690bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner 1170662e5a30e864e71111b885d3da3cdd184772035dChris Lattner // Map this token to an operand. 11710bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner unsigned Idx; 11720bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner if (!Operands.hasOperandNamed(OperandName, Idx)) 11730bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner throw TGError(II->TheDef->getLoc(), "error: unable to find operand: '" + 11740bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner OperandName.str() + "'"); 1175ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner 1176ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner // Set up the operand class. 11775f4280cd2d2d1aeb527c8b161acaa1870cf6ee82Chris Lattner Op.Class = getOperandClass(Operands[Idx]); 1178ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner 1179ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner // If the named operand is tied, canonicalize it to the untied operand. 1180ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner // For example, something like: 1181ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner // (outs GPR:$dst), (ins GPR:$src) 1182ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner // with an asmstring of 1183ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner // "inc $src" 1184ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner // we want to canonicalize to: 1185c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner // "inc $dst" 1186c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner // so that we know how to provide the $dst operand when filling in the result. 1187c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner int OITied = Operands[Idx].getTiedRegister(); 1188c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner if (OITied != -1) { 1189c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner // The tied operand index is an MIOperand index, find the operand that 1190c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner // contains it. 1191c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner for (unsigned i = 0, e = Operands.size(); i != e; ++i) { 1192c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner if (Operands[i].MIOperandNo == unsigned(OITied)) { 1193c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner OperandName = Operands[i].Name; 1194c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner break; 1195c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner } 1196c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner } 1197c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner } 1198c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner 1199c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner Op.SrcOpName = OperandName; 1200c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner} 1201c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner 12023f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner/// BuildAliasOperandReference - When parsing an operand reference out of the 12033f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner/// matching string (e.g. "movsx $src, $dst"), determine what the class of the 12043f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner/// operand reference is by looking it up in the result pattern definition. 1205c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattnervoid AsmMatcherInfo::BuildAliasOperandReference(MatchableInfo *II, 1206c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner StringRef OperandName, 1207c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner MatchableInfo::AsmOperand &Op) { 1208c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner const CodeGenInstAlias &CGA = *II->DefRec.get<const CodeGenInstAlias*>(); 12095bde7345980587284bda6d42a68cdb151fbf5d6bChris Lattner 1210c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner // Set up the operand class. 12113f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner for (unsigned i = 0, e = CGA.ResultOperands.size(); i != e; ++i) 121298c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner if (CGA.ResultOperands[i].isRecord() && 121398c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner CGA.ResultOperands[i].getName() == OperandName) { 1214662e5a30e864e71111b885d3da3cdd184772035dChris Lattner // It's safe to go with the first one we find, because CodeGenInstAlias 1215662e5a30e864e71111b885d3da3cdd184772035dChris Lattner // validates that all operands with the same name have the same record. 12165e8f2a65ca2044815039129610876dfc4de3ebfaBob Wilson unsigned ResultIdx = CGA.ResultInstOperandIndex[i]; 12175bde7345980587284bda6d42a68cdb151fbf5d6bChris Lattner Op.Class = getOperandClass(CGA.ResultInst->Operands[ResultIdx]); 12183f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner Op.SrcOpName = OperandName; 12193f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner return; 12200bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner } 12213f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner 12223f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner throw TGError(II->TheDef->getLoc(), "error: unable to find operand: '" + 12233f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner OperandName.str() + "'"); 12240bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner} 12250bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner 1226414098571b19fc248fda2be194082cfd012d2729Chris Lattnervoid MatchableInfo::BuildInstructionResultOperands() { 1227662e5a30e864e71111b885d3da3cdd184772035dChris Lattner const CodeGenInstruction *ResultInst = getResultInst(); 1228662e5a30e864e71111b885d3da3cdd184772035dChris Lattner 1229662e5a30e864e71111b885d3da3cdd184772035dChris Lattner // Loop over all operands of the result instruction, determining how to 1230662e5a30e864e71111b885d3da3cdd184772035dChris Lattner // populate them. 1231662e5a30e864e71111b885d3da3cdd184772035dChris Lattner for (unsigned i = 0, e = ResultInst->Operands.size(); i != e; ++i) { 1232662e5a30e864e71111b885d3da3cdd184772035dChris Lattner const CGIOperandList::OperandInfo &OpInfo = ResultInst->Operands[i]; 1233567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner 1234567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner // If this is a tied operand, just copy from the previously handled operand. 1235567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner int TiedOp = OpInfo.getTiedRegister(); 1236567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner if (TiedOp != -1) { 1237567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner ResOperands.push_back(ResOperand::getTiedOp(TiedOp, &OpInfo)); 1238567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner continue; 1239567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner } 12401d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner 12411d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner // Find out what operand from the asmparser that this MCInst operand comes 12421d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner // from. 1243ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner int SrcOperand = FindAsmOperandNamed(OpInfo.Name); 1244567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner 1245567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner if (!OpInfo.Name.empty() && SrcOperand != -1) { 12461d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner ResOperands.push_back(ResOperand::getRenderedOp(SrcOperand, &OpInfo)); 12471d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner continue; 12481d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner } 12491d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner 1250567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner throw TGError(TheDef->getLoc(), "Instruction '" + 1251567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner TheDef->getName() + "' has operand '" + OpInfo.Name + 1252567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner "' that doesn't appear in asm string!"); 12531d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner } 12541d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner} 12551d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner 1256414098571b19fc248fda2be194082cfd012d2729Chris Lattnervoid MatchableInfo::BuildAliasResultOperands() { 1257414098571b19fc248fda2be194082cfd012d2729Chris Lattner const CodeGenInstAlias &CGA = *DefRec.get<const CodeGenInstAlias*>(); 1258414098571b19fc248fda2be194082cfd012d2729Chris Lattner const CodeGenInstruction *ResultInst = getResultInst(); 1259414098571b19fc248fda2be194082cfd012d2729Chris Lattner 1260414098571b19fc248fda2be194082cfd012d2729Chris Lattner // Loop over all operands of the result instruction, determining how to 1261414098571b19fc248fda2be194082cfd012d2729Chris Lattner // populate them. 1262414098571b19fc248fda2be194082cfd012d2729Chris Lattner unsigned AliasOpNo = 0; 1263414098571b19fc248fda2be194082cfd012d2729Chris Lattner for (unsigned i = 0, e = ResultInst->Operands.size(); i != e; ++i) { 1264414098571b19fc248fda2be194082cfd012d2729Chris Lattner const CGIOperandList::OperandInfo &OpInfo = ResultInst->Operands[i]; 1265414098571b19fc248fda2be194082cfd012d2729Chris Lattner 1266414098571b19fc248fda2be194082cfd012d2729Chris Lattner // If this is a tied operand, just copy from the previously handled operand. 1267414098571b19fc248fda2be194082cfd012d2729Chris Lattner int TiedOp = OpInfo.getTiedRegister(); 1268414098571b19fc248fda2be194082cfd012d2729Chris Lattner if (TiedOp != -1) { 1269414098571b19fc248fda2be194082cfd012d2729Chris Lattner ResOperands.push_back(ResOperand::getTiedOp(TiedOp, &OpInfo)); 1270414098571b19fc248fda2be194082cfd012d2729Chris Lattner continue; 1271414098571b19fc248fda2be194082cfd012d2729Chris Lattner } 1272414098571b19fc248fda2be194082cfd012d2729Chris Lattner 1273414098571b19fc248fda2be194082cfd012d2729Chris Lattner // Find out what operand from the asmparser that this MCInst operand comes 1274414098571b19fc248fda2be194082cfd012d2729Chris Lattner // from. 127590fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner switch (CGA.ResultOperands[AliasOpNo].Kind) { 127690fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner case CodeGenInstAlias::ResultOperand::K_Record: { 127798c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner StringRef Name = CGA.ResultOperands[AliasOpNo++].getName(); 127898c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner int SrcOperand = FindAsmOperandNamed(Name); 127998c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner if (SrcOperand != -1) { 128098c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner ResOperands.push_back(ResOperand::getRenderedOp(SrcOperand, &OpInfo)); 128198c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner continue; 128298c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner } 128398c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner 128498c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner throw TGError(TheDef->getLoc(), "Instruction '" + 128598c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner TheDef->getName() + "' has operand '" + OpInfo.Name + 128698c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner "' that doesn't appear in asm string!"); 1287414098571b19fc248fda2be194082cfd012d2729Chris Lattner } 128890fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner case CodeGenInstAlias::ResultOperand::K_Imm: { 128990fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner int64_t ImmVal = CGA.ResultOperands[AliasOpNo++].getImm(); 129090fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner ResOperands.push_back(ResOperand::getImmOp(ImmVal, &OpInfo)); 129190fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner continue; 129290fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner } 129390fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner 129490fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner case CodeGenInstAlias::ResultOperand::K_Reg: { 129590fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner Record *Reg = CGA.ResultOperands[AliasOpNo++].getRegister(); 129690fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner ResOperands.push_back(ResOperand::getRegOp(Reg, &OpInfo)); 129790fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner continue; 129890fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner } 129990fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner } 1300414098571b19fc248fda2be194082cfd012d2729Chris Lattner } 1301414098571b19fc248fda2be194082cfd012d2729Chris Lattner} 13021d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner 1303606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbarstatic void EmitConvertToMCInst(CodeGenTarget &Target, 130422bc5c4184a497353e33195dd12541a4f08b008aChris Lattner std::vector<MatchableInfo*> &Infos, 1305606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar raw_ostream &OS) { 1306b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar // Write the convert function to a separate stream, so we can drop it after 1307b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar // the enum. 1308b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar std::string ConvertFnBody; 1309b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar raw_string_ostream CvtOS(ConvertFnBody); 1310b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 131120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // Function we have already generated. 131220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar std::set<std::string> GeneratedFns; 131320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 1314b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar // Start the unified conversion function. 13158cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar CvtOS << "static void ConvertToMCInst(ConversionKind Kind, MCInst &Inst, " 1316b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar << "unsigned Opcode,\n" 13179898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner << " const SmallVectorImpl<MCParsedAsmOperand*" 13189898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner << "> &Operands) {\n"; 1319b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar CvtOS << " Inst.setOpcode(Opcode);\n"; 1320b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar CvtOS << " switch (Kind) {\n"; 1321b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar CvtOS << " default:\n"; 1322b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 1323b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar // Start the enum, which we will generate inline. 1324b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 1325d51257a4368d52e2340073bc7ccd83f3c3f1c04dChris Lattner OS << "// Unified function for converting operands to MCInst instances.\n\n"; 1326b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar OS << "enum ConversionKind {\n"; 1327a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 13289898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner // TargetOperandClass - This is the target's operand class, like X86Operand. 13299898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner std::string TargetOperandClass = Target.getName() + "Operand"; 1330a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 133122bc5c4184a497353e33195dd12541a4f08b008aChris Lattner for (std::vector<MatchableInfo*>::const_iterator it = Infos.begin(), 133220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar ie = Infos.end(); it != ie; ++it) { 133322bc5c4184a497353e33195dd12541a4f08b008aChris Lattner MatchableInfo &II = **it; 133420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 133520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // Build the conversion function signature. 133620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar std::string Signature = "Convert"; 1337dda855de8b3c60bce5d1d0d9eb11470c9710e30fChris Lattner std::string CaseBody; 1338dda855de8b3c60bce5d1d0d9eb11470c9710e30fChris Lattner raw_string_ostream CaseOS(CaseBody); 1339dda855de8b3c60bce5d1d0d9eb11470c9710e30fChris Lattner 1340dda855de8b3c60bce5d1d0d9eb11470c9710e30fChris Lattner // Compute the convert enum and the case body. 13411d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner for (unsigned i = 0, e = II.ResOperands.size(); i != e; ++i) { 13421d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner const MatchableInfo::ResOperand &OpInfo = II.ResOperands[i]; 13431d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner 13441d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner // Generate code to populate each result operand. 13451d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner switch (OpInfo.Kind) { 13461d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner case MatchableInfo::ResOperand::RenderAsmOperand: { 13471d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner // This comes from something we parsed. 13481d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner MatchableInfo::AsmOperand &Op = II.AsmOperands[OpInfo.AsmOperandNum]; 1349dda855de8b3c60bce5d1d0d9eb11470c9710e30fChris Lattner 13509b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner // Registers are always converted the same, don't duplicate the 13519b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner // conversion function based on them. 13529b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner Signature += "__"; 13539b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner if (Op.Class->isRegisterClass()) 13549b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner Signature += "Reg"; 13559b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner else 13569b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner Signature += Op.Class->ClassName; 13570bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner Signature += utostr(OpInfo.OpInfo->MINumOperands); 13581d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner Signature += "_" + itostr(OpInfo.AsmOperandNum); 13599b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner 13609b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner CaseOS << " ((" << TargetOperandClass << "*)Operands[" 13611d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner << (OpInfo.AsmOperandNum+1) << "])->" << Op.Class->RenderMethod 13620bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner << "(Inst, " << OpInfo.OpInfo->MINumOperands << ");\n"; 13631d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner break; 13641d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner } 13651d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner 13661d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner case MatchableInfo::ResOperand::TiedOperand: { 13671d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner // If this operand is tied to a previous one, just copy the MCInst 13681d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner // operand from the earlier one.We can only tie single MCOperand values. 13691d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner //assert(OpInfo.OpInfo->MINumOperands == 1 && "Not a singular MCOperand"); 13701d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner unsigned TiedOp = OpInfo.TiedOperandNum; 13711d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner assert(i > TiedOp && "Tied operand preceeds its target!"); 13721d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner CaseOS << " Inst.addOperand(Inst.getOperand(" << TiedOp << "));\n"; 13731d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner Signature += "__Tie" + utostr(TiedOp); 13741d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner break; 13751d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner } 137698c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner case MatchableInfo::ResOperand::ImmOperand: { 137798c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner int64_t Val = OpInfo.ImmVal; 137898c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner CaseOS << " Inst.addOperand(MCOperand::CreateImm(" << Val << "));\n"; 137998c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner Signature += "__imm" + itostr(Val); 138098c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner break; 138198c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner } 138290fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner case MatchableInfo::ResOperand::RegOperand: { 1383dc1a2bd3aa199693413f39dd723cc14a77e9f131Bob Wilson if (OpInfo.Register == 0) { 1384dc1a2bd3aa199693413f39dd723cc14a77e9f131Bob Wilson CaseOS << " Inst.addOperand(MCOperand::CreateReg(0));\n"; 1385dc1a2bd3aa199693413f39dd723cc14a77e9f131Bob Wilson Signature += "__reg0"; 1386dc1a2bd3aa199693413f39dd723cc14a77e9f131Bob Wilson } else { 1387dc1a2bd3aa199693413f39dd723cc14a77e9f131Bob Wilson std::string N = getQualifiedName(OpInfo.Register); 1388dc1a2bd3aa199693413f39dd723cc14a77e9f131Bob Wilson CaseOS << " Inst.addOperand(MCOperand::CreateReg(" << N << "));\n"; 1389dc1a2bd3aa199693413f39dd723cc14a77e9f131Bob Wilson Signature += "__reg" + OpInfo.Register->getName(); 1390dc1a2bd3aa199693413f39dd723cc14a77e9f131Bob Wilson } 139190fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner } 1392af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar } 13939b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner } 13949b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner 1395b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar II.ConversionFnKind = Signature; 1396a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 1397b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar // Check if we have already generated this signature. 139820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (!GeneratedFns.insert(Signature).second) 139920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar continue; 1400a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 1401dda855de8b3c60bce5d1d0d9eb11470c9710e30fChris Lattner // If not, emit it now. Add to the enum list. 1402b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar OS << " " << Signature << ",\n"; 1403b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 1404b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar CvtOS << " case " << Signature << ":\n"; 1405dda855de8b3c60bce5d1d0d9eb11470c9710e30fChris Lattner CvtOS << CaseOS.str(); 14068cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar CvtOS << " return;\n"; 1407a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar } 1408b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 1409b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar // Finish the convert function. 1410b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 1411b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar CvtOS << " }\n"; 1412b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar CvtOS << "}\n\n"; 1413b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 1414b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar // Finish the enum, and drop the convert function after it. 1415b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 1416b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar OS << " NumConversionVariants\n"; 1417b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar OS << "};\n\n"; 1418a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 1419b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar OS << CvtOS.str(); 142020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar} 142120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 1422a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar/// EmitMatchClassEnumeration - Emit the enumeration for match class kinds. 1423a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarstatic void EmitMatchClassEnumeration(CodeGenTarget &Target, 1424a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::vector<ClassInfo*> &Infos, 1425a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar raw_ostream &OS) { 1426a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "namespace {\n\n"; 1427a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1428a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "/// MatchClassKind - The kinds of classes which participate in\n" 1429a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar << "/// instruction matching.\n"; 1430a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "enum MatchClassKind {\n"; 1431a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " InvalidMatchClass = 0,\n"; 1432a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach for (std::vector<ClassInfo*>::iterator it = Infos.begin(), 1433a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar ie = Infos.end(); it != ie; ++it) { 1434a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar ClassInfo &CI = **it; 1435a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " " << CI.Name << ", // "; 1436a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar if (CI.Kind == ClassInfo::Token) { 1437a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "'" << CI.ValueName << "'\n"; 1438ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } else if (CI.isRegisterClass()) { 1439a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar if (!CI.ValueName.empty()) 1440a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "register class '" << CI.ValueName << "'\n"; 1441a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar else 1442a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "derived register class\n"; 1443a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } else { 1444a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "user defined class '" << CI.ValueName << "'\n"; 1445a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 1446a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 1447a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " NumMatchClassKinds\n"; 1448a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "};\n\n"; 1449a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1450a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "}\n\n"; 1451a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar} 1452a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1453a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar/// EmitClassifyOperand - Emit the function to classify an operand. 145402bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattnerstatic void EmitClassifyOperand(AsmMatcherInfo &Info, 1455a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar raw_ostream &OS) { 14569898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner OS << "static MatchClassKind ClassifyOperand(MCParsedAsmOperand *GOp) {\n" 145702bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner << " " << Info.Target.getName() << "Operand &Operand = *(" 145802bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner << Info.Target.getName() << "Operand*)GOp;\n"; 1459ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 1460ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Classify tokens. 1461a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " if (Operand.isToken())\n"; 1462a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " return MatchTokenString(Operand.getToken());\n\n"; 1463ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 1464ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Classify registers. 1465ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // 1466ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // FIXME: Don't hardcode isReg, getReg. 1467ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " if (Operand.isReg()) {\n"; 1468ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " switch (Operand.getReg()) {\n"; 1469ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " default: return InvalidMatchClass;\n"; 1470a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach for (std::map<Record*, ClassInfo*>::iterator 1471ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar it = Info.RegisterClasses.begin(), ie = Info.RegisterClasses.end(); 1472ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar it != ie; ++it) 147302bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner OS << " case " << Info.Target.getName() << "::" 1474ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar << it->first->getName() << ": return " << it->second->Name << ";\n"; 1475ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " }\n"; 1476ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " }\n\n"; 1477ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 14786cd0b17ba7f7efae41966c4a36ee725523d38575Owen Anderson // Classify user defined operands. To do so, we need to perform a topological 14796cd0b17ba7f7efae41966c4a36ee725523d38575Owen Anderson // sort of the superclass relationship graph so that we always match the 14806cd0b17ba7f7efae41966c4a36ee725523d38575Owen Anderson // narrowest type first. 14816cd0b17ba7f7efae41966c4a36ee725523d38575Owen Anderson 14826cd0b17ba7f7efae41966c4a36ee725523d38575Owen Anderson // Collect the incoming edge counts for each class. 14836cd0b17ba7f7efae41966c4a36ee725523d38575Owen Anderson std::map<ClassInfo*, unsigned> IncomingEdges; 1484a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach for (std::vector<ClassInfo*>::iterator it = Info.Classes.begin(), 1485ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ie = Info.Classes.end(); it != ie; ++it) { 1486a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar ClassInfo &CI = **it; 1487a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1488ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (!CI.isUserClass()) 1489ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar continue; 14906cd0b17ba7f7efae41966c4a36ee725523d38575Owen Anderson 14916cd0b17ba7f7efae41966c4a36ee725523d38575Owen Anderson for (std::vector<ClassInfo*>::iterator SI = CI.SuperClasses.begin(), 14926cd0b17ba7f7efae41966c4a36ee725523d38575Owen Anderson SE = CI.SuperClasses.end(); SI != SE; ++SI) 14936cd0b17ba7f7efae41966c4a36ee725523d38575Owen Anderson ++IncomingEdges[*SI]; 14946cd0b17ba7f7efae41966c4a36ee725523d38575Owen Anderson } 14956cd0b17ba7f7efae41966c4a36ee725523d38575Owen Anderson 14966cd0b17ba7f7efae41966c4a36ee725523d38575Owen Anderson // Initialize a worklist of classes with no incoming edges. 14976cd0b17ba7f7efae41966c4a36ee725523d38575Owen Anderson std::vector<ClassInfo*> LeafClasses; 14986cd0b17ba7f7efae41966c4a36ee725523d38575Owen Anderson for (std::vector<ClassInfo*>::iterator it = Info.Classes.begin(), 14996cd0b17ba7f7efae41966c4a36ee725523d38575Owen Anderson ie = Info.Classes.end(); it != ie; ++it) { 15006cd0b17ba7f7efae41966c4a36ee725523d38575Owen Anderson if (!IncomingEdges[*it]) 15016cd0b17ba7f7efae41966c4a36ee725523d38575Owen Anderson LeafClasses.push_back(*it); 15026cd0b17ba7f7efae41966c4a36ee725523d38575Owen Anderson } 15036cd0b17ba7f7efae41966c4a36ee725523d38575Owen Anderson 15046cd0b17ba7f7efae41966c4a36ee725523d38575Owen Anderson // Iteratively pop the list, process that class, and update the incoming 15056cd0b17ba7f7efae41966c4a36ee725523d38575Owen Anderson // edge counts for its super classes. When a superclass reaches zero 15066cd0b17ba7f7efae41966c4a36ee725523d38575Owen Anderson // incoming edges, push it onto the worklist for processing. 15076cd0b17ba7f7efae41966c4a36ee725523d38575Owen Anderson while (!LeafClasses.empty()) { 15086cd0b17ba7f7efae41966c4a36ee725523d38575Owen Anderson ClassInfo &CI = *LeafClasses.back(); 15096cd0b17ba7f7efae41966c4a36ee725523d38575Owen Anderson LeafClasses.pop_back(); 15106cd0b17ba7f7efae41966c4a36ee725523d38575Owen Anderson 15116cd0b17ba7f7efae41966c4a36ee725523d38575Owen Anderson if (!CI.isUserClass()) 15126cd0b17ba7f7efae41966c4a36ee725523d38575Owen Anderson continue; 15136cd0b17ba7f7efae41966c4a36ee725523d38575Owen Anderson 1514ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " // '" << CI.ClassName << "' class"; 1515ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (!CI.SuperClasses.empty()) { 1516ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << ", subclass of "; 1517ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar for (unsigned i = 0, e = CI.SuperClasses.size(); i != e; ++i) { 1518ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (i) OS << ", "; 1519ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << "'" << CI.SuperClasses[i]->ClassName << "'"; 1520ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar assert(CI < *CI.SuperClasses[i] && "Invalid class relation!"); 15216cd0b17ba7f7efae41966c4a36ee725523d38575Owen Anderson 15226cd0b17ba7f7efae41966c4a36ee725523d38575Owen Anderson --IncomingEdges[CI.SuperClasses[i]]; 15236cd0b17ba7f7efae41966c4a36ee725523d38575Owen Anderson if (!IncomingEdges[CI.SuperClasses[i]]) 15246cd0b17ba7f7efae41966c4a36ee725523d38575Owen Anderson LeafClasses.push_back(CI.SuperClasses[i]); 15255fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar } 1526ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 1527ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << "\n"; 15285fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar 1529ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " if (Operand." << CI.PredicateMethod << "()) {\n"; 1530a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 1531ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Validate subclass relationships. 1532ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (!CI.SuperClasses.empty()) { 1533ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar for (unsigned i = 0, e = CI.SuperClasses.size(); i != e; ++i) 1534ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " assert(Operand." << CI.SuperClasses[i]->PredicateMethod 15355fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar << "() && \"Invalid class relationship!\");\n"; 1536a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 15376cd0b17ba7f7efae41966c4a36ee725523d38575Owen Anderson 1538ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " return " << CI.Name << ";\n"; 1539ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " }\n\n"; 1540a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 15416cd0b17ba7f7efae41966c4a36ee725523d38575Owen Anderson 1542a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " return InvalidMatchClass;\n"; 1543a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "}\n\n"; 1544a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar} 1545a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1546fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar/// EmitIsSubclass - Emit the subclass predicate function. 1547fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbarstatic void EmitIsSubclass(CodeGenTarget &Target, 1548fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar std::vector<ClassInfo*> &Infos, 1549fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar raw_ostream &OS) { 1550fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar OS << "/// IsSubclass - Compute whether \\arg A is a subclass of \\arg B.\n"; 1551fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar OS << "static bool IsSubclass(MatchClassKind A, MatchClassKind B) {\n"; 1552fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar OS << " if (A == B)\n"; 1553fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar OS << " return true;\n\n"; 1554fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar 1555fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar OS << " switch (A) {\n"; 1556fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar OS << " default:\n"; 1557fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar OS << " return false;\n"; 1558a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach for (std::vector<ClassInfo*>::iterator it = Infos.begin(), 1559fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar ie = Infos.end(); it != ie; ++it) { 1560fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar ClassInfo &A = **it; 1561fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar 1562fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar if (A.Kind != ClassInfo::Token) { 1563fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar std::vector<StringRef> SuperClasses; 1564a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach for (std::vector<ClassInfo*>::iterator it = Infos.begin(), 1565fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar ie = Infos.end(); it != ie; ++it) { 1566fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar ClassInfo &B = **it; 1567fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar 1568ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (&A != &B && A.isSubsetOf(B)) 1569fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar SuperClasses.push_back(B.Name); 1570fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar } 1571fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar 1572fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar if (SuperClasses.empty()) 1573fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar continue; 1574fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar 1575fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar OS << "\n case " << A.Name << ":\n"; 1576fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar 1577fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar if (SuperClasses.size() == 1) { 1578ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " return B == " << SuperClasses.back() << ";\n"; 1579fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar continue; 1580fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar } 1581fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar 1582ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " switch (B) {\n"; 1583ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " default: return false;\n"; 1584fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i) 1585ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " case " << SuperClasses[i] << ": return true;\n"; 1586ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " }\n"; 1587fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar } 1588fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar } 1589fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar OS << " }\n"; 1590fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar OS << "}\n\n"; 1591fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar} 1592fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar 159370add884e4967f511e2cbb35c61534186b9b418aChris Lattner 159470add884e4967f511e2cbb35c61534186b9b418aChris Lattner 1595245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar/// EmitMatchTokenString - Emit the function to match a token string to the 1596245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar/// appropriate match class value. 1597245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbarstatic void EmitMatchTokenString(CodeGenTarget &Target, 1598245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar std::vector<ClassInfo*> &Infos, 1599245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar raw_ostream &OS) { 1600245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar // Construct the match list. 16015845e5c62b42d025557765006515156691a6a8b1Chris Lattner std::vector<StringMatcher::StringPair> Matches; 1602a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach for (std::vector<ClassInfo*>::iterator it = Infos.begin(), 1603245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar ie = Infos.end(); it != ie; ++it) { 1604245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar ClassInfo &CI = **it; 1605245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar 1606245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar if (CI.Kind == ClassInfo::Token) 16075845e5c62b42d025557765006515156691a6a8b1Chris Lattner Matches.push_back(StringMatcher::StringPair(CI.ValueName, 16085845e5c62b42d025557765006515156691a6a8b1Chris Lattner "return " + CI.Name + ";")); 1609245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar } 1610245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar 1611b8d6e98e566724f58344d275a4bd675249bb713aChris Lattner OS << "static MatchClassKind MatchTokenString(StringRef Name) {\n"; 1612245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar 16135845e5c62b42d025557765006515156691a6a8b1Chris Lattner StringMatcher("Name", Matches, OS).Emit(); 1614245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar 1615245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar OS << " return InvalidMatchClass;\n"; 1616245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar OS << "}\n\n"; 1617245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar} 161870add884e4967f511e2cbb35c61534186b9b418aChris Lattner 16192234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar/// EmitMatchRegisterName - Emit the function to match a string to the target 16202234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar/// specific register enum. 16212234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbarstatic void EmitMatchRegisterName(CodeGenTarget &Target, Record *AsmParser, 16222234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar raw_ostream &OS) { 1623245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar // Construct the match list. 16245845e5c62b42d025557765006515156691a6a8b1Chris Lattner std::vector<StringMatcher::StringPair> Matches; 1625245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar for (unsigned i = 0, e = Target.getRegisters().size(); i != e; ++i) { 1626245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar const CodeGenRegister &Reg = Target.getRegisters()[i]; 162720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (Reg.TheDef->getValueAsString("AsmName").empty()) 162820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar continue; 162920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 16305845e5c62b42d025557765006515156691a6a8b1Chris Lattner Matches.push_back(StringMatcher::StringPair( 16315845e5c62b42d025557765006515156691a6a8b1Chris Lattner Reg.TheDef->getValueAsString("AsmName"), 16325845e5c62b42d025557765006515156691a6a8b1Chris Lattner "return " + utostr(i + 1) + ";")); 163320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 1634a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 1635b8d6e98e566724f58344d275a4bd675249bb713aChris Lattner OS << "static unsigned MatchRegisterName(StringRef Name) {\n"; 1636245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar 16375845e5c62b42d025557765006515156691a6a8b1Chris Lattner StringMatcher("Name", Matches, OS).Emit(); 1638a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 1639245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar OS << " return 0;\n"; 164020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar OS << "}\n\n"; 16412234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar} 16422234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar 164354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar/// EmitSubtargetFeatureFlagEnumeration - Emit the subtarget feature flag 164454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar/// definitions. 164502bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattnerstatic void EmitSubtargetFeatureFlagEnumeration(AsmMatcherInfo &Info, 164654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar raw_ostream &OS) { 164754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << "// Flags for subtarget features that participate in " 164854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar << "instruction matching.\n"; 164954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << "enum SubtargetFeatureFlag {\n"; 165054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar for (std::map<Record*, SubtargetFeatureInfo*>::const_iterator 165154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar it = Info.SubtargetFeatures.begin(), 165254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar ie = Info.SubtargetFeatures.end(); it != ie; ++it) { 165354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar SubtargetFeatureInfo &SFI = *it->second; 16540aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner OS << " " << SFI.getEnumName() << " = (1 << " << SFI.Index << "),\n"; 165554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar } 165654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << " Feature_None = 0\n"; 165754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << "};\n\n"; 165854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar} 165954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 166054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar/// EmitComputeAvailableFeatures - Emit the function to compute the list of 166154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar/// available features given a subtarget. 166202bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattnerstatic void EmitComputeAvailableFeatures(AsmMatcherInfo &Info, 166354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar raw_ostream &OS) { 166454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar std::string ClassName = 166554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar Info.AsmParser->getValueAsString("AsmParserClassName"); 166654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 166702bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner OS << "unsigned " << Info.Target.getName() << ClassName << "::\n" 166802bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner << "ComputeAvailableFeatures(const " << Info.Target.getName() 166954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar << "Subtarget *Subtarget) const {\n"; 167054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << " unsigned Features = 0;\n"; 167154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar for (std::map<Record*, SubtargetFeatureInfo*>::const_iterator 167254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar it = Info.SubtargetFeatures.begin(), 167354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar ie = Info.SubtargetFeatures.end(); it != ie; ++it) { 167454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar SubtargetFeatureInfo &SFI = *it->second; 167554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << " if (" << SFI.TheDef->getValueAsString("CondString") 167654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar << ")\n"; 16770aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner OS << " Features |= " << SFI.getEnumName() << ";\n"; 167854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar } 167954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << " return Features;\n"; 168054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << "}\n\n"; 168154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar} 168254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 16836fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattnerstatic std::string GetAliasRequiredFeatures(Record *R, 16846fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner const AsmMatcherInfo &Info) { 1685693173feefaa326fad0e386470846fb3199ba381Chris Lattner std::vector<Record*> ReqFeatures = R->getValueAsListOfDefs("Predicates"); 1686693173feefaa326fad0e386470846fb3199ba381Chris Lattner std::string Result; 1687693173feefaa326fad0e386470846fb3199ba381Chris Lattner unsigned NumFeatures = 0; 1688693173feefaa326fad0e386470846fb3199ba381Chris Lattner for (unsigned i = 0, e = ReqFeatures.size(); i != e; ++i) { 16894a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner SubtargetFeatureInfo *F = Info.getSubtargetFeature(ReqFeatures[i]); 1690693173feefaa326fad0e386470846fb3199ba381Chris Lattner 16914a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner if (F == 0) 16924a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner throw TGError(R->getLoc(), "Predicate '" + ReqFeatures[i]->getName() + 16934a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner "' is not marked as an AssemblerPredicate!"); 16944a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner 16954a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner if (NumFeatures) 16964a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner Result += '|'; 16974a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner 16984a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner Result += F->getEnumName(); 16994a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner ++NumFeatures; 1700693173feefaa326fad0e386470846fb3199ba381Chris Lattner } 1701693173feefaa326fad0e386470846fb3199ba381Chris Lattner 1702693173feefaa326fad0e386470846fb3199ba381Chris Lattner if (NumFeatures > 1) 1703693173feefaa326fad0e386470846fb3199ba381Chris Lattner Result = '(' + Result + ')'; 1704693173feefaa326fad0e386470846fb3199ba381Chris Lattner return Result; 1705693173feefaa326fad0e386470846fb3199ba381Chris Lattner} 1706693173feefaa326fad0e386470846fb3199ba381Chris Lattner 1707674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner/// EmitMnemonicAliases - If the target has any MnemonicAlias<> definitions, 17087fd4489de11bdf06f6c852d42abafea013b76f28Chris Lattner/// emit a function for them and return true, otherwise return false. 17090aed1e770149301af473ce05a83f73be01c06fe0Chris Lattnerstatic bool EmitMnemonicAliases(raw_ostream &OS, const AsmMatcherInfo &Info) { 1710674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner std::vector<Record*> Aliases = 171167db883487fca3472fdde51e931657e22d4d0495Chris Lattner Info.getRecords().getAllDerivedDefinitions("MnemonicAlias"); 17127fd4489de11bdf06f6c852d42abafea013b76f28Chris Lattner if (Aliases.empty()) return false; 1713674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner 17148cc0a6b788a17b3afc779e9da90f5203c8b78436Chris Lattner OS << "static void ApplyMnemonicAliases(StringRef &Mnemonic, " 17158cc0a6b788a17b3afc779e9da90f5203c8b78436Chris Lattner "unsigned Features) {\n"; 17168cc0a6b788a17b3afc779e9da90f5203c8b78436Chris Lattner 17174fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner // Keep track of all the aliases from a mnemonic. Use an std::map so that the 17184fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner // iteration order of the map is stable. 17194fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner std::map<std::string, std::vector<Record*> > AliasesFromMnemonic; 17204fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner 1721674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner for (unsigned i = 0, e = Aliases.size(); i != e; ++i) { 1722674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner Record *R = Aliases[i]; 17234fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner AliasesFromMnemonic[R->getValueAsString("FromMnemonic")].push_back(R); 17244fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner } 17254fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner 17264fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner // Process each alias a "from" mnemonic at a time, building the code executed 17274fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner // by the string remapper. 17284fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner std::vector<StringMatcher::StringPair> Cases; 17294fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner for (std::map<std::string, std::vector<Record*> >::iterator 17304fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner I = AliasesFromMnemonic.begin(), E = AliasesFromMnemonic.end(); 17314fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner I != E; ++I) { 17324fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner const std::vector<Record*> &ToVec = I->second; 1733693173feefaa326fad0e386470846fb3199ba381Chris Lattner 1734693173feefaa326fad0e386470846fb3199ba381Chris Lattner // Loop through each alias and emit code that handles each case. If there 1735693173feefaa326fad0e386470846fb3199ba381Chris Lattner // are two instructions without predicates, emit an error. If there is one, 1736693173feefaa326fad0e386470846fb3199ba381Chris Lattner // emit it last. 1737693173feefaa326fad0e386470846fb3199ba381Chris Lattner std::string MatchCode; 1738693173feefaa326fad0e386470846fb3199ba381Chris Lattner int AliasWithNoPredicate = -1; 17394fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner 1740693173feefaa326fad0e386470846fb3199ba381Chris Lattner for (unsigned i = 0, e = ToVec.size(); i != e; ++i) { 1741693173feefaa326fad0e386470846fb3199ba381Chris Lattner Record *R = ToVec[i]; 17426fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner std::string FeatureMask = GetAliasRequiredFeatures(R, Info); 1743693173feefaa326fad0e386470846fb3199ba381Chris Lattner 1744693173feefaa326fad0e386470846fb3199ba381Chris Lattner // If this unconditionally matches, remember it for later and diagnose 1745693173feefaa326fad0e386470846fb3199ba381Chris Lattner // duplicates. 1746693173feefaa326fad0e386470846fb3199ba381Chris Lattner if (FeatureMask.empty()) { 1747693173feefaa326fad0e386470846fb3199ba381Chris Lattner if (AliasWithNoPredicate != -1) { 1748693173feefaa326fad0e386470846fb3199ba381Chris Lattner // We can't have two aliases from the same mnemonic with no predicate. 1749693173feefaa326fad0e386470846fb3199ba381Chris Lattner PrintError(ToVec[AliasWithNoPredicate]->getLoc(), 1750693173feefaa326fad0e386470846fb3199ba381Chris Lattner "two MnemonicAliases with the same 'from' mnemonic!"); 17514164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner throw TGError(R->getLoc(), "this is the other MnemonicAlias."); 1752693173feefaa326fad0e386470846fb3199ba381Chris Lattner } 1753693173feefaa326fad0e386470846fb3199ba381Chris Lattner 1754693173feefaa326fad0e386470846fb3199ba381Chris Lattner AliasWithNoPredicate = i; 1755693173feefaa326fad0e386470846fb3199ba381Chris Lattner continue; 1756693173feefaa326fad0e386470846fb3199ba381Chris Lattner } 1757693173feefaa326fad0e386470846fb3199ba381Chris Lattner 17588cf8bcc40c977713e51fb85fb9f24a0ecfbde24bChris Lattner if (!MatchCode.empty()) 17598cf8bcc40c977713e51fb85fb9f24a0ecfbde24bChris Lattner MatchCode += "else "; 1760693173feefaa326fad0e386470846fb3199ba381Chris Lattner MatchCode += "if ((Features & " + FeatureMask + ") == "+FeatureMask+")\n"; 1761693173feefaa326fad0e386470846fb3199ba381Chris Lattner MatchCode += " Mnemonic = \"" +R->getValueAsString("ToMnemonic")+"\";\n"; 1762693173feefaa326fad0e386470846fb3199ba381Chris Lattner } 1763693173feefaa326fad0e386470846fb3199ba381Chris Lattner 1764693173feefaa326fad0e386470846fb3199ba381Chris Lattner if (AliasWithNoPredicate != -1) { 1765693173feefaa326fad0e386470846fb3199ba381Chris Lattner Record *R = ToVec[AliasWithNoPredicate]; 17668cf8bcc40c977713e51fb85fb9f24a0ecfbde24bChris Lattner if (!MatchCode.empty()) 17678cf8bcc40c977713e51fb85fb9f24a0ecfbde24bChris Lattner MatchCode += "else\n "; 17688cf8bcc40c977713e51fb85fb9f24a0ecfbde24bChris Lattner MatchCode += "Mnemonic = \"" + R->getValueAsString("ToMnemonic")+"\";\n"; 17694fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner } 17704fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner 1771693173feefaa326fad0e386470846fb3199ba381Chris Lattner MatchCode += "return;"; 1772693173feefaa326fad0e386470846fb3199ba381Chris Lattner 1773693173feefaa326fad0e386470846fb3199ba381Chris Lattner Cases.push_back(std::make_pair(I->first, MatchCode)); 1774674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner } 1775674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner 17764fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner 1777674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner StringMatcher("Mnemonic", Cases, OS).Emit(); 177855b5e85643b189636758188f11b598c45178407fDaniel Dunbar OS << "}\n\n"; 17797fd4489de11bdf06f6c852d42abafea013b76f28Chris Lattner 17807fd4489de11bdf06f6c852d42abafea013b76f28Chris Lattner return true; 1781674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner} 1782674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner 17832234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbarvoid AsmMatcherEmitter::run(raw_ostream &OS) { 178467db883487fca3472fdde51e931657e22d4d0495Chris Lattner CodeGenTarget Target(Records); 17852234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar Record *AsmParser = Target.getAsmParser(); 17862234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar std::string ClassName = AsmParser->getValueAsString("AsmParserClassName"); 17872234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar 1788a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // Compute the information on the instructions to match. 178967db883487fca3472fdde51e931657e22d4d0495Chris Lattner AsmMatcherInfo Info(AsmParser, Target, Records); 179002bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner Info.BuildInfo(); 179120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 1792e1f6de3fbd892ea3f918a26912660cf316866fc1Daniel Dunbar // Sort the instruction table using the partial order on classes. We use 1793e1f6de3fbd892ea3f918a26912660cf316866fc1Daniel Dunbar // stable_sort to ensure that ambiguous instructions are still 1794e1f6de3fbd892ea3f918a26912660cf316866fc1Daniel Dunbar // deterministically ordered. 179522bc5c4184a497353e33195dd12541a4f08b008aChris Lattner std::stable_sort(Info.Matchables.begin(), Info.Matchables.end(), 179622bc5c4184a497353e33195dd12541a4f08b008aChris Lattner less_ptr<MatchableInfo>()); 1797a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 1798b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar DEBUG_WITH_TYPE("instruction_info", { 179922bc5c4184a497353e33195dd12541a4f08b008aChris Lattner for (std::vector<MatchableInfo*>::iterator 180022bc5c4184a497353e33195dd12541a4f08b008aChris Lattner it = Info.Matchables.begin(), ie = Info.Matchables.end(); 1801a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar it != ie; ++it) 180220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar (*it)->dump(); 180320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar }); 180420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 180522bc5c4184a497353e33195dd12541a4f08b008aChris Lattner // Check for ambiguous matchables. 1806fa0d74d58e6c70ef032afb5f83680276dc4d7370Chris Lattner DEBUG_WITH_TYPE("ambiguous_instrs", { 1807fa0d74d58e6c70ef032afb5f83680276dc4d7370Chris Lattner unsigned NumAmbiguous = 0; 180822bc5c4184a497353e33195dd12541a4f08b008aChris Lattner for (unsigned i = 0, e = Info.Matchables.size(); i != e; ++i) { 180987410368e1bd50408e787f6ece0e58d94c53c1e1Chris Lattner for (unsigned j = i + 1; j != e; ++j) { 181022bc5c4184a497353e33195dd12541a4f08b008aChris Lattner MatchableInfo &A = *Info.Matchables[i]; 181122bc5c4184a497353e33195dd12541a4f08b008aChris Lattner MatchableInfo &B = *Info.Matchables[j]; 1812a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 181387410368e1bd50408e787f6ece0e58d94c53c1e1Chris Lattner if (A.CouldMatchAmiguouslyWith(B)) { 181422bc5c4184a497353e33195dd12541a4f08b008aChris Lattner errs() << "warning: ambiguous matchables:\n"; 1815fa0d74d58e6c70ef032afb5f83680276dc4d7370Chris Lattner A.dump(); 1816fa0d74d58e6c70ef032afb5f83680276dc4d7370Chris Lattner errs() << "\nis incomparable with:\n"; 1817fa0d74d58e6c70ef032afb5f83680276dc4d7370Chris Lattner B.dump(); 1818fa0d74d58e6c70ef032afb5f83680276dc4d7370Chris Lattner errs() << "\n\n"; 181987410368e1bd50408e787f6ece0e58d94c53c1e1Chris Lattner ++NumAmbiguous; 182087410368e1bd50408e787f6ece0e58d94c53c1e1Chris Lattner } 18212b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar } 1822606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar } 182387410368e1bd50408e787f6ece0e58d94c53c1e1Chris Lattner if (NumAmbiguous) 1824a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach errs() << "warning: " << NumAmbiguous 182522bc5c4184a497353e33195dd12541a4f08b008aChris Lattner << " ambiguous matchables!\n"; 1826fa0d74d58e6c70ef032afb5f83680276dc4d7370Chris Lattner }); 1827606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 18281095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar // Write the output. 18291095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 18301095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar EmitSourceFileHeader("Assembly Matcher Source Fragment", OS); 18311095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 18320692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner // Information for the class declaration. 18330692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner OS << "\n#ifdef GET_ASSEMBLER_HEADER\n"; 18340692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner OS << "#undef GET_ASSEMBLER_HEADER\n"; 183579ed3f77e8b87615b80054ca6e4e3ba5e07445bdChris Lattner OS << " // This should be included into the middle of the declaration of \n"; 183679ed3f77e8b87615b80054ca6e4e3ba5e07445bdChris Lattner OS << " // your subclasses implementation of TargetAsmParser.\n"; 18370692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner OS << " unsigned ComputeAvailableFeatures(const " << 18380692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner Target.getName() << "Subtarget *Subtarget) const;\n"; 183979ed3f77e8b87615b80054ca6e4e3ba5e07445bdChris Lattner OS << " enum MatchResultTy {\n"; 1840a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner OS << " Match_Success, Match_MnemonicFail, Match_InvalidOperand,\n"; 1841a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner OS << " Match_MissingFeature\n"; 184279ed3f77e8b87615b80054ca6e4e3ba5e07445bdChris Lattner OS << " };\n"; 1843083203dde8bd50e1be47ac6509ae52f43abcd12aDaniel Dunbar OS << " MatchResultTy MatchInstructionImpl(\n"; 1844083203dde8bd50e1be47ac6509ae52f43abcd12aDaniel Dunbar OS << " const SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n"; 1845083203dde8bd50e1be47ac6509ae52f43abcd12aDaniel Dunbar OS << " MCInst &Inst, unsigned &ErrorInfo);\n\n"; 18460692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner OS << "#endif // GET_ASSEMBLER_HEADER_INFO\n\n"; 18470692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner 18480692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner OS << "\n#ifdef GET_REGISTER_MATCHER\n"; 18490692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner OS << "#undef GET_REGISTER_MATCHER\n\n"; 18500692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner 185154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar // Emit the subtarget feature enumeration. 185202bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner EmitSubtargetFeatureFlagEnumeration(Info, OS); 185354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 18541095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar // Emit the function to match a register name to number. 18551095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar EmitMatchRegisterName(Target, AsmParser, OS); 18560692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner 18570692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner OS << "#endif // GET_REGISTER_MATCHER\n\n"; 1858a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 18590692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner 18600692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner OS << "\n#ifdef GET_MATCHER_IMPLEMENTATION\n"; 18610692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner OS << "#undef GET_MATCHER_IMPLEMENTATION\n\n"; 18621095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 18637fd4489de11bdf06f6c852d42abafea013b76f28Chris Lattner // Generate the function that remaps for mnemonic aliases. 18640aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner bool HasMnemonicAliases = EmitMnemonicAliases(OS, Info); 18657fd4489de11bdf06f6c852d42abafea013b76f28Chris Lattner 1866606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar // Generate the unified function to convert operands into an MCInst. 186722bc5c4184a497353e33195dd12541a4f08b008aChris Lattner EmitConvertToMCInst(Target, Info.Matchables, OS); 1868a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1869a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // Emit the enumeration for classes which participate in matching. 1870a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar EmitMatchClassEnumeration(Target, Info.Classes, OS); 187120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 1872a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // Emit the routine to match token strings to their match class. 1873a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar EmitMatchTokenString(Target, Info.Classes, OS); 187420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 1875a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // Emit the routine to classify an operand. 187602bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner EmitClassifyOperand(Info, OS); 1877a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1878fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar // Emit the subclass predicate routine. 1879fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar EmitIsSubclass(Target, Info.Classes, OS); 1880fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar 188154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar // Emit the available features compute function. 188202bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner EmitComputeAvailableFeatures(Info, OS); 188354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 1884a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1885a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar size_t MaxNumOperands = 0; 188622bc5c4184a497353e33195dd12541a4f08b008aChris Lattner for (std::vector<MatchableInfo*>::const_iterator it = 188722bc5c4184a497353e33195dd12541a4f08b008aChris Lattner Info.Matchables.begin(), ie = Info.Matchables.end(); 1888a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar it != ie; ++it) 18893116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner MaxNumOperands = std::max(MaxNumOperands, (*it)->AsmOperands.size()); 1890a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 1891a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 1892a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // Emit the static match table; unused classes get initalized to 0 which is 1893a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // guaranteed to be InvalidMatchClass. 1894a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // 1895a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // FIXME: We can reduce the size of this table very easily. First, we change 1896a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // it so that store the kinds in separate bit-fields for each index, which 1897a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // only needs to be the max width used for classes at that index (we also need 1898a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // to reject based on this during classification). If we then make sure to 1899a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // order the match kinds appropriately (putting mnemonics last), then we 1900a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // should only end up using a few bits for each class, especially the ones 1901a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // following the mnemonic. 190296352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner OS << "namespace {\n"; 190396352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner OS << " struct MatchEntry {\n"; 1904a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " unsigned Opcode;\n"; 1905e206fcf0e9c7e79c7f42ff2151f3fb58cba70674Chris Lattner OS << " const char *Mnemonic;\n"; 1906a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " ConversionKind ConvertFn;\n"; 1907a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " MatchClassKind Classes[" << MaxNumOperands << "];\n"; 190854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << " unsigned RequiredFeatures;\n"; 19092b1f943444d1853204725c7b45b1e1032be39958Chris Lattner OS << " };\n\n"; 1910a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 19112b1f943444d1853204725c7b45b1e1032be39958Chris Lattner OS << "// Predicate for searching for an opcode.\n"; 19122b1f943444d1853204725c7b45b1e1032be39958Chris Lattner OS << " struct LessOpcode {\n"; 19132b1f943444d1853204725c7b45b1e1032be39958Chris Lattner OS << " bool operator()(const MatchEntry &LHS, StringRef RHS) {\n"; 19142b1f943444d1853204725c7b45b1e1032be39958Chris Lattner OS << " return StringRef(LHS.Mnemonic) < RHS;\n"; 19152b1f943444d1853204725c7b45b1e1032be39958Chris Lattner OS << " }\n"; 19162b1f943444d1853204725c7b45b1e1032be39958Chris Lattner OS << " bool operator()(StringRef LHS, const MatchEntry &RHS) {\n"; 19172b1f943444d1853204725c7b45b1e1032be39958Chris Lattner OS << " return LHS < StringRef(RHS.Mnemonic);\n"; 19182b1f943444d1853204725c7b45b1e1032be39958Chris Lattner OS << " }\n"; 191932c685cb67ff7701f4970ef61765cae7a50f255cChris Lattner OS << " bool operator()(const MatchEntry &LHS, const MatchEntry &RHS) {\n"; 192032c685cb67ff7701f4970ef61765cae7a50f255cChris Lattner OS << " return StringRef(LHS.Mnemonic) < StringRef(RHS.Mnemonic);\n"; 192132c685cb67ff7701f4970ef61765cae7a50f255cChris Lattner OS << " }\n"; 192296352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner OS << " };\n"; 1923a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 192496352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner OS << "} // end anonymous namespace.\n\n"; 1925a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 192696352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner OS << "static const MatchEntry MatchTable[" 192722bc5c4184a497353e33195dd12541a4f08b008aChris Lattner << Info.Matchables.size() << "] = {\n"; 1928a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 192922bc5c4184a497353e33195dd12541a4f08b008aChris Lattner for (std::vector<MatchableInfo*>::const_iterator it = 193022bc5c4184a497353e33195dd12541a4f08b008aChris Lattner Info.Matchables.begin(), ie = Info.Matchables.end(); 1931a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar it != ie; ++it) { 193222bc5c4184a497353e33195dd12541a4f08b008aChris Lattner MatchableInfo &II = **it; 1933a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 19349cdf42858960b9903587c39d5341cf63b3e665dbChris Lattner 1935662e5a30e864e71111b885d3da3cdd184772035dChris Lattner OS << " { " << Target.getName() << "::" 1936662e5a30e864e71111b885d3da3cdd184772035dChris Lattner << II.getResultInst()->TheDef->getName() << ", \"" << II.Mnemonic << "\"" 1937662e5a30e864e71111b885d3da3cdd184772035dChris Lattner << ", " << II.ConversionFnKind << ", { "; 19383116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner for (unsigned i = 0, e = II.AsmOperands.size(); i != e; ++i) { 1939c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner MatchableInfo::AsmOperand &Op = II.AsmOperands[i]; 1940a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 1941a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar if (i) OS << ", "; 1942a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << Op.Class->Name; 194320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 194454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << " }, "; 1945a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 194654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar // Write the required features mask. 194754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar if (!II.RequiredFeatures.empty()) { 194854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar for (unsigned i = 0, e = II.RequiredFeatures.size(); i != e; ++i) { 194954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar if (i) OS << "|"; 19500aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner OS << II.RequiredFeatures[i]->getEnumName(); 195154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar } 195254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar } else 195354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << "0"; 1954a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 195554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << "},\n"; 1956a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 1957a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 195896352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner OS << "};\n\n"; 1959a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 196096352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner // Finally, build the match function. 196196352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner OS << Target.getName() << ClassName << "::MatchResultTy " 196296352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner << Target.getName() << ClassName << "::\n" 196396352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner << "MatchInstructionImpl(const SmallVectorImpl<MCParsedAsmOperand*>" 196496352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner << " &Operands,\n"; 1965ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " MCInst &Inst, unsigned &ErrorInfo) {\n"; 196654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 196754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar // Emit code to get the available features. 196854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << " // Get the current feature set.\n"; 196954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << " unsigned AvailableFeatures = getAvailableFeatures();\n\n"; 197054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 1971674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner OS << " // Get the instruction mnemonic, which is the first token.\n"; 1972674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner OS << " StringRef Mnemonic = ((" << Target.getName() 1973674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner << "Operand*)Operands[0])->getToken();\n\n"; 1974674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner 19757fd4489de11bdf06f6c852d42abafea013b76f28Chris Lattner if (HasMnemonicAliases) { 19767fd4489de11bdf06f6c852d42abafea013b76f28Chris Lattner OS << " // Process all MnemonicAliases to remap the mnemonic.\n"; 19777fd4489de11bdf06f6c852d42abafea013b76f28Chris Lattner OS << " ApplyMnemonicAliases(Mnemonic, AvailableFeatures);\n\n"; 19787fd4489de11bdf06f6c852d42abafea013b76f28Chris Lattner } 1979674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner 1980a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // Emit code to compute the class list for this operand vector. 1981a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " // Eliminate obvious mismatches.\n"; 1982ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " if (Operands.size() > " << (MaxNumOperands+1) << ") {\n"; 1983ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " ErrorInfo = " << (MaxNumOperands+1) << ";\n"; 1984ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " return Match_InvalidOperand;\n"; 1985ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " }\n\n"; 1986a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1987a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " // Compute the class list for this operand vector.\n"; 1988a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " MatchClassKind Classes[" << MaxNumOperands << "];\n"; 1989e206fcf0e9c7e79c7f42ff2151f3fb58cba70674Chris Lattner OS << " for (unsigned i = 1, e = Operands.size(); i != e; ++i) {\n"; 1990e206fcf0e9c7e79c7f42ff2151f3fb58cba70674Chris Lattner OS << " Classes[i-1] = ClassifyOperand(Operands[i]);\n\n"; 1991a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1992a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " // Check for invalid operands before matching.\n"; 1993ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " if (Classes[i-1] == InvalidMatchClass) {\n"; 1994ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " ErrorInfo = i;\n"; 1995a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner OS << " return Match_InvalidOperand;\n"; 1996ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " }\n"; 1997a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " }\n\n"; 1998a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1999a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " // Mark unused classes.\n"; 2000e206fcf0e9c7e79c7f42ff2151f3fb58cba70674Chris Lattner OS << " for (unsigned i = Operands.size()-1, e = " << MaxNumOperands << "; " 2001a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar << "i != e; ++i)\n"; 2002a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " Classes[i] = InvalidMatchClass;\n\n"; 2003a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 20049bb9fa19a5e121b83866867ad1d8f7bf2618c1a0Chris Lattner OS << " // Some state to try to produce better error messages.\n"; 20052b1f943444d1853204725c7b45b1e1032be39958Chris Lattner OS << " bool HadMatchOtherThanFeatures = false;\n\n"; 20069bb9fa19a5e121b83866867ad1d8f7bf2618c1a0Chris Lattner OS << " // Set ErrorInfo to the operand that mismatches if it is \n"; 20079bb9fa19a5e121b83866867ad1d8f7bf2618c1a0Chris Lattner OS << " // wrong for all instances of the instruction.\n"; 20089bb9fa19a5e121b83866867ad1d8f7bf2618c1a0Chris Lattner OS << " ErrorInfo = ~0U;\n"; 20092b1f943444d1853204725c7b45b1e1032be39958Chris Lattner 2010a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // Emit code to search the table. 2011a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " // Search the table.\n"; 20122b1f943444d1853204725c7b45b1e1032be39958Chris Lattner OS << " std::pair<const MatchEntry*, const MatchEntry*> MnemonicRange =\n"; 20132b1f943444d1853204725c7b45b1e1032be39958Chris Lattner OS << " std::equal_range(MatchTable, MatchTable+" 201422bc5c4184a497353e33195dd12541a4f08b008aChris Lattner << Info.Matchables.size() << ", Mnemonic, LessOpcode());\n\n"; 2015a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 2016a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner OS << " // Return a more specific error code if no mnemonics match.\n"; 2017a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner OS << " if (MnemonicRange.first == MnemonicRange.second)\n"; 2018a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner OS << " return Match_MnemonicFail;\n\n"; 2019a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 20202b1f943444d1853204725c7b45b1e1032be39958Chris Lattner OS << " for (const MatchEntry *it = MnemonicRange.first, " 202180db4e51d2a44bc623b5892bed2351406890b9aaChris Lattner << "*ie = MnemonicRange.second;\n"; 20222b1f943444d1853204725c7b45b1e1032be39958Chris Lattner OS << " it != ie; ++it) {\n"; 202354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 2024e53ee3b112810068b8ca229aff211fc497069273Gabor Greif OS << " // equal_range guarantees that instruction mnemonic matches.\n"; 202544b0daad44791ff249a0bc533a5e58e978c2ca31Chris Lattner OS << " assert(Mnemonic == it->Mnemonic);\n"; 2026a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 202754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar // Emit check that the subclasses match. 2028ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " bool OperandsValid = true;\n"; 2029ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " for (unsigned i = 0; i != " << MaxNumOperands << "; ++i) {\n"; 2030ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " if (IsSubclass(Classes[i], it->Classes[i]))\n"; 2031ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " continue;\n"; 20329bb9fa19a5e121b83866867ad1d8f7bf2618c1a0Chris Lattner OS << " // If this operand is broken for all of the instances of this\n"; 20339bb9fa19a5e121b83866867ad1d8f7bf2618c1a0Chris Lattner OS << " // mnemonic, keep track of it so we can report loc info.\n"; 20349bb9fa19a5e121b83866867ad1d8f7bf2618c1a0Chris Lattner OS << " if (it == MnemonicRange.first || ErrorInfo == i+1)\n"; 2035ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " ErrorInfo = i+1;\n"; 20369bb9fa19a5e121b83866867ad1d8f7bf2618c1a0Chris Lattner OS << " else\n"; 20379bb9fa19a5e121b83866867ad1d8f7bf2618c1a0Chris Lattner OS << " ErrorInfo = ~0U;"; 2038ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " // Otherwise, just reject this instance of the mnemonic.\n"; 2039ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " OperandsValid = false;\n"; 2040ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " break;\n"; 2041ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " }\n\n"; 2042a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 2043ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " if (!OperandsValid) continue;\n"; 2044ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner 2045ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner // Emit check that the required features are available. 2046ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner OS << " if ((AvailableFeatures & it->RequiredFeatures) " 2047ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner << "!= it->RequiredFeatures) {\n"; 2048ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner OS << " HadMatchOtherThanFeatures = true;\n"; 2049ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner OS << " continue;\n"; 2050ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner OS << " }\n"; 2051a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 2052a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "\n"; 20538cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar OS << " ConvertToMCInst(it->ConvertFn, Inst, it->Opcode, Operands);\n"; 20548cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar 20558cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar // Call the post-processing function, if used. 20568cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar std::string InsnCleanupFn = 20578cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar AsmParser->getValueAsString("AsmParserInstCleanup"); 20588cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar if (!InsnCleanupFn.empty()) 20598cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar OS << " " << InsnCleanupFn << "(Inst);\n"; 20608cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar 206179ed3f77e8b87615b80054ca6e4e3ba5e07445bdChris Lattner OS << " return Match_Success;\n"; 2062a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " }\n\n"; 2063a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 2064ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner OS << " // Okay, we had no match. Try to return a useful error code.\n"; 2065ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner OS << " if (HadMatchOtherThanFeatures) return Match_MissingFeature;\n"; 2066a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner OS << " return Match_InvalidOperand;\n"; 2067a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar OS << "}\n\n"; 2068a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 20690692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner OS << "#endif // GET_MATCHER_IMPLEMENTATION\n\n"; 2070d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar} 2071