AsmMatcherEmitter.cpp revision ebdeeab812beec0385b445f3d4c41a114e0d972f
1d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar//===- AsmMatcherEmitter.cpp - Generate an assembly matcher ---------------===// 2d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar// 3d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar// The LLVM Compiler Infrastructure 4d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar// 5d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar// This file is distributed under the University of Illinois Open Source 6d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar// License. See LICENSE.TXT for details. 7d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar// 8d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar//===----------------------------------------------------------------------===// 9d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar// 10d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar// This tablegen backend emits a target specifier matcher for converting parsed 11e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// assembly operands in the MCInst structures. It also emits a matcher for 12e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// custom operand parsing. 13e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// 14e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// Converting assembly operands into MCInst structures 15e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// --------------------------------------------------- 16d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar// 1720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// The input to the target specific matcher is a list of literal tokens and 1820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// operands. The target specific parser should generally eliminate any syntax 1920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// which is not relevant for matching; for example, comma tokens should have 2020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// already been consumed and eliminated by the parser. Most instructions will 2120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// end up with a single literal token (the instruction name) and some number of 2220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// operands. 2320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 2420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// Some example inputs, for X86: 2520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 'addl' (immediate ...) (register ...) 2620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 'add' (immediate ...) (memory ...) 27a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach// 'call' '*' %epc 2820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 2920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// The assembly matcher is responsible for converting this input into a precise 3020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// machine instruction (i.e., an instruction with a well defined encoding). This 3120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// mapping has several properties which complicate matching: 3220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 3320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// - It may be ambiguous; many architectures can legally encode particular 3420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// variants of an instruction in different ways (for example, using a smaller 3520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// encoding for small immediates). Such ambiguities should never be 3620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// arbitrarily resolved by the assembler, the assembler is always responsible 3720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// for choosing the "best" available instruction. 3820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 3920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// - It may depend on the subtarget or the assembler context. Instructions 4020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// which are invalid for the current mode, but otherwise unambiguous (e.g., 4120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// an SSE instruction in a file being assembled for i486) should be accepted 4220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// and rejected by the assembler front end. However, if the proper encoding 4320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// for an instruction is dependent on the assembler context then the matcher 4420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// is responsible for selecting the correct machine instruction for the 4520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// current mode. 4620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 4720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// The core matching algorithm attempts to exploit the regularity in most 4820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// instruction sets to quickly determine the set of possibly matching 4920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// instructions, and the simplify the generated code. Additionally, this helps 5020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// to ensure that the ambiguities are intentionally resolved by the user. 5120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 5220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// The matching is divided into two distinct phases: 5320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 5420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 1. Classification: Each operand is mapped to the unique set which (a) 5520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// contains it, and (b) is the largest such subset for which a single 5620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// instruction could match all members. 5720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 5820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// For register classes, we can generate these subgroups automatically. For 5920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// arbitrary operands, we expect the user to define the classes and their 6020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// relations to one another (for example, 8-bit signed immediates as a 6120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// subset of 32-bit immediates). 6220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 6320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// By partitioning the operands in this way, we guarantee that for any 6420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// tuple of classes, any single instruction must match either all or none 6520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// of the sets of operands which could classify to that tuple. 6620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 6720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// In addition, the subset relation amongst classes induces a partial order 6820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// on such tuples, which we use to resolve ambiguities. 6920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 7020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 2. The input can now be treated as a tuple of classes (static tokens are 7120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// simple singleton sets). Each such tuple should generally map to a single 7220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// instruction (we currently ignore cases where this isn't true, whee!!!), 7320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// which we can emit a simple matcher for. 7420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 75e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// Custom Operand Parsing 76e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// ---------------------- 77e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// 78e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// Some targets need a custom way to parse operands, some specific instructions 79e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// can contain arguments that can represent processor flags and other kinds of 80e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// identifiers that need to be mapped to specific valeus in the final encoded 81e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// instructions. The target specific custom operand parsing works in the 82e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// following way: 83e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// 84e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// 1. A operand match table is built, each entry contains a mnemonic, an 85e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// operand class, a mask for all operand positions for that same 86e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// class/mnemonic and target features to be checked while trying to match. 87e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// 88e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// 2. The operand matcher will try every possible entry with the same 89e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// mnemonic and will check if the target feature for this mnemonic also 90e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// matches. After that, if the operand to be matched has its index 917a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner// present in the mask, a successful match occurs. Otherwise, fallback 92e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// to the regular operand parsing. 93e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// 94e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// 3. For a match success, each operand class that has a 'ParserMethod' 95e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// becomes part of a switch from where the custom method is called. 96e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// 97d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar//===----------------------------------------------------------------------===// 98d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar 99d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar#include "AsmMatcherEmitter.h" 100d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar#include "CodeGenTarget.h" 1010b6a44afb92fed0365b6709c1f46b0c5e49e1a72Jim Grosbach#include "Error.h" 102d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar#include "Record.h" 1035845e5c62b42d025557765006515156691a6a8b1Chris Lattner#include "StringMatcher.h" 10420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar#include "llvm/ADT/OwningPtr.h" 105c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner#include "llvm/ADT/PointerUnion.h" 1061de88235781c45c0afc0c7500d65b59775196c4cChris Lattner#include "llvm/ADT/SmallPtrSet.h" 107a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar#include "llvm/ADT/SmallVector.h" 108606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar#include "llvm/ADT/STLExtras.h" 10920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar#include "llvm/ADT/StringExtras.h" 11020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar#include "llvm/Support/CommandLine.h" 111a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar#include "llvm/Support/Debug.h" 112b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar#include <map> 113b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar#include <set> 114d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbarusing namespace llvm; 115d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar 1162724915c171b08fa9f7f9e54a46ea81708d9c5b2Daniel Dunbarstatic cl::opt<std::string> 117606e8ad796f72824f5509e2657c44eca025d4bafDaniel DunbarMatchPrefix("match-prefix", cl::init(""), 118606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar cl::desc("Only match instructions with the given prefix")); 11920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 12020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbarnamespace { 121828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilsonclass AsmMatcherInfo; 12254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbarstruct SubtargetFeatureInfo; 12354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 124a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar/// ClassInfo - Helper class for storing the information about a particular 125a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar/// class of operands which can be matched. 126a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarstruct ClassInfo { 127606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar enum ClassInfoKind { 128ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// Invalid kind, for use as a sentinel value. 129ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar Invalid = 0, 130ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 131ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// The class for a particular token. 132ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar Token, 133ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 134ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// The (first) register class, subsequent register classes are 135ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// RegisterClass0+1, and so on. 136ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar RegisterClass0, 137ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 138ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// The (first) user defined class, subsequent user defined classes are 139ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// UserClass0+1, and so on. 140ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar UserClass0 = 1<<16 141606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar }; 142606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 143606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar /// Kind - The class kind, which is either a predefined kind, or (UserClass0 + 144606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar /// N) for the Nth user defined class. 145606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar unsigned Kind; 146a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 147ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// SuperClasses - The super classes of this class. Note that for simplicities 148ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// sake user operands only record their immediate super class, while register 149ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// operands include all superclasses. 150ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar std::vector<ClassInfo*> SuperClasses; 1515fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar 1526745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar /// Name - The full class name, suitable for use in an enum. 153a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::string Name; 154a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1556745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar /// ClassName - The unadorned generic name for this class (e.g., Token). 1566745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar std::string ClassName; 1576745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar 158a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// ValueName - The name of the value this class represents; for a token this 159a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// is the literal token string, for an operand it is the TableGen class (or 160a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// empty if this is a derived class). 161a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::string ValueName; 162a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 163a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// PredicateMethod - The name of the operand method to test whether the 164ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// operand matches this class; this is not valid for Token or register kinds. 165a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::string PredicateMethod; 166a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 167a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// RenderMethod - The name of the operand method to add this operand to an 168ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// MCInst; this is not valid for Token or register kinds. 169a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::string RenderMethod; 170606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 171e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes /// ParserMethod - The name of the operand method to do a target specific 172e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes /// parsing on the operand. 173e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes std::string ParserMethod; 174e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 1758409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar /// For register classes, the records for all the registers in this class. 1768409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar std::set<Record*> Registers; 1778409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar 1788409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbarpublic: 179ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// isRegisterClass() - Check if this is a register class. 180ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar bool isRegisterClass() const { 181ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar return Kind >= RegisterClass0 && Kind < UserClass0; 182ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 183ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 1845fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar /// isUserClass() - Check if this is a user defined class. 1855fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar bool isUserClass() const { 1865fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar return Kind >= UserClass0; 1875fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar } 1885fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar 189ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// isRelatedTo - Check whether this class is "related" to \arg RHS. Classes 190ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// are related if they are in the same class hierarchy. 191ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar bool isRelatedTo(const ClassInfo &RHS) const { 192ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Tokens are only related to tokens. 193ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (Kind == Token || RHS.Kind == Token) 194ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar return Kind == Token && RHS.Kind == Token; 195ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 1968409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar // Registers classes are only related to registers classes, and only if 1978409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar // their intersection is non-empty. 1988409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar if (isRegisterClass() || RHS.isRegisterClass()) { 1998409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar if (!isRegisterClass() || !RHS.isRegisterClass()) 2008409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar return false; 2018409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar 2028409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar std::set<Record*> Tmp; 2038409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar std::insert_iterator< std::set<Record*> > II(Tmp, Tmp.begin()); 204a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach std::set_intersection(Registers.begin(), Registers.end(), 2058409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar RHS.Registers.begin(), RHS.Registers.end(), 2068409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar II); 2078409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar 2088409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar return !Tmp.empty(); 2098409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar } 210ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 211ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Otherwise we have two users operands; they are related if they are in the 212ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // same class hierarchy. 2138409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar // 2148409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar // FIXME: This is an oversimplification, they should only be related if they 2158409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar // intersect, however we don't have that information. 216ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar assert(isUserClass() && RHS.isUserClass() && "Unexpected class!"); 217ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar const ClassInfo *Root = this; 218ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar while (!Root->SuperClasses.empty()) 219ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar Root = Root->SuperClasses.front(); 220ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 2218409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar const ClassInfo *RHSRoot = &RHS; 222ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar while (!RHSRoot->SuperClasses.empty()) 223ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar RHSRoot = RHSRoot->SuperClasses.front(); 224a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 225ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar return Root == RHSRoot; 226ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 227ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 228a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach /// isSubsetOf - Test whether this class is a subset of \arg RHS; 229ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar bool isSubsetOf(const ClassInfo &RHS) const { 230ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // This is a subset of RHS if it is the same class... 231ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (this == &RHS) 232ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar return true; 233ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 234ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // ... or if any of its super classes are a subset of RHS. 235ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar for (std::vector<ClassInfo*>::const_iterator it = SuperClasses.begin(), 236ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ie = SuperClasses.end(); it != ie; ++it) 237ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if ((*it)->isSubsetOf(RHS)) 238ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar return true; 239ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 240ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar return false; 2415fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar } 2425fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar 243606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar /// operator< - Compare two classes. 244606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar bool operator<(const ClassInfo &RHS) const { 245368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar if (this == &RHS) 246368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar return false; 247368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar 248ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Unrelated classes can be ordered by kind. 249ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (!isRelatedTo(RHS)) 250606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar return Kind < RHS.Kind; 251606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 252606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar switch (Kind) { 2536745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar case Invalid: 2546745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar assert(0 && "Invalid kind!"); 255606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar case Token: 2565fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar // Tokens are comparable by value. 257606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar // 258606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar // FIXME: Compare by enum value. 259606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar return ValueName < RHS.ValueName; 260606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 261606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar default: 2627a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // This class precedes the RHS if it is a proper subset of the RHS. 263368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar if (isSubsetOf(RHS)) 2643472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands return true; 265368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar if (RHS.isSubsetOf(*this)) 2663472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands return false; 267368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar 268368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar // Otherwise, order by name to ensure we have a total ordering. 269368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar return ValueName < RHS.ValueName; 270606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar } 271606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar } 272a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar}; 273a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 27422bc5c4184a497353e33195dd12541a4f08b008aChris Lattner/// MatchableInfo - Helper class for storing the necessary information for an 27522bc5c4184a497353e33195dd12541a4f08b008aChris Lattner/// instruction or alias which is capable of being matched. 27622bc5c4184a497353e33195dd12541a4f08b008aChris Lattnerstruct MatchableInfo { 277c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner struct AsmOperand { 278d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner /// Token - This is the token that the operand came from. 279d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner StringRef Token; 280828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 281a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// The unique class instance this operand should match. 282a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar ClassInfo *Class; 283a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 284567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner /// The operand name this is, if anything. 285567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner StringRef SrcOpName; 286a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson 287a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson /// The suboperand index within SrcOpName, or -1 for the entire operand. 288a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson int SubOpIdx; 289828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 290a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson explicit AsmOperand(StringRef T) : Token(T), Class(0), SubOpIdx(-1) {} 29120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar }; 292828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 2931d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// ResOperand - This represents a single operand in the result instruction 2941d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// generated by the match. In cases (like addressing modes) where a single 2951d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// assembler operand expands to multiple MCOperands, this represents the 2961d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// single assembler operand, not the MCOperand. 2971d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner struct ResOperand { 2981d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner enum { 2991d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// RenderAsmOperand - This represents an operand result that is 3001d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// generated by calling the render method on the assembly operand. The 3011d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// corresponding AsmOperand is specified by AsmOperandNum. 3021d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner RenderAsmOperand, 303828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 3041d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// TiedOperand - This represents a result operand that is a duplicate of 3051d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// a previous result operand. 30698c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner TiedOperand, 307828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 30898c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner /// ImmOperand - This represents an immediate value that is dumped into 30998c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner /// the operand. 31090fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner ImmOperand, 311828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 31290fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner /// RegOperand - This represents a fixed register that is dumped in. 31390fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner RegOperand 3141d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner } Kind; 315828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 3161d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner union { 3171d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// This is the operand # in the AsmOperands list that this should be 3181d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// copied from. 3191d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner unsigned AsmOperandNum; 320828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 3211d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// TiedOperandNum - This is the (earlier) result operand that should be 3221d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// copied from. 3231d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner unsigned TiedOperandNum; 324828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 32598c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner /// ImmVal - This is the immediate value added to the instruction. 32698c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner int64_t ImmVal; 327828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 32890fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner /// Register - This is the register record. 32990fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner Record *Register; 3301d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner }; 331828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 332a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson /// MINumOperands - The number of MCInst operands populated by this 333a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson /// operand. 334a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson unsigned MINumOperands; 335828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 336a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson static ResOperand getRenderedOp(unsigned AsmOpNum, unsigned NumOperands) { 3371d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner ResOperand X; 3381d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner X.Kind = RenderAsmOperand; 3391d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner X.AsmOperandNum = AsmOpNum; 340a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson X.MINumOperands = NumOperands; 3411d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner return X; 3421d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner } 343828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 344a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson static ResOperand getTiedOp(unsigned TiedOperandNum) { 3451d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner ResOperand X; 3461d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner X.Kind = TiedOperand; 3471d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner X.TiedOperandNum = TiedOperandNum; 348a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson X.MINumOperands = 1; 3491d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner return X; 3501d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner } 351828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 352a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson static ResOperand getImmOp(int64_t Val) { 35398c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner ResOperand X; 35498c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner X.Kind = ImmOperand; 35598c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner X.ImmVal = Val; 356a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson X.MINumOperands = 1; 35798c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner return X; 35898c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner } 359828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 360a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson static ResOperand getRegOp(Record *Reg) { 36190fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner ResOperand X; 36290fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner X.Kind = RegOperand; 36390fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner X.Register = Reg; 364a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson X.MINumOperands = 1; 36590fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner return X; 36690fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner } 3671d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner }; 36820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 3693b5aec67ef174c74ff6620ddd71ad3b0cb39030cChris Lattner /// TheDef - This is the definition of the instruction or InstAlias that this 3703b5aec67ef174c74ff6620ddd71ad3b0cb39030cChris Lattner /// matchable came from. 3715bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner Record *const TheDef; 372828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 373c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner /// DefRec - This is the definition that it came from. 374c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner PointerUnion<const CodeGenInstruction*, const CodeGenInstAlias*> DefRec; 375828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 376662e5a30e864e71111b885d3da3cdd184772035dChris Lattner const CodeGenInstruction *getResultInst() const { 377662e5a30e864e71111b885d3da3cdd184772035dChris Lattner if (DefRec.is<const CodeGenInstruction*>()) 378662e5a30e864e71111b885d3da3cdd184772035dChris Lattner return DefRec.get<const CodeGenInstruction*>(); 379662e5a30e864e71111b885d3da3cdd184772035dChris Lattner return DefRec.get<const CodeGenInstAlias*>()->ResultInst; 380662e5a30e864e71111b885d3da3cdd184772035dChris Lattner } 381828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 3821d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// ResOperands - This is the operand list that should be built for the result 3831d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// MCInst. 3841d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner std::vector<ResOperand> ResOperands; 38520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 38620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar /// AsmString - The assembly string for this instruction (with variants 3873b5aec67ef174c74ff6620ddd71ad3b0cb39030cChris Lattner /// removed), e.g. "movsx $src, $dst". 38820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar std::string AsmString; 38920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 390d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner /// Mnemonic - This is the first token of the matched instruction, its 391d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner /// mnemonic. 392d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner StringRef Mnemonic; 393828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 3943116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner /// AsmOperands - The textual operands that this instruction matches, 3953b5aec67ef174c74ff6620ddd71ad3b0cb39030cChris Lattner /// annotated with a class and where in the OperandList they were defined. 3963b5aec67ef174c74ff6620ddd71ad3b0cb39030cChris Lattner /// This directly corresponds to the tokenized AsmString after the mnemonic is 3973b5aec67ef174c74ff6620ddd71ad3b0cb39030cChris Lattner /// removed. 398c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner SmallVector<AsmOperand, 4> AsmOperands; 39920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 40054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar /// Predicates - The required subtarget features to match this instruction. 40154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar SmallVector<SubtargetFeatureInfo*, 4> RequiredFeatures; 40254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 403b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar /// ConversionFnKind - The enum value which is passed to the generated 404b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar /// ConvertToMCInst to convert parsed operands into an MCInst for this 405b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar /// function. 406b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar std::string ConversionFnKind; 407828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 40822bc5c4184a497353e33195dd12541a4f08b008aChris Lattner MatchableInfo(const CodeGenInstruction &CGI) 409662e5a30e864e71111b885d3da3cdd184772035dChris Lattner : TheDef(CGI.TheDef), DefRec(&CGI), AsmString(CGI.AsmString) { 4105bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner } 4115bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner 41222bc5c4184a497353e33195dd12541a4f08b008aChris Lattner MatchableInfo(const CodeGenInstAlias *Alias) 413662e5a30e864e71111b885d3da3cdd184772035dChris Lattner : TheDef(Alias->TheDef), DefRec(Alias), AsmString(Alias->AsmString) { 414c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner } 415828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 416c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner void Initialize(const AsmMatcherInfo &Info, 417c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner SmallPtrSet<Record*, 16> &SingletonRegisters); 418828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 41922bc5c4184a497353e33195dd12541a4f08b008aChris Lattner /// Validate - Return true if this matchable is a valid thing to match against 42022bc5c4184a497353e33195dd12541a4f08b008aChris Lattner /// and perform a bunch of validity checking. 42122bc5c4184a497353e33195dd12541a4f08b008aChris Lattner bool Validate(StringRef CommentDelimiter, bool Hack) const; 422828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 423d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner /// getSingletonRegisterForAsmOperand - If the specified token is a singleton 4241de88235781c45c0afc0c7500d65b59775196c4cChris Lattner /// register, return the Record for it, otherwise return null. 425d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner Record *getSingletonRegisterForAsmOperand(unsigned i, 426828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson const AsmMatcherInfo &Info) const; 42720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 428a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson /// FindAsmOperand - Find the AsmOperand with the specified name and 429a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson /// suboperand index. 430a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson int FindAsmOperand(StringRef N, int SubOpIdx) const { 431a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) 432a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson if (N == AsmOperands[i].SrcOpName && 433a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson SubOpIdx == AsmOperands[i].SubOpIdx) 434a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson return i; 435a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson return -1; 436a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson } 437828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 438a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson /// FindAsmOperandNamed - Find the first AsmOperand with the specified name. 439a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson /// This does not check the suboperand index. 440ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner int FindAsmOperandNamed(StringRef N) const { 441ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) 442ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner if (N == AsmOperands[i].SrcOpName) 443ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner return i; 444ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner return -1; 445ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner } 446828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 447414098571b19fc248fda2be194082cfd012d2729Chris Lattner void BuildInstructionResultOperands(); 448414098571b19fc248fda2be194082cfd012d2729Chris Lattner void BuildAliasResultOperands(); 4491d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner 45022bc5c4184a497353e33195dd12541a4f08b008aChris Lattner /// operator< - Compare two matchables. 45122bc5c4184a497353e33195dd12541a4f08b008aChris Lattner bool operator<(const MatchableInfo &RHS) const { 452e206fcf0e9c7e79c7f42ff2151f3fb58cba70674Chris Lattner // The primary comparator is the instruction mnemonic. 453d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner if (Mnemonic != RHS.Mnemonic) 454d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner return Mnemonic < RHS.Mnemonic; 455a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 4563116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner if (AsmOperands.size() != RHS.AsmOperands.size()) 4573116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner return AsmOperands.size() < RHS.AsmOperands.size(); 4582b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar 459db2ddb5dc57319eff249144f1d9a553a3278d2e0Daniel Dunbar // Compare lexicographically by operand. The matcher validates that other 4601f64ac403549413b7d5c735d8530257f8661943bBob Wilson // orderings wouldn't be ambiguous using \see CouldMatchAmbiguouslyWith(). 4613116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) { 4623116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner if (*AsmOperands[i].Class < *RHS.AsmOperands[i].Class) 4632b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar return true; 4643116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner if (*RHS.AsmOperands[i].Class < *AsmOperands[i].Class) 465db2ddb5dc57319eff249144f1d9a553a3278d2e0Daniel Dunbar return false; 466db2ddb5dc57319eff249144f1d9a553a3278d2e0Daniel Dunbar } 467db2ddb5dc57319eff249144f1d9a553a3278d2e0Daniel Dunbar 4682b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar return false; 4692b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar } 470606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 4711f64ac403549413b7d5c735d8530257f8661943bBob Wilson /// CouldMatchAmbiguouslyWith - Check whether this matchable could 4722b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar /// ambiguously match the same set of operands as \arg RHS (without being a 4732b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar /// strictly superior match). 4741f64ac403549413b7d5c735d8530257f8661943bBob Wilson bool CouldMatchAmbiguouslyWith(const MatchableInfo &RHS) { 475e66b7ebfb426c7ed9bc911e9708321e2d8510b41Chris Lattner // The primary comparator is the instruction mnemonic. 476d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner if (Mnemonic != RHS.Mnemonic) 477e66b7ebfb426c7ed9bc911e9708321e2d8510b41Chris Lattner return false; 478828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 4792b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar // The number of operands is unambiguous. 4803116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner if (AsmOperands.size() != RHS.AsmOperands.size()) 4812b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar return false; 482606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 4831402f0b2cac017ab997f71ab4909a2ccfea7be4bDaniel Dunbar // Otherwise, make sure the ordering of the two instructions is unambiguous 4841402f0b2cac017ab997f71ab4909a2ccfea7be4bDaniel Dunbar // by checking that either (a) a token or operand kind discriminates them, 4851402f0b2cac017ab997f71ab4909a2ccfea7be4bDaniel Dunbar // or (b) the ordering among equivalent kinds is consistent. 4861402f0b2cac017ab997f71ab4909a2ccfea7be4bDaniel Dunbar 4872b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar // Tokens and operand kinds are unambiguous (assuming a correct target 4882b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar // specific parser). 4893116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) 4903116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner if (AsmOperands[i].Class->Kind != RHS.AsmOperands[i].Class->Kind || 4913116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner AsmOperands[i].Class->Kind == ClassInfo::Token) 4923116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner if (*AsmOperands[i].Class < *RHS.AsmOperands[i].Class || 4933116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner *RHS.AsmOperands[i].Class < *AsmOperands[i].Class) 4942b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar return false; 495a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 4962b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar // Otherwise, this operand could commute if all operands are equivalent, or 4972b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar // there is a pair of operands that compare less than and a pair that 4982b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar // compare greater than. 4992b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar bool HasLT = false, HasGT = false; 5003116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) { 5013116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner if (*AsmOperands[i].Class < *RHS.AsmOperands[i].Class) 5022b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar HasLT = true; 5033116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner if (*RHS.AsmOperands[i].Class < *AsmOperands[i].Class) 5042b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar HasGT = true; 5052b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar } 506606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 5072b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar return !(HasLT ^ HasGT); 508606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar } 509606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 51020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar void dump(); 511828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 512d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattnerprivate: 513d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner void TokenizeAsmString(const AsmMatcherInfo &Info); 51420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar}; 51520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 51654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar/// SubtargetFeatureInfo - Helper class for storing information on a subtarget 51754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar/// feature which participates in instruction matching. 51854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbarstruct SubtargetFeatureInfo { 51954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar /// \brief The predicate record for this feature. 52054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar Record *TheDef; 52154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 52254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar /// \brief An unique index assigned to represent this feature. 52354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar unsigned Index; 52454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 5250aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner SubtargetFeatureInfo(Record *D, unsigned Idx) : TheDef(D), Index(Idx) {} 526828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 52754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar /// \brief The name of the enumerated constant identifying this feature. 5280aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner std::string getEnumName() const { 5290aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner return "Feature_" + TheDef->getName(); 5300aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner } 53154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar}; 53254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 533e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopesstruct OperandMatchEntry { 534e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes unsigned OperandMask; 535e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes MatchableInfo* MI; 536e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes ClassInfo *CI; 537e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 538e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes static OperandMatchEntry Create(MatchableInfo* mi, ClassInfo *ci, 539e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes unsigned opMask) { 540e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OperandMatchEntry X; 541e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes X.OperandMask = opMask; 542e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes X.CI = ci; 543e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes X.MI = mi; 544e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes return X; 545e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes } 546e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes}; 547e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 548e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 549a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarclass AsmMatcherInfo { 550a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarpublic: 55167db883487fca3472fdde51e931657e22d4d0495Chris Lattner /// Tracked Records 5529c6b60eb28d2717008f8d6ff52f7666ebc81113dChris Lattner RecordKeeper &Records; 55367db883487fca3472fdde51e931657e22d4d0495Chris Lattner 55459fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar /// The tablegen AsmParser record. 55559fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar Record *AsmParser; 55659fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar 55702bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner /// Target - The target information. 55802bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner CodeGenTarget &Target; 55902bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner 56059fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar /// The AsmParser "RegisterPrefix" value. 56159fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar std::string RegisterPrefix; 56259fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar 563a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// The classes which are needed for matching. 564a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::vector<ClassInfo*> Classes; 565a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 56622bc5c4184a497353e33195dd12541a4f08b008aChris Lattner /// The information on the matchables to match. 56722bc5c4184a497353e33195dd12541a4f08b008aChris Lattner std::vector<MatchableInfo*> Matchables; 568a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 569e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes /// Info for custom matching operands by user defined methods. 570e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes std::vector<OperandMatchEntry> OperandMatchInfo; 571e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 572ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// Map of Register records to their class information. 573ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar std::map<Record*, ClassInfo*> RegisterClasses; 574ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 57554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar /// Map of Predicate records to their subtarget information. 57654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar std::map<Record*, SubtargetFeatureInfo*> SubtargetFeatures; 577828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 578a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarprivate: 579a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// Map of token to class information which has already been constructed. 580a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::map<std::string, ClassInfo*> TokenClasses; 581a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 582ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// Map of RegisterClass records to their class information. 583ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar std::map<Record*, ClassInfo*> RegisterClassClasses; 584a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 585338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar /// Map of AsmOperandClass records to their class information. 586338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar std::map<Record*, ClassInfo*> AsmOperandClasses; 5876745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar 588a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarprivate: 589a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// getTokenClass - Lookup or create the class for the given token. 590b8d6e98e566724f58344d275a4bd675249bb713aChris Lattner ClassInfo *getTokenClass(StringRef Token); 591a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 592a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// getOperandClass - Lookup or create the class for the given operand. 593a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson ClassInfo *getOperandClass(const CGIOperandList::OperandInfo &OI, 594a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson int SubOpIdx = -1); 595a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 596ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// BuildRegisterClasses - Build the ClassInfo* instances for register 597ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// classes. 5981de88235781c45c0afc0c7500d65b59775196c4cChris Lattner void BuildRegisterClasses(SmallPtrSet<Record*, 16> &SingletonRegisters); 599ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 600ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// BuildOperandClasses - Build the ClassInfo* instances for user defined 601ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// operand classes. 60202bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner void BuildOperandClasses(); 603ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 604a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson void BuildInstructionOperandReference(MatchableInfo *II, StringRef OpName, 605a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson unsigned AsmOpIdx); 606a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson void BuildAliasOperandReference(MatchableInfo *II, StringRef OpName, 607c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner MatchableInfo::AsmOperand &Op); 608828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 609a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarpublic: 610828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson AsmMatcherInfo(Record *AsmParser, 611828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson CodeGenTarget &Target, 6129c6b60eb28d2717008f8d6ff52f7666ebc81113dChris Lattner RecordKeeper &Records); 61359fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar 614a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// BuildInfo - Construct the various tables used during matching. 61502bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner void BuildInfo(); 616828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 617e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes /// BuildOperandMatchInfo - Build the necessary information to handle user 618e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes /// defined operand parsing methods. 619e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes void BuildOperandMatchInfo(); 620e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 6216fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner /// getSubtargetFeature - Lookup or create the subtarget feature info for the 6226fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner /// given operand. 6236fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner SubtargetFeatureInfo *getSubtargetFeature(Record *Def) const { 6246fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner assert(Def->isSubClassOf("Predicate") && "Invalid predicate type!"); 6256fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner std::map<Record*, SubtargetFeatureInfo*>::const_iterator I = 6266fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner SubtargetFeatures.find(Def); 6276fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner return I == SubtargetFeatures.end() ? 0 : I->second; 6286fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner } 62967db883487fca3472fdde51e931657e22d4d0495Chris Lattner 6309c6b60eb28d2717008f8d6ff52f7666ebc81113dChris Lattner RecordKeeper &getRecords() const { 6319c6b60eb28d2717008f8d6ff52f7666ebc81113dChris Lattner return Records; 63267db883487fca3472fdde51e931657e22d4d0495Chris Lattner } 633a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar}; 634a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 63520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar} 63620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 63722bc5c4184a497353e33195dd12541a4f08b008aChris Lattnervoid MatchableInfo::dump() { 6385abd1ebcb380664ae5010395b217e01f7190046cChris Lattner errs() << TheDef->getName() << " -- " << "flattened:\"" << AsmString <<"\"\n"; 639a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 6403116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) { 641c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner AsmOperand &Op = AsmOperands[i]; 6426745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar errs() << " op[" << i << "] = " << Op.Class->ClassName << " - "; 6430bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner errs() << '\"' << Op.Token << "\"\n"; 64420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 64520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar} 646a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 64722bc5c4184a497353e33195dd12541a4f08b008aChris Lattnervoid MatchableInfo::Initialize(const AsmMatcherInfo &Info, 64822bc5c4184a497353e33195dd12541a4f08b008aChris Lattner SmallPtrSet<Record*, 16> &SingletonRegisters) { 649c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner // TODO: Eventually support asmparser for Variant != 0. 650c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner AsmString = CodeGenInstruction::FlattenAsmStringVariants(AsmString, 0); 651828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 652d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner TokenizeAsmString(Info); 653828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 654c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner // Compute the require features. 655c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner std::vector<Record*> Predicates =TheDef->getValueAsListOfDefs("Predicates"); 656c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner for (unsigned i = 0, e = Predicates.size(); i != e; ++i) 657c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner if (SubtargetFeatureInfo *Feature = 658c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner Info.getSubtargetFeature(Predicates[i])) 659c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner RequiredFeatures.push_back(Feature); 660828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 661c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner // Collect singleton registers, if used. 662d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) { 663d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner if (Record *Reg = getSingletonRegisterForAsmOperand(i, Info)) 664c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner SingletonRegisters.insert(Reg); 665c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner } 666c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner} 667c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner 668d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner/// TokenizeAsmString - Tokenize a simplified assembly string. 669d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattnervoid MatchableInfo::TokenizeAsmString(const AsmMatcherInfo &Info) { 670d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner StringRef String = AsmString; 671d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner unsigned Prev = 0; 672d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner bool InTok = true; 673d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner for (unsigned i = 0, e = String.size(); i != e; ++i) { 674d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner switch (String[i]) { 675d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner case '[': 676d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner case ']': 677d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner case '*': 678d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner case '!': 679d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner case ' ': 680d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner case '\t': 681d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner case ',': 682d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner if (InTok) { 683c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner AsmOperands.push_back(AsmOperand(String.slice(Prev, i))); 684d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner InTok = false; 685d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner } 686d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner if (!isspace(String[i]) && String[i] != ',') 687c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner AsmOperands.push_back(AsmOperand(String.substr(i, 1))); 688d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner Prev = i + 1; 689d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner break; 690d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner 691d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner case '\\': 692d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner if (InTok) { 693c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner AsmOperands.push_back(AsmOperand(String.slice(Prev, i))); 694d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner InTok = false; 695d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner } 696d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner ++i; 697d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner assert(i != String.size() && "Invalid quoted character"); 698c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner AsmOperands.push_back(AsmOperand(String.substr(i, 1))); 699d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner Prev = i + 1; 700d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner break; 701d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner 702d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner case '$': { 7037ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner if (InTok) { 7047ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner AsmOperands.push_back(AsmOperand(String.slice(Prev, i))); 7057ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner InTok = false; 7067ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner } 707828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 708d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner // If this isn't "${", treat like a normal token. 709d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner if (i + 1 == String.size() || String[i + 1] != '{') { 710d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner Prev = i; 711d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner break; 712d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner } 713d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner 714d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner StringRef::iterator End = std::find(String.begin() + i, String.end(),'}'); 715d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner assert(End != String.end() && "Missing brace in operand reference!"); 716d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner size_t EndPos = End - String.begin(); 717c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner AsmOperands.push_back(AsmOperand(String.slice(i, EndPos+1))); 718d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner Prev = EndPos + 1; 719d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner i = EndPos; 720d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner break; 721d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner } 722d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner 723d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner case '.': 724d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner if (InTok) 725c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner AsmOperands.push_back(AsmOperand(String.slice(Prev, i))); 726d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner Prev = i; 727d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner InTok = true; 728d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner break; 729d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner 730d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner default: 731d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner InTok = true; 732d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner } 733d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner } 734d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner if (InTok && Prev != String.size()) 735c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner AsmOperands.push_back(AsmOperand(String.substr(Prev))); 736828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 737d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner // The first token of the instruction is the mnemonic, which must be a 738d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner // simple string, not a $foo variable or a singleton register. 739d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner assert(!AsmOperands.empty() && "Instruction has no tokens?"); 740d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner Mnemonic = AsmOperands[0].Token; 741d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner if (Mnemonic[0] == '$' || getSingletonRegisterForAsmOperand(0, Info)) 742d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner throw TGError(TheDef->getLoc(), 743d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner "Invalid instruction mnemonic '" + Mnemonic.str() + "'!"); 744828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 745d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner // Remove the first operand, it is tracked in the mnemonic field. 746d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner AsmOperands.erase(AsmOperands.begin()); 747d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner} 748d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner 74922bc5c4184a497353e33195dd12541a4f08b008aChris Lattnerbool MatchableInfo::Validate(StringRef CommentDelimiter, bool Hack) const { 75022bc5c4184a497353e33195dd12541a4f08b008aChris Lattner // Reject matchables with no .s string. 7515bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner if (AsmString.empty()) 7525bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner throw TGError(TheDef->getLoc(), "instruction with empty asm string"); 753828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 75422bc5c4184a497353e33195dd12541a4f08b008aChris Lattner // Reject any matchables with a newline in them, they should be marked 7555bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner // isCodeGenOnly if they are pseudo instructions. 7565bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner if (AsmString.find('\n') != std::string::npos) 7575bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner throw TGError(TheDef->getLoc(), 7585bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner "multiline instruction is not valid for the asmparser, " 7595bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner "mark it isCodeGenOnly"); 760828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 7614164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner // Remove comments from the asm string. We know that the asmstring only 7624164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner // has one line. 7634164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner if (!CommentDelimiter.empty() && 7644164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner StringRef(AsmString).find(CommentDelimiter) != StringRef::npos) 7654164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner throw TGError(TheDef->getLoc(), 7664164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner "asmstring for instruction has comment character in it, " 7674164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner "mark it isCodeGenOnly"); 768828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 76922bc5c4184a497353e33195dd12541a4f08b008aChris Lattner // Reject matchables with operand modifiers, these aren't something we can 770906bc368bc0fe18682edc0743ada41f62e436383Bob Wilson // handle, the target should be refactored to use operands instead of 771906bc368bc0fe18682edc0743ada41f62e436383Bob Wilson // modifiers. 7725bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner // 7735bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner // Also, check for instructions which reference the operand multiple times; 7745bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner // this implies a constraint we would not honor. 7755bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner std::set<std::string> OperandNames; 776d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) { 777d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner StringRef Tok = AsmOperands[i].Token; 778d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner if (Tok[0] == '$' && Tok.find(':') != StringRef::npos) 7795bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner throw TGError(TheDef->getLoc(), 780d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner "matchable with operand modifier '" + Tok.str() + 7815bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner "' not supported by asm matcher. Mark isCodeGenOnly!"); 782828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 78322bc5c4184a497353e33195dd12541a4f08b008aChris Lattner // Verify that any operand is only mentioned once. 784d51257a4368d52e2340073bc7ccd83f3c3f1c04dChris Lattner // We reject aliases and ignore instructions for now. 785d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner if (Tok[0] == '$' && !OperandNames.insert(Tok).second) { 78622bc5c4184a497353e33195dd12541a4f08b008aChris Lattner if (!Hack) 78722bc5c4184a497353e33195dd12541a4f08b008aChris Lattner throw TGError(TheDef->getLoc(), 788d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner "ERROR: matchable with tied operand '" + Tok.str() + 78922bc5c4184a497353e33195dd12541a4f08b008aChris Lattner "' can never be matched!"); 79022bc5c4184a497353e33195dd12541a4f08b008aChris Lattner // FIXME: Should reject these. The ARM backend hits this with $lane in a 79122bc5c4184a497353e33195dd12541a4f08b008aChris Lattner // bunch of instructions. It is unclear what the right answer is. 7925bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner DEBUG({ 7935abd1ebcb380664ae5010395b217e01f7190046cChris Lattner errs() << "warning: '" << TheDef->getName() << "': " 79422bc5c4184a497353e33195dd12541a4f08b008aChris Lattner << "ignoring instruction with tied operand '" 795d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner << Tok.str() << "'\n"; 7965bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner }); 7975bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner return false; 7985bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner } 7995bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner } 800828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 8015bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner return true; 8025bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner} 8035bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner 804d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner/// getSingletonRegisterForAsmOperand - If the specified token is a singleton 80502bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner/// register, return the register name, otherwise return a null StringRef. 80622bc5c4184a497353e33195dd12541a4f08b008aChris LattnerRecord *MatchableInfo:: 807d19ec05e0785152e7a520ffd4a88da4459a380aaChris LattnergetSingletonRegisterForAsmOperand(unsigned i, const AsmMatcherInfo &Info) const{ 808d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner StringRef Tok = AsmOperands[i].Token; 80902bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner if (!Tok.startswith(Info.RegisterPrefix)) 8101de88235781c45c0afc0c7500d65b59775196c4cChris Lattner return 0; 811828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 81202bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner StringRef RegName = Tok.substr(Info.RegisterPrefix.size()); 813ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner if (const CodeGenRegister *Reg = Info.Target.getRegisterByName(RegName)) 814ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner return Reg->TheDef; 815828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 8161de88235781c45c0afc0c7500d65b59775196c4cChris Lattner // If there is no register prefix (i.e. "%" in "%eax"), then this may 8171de88235781c45c0afc0c7500d65b59775196c4cChris Lattner // be some random non-register token, just ignore it. 8181de88235781c45c0afc0c7500d65b59775196c4cChris Lattner if (Info.RegisterPrefix.empty()) 8191de88235781c45c0afc0c7500d65b59775196c4cChris Lattner return 0; 820828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 821ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner // Otherwise, we have something invalid prefixed with the register prefix, 822ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner // such as %foo. 8231de88235781c45c0afc0c7500d65b59775196c4cChris Lattner std::string Err = "unable to find register for '" + RegName.str() + 8241de88235781c45c0afc0c7500d65b59775196c4cChris Lattner "' (which matches register prefix)"; 8255bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner throw TGError(TheDef->getLoc(), Err); 82602bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner} 82702bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner 828b8d6e98e566724f58344d275a4bd675249bb713aChris Lattnerstatic std::string getEnumNameForToken(StringRef Str) { 829a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::string Res; 830a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 831a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar for (StringRef::iterator it = Str.begin(), ie = Str.end(); it != ie; ++it) { 832a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar switch (*it) { 833a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar case '*': Res += "_STAR_"; break; 834a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar case '%': Res += "_PCT_"; break; 835a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar case ':': Res += "_COLON_"; break; 836bd9c77bc9ad384d046a7967d160ad96f61916d9dBill Wendling case '!': Res += "_EXCLAIM_"; break; 8370ef755d9051a79680326d6144a2401660fc93e57Bill Wendling case '.': Res += "_DOT_"; break; 838a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar default: 83939ee036f407bd0c94cb993cf9b97348843cfafa4Chris Lattner if (isalnum(*it)) 840a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Res += *it; 84139ee036f407bd0c94cb993cf9b97348843cfafa4Chris Lattner else 842a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Res += "_" + utostr((unsigned) *it) + "_"; 843a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 844a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 84520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 846a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar return Res; 847a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar} 848a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 849b8d6e98e566724f58344d275a4bd675249bb713aChris LattnerClassInfo *AsmMatcherInfo::getTokenClass(StringRef Token) { 850a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar ClassInfo *&Entry = TokenClasses[Token]; 851a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 852a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar if (!Entry) { 853a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Entry = new ClassInfo(); 854a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Entry->Kind = ClassInfo::Token; 8556745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar Entry->ClassName = "Token"; 856a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Entry->Name = "MCK_" + getEnumNameForToken(Token); 857a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Entry->ValueName = Token; 858a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Entry->PredicateMethod = "<invalid>"; 859a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Entry->RenderMethod = "<invalid>"; 860e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes Entry->ParserMethod = ""; 861a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Classes.push_back(Entry); 862a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 863a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 864a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar return Entry; 865a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar} 866a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 867a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel DunbarClassInfo * 868a49c7dfb360154070c08b8eb94ad31711d1babaeBob WilsonAsmMatcherInfo::getOperandClass(const CGIOperandList::OperandInfo &OI, 869a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson int SubOpIdx) { 870a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson Record *Rec = OI.Rec; 871a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson if (SubOpIdx != -1) 872a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson Rec = dynamic_cast<DefInit*>(OI.MIOperandInfo->getArg(SubOpIdx))->getDef(); 873a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson 874bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson if (Rec->isSubClassOf("RegisterOperand")) { 875bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson // RegisterOperand may have an associated ParserMatchClass. If it does, 876bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson // use it, else just fall back to the underlying register class. 877bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson const RecordVal *R = Rec->getValue("ParserMatchClass"); 878bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson if (R == 0 || R->getValue() == 0) 879bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson throw "Record `" + Rec->getName() + 880bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson "' does not have a ParserMatchClass!\n"; 881bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson 882bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson if (DefInit *DI= dynamic_cast<DefInit*>(R->getValue())) { 883bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson Record *MatchClass = DI->getDef(); 884bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson if (ClassInfo *CI = AsmOperandClasses[MatchClass]) 885bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson return CI; 886bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson } 887bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson 888bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson // No custom match class. Just use the register class. 889bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson Record *ClassRec = Rec->getValueAsDef("RegClass"); 890bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson if (!ClassRec) 891bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson throw TGError(Rec->getLoc(), "RegisterOperand `" + Rec->getName() + 892bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson "' has no associated register class!\n"); 893bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson if (ClassInfo *CI = RegisterClassClasses[ClassRec]) 894bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson return CI; 895bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson throw TGError(Rec->getLoc(), "register class has no class info!"); 896bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson } 897bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson 898bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson 899a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson if (Rec->isSubClassOf("RegisterClass")) { 900a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson if (ClassInfo *CI = RegisterClassClasses[Rec]) 901ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner return CI; 902a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson throw TGError(Rec->getLoc(), "register class has no class info!"); 903ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 904338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar 905a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson assert(Rec->isSubClassOf("Operand") && "Unexpected operand!"); 906a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson Record *MatchClass = Rec->getValueAsDef("ParserMatchClass"); 907ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner if (ClassInfo *CI = AsmOperandClasses[MatchClass]) 908ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner return CI; 909a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 910a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson throw TGError(Rec->getLoc(), "operand has no match class!"); 911338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar} 912338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar 9131de88235781c45c0afc0c7500d65b59775196c4cChris Lattnervoid AsmMatcherInfo:: 9141de88235781c45c0afc0c7500d65b59775196c4cChris LattnerBuildRegisterClasses(SmallPtrSet<Record*, 16> &SingletonRegisters) { 915abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen const std::vector<CodeGenRegister*> &Registers = 916abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen Target.getRegBank().getRegisters(); 917ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner const std::vector<CodeGenRegisterClass> &RegClassList = 918ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner Target.getRegisterClasses(); 919338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar 920ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // The register sets used for matching. 921ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar std::set< std::set<Record*> > RegisterSets; 922ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 923a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach // Gather the defined sets. 924ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner for (std::vector<CodeGenRegisterClass>::const_iterator it = 925ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner RegClassList.begin(), ie = RegClassList.end(); it != ie; ++it) 926ae1920b1efa72c1789d562df4746110d0c2e10bdJakob Stoklund Olesen RegisterSets.insert(std::set<Record*>(it->getOrder().begin(), 927ae1920b1efa72c1789d562df4746110d0c2e10bdJakob Stoklund Olesen it->getOrder().end())); 9281095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 9291095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar // Add any required singleton sets. 9301de88235781c45c0afc0c7500d65b59775196c4cChris Lattner for (SmallPtrSet<Record*, 16>::iterator it = SingletonRegisters.begin(), 9311de88235781c45c0afc0c7500d65b59775196c4cChris Lattner ie = SingletonRegisters.end(); it != ie; ++it) { 9321de88235781c45c0afc0c7500d65b59775196c4cChris Lattner Record *Rec = *it; 9331de88235781c45c0afc0c7500d65b59775196c4cChris Lattner RegisterSets.insert(std::set<Record*>(&Rec, &Rec + 1)); 9341de88235781c45c0afc0c7500d65b59775196c4cChris Lattner } 935a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 936ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Introduce derived sets where necessary (when a register does not determine 937ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // a unique register set class), and build the mapping of registers to the set 938ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // they should classify to. 939ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar std::map<Record*, std::set<Record*> > RegisterMap; 940abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen for (std::vector<CodeGenRegister*>::const_iterator it = Registers.begin(), 941ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ie = Registers.end(); it != ie; ++it) { 942abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen const CodeGenRegister &CGR = **it; 943ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Compute the intersection of all sets containing this register. 944ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar std::set<Record*> ContainingSet; 945a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 946ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar for (std::set< std::set<Record*> >::iterator it = RegisterSets.begin(), 947ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ie = RegisterSets.end(); it != ie; ++it) { 948ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (!it->count(CGR.TheDef)) 949ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar continue; 950ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 951ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (ContainingSet.empty()) { 952ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ContainingSet = *it; 953ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner continue; 954ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 955828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 956ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner std::set<Record*> Tmp; 957ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner std::swap(Tmp, ContainingSet); 958ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner std::insert_iterator< std::set<Record*> > II(ContainingSet, 959ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner ContainingSet.begin()); 960ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner std::set_intersection(Tmp.begin(), Tmp.end(), it->begin(), it->end(), II); 961ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 962ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 963ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (!ContainingSet.empty()) { 964ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar RegisterSets.insert(ContainingSet); 965ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar RegisterMap.insert(std::make_pair(CGR.TheDef, ContainingSet)); 966ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 967ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 968ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 969ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Construct the register classes. 970ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar std::map<std::set<Record*>, ClassInfo*> RegisterSetClasses; 971ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar unsigned Index = 0; 972ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar for (std::set< std::set<Record*> >::iterator it = RegisterSets.begin(), 973ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ie = RegisterSets.end(); it != ie; ++it, ++Index) { 974ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ClassInfo *CI = new ClassInfo(); 975ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->Kind = ClassInfo::RegisterClass0 + Index; 976ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->ClassName = "Reg" + utostr(Index); 977ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->Name = "MCK_Reg" + utostr(Index); 978ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->ValueName = ""; 979ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->PredicateMethod = ""; // unused 980ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->RenderMethod = "addRegOperands"; 9818409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar CI->Registers = *it; 982ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar Classes.push_back(CI); 983ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar RegisterSetClasses.insert(std::make_pair(*it, CI)); 984ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 985ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 986ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Find the superclasses; we could compute only the subgroup lattice edges, 987ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // but there isn't really a point. 988ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar for (std::set< std::set<Record*> >::iterator it = RegisterSets.begin(), 989ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ie = RegisterSets.end(); it != ie; ++it) { 990ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ClassInfo *CI = RegisterSetClasses[*it]; 991ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar for (std::set< std::set<Record*> >::iterator it2 = RegisterSets.begin(), 992ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ie2 = RegisterSets.end(); it2 != ie2; ++it2) 993a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach if (*it != *it2 && 994ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar std::includes(it2->begin(), it2->end(), it->begin(), it->end())) 995ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->SuperClasses.push_back(RegisterSetClasses[*it2]); 996ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 997ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 998ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Name the register classes which correspond to a user defined RegisterClass. 999ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner for (std::vector<CodeGenRegisterClass>::const_iterator 1000ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner it = RegClassList.begin(), ie = RegClassList.end(); it != ie; ++it) { 1001ae1920b1efa72c1789d562df4746110d0c2e10bdJakob Stoklund Olesen ClassInfo *CI = RegisterSetClasses[std::set<Record*>(it->getOrder().begin(), 1002ae1920b1efa72c1789d562df4746110d0c2e10bdJakob Stoklund Olesen it->getOrder().end())]; 1003ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (CI->ValueName.empty()) { 1004ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->ClassName = it->getName(); 1005ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->Name = "MCK_" + it->getName(); 1006ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->ValueName = it->getName(); 1007ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } else 1008ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->ValueName = CI->ValueName + "," + it->getName(); 1009ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 1010ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar RegisterClassClasses.insert(std::make_pair(it->TheDef, CI)); 1011ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 1012ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 1013ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Populate the map for individual registers. 1014ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar for (std::map<Record*, std::set<Record*> >::iterator it = RegisterMap.begin(), 1015ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ie = RegisterMap.end(); it != ie; ++it) 1016ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner RegisterClasses[it->first] = RegisterSetClasses[it->second]; 10171095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 10181095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar // Name the register classes which correspond to singleton registers. 10191de88235781c45c0afc0c7500d65b59775196c4cChris Lattner for (SmallPtrSet<Record*, 16>::iterator it = SingletonRegisters.begin(), 10201de88235781c45c0afc0c7500d65b59775196c4cChris Lattner ie = SingletonRegisters.end(); it != ie; ++it) { 10211de88235781c45c0afc0c7500d65b59775196c4cChris Lattner Record *Rec = *it; 1022ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner ClassInfo *CI = RegisterClasses[Rec]; 10231de88235781c45c0afc0c7500d65b59775196c4cChris Lattner assert(CI && "Missing singleton register class info!"); 10241de88235781c45c0afc0c7500d65b59775196c4cChris Lattner 10251de88235781c45c0afc0c7500d65b59775196c4cChris Lattner if (CI->ValueName.empty()) { 10261de88235781c45c0afc0c7500d65b59775196c4cChris Lattner CI->ClassName = Rec->getName(); 10271de88235781c45c0afc0c7500d65b59775196c4cChris Lattner CI->Name = "MCK_" + Rec->getName(); 10281de88235781c45c0afc0c7500d65b59775196c4cChris Lattner CI->ValueName = Rec->getName(); 10291de88235781c45c0afc0c7500d65b59775196c4cChris Lattner } else 10301de88235781c45c0afc0c7500d65b59775196c4cChris Lattner CI->ValueName = CI->ValueName + "," + Rec->getName(); 10311095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar } 1032ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar} 1033ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 103402bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattnervoid AsmMatcherInfo::BuildOperandClasses() { 1035e66b7ebfb426c7ed9bc911e9708321e2d8510b41Chris Lattner std::vector<Record*> AsmOperands = 1036e66b7ebfb426c7ed9bc911e9708321e2d8510b41Chris Lattner Records.getAllDerivedDefinitions("AsmOperandClass"); 1037a2f5e00347641d1b46ce4f65bf9378fecce9be14Daniel Dunbar 1038a2f5e00347641d1b46ce4f65bf9378fecce9be14Daniel Dunbar // Pre-populate AsmOperandClasses map. 1039a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach for (std::vector<Record*>::iterator it = AsmOperands.begin(), 1040a2f5e00347641d1b46ce4f65bf9378fecce9be14Daniel Dunbar ie = AsmOperands.end(); it != ie; ++it) 1041a2f5e00347641d1b46ce4f65bf9378fecce9be14Daniel Dunbar AsmOperandClasses[*it] = new ClassInfo(); 1042a2f5e00347641d1b46ce4f65bf9378fecce9be14Daniel Dunbar 1043338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar unsigned Index = 0; 1044a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach for (std::vector<Record*>::iterator it = AsmOperands.begin(), 1045338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar ie = AsmOperands.end(); it != ie; ++it, ++Index) { 1046a2f5e00347641d1b46ce4f65bf9378fecce9be14Daniel Dunbar ClassInfo *CI = AsmOperandClasses[*it]; 1047338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar CI->Kind = ClassInfo::UserClass0 + Index; 1048338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar 104954ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar ListInit *Supers = (*it)->getValueAsListInit("SuperClasses"); 105054ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar for (unsigned i = 0, e = Supers->getSize(); i != e; ++i) { 105154ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar DefInit *DI = dynamic_cast<DefInit*>(Supers->getElement(i)); 105254ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar if (!DI) { 105354ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar PrintError((*it)->getLoc(), "Invalid super class reference!"); 105454ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar continue; 105554ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar } 105654ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar 1057ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ClassInfo *SC = AsmOperandClasses[DI->getDef()]; 1058ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (!SC) 1059338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar PrintError((*it)->getLoc(), "Invalid super class reference!"); 1060ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar else 1061ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->SuperClasses.push_back(SC); 1062a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 1063338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar CI->ClassName = (*it)->getValueAsString("Name"); 1064338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar CI->Name = "MCK_" + CI->ClassName; 1065338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar CI->ValueName = (*it)->getName(); 10665c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar 10675c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar // Get or construct the predicate method name. 10685c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar Init *PMName = (*it)->getValueInit("PredicateMethod"); 10695c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar if (StringInit *SI = dynamic_cast<StringInit*>(PMName)) { 10705c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar CI->PredicateMethod = SI->getValue(); 10715c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar } else { 1072a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach assert(dynamic_cast<UnsetInit*>(PMName) && 10735c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar "Unexpected PredicateMethod field!"); 10745c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar CI->PredicateMethod = "is" + CI->ClassName; 10755c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar } 10765c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar 10775c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar // Get or construct the render method name. 10785c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar Init *RMName = (*it)->getValueInit("RenderMethod"); 10795c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar if (StringInit *SI = dynamic_cast<StringInit*>(RMName)) { 10805c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar CI->RenderMethod = SI->getValue(); 10815c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar } else { 10825c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar assert(dynamic_cast<UnsetInit*>(RMName) && 10835c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar "Unexpected RenderMethod field!"); 10845c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar CI->RenderMethod = "add" + CI->ClassName + "Operands"; 10855c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar } 10865c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar 1087e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes // Get the parse method name or leave it as empty. 1088e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes Init *PRMName = (*it)->getValueInit("ParserMethod"); 1089e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes if (StringInit *SI = dynamic_cast<StringInit*>(PRMName)) 1090e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes CI->ParserMethod = SI->getValue(); 1091e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 1092338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar AsmOperandClasses[*it] = CI; 1093338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar Classes.push_back(CI); 1094a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 1095ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar} 1096ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 1097828295bb301d6cd3683751c2da1c2dd22ec6423fBob WilsonAsmMatcherInfo::AsmMatcherInfo(Record *asmParser, 1098828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson CodeGenTarget &target, 10999c6b60eb28d2717008f8d6ff52f7666ebc81113dChris Lattner RecordKeeper &records) 110067db883487fca3472fdde51e931657e22d4d0495Chris Lattner : Records(records), AsmParser(asmParser), Target(target), 1101c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner RegisterPrefix(AsmParser->getValueAsString("RegisterPrefix")) { 110259fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar} 110359fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar 1104e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes/// BuildOperandMatchInfo - Build the necessary information to handle user 1105e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes/// defined operand parsing methods. 1106e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopesvoid AsmMatcherInfo::BuildOperandMatchInfo() { 1107e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 1108e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes /// Map containing a mask with all operands indicies that can be found for 1109e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes /// that class inside a instruction. 1110e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes std::map<ClassInfo*, unsigned> OpClassMask; 1111e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 1112e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes for (std::vector<MatchableInfo*>::const_iterator it = 1113e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes Matchables.begin(), ie = Matchables.end(); 1114e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes it != ie; ++it) { 1115e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes MatchableInfo &II = **it; 1116e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OpClassMask.clear(); 1117e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 1118e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes // Keep track of all operands of this instructions which belong to the 1119e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes // same class. 1120e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes for (unsigned i = 0, e = II.AsmOperands.size(); i != e; ++i) { 1121e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes MatchableInfo::AsmOperand &Op = II.AsmOperands[i]; 1122e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes if (Op.Class->ParserMethod.empty()) 1123e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes continue; 1124e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes unsigned &OperandMask = OpClassMask[Op.Class]; 1125e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OperandMask |= (1 << i); 1126e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes } 1127e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 1128e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes // Generate operand match info for each mnemonic/operand class pair. 1129e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes for (std::map<ClassInfo*, unsigned>::iterator iit = OpClassMask.begin(), 1130e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes iie = OpClassMask.end(); iit != iie; ++iit) { 1131e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes unsigned OpMask = iit->second; 1132e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes ClassInfo *CI = iit->first; 1133e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OperandMatchInfo.push_back(OperandMatchEntry::Create(&II, CI, OpMask)); 1134e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes } 1135e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes } 1136e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes} 1137e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 113802bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattnervoid AsmMatcherInfo::BuildInfo() { 11390aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner // Build information about all of the AssemblerPredicates. 11400aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner std::vector<Record*> AllPredicates = 11410aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner Records.getAllDerivedDefinitions("Predicate"); 11420aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner for (unsigned i = 0, e = AllPredicates.size(); i != e; ++i) { 11430aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner Record *Pred = AllPredicates[i]; 11440aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner // Ignore predicates that are not intended for the assembler. 11450aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner if (!Pred->getValueAsBit("AssemblerMatcherPredicate")) 11460aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner continue; 1147828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 11484164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner if (Pred->getName().empty()) 11494164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner throw TGError(Pred->getLoc(), "Predicate has no name!"); 1150828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 11510aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner unsigned FeatureNo = SubtargetFeatures.size(); 11520aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner SubtargetFeatures[Pred] = new SubtargetFeatureInfo(Pred, FeatureNo); 11530aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner assert(FeatureNo < 32 && "Too many subtarget features!"); 11540aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner } 1155a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 11564164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner StringRef CommentDelimiter = AsmParser->getValueAsString("CommentDelimiter"); 1157828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 115839ee036f407bd0c94cb993cf9b97348843cfafa4Chris Lattner // Parse the instructions; we need to do this first so that we can gather the 115939ee036f407bd0c94cb993cf9b97348843cfafa4Chris Lattner // singleton register classes. 11601de88235781c45c0afc0c7500d65b59775196c4cChris Lattner SmallPtrSet<Record*, 16> SingletonRegisters; 116102bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner for (CodeGenTarget::inst_iterator I = Target.inst_begin(), 116202bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner E = Target.inst_end(); I != E; ++I) { 116302bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner const CodeGenInstruction &CGI = **I; 1164a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 116539ee036f407bd0c94cb993cf9b97348843cfafa4Chris Lattner // If the tblgen -match-prefix option is specified (for tblgen hackers), 116639ee036f407bd0c94cb993cf9b97348843cfafa4Chris Lattner // filter the set of instructions we consider. 1167b61e09de6d0cd7241ddc6dee3efef416552eec3bChris Lattner if (!StringRef(CGI.TheDef->getName()).startswith(MatchPrefix)) 116853a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar continue; 116953a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar 11705bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner // Ignore "codegen only" instructions. 11715bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner if (CGI.TheDef->getValueAsBit("isCodeGenOnly")) 11725bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner continue; 1173828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 11741d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner // Validate the operand list to ensure we can handle this instruction. 11751d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner for (unsigned i = 0, e = CGI.Operands.size(); i != e; ++i) { 11761d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner const CGIOperandList::OperandInfo &OI = CGI.Operands[i]; 1177828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 11781d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner // Validate tied operands. 11791d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner if (OI.getTiedRegister() != -1) { 1180828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson // If we have a tied operand that consists of multiple MCOperands, 1181828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson // reject it. We reject aliases and ignore instructions for now. 11821d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner if (OI.MINumOperands != 1) { 11831d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner // FIXME: Should reject these. The ARM backend hits this with $lane 11841d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner // in a bunch of instructions. It is unclear what the right answer is. 11851d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner DEBUG({ 11861d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner errs() << "warning: '" << CGI.TheDef->getName() << "': " 11871d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner << "ignoring instruction with multi-operand tied operand '" 11881d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner << OI.Name << "'\n"; 11891d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner }); 11901d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner continue; 11911d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner } 11921d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner } 11931d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner } 1194828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 119522bc5c4184a497353e33195dd12541a4f08b008aChris Lattner OwningPtr<MatchableInfo> II(new MatchableInfo(CGI)); 1196a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 1197c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner II->Initialize(*this, SingletonRegisters); 1198828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 11994d43d0fd996a01c2cd21fd51082bc1bba783ef3cChris Lattner // Ignore instructions which shouldn't be matched and diagnose invalid 12004d43d0fd996a01c2cd21fd51082bc1bba783ef3cChris Lattner // instruction definitions with an error. 120122bc5c4184a497353e33195dd12541a4f08b008aChris Lattner if (!II->Validate(CommentDelimiter, true)) 12025bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner continue; 1203828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 12045bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner // Ignore "Int_*" and "*_Int" instructions, which are internal aliases. 12055bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner // 12065bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner // FIXME: This is a total hack. 12075abd1ebcb380664ae5010395b217e01f7190046cChris Lattner if (StringRef(II->TheDef->getName()).startswith("Int_") || 12085abd1ebcb380664ae5010395b217e01f7190046cChris Lattner StringRef(II->TheDef->getName()).endswith("_Int")) 1209a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar continue; 1210828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 121122bc5c4184a497353e33195dd12541a4f08b008aChris Lattner Matchables.push_back(II.take()); 12121095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar } 1213828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 1214c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner // Parse all of the InstAlias definitions and stick them in the list of 1215c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner // matchables. 1216c76e80ded753b78a72be0db40fcdba543435d818Chris Lattner std::vector<Record*> AllInstAliases = 1217c76e80ded753b78a72be0db40fcdba543435d818Chris Lattner Records.getAllDerivedDefinitions("InstAlias"); 1218c76e80ded753b78a72be0db40fcdba543435d818Chris Lattner for (unsigned i = 0, e = AllInstAliases.size(); i != e; ++i) { 1219225549f775db61c5dba10e14758f4b43c53ef593Chris Lattner CodeGenInstAlias *Alias = new CodeGenInstAlias(AllInstAliases[i], Target); 1220c76e80ded753b78a72be0db40fcdba543435d818Chris Lattner 1221c0a7007d3a6a7bb31eec568b9dfdb8fb137702e5Daniel Dunbar // If the tblgen -match-prefix option is specified (for tblgen hackers), 1222c0a7007d3a6a7bb31eec568b9dfdb8fb137702e5Daniel Dunbar // filter the set of instruction aliases we consider, based on the target 1223c0a7007d3a6a7bb31eec568b9dfdb8fb137702e5Daniel Dunbar // instruction. 1224c0a7007d3a6a7bb31eec568b9dfdb8fb137702e5Daniel Dunbar if (!StringRef(Alias->ResultInst->TheDef->getName()).startswith( 1225c0a7007d3a6a7bb31eec568b9dfdb8fb137702e5Daniel Dunbar MatchPrefix)) 1226c0a7007d3a6a7bb31eec568b9dfdb8fb137702e5Daniel Dunbar continue; 1227c0a7007d3a6a7bb31eec568b9dfdb8fb137702e5Daniel Dunbar 122822bc5c4184a497353e33195dd12541a4f08b008aChris Lattner OwningPtr<MatchableInfo> II(new MatchableInfo(Alias)); 1229828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 1230c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner II->Initialize(*this, SingletonRegisters); 1231828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 123222bc5c4184a497353e33195dd12541a4f08b008aChris Lattner // Validate the alias definitions. 123322bc5c4184a497353e33195dd12541a4f08b008aChris Lattner II->Validate(CommentDelimiter, false); 1234828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 1235b501d4f673c0db267a76800339f9943f2ce6fe33Chris Lattner Matchables.push_back(II.take()); 1236c76e80ded753b78a72be0db40fcdba543435d818Chris Lattner } 1237c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner 12381095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar // Build info for the register classes. 12391de88235781c45c0afc0c7500d65b59775196c4cChris Lattner BuildRegisterClasses(SingletonRegisters); 12401095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 12411095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar // Build info for the user defined assembly operand classes. 124202bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner BuildOperandClasses(); 12431095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 12440bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner // Build the information about matchables, now that we have fully formed 12450bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner // classes. 124622bc5c4184a497353e33195dd12541a4f08b008aChris Lattner for (std::vector<MatchableInfo*>::iterator it = Matchables.begin(), 124722bc5c4184a497353e33195dd12541a4f08b008aChris Lattner ie = Matchables.end(); it != ie; ++it) { 124822bc5c4184a497353e33195dd12541a4f08b008aChris Lattner MatchableInfo *II = *it; 1249a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 1250e206fcf0e9c7e79c7f42ff2151f3fb58cba70674Chris Lattner // Parse the tokens after the mnemonic. 1251a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson // Note: BuildInstructionOperandReference may insert new AsmOperands, so 1252a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson // don't precompute the loop bound. 1253a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson for (unsigned i = 0; i != II->AsmOperands.size(); ++i) { 1254c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner MatchableInfo::AsmOperand &Op = II->AsmOperands[i]; 1255d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner StringRef Token = Op.Token; 125620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 12571095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar // Check for singleton registers. 1258d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner if (Record *RegRecord = II->getSingletonRegisterForAsmOperand(i, *this)) { 1259d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner Op.Class = RegisterClasses[RegRecord]; 126002bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner assert(Op.Class && Op.Class->Registers.size() == 1 && 126102bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner "Unexpected class for singleton register"); 126202bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner continue; 12631095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar } 12641095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 126520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // Check for simple tokens. 126620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (Token[0] != '$') { 1267d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner Op.Class = getTokenClass(Token); 126820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar continue; 126920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 1270a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 12717ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner if (Token.size() > 1 && isdigit(Token[1])) { 12727ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner Op.Class = getTokenClass(Token); 12737ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner continue; 12747ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner } 1275828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 1276c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner // Otherwise this is an operand reference. 12775f4280cd2d2d1aeb527c8b161acaa1870cf6ee82Chris Lattner StringRef OperandName; 12785f4280cd2d2d1aeb527c8b161acaa1870cf6ee82Chris Lattner if (Token[1] == '{') 12795f4280cd2d2d1aeb527c8b161acaa1870cf6ee82Chris Lattner OperandName = Token.substr(2, Token.size() - 3); 12805f4280cd2d2d1aeb527c8b161acaa1870cf6ee82Chris Lattner else 12815f4280cd2d2d1aeb527c8b161acaa1870cf6ee82Chris Lattner OperandName = Token.substr(1); 1282828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 1283c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner if (II->DefRec.is<const CodeGenInstruction*>()) 1284a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson BuildInstructionOperandReference(II, OperandName, i); 1285c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner else 1286225549f775db61c5dba10e14758f4b43c53ef593Chris Lattner BuildAliasOperandReference(II, OperandName, Op); 128753a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar } 1288828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 1289414098571b19fc248fda2be194082cfd012d2729Chris Lattner if (II->DefRec.is<const CodeGenInstruction*>()) 1290414098571b19fc248fda2be194082cfd012d2729Chris Lattner II->BuildInstructionResultOperands(); 1291414098571b19fc248fda2be194082cfd012d2729Chris Lattner else 1292414098571b19fc248fda2be194082cfd012d2729Chris Lattner II->BuildAliasResultOperands(); 129320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 12945fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar 12957a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // Reorder classes so that classes precede super classes. 12965fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar std::sort(Classes.begin(), Classes.end(), less_ptr<ClassInfo>()); 129720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar} 1298a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 12990bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner/// BuildInstructionOperandReference - The specified operand is a reference to a 13000bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner/// named operand such as $src. Resolve the Class and OperandInfo pointers. 13010bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattnervoid AsmMatcherInfo:: 13020bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris LattnerBuildInstructionOperandReference(MatchableInfo *II, 13035f4280cd2d2d1aeb527c8b161acaa1870cf6ee82Chris Lattner StringRef OperandName, 1304a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson unsigned AsmOpIdx) { 1305c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner const CodeGenInstruction &CGI = *II->DefRec.get<const CodeGenInstruction*>(); 1306c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner const CGIOperandList &Operands = CGI.Operands; 1307a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson MatchableInfo::AsmOperand *Op = &II->AsmOperands[AsmOpIdx]; 1308828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 1309662e5a30e864e71111b885d3da3cdd184772035dChris Lattner // Map this token to an operand. 13100bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner unsigned Idx; 13110bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner if (!Operands.hasOperandNamed(OperandName, Idx)) 13120bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner throw TGError(II->TheDef->getLoc(), "error: unable to find operand: '" + 13130bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner OperandName.str() + "'"); 1314ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner 1315a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson // If the instruction operand has multiple suboperands, but the parser 1316a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson // match class for the asm operand is still the default "ImmAsmOperand", 1317a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson // then handle each suboperand separately. 1318a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson if (Op->SubOpIdx == -1 && Operands[Idx].MINumOperands > 1) { 1319a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson Record *Rec = Operands[Idx].Rec; 1320a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson assert(Rec->isSubClassOf("Operand") && "Unexpected operand!"); 1321a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson Record *MatchClass = Rec->getValueAsDef("ParserMatchClass"); 1322a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson if (MatchClass && MatchClass->getValueAsString("Name") == "Imm") { 1323a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson // Insert remaining suboperands after AsmOpIdx in II->AsmOperands. 1324a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson StringRef Token = Op->Token; // save this in case Op gets moved 1325a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson for (unsigned SI = 1, SE = Operands[Idx].MINumOperands; SI != SE; ++SI) { 1326a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson MatchableInfo::AsmOperand NewAsmOp(Token); 1327a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson NewAsmOp.SubOpIdx = SI; 1328a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson II->AsmOperands.insert(II->AsmOperands.begin()+AsmOpIdx+SI, NewAsmOp); 1329a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson } 1330a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson // Replace Op with first suboperand. 1331a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson Op = &II->AsmOperands[AsmOpIdx]; // update the pointer in case it moved 1332a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson Op->SubOpIdx = 0; 1333a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson } 1334a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson } 1335a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson 1336ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner // Set up the operand class. 1337a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson Op->Class = getOperandClass(Operands[Idx], Op->SubOpIdx); 1338ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner 1339ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner // If the named operand is tied, canonicalize it to the untied operand. 1340ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner // For example, something like: 1341ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner // (outs GPR:$dst), (ins GPR:$src) 1342ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner // with an asmstring of 1343ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner // "inc $src" 1344ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner // we want to canonicalize to: 1345c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner // "inc $dst" 1346c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner // so that we know how to provide the $dst operand when filling in the result. 1347c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner int OITied = Operands[Idx].getTiedRegister(); 1348c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner if (OITied != -1) { 1349c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner // The tied operand index is an MIOperand index, find the operand that 1350c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner // contains it. 1351a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson std::pair<unsigned, unsigned> Idx = Operands.getSubOperandNumber(OITied); 1352a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson OperandName = Operands[Idx.first].Name; 1353a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson Op->SubOpIdx = Idx.second; 1354c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner } 1355828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 1356a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson Op->SrcOpName = OperandName; 1357c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner} 1358c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner 13593f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner/// BuildAliasOperandReference - When parsing an operand reference out of the 13603f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner/// matching string (e.g. "movsx $src, $dst"), determine what the class of the 13613f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner/// operand reference is by looking it up in the result pattern definition. 1362c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattnervoid AsmMatcherInfo::BuildAliasOperandReference(MatchableInfo *II, 1363c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner StringRef OperandName, 1364c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner MatchableInfo::AsmOperand &Op) { 1365c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner const CodeGenInstAlias &CGA = *II->DefRec.get<const CodeGenInstAlias*>(); 1366828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 1367c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner // Set up the operand class. 13683f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner for (unsigned i = 0, e = CGA.ResultOperands.size(); i != e; ++i) 136998c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner if (CGA.ResultOperands[i].isRecord() && 137098c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner CGA.ResultOperands[i].getName() == OperandName) { 1371662e5a30e864e71111b885d3da3cdd184772035dChris Lattner // It's safe to go with the first one we find, because CodeGenInstAlias 1372662e5a30e864e71111b885d3da3cdd184772035dChris Lattner // validates that all operands with the same name have the same record. 1373a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson unsigned ResultIdx = CGA.ResultInstOperandIndex[i].first; 1374a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson Op.SubOpIdx = CGA.ResultInstOperandIndex[i].second; 1375a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson Op.Class = getOperandClass(CGA.ResultInst->Operands[ResultIdx], 1376a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson Op.SubOpIdx); 13773f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner Op.SrcOpName = OperandName; 13783f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner return; 13790bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner } 13803f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner 13813f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner throw TGError(II->TheDef->getLoc(), "error: unable to find operand: '" + 13823f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner OperandName.str() + "'"); 13830bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner} 13840bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner 1385414098571b19fc248fda2be194082cfd012d2729Chris Lattnervoid MatchableInfo::BuildInstructionResultOperands() { 1386662e5a30e864e71111b885d3da3cdd184772035dChris Lattner const CodeGenInstruction *ResultInst = getResultInst(); 1387828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 1388662e5a30e864e71111b885d3da3cdd184772035dChris Lattner // Loop over all operands of the result instruction, determining how to 1389662e5a30e864e71111b885d3da3cdd184772035dChris Lattner // populate them. 1390662e5a30e864e71111b885d3da3cdd184772035dChris Lattner for (unsigned i = 0, e = ResultInst->Operands.size(); i != e; ++i) { 1391662e5a30e864e71111b885d3da3cdd184772035dChris Lattner const CGIOperandList::OperandInfo &OpInfo = ResultInst->Operands[i]; 1392567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner 1393567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner // If this is a tied operand, just copy from the previously handled operand. 1394567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner int TiedOp = OpInfo.getTiedRegister(); 1395567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner if (TiedOp != -1) { 1396a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson ResOperands.push_back(ResOperand::getTiedOp(TiedOp)); 1397567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner continue; 1398567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner } 1399828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 1400a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson // Find out what operand from the asmparser this MCInst operand comes from. 1401ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner int SrcOperand = FindAsmOperandNamed(OpInfo.Name); 1402a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson if (OpInfo.Name.empty() || SrcOperand == -1) 1403a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson throw TGError(TheDef->getLoc(), "Instruction '" + 1404a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson TheDef->getName() + "' has operand '" + OpInfo.Name + 1405a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson "' that doesn't appear in asm string!"); 1406567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner 1407a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson // Check if the one AsmOperand populates the entire operand. 1408a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson unsigned NumOperands = OpInfo.MINumOperands; 1409a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson if (AsmOperands[SrcOperand].SubOpIdx == -1) { 1410a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson ResOperands.push_back(ResOperand::getRenderedOp(SrcOperand, NumOperands)); 14111d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner continue; 14121d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner } 1413a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson 1414a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson // Add a separate ResOperand for each suboperand. 1415a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson for (unsigned AI = 0; AI < NumOperands; ++AI) { 1416a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson assert(AsmOperands[SrcOperand+AI].SubOpIdx == (int)AI && 1417a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson AsmOperands[SrcOperand+AI].SrcOpName == OpInfo.Name && 1418a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson "unexpected AsmOperands for suboperands"); 1419a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson ResOperands.push_back(ResOperand::getRenderedOp(SrcOperand + AI, 1)); 1420a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson } 14211d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner } 14221d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner} 14231d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner 1424414098571b19fc248fda2be194082cfd012d2729Chris Lattnervoid MatchableInfo::BuildAliasResultOperands() { 1425414098571b19fc248fda2be194082cfd012d2729Chris Lattner const CodeGenInstAlias &CGA = *DefRec.get<const CodeGenInstAlias*>(); 1426414098571b19fc248fda2be194082cfd012d2729Chris Lattner const CodeGenInstruction *ResultInst = getResultInst(); 1427828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 1428414098571b19fc248fda2be194082cfd012d2729Chris Lattner // Loop over all operands of the result instruction, determining how to 1429414098571b19fc248fda2be194082cfd012d2729Chris Lattner // populate them. 1430414098571b19fc248fda2be194082cfd012d2729Chris Lattner unsigned AliasOpNo = 0; 1431a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson unsigned LastOpNo = CGA.ResultInstOperandIndex.size(); 1432414098571b19fc248fda2be194082cfd012d2729Chris Lattner for (unsigned i = 0, e = ResultInst->Operands.size(); i != e; ++i) { 1433a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson const CGIOperandList::OperandInfo *OpInfo = &ResultInst->Operands[i]; 1434828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 1435414098571b19fc248fda2be194082cfd012d2729Chris Lattner // If this is a tied operand, just copy from the previously handled operand. 1436a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson int TiedOp = OpInfo->getTiedRegister(); 1437414098571b19fc248fda2be194082cfd012d2729Chris Lattner if (TiedOp != -1) { 1438a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson ResOperands.push_back(ResOperand::getTiedOp(TiedOp)); 143990fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner continue; 144090fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner } 144190fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner 1442a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson // Handle all the suboperands for this operand. 1443a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson const std::string &OpName = OpInfo->Name; 1444a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson for ( ; AliasOpNo < LastOpNo && 1445a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson CGA.ResultInstOperandIndex[AliasOpNo].first == i; ++AliasOpNo) { 1446a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson int SubIdx = CGA.ResultInstOperandIndex[AliasOpNo].second; 1447a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson 1448a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson // Find out what operand from the asmparser that this MCInst operand 1449a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson // comes from. 1450a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson switch (CGA.ResultOperands[AliasOpNo].Kind) { 1451a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson default: assert(0 && "unexpected InstAlias operand kind"); 1452a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson case CodeGenInstAlias::ResultOperand::K_Record: { 1453a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson StringRef Name = CGA.ResultOperands[AliasOpNo].getName(); 1454a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson int SrcOperand = FindAsmOperand(Name, SubIdx); 1455a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson if (SrcOperand == -1) 1456a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson throw TGError(TheDef->getLoc(), "Instruction '" + 1457a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson TheDef->getName() + "' has operand '" + OpName + 1458a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson "' that doesn't appear in asm string!"); 1459a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson unsigned NumOperands = (SubIdx == -1 ? OpInfo->MINumOperands : 1); 1460a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson ResOperands.push_back(ResOperand::getRenderedOp(SrcOperand, 1461a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson NumOperands)); 1462a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson break; 1463a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson } 1464a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson case CodeGenInstAlias::ResultOperand::K_Imm: { 1465a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson int64_t ImmVal = CGA.ResultOperands[AliasOpNo].getImm(); 1466a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson ResOperands.push_back(ResOperand::getImmOp(ImmVal)); 1467a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson break; 1468a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson } 1469a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson case CodeGenInstAlias::ResultOperand::K_Reg: { 1470a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson Record *Reg = CGA.ResultOperands[AliasOpNo].getRegister(); 1471a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson ResOperands.push_back(ResOperand::getRegOp(Reg)); 1472a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson break; 1473a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson } 1474a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson } 147590fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner } 1476414098571b19fc248fda2be194082cfd012d2729Chris Lattner } 1477414098571b19fc248fda2be194082cfd012d2729Chris Lattner} 14781d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner 14795c228a945fe3e25a12d0f7e2e9b26b548d6f29f5Daniel Dunbarstatic void EmitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName, 148022bc5c4184a497353e33195dd12541a4f08b008aChris Lattner std::vector<MatchableInfo*> &Infos, 1481606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar raw_ostream &OS) { 1482b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar // Write the convert function to a separate stream, so we can drop it after 1483b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar // the enum. 1484b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar std::string ConvertFnBody; 1485b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar raw_string_ostream CvtOS(ConvertFnBody); 1486b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 148720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // Function we have already generated. 148820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar std::set<std::string> GeneratedFns; 148920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 1490b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar // Start the unified conversion function. 14915c228a945fe3e25a12d0f7e2e9b26b548d6f29f5Daniel Dunbar CvtOS << "bool " << Target.getName() << ClassName << "::\n"; 14925c228a945fe3e25a12d0f7e2e9b26b548d6f29f5Daniel Dunbar CvtOS << "ConvertToMCInst(unsigned Kind, MCInst &Inst, " 1493b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar << "unsigned Opcode,\n" 14949898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner << " const SmallVectorImpl<MCParsedAsmOperand*" 14959898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner << "> &Operands) {\n"; 1496b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar CvtOS << " Inst.setOpcode(Opcode);\n"; 1497b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar CvtOS << " switch (Kind) {\n"; 1498b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar CvtOS << " default:\n"; 1499b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 1500b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar // Start the enum, which we will generate inline. 1501b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 1502d51257a4368d52e2340073bc7ccd83f3c3f1c04dChris Lattner OS << "// Unified function for converting operands to MCInst instances.\n\n"; 1503b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar OS << "enum ConversionKind {\n"; 1504a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 15059898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner // TargetOperandClass - This is the target's operand class, like X86Operand. 15069898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner std::string TargetOperandClass = Target.getName() + "Operand"; 1507a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 150822bc5c4184a497353e33195dd12541a4f08b008aChris Lattner for (std::vector<MatchableInfo*>::const_iterator it = Infos.begin(), 150920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar ie = Infos.end(); it != ie; ++it) { 151022bc5c4184a497353e33195dd12541a4f08b008aChris Lattner MatchableInfo &II = **it; 151120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 1512cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar // Check if we have a custom match function. 151327b83d4ff2264d9a0e2367d92543efe4c0148931Daniel Dunbar std::string AsmMatchConverter = 151427b83d4ff2264d9a0e2367d92543efe4c0148931Daniel Dunbar II.getResultInst()->TheDef->getValueAsString("AsmMatchConverter"); 1515cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar if (!AsmMatchConverter.empty()) { 151627b83d4ff2264d9a0e2367d92543efe4c0148931Daniel Dunbar std::string Signature = "ConvertCustom_" + AsmMatchConverter; 1517cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar II.ConversionFnKind = Signature; 1518cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar 1519cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar // Check if we have already generated this signature. 1520cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar if (!GeneratedFns.insert(Signature).second) 1521cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar continue; 1522cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar 1523cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar // If not, emit it now. Add to the enum list. 1524cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar OS << " " << Signature << ",\n"; 1525cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar 1526cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar CvtOS << " case " << Signature << ":\n"; 1527b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar CvtOS << " return " << AsmMatchConverter 1528b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar << "(Inst, Opcode, Operands);\n"; 1529cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar continue; 1530cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar } 1531cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar 153220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // Build the conversion function signature. 153320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar std::string Signature = "Convert"; 1534dda855de8b3c60bce5d1d0d9eb11470c9710e30fChris Lattner std::string CaseBody; 1535dda855de8b3c60bce5d1d0d9eb11470c9710e30fChris Lattner raw_string_ostream CaseOS(CaseBody); 1536828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 1537dda855de8b3c60bce5d1d0d9eb11470c9710e30fChris Lattner // Compute the convert enum and the case body. 15381d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner for (unsigned i = 0, e = II.ResOperands.size(); i != e; ++i) { 15391d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner const MatchableInfo::ResOperand &OpInfo = II.ResOperands[i]; 15401d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner 15411d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner // Generate code to populate each result operand. 15421d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner switch (OpInfo.Kind) { 15431d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner case MatchableInfo::ResOperand::RenderAsmOperand: { 15441d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner // This comes from something we parsed. 15451d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner MatchableInfo::AsmOperand &Op = II.AsmOperands[OpInfo.AsmOperandNum]; 1546828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 15479b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner // Registers are always converted the same, don't duplicate the 15489b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner // conversion function based on them. 15499b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner Signature += "__"; 15509b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner if (Op.Class->isRegisterClass()) 15519b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner Signature += "Reg"; 15529b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner else 15539b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner Signature += Op.Class->ClassName; 1554a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson Signature += utostr(OpInfo.MINumOperands); 15551d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner Signature += "_" + itostr(OpInfo.AsmOperandNum); 1556828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 15579b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner CaseOS << " ((" << TargetOperandClass << "*)Operands[" 15581d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner << (OpInfo.AsmOperandNum+1) << "])->" << Op.Class->RenderMethod 1559a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson << "(Inst, " << OpInfo.MINumOperands << ");\n"; 15601d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner break; 15611d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner } 1562828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 15631d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner case MatchableInfo::ResOperand::TiedOperand: { 15641d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner // If this operand is tied to a previous one, just copy the MCInst 15651d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner // operand from the earlier one.We can only tie single MCOperand values. 1566a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson //assert(OpInfo.MINumOperands == 1 && "Not a singular MCOperand"); 15671d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner unsigned TiedOp = OpInfo.TiedOperandNum; 15687a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner assert(i > TiedOp && "Tied operand precedes its target!"); 15691d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner CaseOS << " Inst.addOperand(Inst.getOperand(" << TiedOp << "));\n"; 15701d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner Signature += "__Tie" + utostr(TiedOp); 15711d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner break; 15721d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner } 157398c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner case MatchableInfo::ResOperand::ImmOperand: { 157498c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner int64_t Val = OpInfo.ImmVal; 157598c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner CaseOS << " Inst.addOperand(MCOperand::CreateImm(" << Val << "));\n"; 157698c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner Signature += "__imm" + itostr(Val); 157798c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner break; 157898c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner } 157990fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner case MatchableInfo::ResOperand::RegOperand: { 1580dc1a2bd3aa199693413f39dd723cc14a77e9f131Bob Wilson if (OpInfo.Register == 0) { 1581dc1a2bd3aa199693413f39dd723cc14a77e9f131Bob Wilson CaseOS << " Inst.addOperand(MCOperand::CreateReg(0));\n"; 1582dc1a2bd3aa199693413f39dd723cc14a77e9f131Bob Wilson Signature += "__reg0"; 1583dc1a2bd3aa199693413f39dd723cc14a77e9f131Bob Wilson } else { 1584dc1a2bd3aa199693413f39dd723cc14a77e9f131Bob Wilson std::string N = getQualifiedName(OpInfo.Register); 1585dc1a2bd3aa199693413f39dd723cc14a77e9f131Bob Wilson CaseOS << " Inst.addOperand(MCOperand::CreateReg(" << N << "));\n"; 1586dc1a2bd3aa199693413f39dd723cc14a77e9f131Bob Wilson Signature += "__reg" + OpInfo.Register->getName(); 1587dc1a2bd3aa199693413f39dd723cc14a77e9f131Bob Wilson } 1588828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson } 1589af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar } 15909b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner } 1591828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 1592b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar II.ConversionFnKind = Signature; 1593a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 1594b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar // Check if we have already generated this signature. 159520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (!GeneratedFns.insert(Signature).second) 159620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar continue; 1597a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 1598dda855de8b3c60bce5d1d0d9eb11470c9710e30fChris Lattner // If not, emit it now. Add to the enum list. 1599b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar OS << " " << Signature << ",\n"; 1600b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 1601b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar CvtOS << " case " << Signature << ":\n"; 1602dda855de8b3c60bce5d1d0d9eb11470c9710e30fChris Lattner CvtOS << CaseOS.str(); 1603b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar CvtOS << " return true;\n"; 1604a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar } 1605b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 1606b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar // Finish the convert function. 1607b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 1608b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar CvtOS << " }\n"; 1609b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar CvtOS << " return false;\n"; 1610b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar CvtOS << "}\n\n"; 1611b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 1612b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar // Finish the enum, and drop the convert function after it. 1613b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 1614b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar OS << " NumConversionVariants\n"; 1615b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar OS << "};\n\n"; 1616a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 1617b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar OS << CvtOS.str(); 161820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar} 161920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 1620a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar/// EmitMatchClassEnumeration - Emit the enumeration for match class kinds. 1621a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarstatic void EmitMatchClassEnumeration(CodeGenTarget &Target, 1622a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::vector<ClassInfo*> &Infos, 1623a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar raw_ostream &OS) { 1624a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "namespace {\n\n"; 1625a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1626a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "/// MatchClassKind - The kinds of classes which participate in\n" 1627a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar << "/// instruction matching.\n"; 1628a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "enum MatchClassKind {\n"; 1629a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " InvalidMatchClass = 0,\n"; 1630a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach for (std::vector<ClassInfo*>::iterator it = Infos.begin(), 1631a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar ie = Infos.end(); it != ie; ++it) { 1632a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar ClassInfo &CI = **it; 1633a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " " << CI.Name << ", // "; 1634a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar if (CI.Kind == ClassInfo::Token) { 1635a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "'" << CI.ValueName << "'\n"; 1636ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } else if (CI.isRegisterClass()) { 1637a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar if (!CI.ValueName.empty()) 1638a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "register class '" << CI.ValueName << "'\n"; 1639a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar else 1640a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "derived register class\n"; 1641a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } else { 1642a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "user defined class '" << CI.ValueName << "'\n"; 1643a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 1644a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 1645a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " NumMatchClassKinds\n"; 1646a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "};\n\n"; 1647a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1648a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "}\n\n"; 1649a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar} 1650a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1651b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach/// EmitValidateOperandClass - Emit the function to validate an operand class. 1652b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbachstatic void EmitValidateOperandClass(AsmMatcherInfo &Info, 1653b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach raw_ostream &OS) { 1654b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach OS << "static bool ValidateOperandClass(MCParsedAsmOperand *GOp, " 1655b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach << "MatchClassKind Kind) {\n"; 1656b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach OS << " " << Info.Target.getName() << "Operand &Operand = *(" 165702bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner << Info.Target.getName() << "Operand*)GOp;\n"; 1658ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 1659b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach // Check for Token operands first. 1660a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " if (Operand.isToken())\n"; 1661b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach OS << " return MatchTokenString(Operand.getToken()) == Kind;\n\n"; 1662ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 1663b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach // Check for register operands, including sub-classes. 1664ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " if (Operand.isReg()) {\n"; 1665b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach OS << " MatchClassKind OpKind;\n"; 1666ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " switch (Operand.getReg()) {\n"; 1667b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach OS << " default: OpKind = InvalidMatchClass; break;\n"; 1668a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach for (std::map<Record*, ClassInfo*>::iterator 1669ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar it = Info.RegisterClasses.begin(), ie = Info.RegisterClasses.end(); 1670ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar it != ie; ++it) 167102bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner OS << " case " << Info.Target.getName() << "::" 1672b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach << it->first->getName() << ": OpKind = " << it->second->Name 1673b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach << "; break;\n"; 1674ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " }\n"; 1675b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach OS << " return IsSubclass(OpKind, Kind);\n"; 1676ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " }\n\n"; 1677ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 1678b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach // Check the user classes. We don't care what order since we're only 1679b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach // actually matching against one of them. 1680a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach for (std::vector<ClassInfo*>::iterator it = Info.Classes.begin(), 1681ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ie = Info.Classes.end(); it != ie; ++it) { 1682a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar ClassInfo &CI = **it; 1683a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1684ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (!CI.isUserClass()) 1685ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar continue; 1686828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 1687b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach OS << " // '" << CI.ClassName << "' class\n"; 1688b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach OS << " if (Kind == " << CI.Name 1689b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach << " && Operand." << CI.PredicateMethod << "()) {\n"; 1690b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach OS << " return true;\n"; 1691ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " }\n\n"; 1692a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 1693828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 1694b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach OS << " return false;\n"; 1695a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "}\n\n"; 1696a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar} 1697a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1698fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar/// EmitIsSubclass - Emit the subclass predicate function. 1699fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbarstatic void EmitIsSubclass(CodeGenTarget &Target, 1700fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar std::vector<ClassInfo*> &Infos, 1701fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar raw_ostream &OS) { 1702fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar OS << "/// IsSubclass - Compute whether \\arg A is a subclass of \\arg B.\n"; 1703fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar OS << "static bool IsSubclass(MatchClassKind A, MatchClassKind B) {\n"; 1704fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar OS << " if (A == B)\n"; 1705fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar OS << " return true;\n\n"; 1706fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar 1707fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar OS << " switch (A) {\n"; 1708fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar OS << " default:\n"; 1709fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar OS << " return false;\n"; 1710a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach for (std::vector<ClassInfo*>::iterator it = Infos.begin(), 1711fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar ie = Infos.end(); it != ie; ++it) { 1712fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar ClassInfo &A = **it; 1713fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar 1714fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar if (A.Kind != ClassInfo::Token) { 1715fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar std::vector<StringRef> SuperClasses; 1716a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach for (std::vector<ClassInfo*>::iterator it = Infos.begin(), 1717fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar ie = Infos.end(); it != ie; ++it) { 1718fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar ClassInfo &B = **it; 1719fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar 1720ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (&A != &B && A.isSubsetOf(B)) 1721fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar SuperClasses.push_back(B.Name); 1722fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar } 1723fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar 1724fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar if (SuperClasses.empty()) 1725fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar continue; 1726fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar 1727fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar OS << "\n case " << A.Name << ":\n"; 1728fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar 1729fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar if (SuperClasses.size() == 1) { 1730ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " return B == " << SuperClasses.back() << ";\n"; 1731fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar continue; 1732fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar } 1733fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar 1734ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " switch (B) {\n"; 1735ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " default: return false;\n"; 1736fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i) 1737ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " case " << SuperClasses[i] << ": return true;\n"; 1738ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " }\n"; 1739fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar } 1740fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar } 1741fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar OS << " }\n"; 1742fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar OS << "}\n\n"; 1743fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar} 1744fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar 1745245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar/// EmitMatchTokenString - Emit the function to match a token string to the 1746245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar/// appropriate match class value. 1747245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbarstatic void EmitMatchTokenString(CodeGenTarget &Target, 1748245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar std::vector<ClassInfo*> &Infos, 1749245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar raw_ostream &OS) { 1750245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar // Construct the match list. 17515845e5c62b42d025557765006515156691a6a8b1Chris Lattner std::vector<StringMatcher::StringPair> Matches; 1752a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach for (std::vector<ClassInfo*>::iterator it = Infos.begin(), 1753245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar ie = Infos.end(); it != ie; ++it) { 1754245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar ClassInfo &CI = **it; 1755245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar 1756245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar if (CI.Kind == ClassInfo::Token) 17575845e5c62b42d025557765006515156691a6a8b1Chris Lattner Matches.push_back(StringMatcher::StringPair(CI.ValueName, 17585845e5c62b42d025557765006515156691a6a8b1Chris Lattner "return " + CI.Name + ";")); 1759245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar } 1760245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar 1761b8d6e98e566724f58344d275a4bd675249bb713aChris Lattner OS << "static MatchClassKind MatchTokenString(StringRef Name) {\n"; 1762245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar 17635845e5c62b42d025557765006515156691a6a8b1Chris Lattner StringMatcher("Name", Matches, OS).Emit(); 1764245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar 1765245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar OS << " return InvalidMatchClass;\n"; 1766245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar OS << "}\n\n"; 1767245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar} 176870add884e4967f511e2cbb35c61534186b9b418aChris Lattner 17692234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar/// EmitMatchRegisterName - Emit the function to match a string to the target 17702234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar/// specific register enum. 17712234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbarstatic void EmitMatchRegisterName(CodeGenTarget &Target, Record *AsmParser, 17722234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar raw_ostream &OS) { 1773245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar // Construct the match list. 17745845e5c62b42d025557765006515156691a6a8b1Chris Lattner std::vector<StringMatcher::StringPair> Matches; 1775abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen const std::vector<CodeGenRegister*> &Regs = 1776abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen Target.getRegBank().getRegisters(); 1777abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen for (unsigned i = 0, e = Regs.size(); i != e; ++i) { 1778abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen const CodeGenRegister *Reg = Regs[i]; 1779abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen if (Reg->TheDef->getValueAsString("AsmName").empty()) 178020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar continue; 178120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 17825845e5c62b42d025557765006515156691a6a8b1Chris Lattner Matches.push_back(StringMatcher::StringPair( 1783abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen Reg->TheDef->getValueAsString("AsmName"), 1784abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen "return " + utostr(Reg->EnumValue) + ";")); 178520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 1786a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 1787b8d6e98e566724f58344d275a4bd675249bb713aChris Lattner OS << "static unsigned MatchRegisterName(StringRef Name) {\n"; 1788245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar 17895845e5c62b42d025557765006515156691a6a8b1Chris Lattner StringMatcher("Name", Matches, OS).Emit(); 1790a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 1791245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar OS << " return 0;\n"; 179220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar OS << "}\n\n"; 17932234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar} 17942234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar 179554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar/// EmitSubtargetFeatureFlagEnumeration - Emit the subtarget feature flag 179654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar/// definitions. 179702bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattnerstatic void EmitSubtargetFeatureFlagEnumeration(AsmMatcherInfo &Info, 179854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar raw_ostream &OS) { 179954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << "// Flags for subtarget features that participate in " 180054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar << "instruction matching.\n"; 180154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << "enum SubtargetFeatureFlag {\n"; 180254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar for (std::map<Record*, SubtargetFeatureInfo*>::const_iterator 180354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar it = Info.SubtargetFeatures.begin(), 180454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar ie = Info.SubtargetFeatures.end(); it != ie; ++it) { 180554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar SubtargetFeatureInfo &SFI = *it->second; 18060aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner OS << " " << SFI.getEnumName() << " = (1 << " << SFI.Index << "),\n"; 180754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar } 180854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << " Feature_None = 0\n"; 180954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << "};\n\n"; 181054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar} 181154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 181254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar/// EmitComputeAvailableFeatures - Emit the function to compute the list of 181354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar/// available features given a subtarget. 181402bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattnerstatic void EmitComputeAvailableFeatures(AsmMatcherInfo &Info, 181554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar raw_ostream &OS) { 181654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar std::string ClassName = 181754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar Info.AsmParser->getValueAsString("AsmParserClassName"); 181854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 181902bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner OS << "unsigned " << Info.Target.getName() << ClassName << "::\n" 1820ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng << "ComputeAvailableFeatures(uint64_t FB) const {\n"; 182154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << " unsigned Features = 0;\n"; 182254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar for (std::map<Record*, SubtargetFeatureInfo*>::const_iterator 182354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar it = Info.SubtargetFeatures.begin(), 182454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar ie = Info.SubtargetFeatures.end(); it != ie; ++it) { 182554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar SubtargetFeatureInfo &SFI = *it->second; 1826ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 1827ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng OS << " if ("; 1828ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng StringRef Conds = SFI.TheDef->getValueAsString("AssemblerCondString"); 1829ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng std::pair<StringRef,StringRef> Comma = Conds.split(','); 1830ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng bool First = true; 1831ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng do { 1832ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng if (!First) 1833ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng OS << " && "; 1834ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 1835ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng bool Neg = false; 1836ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng StringRef Cond = Comma.first; 1837ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng if (Cond[0] == '!') { 1838ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng Neg = true; 1839ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng Cond = Cond.substr(1); 1840ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 1841ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 1842ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng OS << "((FB & " << Info.Target.getName() << "::" << Cond << ")"; 1843ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng if (Neg) 1844ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng OS << " == 0"; 1845ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng else 1846ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng OS << " != 0"; 1847ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng OS << ")"; 1848ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 1849ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng if (Comma.second.empty()) 1850ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng break; 1851ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 1852ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng First = false; 1853ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng Comma = Comma.second.split(','); 1854ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } while (true); 1855ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 1856ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng OS << ")\n"; 18570aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner OS << " Features |= " << SFI.getEnumName() << ";\n"; 185854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar } 185954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << " return Features;\n"; 186054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << "}\n\n"; 186154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar} 186254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 18636fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattnerstatic std::string GetAliasRequiredFeatures(Record *R, 18646fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner const AsmMatcherInfo &Info) { 1865693173feefaa326fad0e386470846fb3199ba381Chris Lattner std::vector<Record*> ReqFeatures = R->getValueAsListOfDefs("Predicates"); 1866693173feefaa326fad0e386470846fb3199ba381Chris Lattner std::string Result; 1867693173feefaa326fad0e386470846fb3199ba381Chris Lattner unsigned NumFeatures = 0; 1868693173feefaa326fad0e386470846fb3199ba381Chris Lattner for (unsigned i = 0, e = ReqFeatures.size(); i != e; ++i) { 18694a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner SubtargetFeatureInfo *F = Info.getSubtargetFeature(ReqFeatures[i]); 1870828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 18714a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner if (F == 0) 18724a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner throw TGError(R->getLoc(), "Predicate '" + ReqFeatures[i]->getName() + 18734a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner "' is not marked as an AssemblerPredicate!"); 1874828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 18754a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner if (NumFeatures) 18764a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner Result += '|'; 1877828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 18784a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner Result += F->getEnumName(); 18794a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner ++NumFeatures; 1880693173feefaa326fad0e386470846fb3199ba381Chris Lattner } 1881828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 1882693173feefaa326fad0e386470846fb3199ba381Chris Lattner if (NumFeatures > 1) 1883693173feefaa326fad0e386470846fb3199ba381Chris Lattner Result = '(' + Result + ')'; 1884693173feefaa326fad0e386470846fb3199ba381Chris Lattner return Result; 1885693173feefaa326fad0e386470846fb3199ba381Chris Lattner} 1886693173feefaa326fad0e386470846fb3199ba381Chris Lattner 1887674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner/// EmitMnemonicAliases - If the target has any MnemonicAlias<> definitions, 18887fd4489de11bdf06f6c852d42abafea013b76f28Chris Lattner/// emit a function for them and return true, otherwise return false. 18890aed1e770149301af473ce05a83f73be01c06fe0Chris Lattnerstatic bool EmitMnemonicAliases(raw_ostream &OS, const AsmMatcherInfo &Info) { 1890c0a7007d3a6a7bb31eec568b9dfdb8fb137702e5Daniel Dunbar // Ignore aliases when match-prefix is set. 1891c0a7007d3a6a7bb31eec568b9dfdb8fb137702e5Daniel Dunbar if (!MatchPrefix.empty()) 1892c0a7007d3a6a7bb31eec568b9dfdb8fb137702e5Daniel Dunbar return false; 1893c0a7007d3a6a7bb31eec568b9dfdb8fb137702e5Daniel Dunbar 1894674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner std::vector<Record*> Aliases = 189567db883487fca3472fdde51e931657e22d4d0495Chris Lattner Info.getRecords().getAllDerivedDefinitions("MnemonicAlias"); 18967fd4489de11bdf06f6c852d42abafea013b76f28Chris Lattner if (Aliases.empty()) return false; 1897674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner 18988cc0a6b788a17b3afc779e9da90f5203c8b78436Chris Lattner OS << "static void ApplyMnemonicAliases(StringRef &Mnemonic, " 18998cc0a6b788a17b3afc779e9da90f5203c8b78436Chris Lattner "unsigned Features) {\n"; 1900828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 19014fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner // Keep track of all the aliases from a mnemonic. Use an std::map so that the 19024fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner // iteration order of the map is stable. 19034fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner std::map<std::string, std::vector<Record*> > AliasesFromMnemonic; 1904828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 1905674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner for (unsigned i = 0, e = Aliases.size(); i != e; ++i) { 1906674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner Record *R = Aliases[i]; 19074fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner AliasesFromMnemonic[R->getValueAsString("FromMnemonic")].push_back(R); 19084fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner } 19094fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner 19104fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner // Process each alias a "from" mnemonic at a time, building the code executed 19114fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner // by the string remapper. 19124fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner std::vector<StringMatcher::StringPair> Cases; 19134fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner for (std::map<std::string, std::vector<Record*> >::iterator 19144fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner I = AliasesFromMnemonic.begin(), E = AliasesFromMnemonic.end(); 19154fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner I != E; ++I) { 19164fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner const std::vector<Record*> &ToVec = I->second; 1917693173feefaa326fad0e386470846fb3199ba381Chris Lattner 1918693173feefaa326fad0e386470846fb3199ba381Chris Lattner // Loop through each alias and emit code that handles each case. If there 1919693173feefaa326fad0e386470846fb3199ba381Chris Lattner // are two instructions without predicates, emit an error. If there is one, 1920693173feefaa326fad0e386470846fb3199ba381Chris Lattner // emit it last. 1921693173feefaa326fad0e386470846fb3199ba381Chris Lattner std::string MatchCode; 1922693173feefaa326fad0e386470846fb3199ba381Chris Lattner int AliasWithNoPredicate = -1; 1923828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 1924693173feefaa326fad0e386470846fb3199ba381Chris Lattner for (unsigned i = 0, e = ToVec.size(); i != e; ++i) { 1925693173feefaa326fad0e386470846fb3199ba381Chris Lattner Record *R = ToVec[i]; 19266fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner std::string FeatureMask = GetAliasRequiredFeatures(R, Info); 1927828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 1928693173feefaa326fad0e386470846fb3199ba381Chris Lattner // If this unconditionally matches, remember it for later and diagnose 1929693173feefaa326fad0e386470846fb3199ba381Chris Lattner // duplicates. 1930693173feefaa326fad0e386470846fb3199ba381Chris Lattner if (FeatureMask.empty()) { 1931693173feefaa326fad0e386470846fb3199ba381Chris Lattner if (AliasWithNoPredicate != -1) { 1932693173feefaa326fad0e386470846fb3199ba381Chris Lattner // We can't have two aliases from the same mnemonic with no predicate. 1933693173feefaa326fad0e386470846fb3199ba381Chris Lattner PrintError(ToVec[AliasWithNoPredicate]->getLoc(), 1934693173feefaa326fad0e386470846fb3199ba381Chris Lattner "two MnemonicAliases with the same 'from' mnemonic!"); 19354164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner throw TGError(R->getLoc(), "this is the other MnemonicAlias."); 1936693173feefaa326fad0e386470846fb3199ba381Chris Lattner } 1937828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 1938693173feefaa326fad0e386470846fb3199ba381Chris Lattner AliasWithNoPredicate = i; 1939693173feefaa326fad0e386470846fb3199ba381Chris Lattner continue; 1940693173feefaa326fad0e386470846fb3199ba381Chris Lattner } 19416ef6ceda6883d0ee543d8da86d16b0fcdcecab96Joerg Sonnenberger if (R->getValueAsString("ToMnemonic") == I->first) 19426ef6ceda6883d0ee543d8da86d16b0fcdcecab96Joerg Sonnenberger throw TGError(R->getLoc(), "MnemonicAlias to the same string"); 1943828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 19448cf8bcc40c977713e51fb85fb9f24a0ecfbde24bChris Lattner if (!MatchCode.empty()) 19458cf8bcc40c977713e51fb85fb9f24a0ecfbde24bChris Lattner MatchCode += "else "; 1946693173feefaa326fad0e386470846fb3199ba381Chris Lattner MatchCode += "if ((Features & " + FeatureMask + ") == "+FeatureMask+")\n"; 1947693173feefaa326fad0e386470846fb3199ba381Chris Lattner MatchCode += " Mnemonic = \"" +R->getValueAsString("ToMnemonic")+"\";\n"; 1948693173feefaa326fad0e386470846fb3199ba381Chris Lattner } 1949828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 1950693173feefaa326fad0e386470846fb3199ba381Chris Lattner if (AliasWithNoPredicate != -1) { 1951693173feefaa326fad0e386470846fb3199ba381Chris Lattner Record *R = ToVec[AliasWithNoPredicate]; 19528cf8bcc40c977713e51fb85fb9f24a0ecfbde24bChris Lattner if (!MatchCode.empty()) 19538cf8bcc40c977713e51fb85fb9f24a0ecfbde24bChris Lattner MatchCode += "else\n "; 19548cf8bcc40c977713e51fb85fb9f24a0ecfbde24bChris Lattner MatchCode += "Mnemonic = \"" + R->getValueAsString("ToMnemonic")+"\";\n"; 19554fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner } 1956828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 1957693173feefaa326fad0e386470846fb3199ba381Chris Lattner MatchCode += "return;"; 1958693173feefaa326fad0e386470846fb3199ba381Chris Lattner 1959693173feefaa326fad0e386470846fb3199ba381Chris Lattner Cases.push_back(std::make_pair(I->first, MatchCode)); 1960674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner } 1961828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 1962674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner StringMatcher("Mnemonic", Cases, OS).Emit(); 196355b5e85643b189636758188f11b598c45178407fDaniel Dunbar OS << "}\n\n"; 1964828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 19657fd4489de11bdf06f6c852d42abafea013b76f28Chris Lattner return true; 1966674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner} 1967674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner 1968e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopesstatic void EmitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target, 1969e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes const AsmMatcherInfo &Info, StringRef ClassName) { 1970e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes // Emit the static custom operand parsing table; 1971e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << "namespace {\n"; 1972e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " struct OperandMatchEntry {\n"; 1973e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " const char *Mnemonic;\n"; 1974e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " unsigned OperandMask;\n"; 1975e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " MatchClassKind Class;\n"; 1976e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " unsigned RequiredFeatures;\n"; 1977e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " };\n\n"; 1978e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 1979e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " // Predicate for searching for an opcode.\n"; 1980e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " struct LessOpcodeOperand {\n"; 1981e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " bool operator()(const OperandMatchEntry &LHS, StringRef RHS) {\n"; 1982e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " return StringRef(LHS.Mnemonic) < RHS;\n"; 1983e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " }\n"; 1984e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " bool operator()(StringRef LHS, const OperandMatchEntry &RHS) {\n"; 1985e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " return LHS < StringRef(RHS.Mnemonic);\n"; 1986e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " }\n"; 1987e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " bool operator()(const OperandMatchEntry &LHS,"; 1988e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " const OperandMatchEntry &RHS) {\n"; 1989e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " return StringRef(LHS.Mnemonic) < StringRef(RHS.Mnemonic);\n"; 1990e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " }\n"; 1991e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " };\n"; 1992e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 1993e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << "} // end anonymous namespace.\n\n"; 1994e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 1995e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << "static const OperandMatchEntry OperandMatchTable[" 1996e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes << Info.OperandMatchInfo.size() << "] = {\n"; 1997e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 1998e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " /* Mnemonic, Operand List Mask, Operand Class, Features */\n"; 1999e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes for (std::vector<OperandMatchEntry>::const_iterator it = 2000e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes Info.OperandMatchInfo.begin(), ie = Info.OperandMatchInfo.end(); 2001e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes it != ie; ++it) { 2002e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes const OperandMatchEntry &OMI = *it; 2003e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes const MatchableInfo &II = *OMI.MI; 2004e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2005e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " { \"" << II.Mnemonic << "\"" 2006e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes << ", " << OMI.OperandMask; 2007e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2008e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " /* "; 2009e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes bool printComma = false; 2010e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes for (int i = 0, e = 31; i !=e; ++i) 2011e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes if (OMI.OperandMask & (1 << i)) { 2012e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes if (printComma) 2013e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << ", "; 2014e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << i; 2015e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes printComma = true; 2016e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes } 2017e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " */"; 2018e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2019e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << ", " << OMI.CI->Name 2020e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes << ", "; 2021e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2022e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes // Write the required features mask. 2023e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes if (!II.RequiredFeatures.empty()) { 2024e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes for (unsigned i = 0, e = II.RequiredFeatures.size(); i != e; ++i) { 2025e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes if (i) OS << "|"; 2026e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << II.RequiredFeatures[i]->getEnumName(); 2027e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes } 2028e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes } else 2029e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << "0"; 2030e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " },\n"; 2031e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes } 2032e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << "};\n\n"; 2033e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2034e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes // Emit the operand class switch to call the correct custom parser for 2035e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes // the found operand class. 2036f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OS << Target.getName() << ClassName << "::OperandMatchResultTy " 2037f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach << Target.getName() << ClassName << "::\n" 2038e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes << "TryCustomParseOperand(SmallVectorImpl<MCParsedAsmOperand*>" 2039e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes << " &Operands,\n unsigned MCK) {\n\n" 2040e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes << " switch(MCK) {\n"; 2041e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2042e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes for (std::vector<ClassInfo*>::const_iterator it = Info.Classes.begin(), 2043e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes ie = Info.Classes.end(); it != ie; ++it) { 2044e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes ClassInfo *CI = *it; 2045e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes if (CI->ParserMethod.empty()) 2046e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes continue; 2047e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " case " << CI->Name << ":\n" 2048e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes << " return " << CI->ParserMethod << "(Operands);\n"; 2049e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes } 2050e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2051e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " default:\n"; 2052f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OS << " return MatchOperand_NoMatch;\n"; 2053e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " }\n"; 2054f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OS << " return MatchOperand_NoMatch;\n"; 2055e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << "}\n\n"; 2056e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2057e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes // Emit the static custom operand parser. This code is very similar with 2058e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes // the other matcher. Also use MatchResultTy here just in case we go for 2059e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes // a better error handling. 2060f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OS << Target.getName() << ClassName << "::OperandMatchResultTy " 2061e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes << Target.getName() << ClassName << "::\n" 2062e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes << "MatchOperandParserImpl(SmallVectorImpl<MCParsedAsmOperand*>" 2063e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes << " &Operands,\n StringRef Mnemonic) {\n"; 2064e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2065e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes // Emit code to get the available features. 2066e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " // Get the current feature set.\n"; 2067e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " unsigned AvailableFeatures = getAvailableFeatures();\n\n"; 2068e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2069e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " // Get the next operand index.\n"; 2070e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " unsigned NextOpNum = Operands.size()-1;\n"; 2071e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2072e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes // Emit code to search the table. 2073e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " // Search the table.\n"; 2074e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " std::pair<const OperandMatchEntry*, const OperandMatchEntry*>"; 2075e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " MnemonicRange =\n"; 2076e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " std::equal_range(OperandMatchTable, OperandMatchTable+" 2077e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes << Info.OperandMatchInfo.size() << ", Mnemonic,\n" 2078e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes << " LessOpcodeOperand());\n\n"; 2079e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2080e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " if (MnemonicRange.first == MnemonicRange.second)\n"; 2081f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OS << " return MatchOperand_NoMatch;\n\n"; 2082e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2083e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " for (const OperandMatchEntry *it = MnemonicRange.first,\n" 2084e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes << " *ie = MnemonicRange.second; it != ie; ++it) {\n"; 2085e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2086e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " // equal_range guarantees that instruction mnemonic matches.\n"; 2087e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " assert(Mnemonic == it->Mnemonic);\n\n"; 2088e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2089e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes // Emit check that the required features are available. 2090e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " // check if the available features match\n"; 2091e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " if ((AvailableFeatures & it->RequiredFeatures) " 2092e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes << "!= it->RequiredFeatures) {\n"; 2093e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " continue;\n"; 2094e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " }\n\n"; 2095e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2096e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes // Emit check to ensure the operand number matches. 2097e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " // check if the operand in question has a custom parser.\n"; 2098e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " if (!(it->OperandMask & (1 << NextOpNum)))\n"; 2099e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " continue;\n\n"; 2100e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2101e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes // Emit call to the custom parser method 2102e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " // call custom parse method to handle the operand\n"; 2103f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OS << " OperandMatchResultTy Result = "; 2104f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OS << "TryCustomParseOperand(Operands, it->Class);\n"; 2105f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OS << " if (Result != MatchOperand_NoMatch)\n"; 2106f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OS << " return Result;\n"; 2107e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " }\n\n"; 2108e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2109f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OS << " // Okay, we had no match.\n"; 2110f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OS << " return MatchOperand_NoMatch;\n"; 2111e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << "}\n\n"; 2112e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes} 2113e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 21142234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbarvoid AsmMatcherEmitter::run(raw_ostream &OS) { 211567db883487fca3472fdde51e931657e22d4d0495Chris Lattner CodeGenTarget Target(Records); 21162234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar Record *AsmParser = Target.getAsmParser(); 21172234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar std::string ClassName = AsmParser->getValueAsString("AsmParserClassName"); 21182234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar 2119a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // Compute the information on the instructions to match. 212067db883487fca3472fdde51e931657e22d4d0495Chris Lattner AsmMatcherInfo Info(AsmParser, Target, Records); 212102bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner Info.BuildInfo(); 212220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 2123e1f6de3fbd892ea3f918a26912660cf316866fc1Daniel Dunbar // Sort the instruction table using the partial order on classes. We use 2124e1f6de3fbd892ea3f918a26912660cf316866fc1Daniel Dunbar // stable_sort to ensure that ambiguous instructions are still 2125e1f6de3fbd892ea3f918a26912660cf316866fc1Daniel Dunbar // deterministically ordered. 212622bc5c4184a497353e33195dd12541a4f08b008aChris Lattner std::stable_sort(Info.Matchables.begin(), Info.Matchables.end(), 212722bc5c4184a497353e33195dd12541a4f08b008aChris Lattner less_ptr<MatchableInfo>()); 2128a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 2129b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar DEBUG_WITH_TYPE("instruction_info", { 213022bc5c4184a497353e33195dd12541a4f08b008aChris Lattner for (std::vector<MatchableInfo*>::iterator 213122bc5c4184a497353e33195dd12541a4f08b008aChris Lattner it = Info.Matchables.begin(), ie = Info.Matchables.end(); 2132a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar it != ie; ++it) 213320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar (*it)->dump(); 213420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar }); 213520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 213622bc5c4184a497353e33195dd12541a4f08b008aChris Lattner // Check for ambiguous matchables. 2137fa0d74d58e6c70ef032afb5f83680276dc4d7370Chris Lattner DEBUG_WITH_TYPE("ambiguous_instrs", { 2138fa0d74d58e6c70ef032afb5f83680276dc4d7370Chris Lattner unsigned NumAmbiguous = 0; 213922bc5c4184a497353e33195dd12541a4f08b008aChris Lattner for (unsigned i = 0, e = Info.Matchables.size(); i != e; ++i) { 214087410368e1bd50408e787f6ece0e58d94c53c1e1Chris Lattner for (unsigned j = i + 1; j != e; ++j) { 214122bc5c4184a497353e33195dd12541a4f08b008aChris Lattner MatchableInfo &A = *Info.Matchables[i]; 214222bc5c4184a497353e33195dd12541a4f08b008aChris Lattner MatchableInfo &B = *Info.Matchables[j]; 2143a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 21441f64ac403549413b7d5c735d8530257f8661943bBob Wilson if (A.CouldMatchAmbiguouslyWith(B)) { 214522bc5c4184a497353e33195dd12541a4f08b008aChris Lattner errs() << "warning: ambiguous matchables:\n"; 2146fa0d74d58e6c70ef032afb5f83680276dc4d7370Chris Lattner A.dump(); 2147fa0d74d58e6c70ef032afb5f83680276dc4d7370Chris Lattner errs() << "\nis incomparable with:\n"; 2148fa0d74d58e6c70ef032afb5f83680276dc4d7370Chris Lattner B.dump(); 2149fa0d74d58e6c70ef032afb5f83680276dc4d7370Chris Lattner errs() << "\n\n"; 215087410368e1bd50408e787f6ece0e58d94c53c1e1Chris Lattner ++NumAmbiguous; 215187410368e1bd50408e787f6ece0e58d94c53c1e1Chris Lattner } 21522b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar } 2153606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar } 215487410368e1bd50408e787f6ece0e58d94c53c1e1Chris Lattner if (NumAmbiguous) 2155a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach errs() << "warning: " << NumAmbiguous 215622bc5c4184a497353e33195dd12541a4f08b008aChris Lattner << " ambiguous matchables!\n"; 2157fa0d74d58e6c70ef032afb5f83680276dc4d7370Chris Lattner }); 2158606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 2159e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes // Compute the information on the custom operand parsing. 2160e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes Info.BuildOperandMatchInfo(); 2161e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 21621095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar // Write the output. 21631095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 21641095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar EmitSourceFileHeader("Assembly Matcher Source Fragment", OS); 21651095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 21660692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner // Information for the class declaration. 21670692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner OS << "\n#ifdef GET_ASSEMBLER_HEADER\n"; 21680692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner OS << "#undef GET_ASSEMBLER_HEADER\n"; 216984cb033bf30b6f93ae2fbea71513970147e08dc2Jim Grosbach OS << " // This should be included into the middle of the declaration of\n"; 217079ed3f77e8b87615b80054ca6e4e3ba5e07445bdChris Lattner OS << " // your subclasses implementation of TargetAsmParser.\n"; 2171ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng OS << " unsigned ComputeAvailableFeatures(uint64_t FeatureBits) const;\n"; 217279ed3f77e8b87615b80054ca6e4e3ba5e07445bdChris Lattner OS << " enum MatchResultTy {\n"; 2173b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar OS << " Match_ConversionFail,\n"; 2174b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar OS << " Match_InvalidOperand,\n"; 2175b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar OS << " Match_MissingFeature,\n"; 2176b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar OS << " Match_MnemonicFail,\n"; 2177b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar OS << " Match_Success\n"; 217879ed3f77e8b87615b80054ca6e4e3ba5e07445bdChris Lattner OS << " };\n"; 21795c228a945fe3e25a12d0f7e2e9b26b548d6f29f5Daniel Dunbar OS << " bool ConvertToMCInst(unsigned Kind, MCInst &Inst, " 21805c228a945fe3e25a12d0f7e2e9b26b548d6f29f5Daniel Dunbar << "unsigned Opcode,\n" 21815c228a945fe3e25a12d0f7e2e9b26b548d6f29f5Daniel Dunbar << " const SmallVectorImpl<MCParsedAsmOperand*> " 21825c228a945fe3e25a12d0f7e2e9b26b548d6f29f5Daniel Dunbar << "&Operands);\n"; 21831fe3aa15e9cdc4981d7a125d87eaf257c1d75af1Bob Wilson OS << " bool MnemonicIsValid(StringRef Mnemonic);\n"; 2184083203dde8bd50e1be47ac6509ae52f43abcd12aDaniel Dunbar OS << " MatchResultTy MatchInstructionImpl(\n"; 2185083203dde8bd50e1be47ac6509ae52f43abcd12aDaniel Dunbar OS << " const SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n"; 2186e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " MCInst &Inst, unsigned &ErrorInfo);\n"; 2187e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2188e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes if (Info.OperandMatchInfo.size()) { 2189f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OS << "\n enum OperandMatchResultTy {\n"; 2190f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OS << " MatchOperand_Success, // operand matched successfully\n"; 2191f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OS << " MatchOperand_NoMatch, // operand did not match\n"; 2192f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OS << " MatchOperand_ParseFail // operand matched but had errors\n"; 2193f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OS << " };\n"; 2194f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OS << " OperandMatchResultTy MatchOperandParserImpl(\n"; 2195e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n"; 2196e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " StringRef Mnemonic);\n"; 2197e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2198f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OS << " OperandMatchResultTy TryCustomParseOperand(\n"; 2199e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n"; 2200e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " unsigned MCK);\n\n"; 2201e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes } 2202e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 22030692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner OS << "#endif // GET_ASSEMBLER_HEADER_INFO\n\n"; 22040692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner 22050692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner OS << "\n#ifdef GET_REGISTER_MATCHER\n"; 22060692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner OS << "#undef GET_REGISTER_MATCHER\n\n"; 22070692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner 220854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar // Emit the subtarget feature enumeration. 220902bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner EmitSubtargetFeatureFlagEnumeration(Info, OS); 221054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 22111095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar // Emit the function to match a register name to number. 22121095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar EmitMatchRegisterName(Target, AsmParser, OS); 22130692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner 22140692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner OS << "#endif // GET_REGISTER_MATCHER\n\n"; 2215a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 22160692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner 22170692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner OS << "\n#ifdef GET_MATCHER_IMPLEMENTATION\n"; 22180692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner OS << "#undef GET_MATCHER_IMPLEMENTATION\n\n"; 22191095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 22207fd4489de11bdf06f6c852d42abafea013b76f28Chris Lattner // Generate the function that remaps for mnemonic aliases. 22210aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner bool HasMnemonicAliases = EmitMnemonicAliases(OS, Info); 2222828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 2223606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar // Generate the unified function to convert operands into an MCInst. 22245c228a945fe3e25a12d0f7e2e9b26b548d6f29f5Daniel Dunbar EmitConvertToMCInst(Target, ClassName, Info.Matchables, OS); 2225a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 2226a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // Emit the enumeration for classes which participate in matching. 2227a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar EmitMatchClassEnumeration(Target, Info.Classes, OS); 222820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 2229a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // Emit the routine to match token strings to their match class. 2230a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar EmitMatchTokenString(Target, Info.Classes, OS); 223120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 2232fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar // Emit the subclass predicate routine. 2233fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar EmitIsSubclass(Target, Info.Classes, OS); 2234fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar 2235b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach // Emit the routine to validate an operand against a match class. 2236b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach EmitValidateOperandClass(Info, OS); 2237b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach 223854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar // Emit the available features compute function. 223902bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner EmitComputeAvailableFeatures(Info, OS); 224054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 2241a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 2242a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar size_t MaxNumOperands = 0; 224322bc5c4184a497353e33195dd12541a4f08b008aChris Lattner for (std::vector<MatchableInfo*>::const_iterator it = 224422bc5c4184a497353e33195dd12541a4f08b008aChris Lattner Info.Matchables.begin(), ie = Info.Matchables.end(); 2245a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar it != ie; ++it) 22463116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner MaxNumOperands = std::max(MaxNumOperands, (*it)->AsmOperands.size()); 2247a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 2248a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // Emit the static match table; unused classes get initalized to 0 which is 2249a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // guaranteed to be InvalidMatchClass. 2250a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // 2251a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // FIXME: We can reduce the size of this table very easily. First, we change 2252a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // it so that store the kinds in separate bit-fields for each index, which 2253a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // only needs to be the max width used for classes at that index (we also need 2254a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // to reject based on this during classification). If we then make sure to 2255a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // order the match kinds appropriately (putting mnemonics last), then we 2256a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // should only end up using a few bits for each class, especially the ones 2257a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // following the mnemonic. 225896352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner OS << "namespace {\n"; 225996352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner OS << " struct MatchEntry {\n"; 2260a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " unsigned Opcode;\n"; 2261e206fcf0e9c7e79c7f42ff2151f3fb58cba70674Chris Lattner OS << " const char *Mnemonic;\n"; 2262a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " ConversionKind ConvertFn;\n"; 2263a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " MatchClassKind Classes[" << MaxNumOperands << "];\n"; 226454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << " unsigned RequiredFeatures;\n"; 22652b1f943444d1853204725c7b45b1e1032be39958Chris Lattner OS << " };\n\n"; 2266a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 2267e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " // Predicate for searching for an opcode.\n"; 22682b1f943444d1853204725c7b45b1e1032be39958Chris Lattner OS << " struct LessOpcode {\n"; 22692b1f943444d1853204725c7b45b1e1032be39958Chris Lattner OS << " bool operator()(const MatchEntry &LHS, StringRef RHS) {\n"; 22702b1f943444d1853204725c7b45b1e1032be39958Chris Lattner OS << " return StringRef(LHS.Mnemonic) < RHS;\n"; 22712b1f943444d1853204725c7b45b1e1032be39958Chris Lattner OS << " }\n"; 22722b1f943444d1853204725c7b45b1e1032be39958Chris Lattner OS << " bool operator()(StringRef LHS, const MatchEntry &RHS) {\n"; 22732b1f943444d1853204725c7b45b1e1032be39958Chris Lattner OS << " return LHS < StringRef(RHS.Mnemonic);\n"; 22742b1f943444d1853204725c7b45b1e1032be39958Chris Lattner OS << " }\n"; 227532c685cb67ff7701f4970ef61765cae7a50f255cChris Lattner OS << " bool operator()(const MatchEntry &LHS, const MatchEntry &RHS) {\n"; 227632c685cb67ff7701f4970ef61765cae7a50f255cChris Lattner OS << " return StringRef(LHS.Mnemonic) < StringRef(RHS.Mnemonic);\n"; 227732c685cb67ff7701f4970ef61765cae7a50f255cChris Lattner OS << " }\n"; 227896352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner OS << " };\n"; 2279a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 228096352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner OS << "} // end anonymous namespace.\n\n"; 2281a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 228296352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner OS << "static const MatchEntry MatchTable[" 228322bc5c4184a497353e33195dd12541a4f08b008aChris Lattner << Info.Matchables.size() << "] = {\n"; 2284a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 228522bc5c4184a497353e33195dd12541a4f08b008aChris Lattner for (std::vector<MatchableInfo*>::const_iterator it = 228622bc5c4184a497353e33195dd12541a4f08b008aChris Lattner Info.Matchables.begin(), ie = Info.Matchables.end(); 2287a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar it != ie; ++it) { 228822bc5c4184a497353e33195dd12541a4f08b008aChris Lattner MatchableInfo &II = **it; 2289a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 2290662e5a30e864e71111b885d3da3cdd184772035dChris Lattner OS << " { " << Target.getName() << "::" 2291662e5a30e864e71111b885d3da3cdd184772035dChris Lattner << II.getResultInst()->TheDef->getName() << ", \"" << II.Mnemonic << "\"" 2292662e5a30e864e71111b885d3da3cdd184772035dChris Lattner << ", " << II.ConversionFnKind << ", { "; 22933116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner for (unsigned i = 0, e = II.AsmOperands.size(); i != e; ++i) { 2294c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner MatchableInfo::AsmOperand &Op = II.AsmOperands[i]; 2295a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 2296a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar if (i) OS << ", "; 2297a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << Op.Class->Name; 229820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 229954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << " }, "; 2300a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 230154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar // Write the required features mask. 230254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar if (!II.RequiredFeatures.empty()) { 230354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar for (unsigned i = 0, e = II.RequiredFeatures.size(); i != e; ++i) { 230454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar if (i) OS << "|"; 23050aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner OS << II.RequiredFeatures[i]->getEnumName(); 230654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar } 230754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar } else 230854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << "0"; 2309a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 231054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << "},\n"; 2311a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 2312a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 231396352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner OS << "};\n\n"; 2314a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 23151fe3aa15e9cdc4981d7a125d87eaf257c1d75af1Bob Wilson // A method to determine if a mnemonic is in the list. 23161fe3aa15e9cdc4981d7a125d87eaf257c1d75af1Bob Wilson OS << "bool " << Target.getName() << ClassName << "::\n" 23171fe3aa15e9cdc4981d7a125d87eaf257c1d75af1Bob Wilson << "MnemonicIsValid(StringRef Mnemonic) {\n"; 23181fe3aa15e9cdc4981d7a125d87eaf257c1d75af1Bob Wilson OS << " // Search the table.\n"; 23191fe3aa15e9cdc4981d7a125d87eaf257c1d75af1Bob Wilson OS << " std::pair<const MatchEntry*, const MatchEntry*> MnemonicRange =\n"; 23201fe3aa15e9cdc4981d7a125d87eaf257c1d75af1Bob Wilson OS << " std::equal_range(MatchTable, MatchTable+" 23211fe3aa15e9cdc4981d7a125d87eaf257c1d75af1Bob Wilson << Info.Matchables.size() << ", Mnemonic, LessOpcode());\n"; 23221fe3aa15e9cdc4981d7a125d87eaf257c1d75af1Bob Wilson OS << " return MnemonicRange.first != MnemonicRange.second;\n"; 23231fe3aa15e9cdc4981d7a125d87eaf257c1d75af1Bob Wilson OS << "}\n\n"; 23241fe3aa15e9cdc4981d7a125d87eaf257c1d75af1Bob Wilson 232596352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner // Finally, build the match function. 232696352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner OS << Target.getName() << ClassName << "::MatchResultTy " 232796352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner << Target.getName() << ClassName << "::\n" 232896352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner << "MatchInstructionImpl(const SmallVectorImpl<MCParsedAsmOperand*>" 232996352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner << " &Operands,\n"; 2330ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " MCInst &Inst, unsigned &ErrorInfo) {\n"; 233154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 233254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar // Emit code to get the available features. 233354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << " // Get the current feature set.\n"; 233454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << " unsigned AvailableFeatures = getAvailableFeatures();\n\n"; 233554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 2336674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner OS << " // Get the instruction mnemonic, which is the first token.\n"; 2337674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner OS << " StringRef Mnemonic = ((" << Target.getName() 2338674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner << "Operand*)Operands[0])->getToken();\n\n"; 2339674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner 23407fd4489de11bdf06f6c852d42abafea013b76f28Chris Lattner if (HasMnemonicAliases) { 23417fd4489de11bdf06f6c852d42abafea013b76f28Chris Lattner OS << " // Process all MnemonicAliases to remap the mnemonic.\n"; 23427fd4489de11bdf06f6c852d42abafea013b76f28Chris Lattner OS << " ApplyMnemonicAliases(Mnemonic, AvailableFeatures);\n\n"; 23437fd4489de11bdf06f6c852d42abafea013b76f28Chris Lattner } 2344828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 2345a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // Emit code to compute the class list for this operand vector. 2346a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " // Eliminate obvious mismatches.\n"; 2347ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " if (Operands.size() > " << (MaxNumOperands+1) << ") {\n"; 2348ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " ErrorInfo = " << (MaxNumOperands+1) << ";\n"; 2349ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " return Match_InvalidOperand;\n"; 2350ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " }\n\n"; 2351a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 23529bb9fa19a5e121b83866867ad1d8f7bf2618c1a0Chris Lattner OS << " // Some state to try to produce better error messages.\n"; 23532b1f943444d1853204725c7b45b1e1032be39958Chris Lattner OS << " bool HadMatchOtherThanFeatures = false;\n\n"; 235484cb033bf30b6f93ae2fbea71513970147e08dc2Jim Grosbach OS << " // Set ErrorInfo to the operand that mismatches if it is\n"; 23559bb9fa19a5e121b83866867ad1d8f7bf2618c1a0Chris Lattner OS << " // wrong for all instances of the instruction.\n"; 23569bb9fa19a5e121b83866867ad1d8f7bf2618c1a0Chris Lattner OS << " ErrorInfo = ~0U;\n"; 23572b1f943444d1853204725c7b45b1e1032be39958Chris Lattner 2358a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // Emit code to search the table. 2359a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " // Search the table.\n"; 23602b1f943444d1853204725c7b45b1e1032be39958Chris Lattner OS << " std::pair<const MatchEntry*, const MatchEntry*> MnemonicRange =\n"; 23612b1f943444d1853204725c7b45b1e1032be39958Chris Lattner OS << " std::equal_range(MatchTable, MatchTable+" 236222bc5c4184a497353e33195dd12541a4f08b008aChris Lattner << Info.Matchables.size() << ", Mnemonic, LessOpcode());\n\n"; 2363a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 2364a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner OS << " // Return a more specific error code if no mnemonics match.\n"; 2365a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner OS << " if (MnemonicRange.first == MnemonicRange.second)\n"; 2366a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner OS << " return Match_MnemonicFail;\n\n"; 2367a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 23682b1f943444d1853204725c7b45b1e1032be39958Chris Lattner OS << " for (const MatchEntry *it = MnemonicRange.first, " 236980db4e51d2a44bc623b5892bed2351406890b9aaChris Lattner << "*ie = MnemonicRange.second;\n"; 23702b1f943444d1853204725c7b45b1e1032be39958Chris Lattner OS << " it != ie; ++it) {\n"; 237154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 2372e53ee3b112810068b8ca229aff211fc497069273Gabor Greif OS << " // equal_range guarantees that instruction mnemonic matches.\n"; 237344b0daad44791ff249a0bc533a5e58e978c2ca31Chris Lattner OS << " assert(Mnemonic == it->Mnemonic);\n"; 2374a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 237554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar // Emit check that the subclasses match. 2376ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " bool OperandsValid = true;\n"; 2377ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " for (unsigned i = 0; i != " << MaxNumOperands << "; ++i) {\n"; 2378b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach OS << " if (i + 1 >= Operands.size()) {\n"; 2379b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach OS << " OperandsValid = (it->Classes[i] == " <<"InvalidMatchClass);\n"; 2380b9d5af05fdc0867ed772c4bbfe3f3acc9fb3d628Jim Grosbach OS << " break;\n"; 2381b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach OS << " }\n"; 2382b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach OS << " if (ValidateOperandClass(Operands[i+1], it->Classes[i]))\n"; 2383ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " continue;\n"; 23849bb9fa19a5e121b83866867ad1d8f7bf2618c1a0Chris Lattner OS << " // If this operand is broken for all of the instances of this\n"; 23859bb9fa19a5e121b83866867ad1d8f7bf2618c1a0Chris Lattner OS << " // mnemonic, keep track of it so we can report loc info.\n"; 238679fcb6dec3e6e30a30835ebc781e5abc275e12e9Kevin Enderby OS << " if (it == MnemonicRange.first || ErrorInfo <= i+1)\n"; 2387ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " ErrorInfo = i+1;\n"; 2388ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " // Otherwise, just reject this instance of the mnemonic.\n"; 2389ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " OperandsValid = false;\n"; 2390ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " break;\n"; 2391ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " }\n\n"; 2392a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 2393ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " if (!OperandsValid) continue;\n"; 2394ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner 2395ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner // Emit check that the required features are available. 2396ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner OS << " if ((AvailableFeatures & it->RequiredFeatures) " 2397ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner << "!= it->RequiredFeatures) {\n"; 2398ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner OS << " HadMatchOtherThanFeatures = true;\n"; 2399ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner OS << " continue;\n"; 2400ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner OS << " }\n"; 2401a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "\n"; 2402b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar OS << " // We have selected a definite instruction, convert the parsed\n" 2403b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar << " // operands into the appropriate MCInst.\n"; 2404b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar OS << " if (!ConvertToMCInst(it->ConvertFn, Inst,\n" 2405b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar << " it->Opcode, Operands))\n"; 2406b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar OS << " return Match_ConversionFail;\n"; 2407b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar OS << "\n"; 24088cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar 24098cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar // Call the post-processing function, if used. 24108cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar std::string InsnCleanupFn = 24118cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar AsmParser->getValueAsString("AsmParserInstCleanup"); 24128cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar if (!InsnCleanupFn.empty()) 24138cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar OS << " " << InsnCleanupFn << "(Inst);\n"; 24148cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar 241579ed3f77e8b87615b80054ca6e4e3ba5e07445bdChris Lattner OS << " return Match_Success;\n"; 2416a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " }\n\n"; 2417a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 2418ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner OS << " // Okay, we had no match. Try to return a useful error code.\n"; 2419ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner OS << " if (HadMatchOtherThanFeatures) return Match_MissingFeature;\n"; 2420a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner OS << " return Match_InvalidOperand;\n"; 2421a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar OS << "}\n\n"; 2422a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 2423e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes if (Info.OperandMatchInfo.size()) 2424e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes EmitCustomOperandParsing(OS, Target, Info, ClassName); 2425e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 24260692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner OS << "#endif // GET_MATCHER_IMPLEMENTATION\n\n"; 2427d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar} 2428