1d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar//===- AsmMatcherEmitter.cpp - Generate an assembly matcher ---------------===// 2d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar// 3d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar// The LLVM Compiler Infrastructure 4d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar// 5d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar// This file is distributed under the University of Illinois Open Source 6d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar// License. See LICENSE.TXT for details. 7d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar// 8d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar//===----------------------------------------------------------------------===// 9d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar// 10d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar// This tablegen backend emits a target specifier matcher for converting parsed 11e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// assembly operands in the MCInst structures. It also emits a matcher for 12e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// custom operand parsing. 13e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// 14e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// Converting assembly operands into MCInst structures 15e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// --------------------------------------------------- 16d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar// 1720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// The input to the target specific matcher is a list of literal tokens and 1820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// operands. The target specific parser should generally eliminate any syntax 1920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// which is not relevant for matching; for example, comma tokens should have 2020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// already been consumed and eliminated by the parser. Most instructions will 2120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// end up with a single literal token (the instruction name) and some number of 2220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// operands. 2320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 2420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// Some example inputs, for X86: 2520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 'addl' (immediate ...) (register ...) 2620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 'add' (immediate ...) (memory ...) 27a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach// 'call' '*' %epc 2820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 2920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// The assembly matcher is responsible for converting this input into a precise 3020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// machine instruction (i.e., an instruction with a well defined encoding). This 3120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// mapping has several properties which complicate matching: 3220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 3320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// - It may be ambiguous; many architectures can legally encode particular 3420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// variants of an instruction in different ways (for example, using a smaller 3520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// encoding for small immediates). Such ambiguities should never be 3620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// arbitrarily resolved by the assembler, the assembler is always responsible 3720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// for choosing the "best" available instruction. 3820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 3920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// - It may depend on the subtarget or the assembler context. Instructions 4020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// which are invalid for the current mode, but otherwise unambiguous (e.g., 4120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// an SSE instruction in a file being assembled for i486) should be accepted 4220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// and rejected by the assembler front end. However, if the proper encoding 4320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// for an instruction is dependent on the assembler context then the matcher 4420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// is responsible for selecting the correct machine instruction for the 4520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// current mode. 4620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 4720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// The core matching algorithm attempts to exploit the regularity in most 4820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// instruction sets to quickly determine the set of possibly matching 4920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// instructions, and the simplify the generated code. Additionally, this helps 5020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// to ensure that the ambiguities are intentionally resolved by the user. 5120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 5220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// The matching is divided into two distinct phases: 5320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 5420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 1. Classification: Each operand is mapped to the unique set which (a) 5520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// contains it, and (b) is the largest such subset for which a single 5620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// instruction could match all members. 5720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 5820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// For register classes, we can generate these subgroups automatically. For 5920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// arbitrary operands, we expect the user to define the classes and their 6020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// relations to one another (for example, 8-bit signed immediates as a 6120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// subset of 32-bit immediates). 6220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 6320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// By partitioning the operands in this way, we guarantee that for any 6420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// tuple of classes, any single instruction must match either all or none 6520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// of the sets of operands which could classify to that tuple. 6620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 6720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// In addition, the subset relation amongst classes induces a partial order 6820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// on such tuples, which we use to resolve ambiguities. 6920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 7020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 2. The input can now be treated as a tuple of classes (static tokens are 7120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// simple singleton sets). Each such tuple should generally map to a single 7220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// instruction (we currently ignore cases where this isn't true, whee!!!), 7320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// which we can emit a simple matcher for. 7420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 75e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// Custom Operand Parsing 76e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// ---------------------- 77e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// 78e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// Some targets need a custom way to parse operands, some specific instructions 79e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// can contain arguments that can represent processor flags and other kinds of 80be480ff607285157361a100e72ac5ed84ccce328Craig Topper// identifiers that need to be mapped to specific values in the final encoded 81e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// instructions. The target specific custom operand parsing works in the 82e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// following way: 83e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// 84e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// 1. A operand match table is built, each entry contains a mnemonic, an 85e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// operand class, a mask for all operand positions for that same 86e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// class/mnemonic and target features to be checked while trying to match. 87e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// 88e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// 2. The operand matcher will try every possible entry with the same 89e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// mnemonic and will check if the target feature for this mnemonic also 90e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// matches. After that, if the operand to be matched has its index 917a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner// present in the mask, a successful match occurs. Otherwise, fallback 92e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// to the regular operand parsing. 93e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// 94e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// 3. For a match success, each operand class that has a 'ParserMethod' 95e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// becomes part of a switch from where the custom method is called. 96e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes// 97d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar//===----------------------------------------------------------------------===// 98d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar 99d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar#include "CodeGenTarget.h" 100c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner#include "llvm/ADT/PointerUnion.h" 1014ffd89fa4d2788611187d1a534d2ed46adf1702cChandler Carruth#include "llvm/ADT/STLExtras.h" 1021de88235781c45c0afc0c7500d65b59775196c4cChris Lattner#include "llvm/ADT/SmallPtrSet.h" 103a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar#include "llvm/ADT/SmallVector.h" 10420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar#include "llvm/ADT/StringExtras.h" 10520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar#include "llvm/Support/CommandLine.h" 106a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar#include "llvm/Support/Debug.h" 107655b8de7b2ab773a977e0c524307e71354d8af29Craig Topper#include "llvm/Support/ErrorHandling.h" 1087c788888872233748da10a8177a9a1eb176c1bc8Peter Collingbourne#include "llvm/TableGen/Error.h" 1097c788888872233748da10a8177a9a1eb176c1bc8Peter Collingbourne#include "llvm/TableGen/Record.h" 110f657da2e4896732f306a9e62261418112e7337ceDouglas Gregor#include "llvm/TableGen/StringMatcher.h" 111aae60d1dc417dffb1b2486c8e7ca546cf3777901Craig Topper#include "llvm/TableGen/StringToOffsetTable.h" 1126f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include "llvm/TableGen/TableGenBackend.h" 1136f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include <cassert> 114e3ba15c794839abe076e3e2bdf6c626396a19d4dWill Dietz#include <cctype> 115b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar#include <map> 116b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar#include <set> 11754911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman#include <sstream> 118d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbarusing namespace llvm; 119d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar 120dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "asm-matcher-emitter" 121dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 1222724915c171b08fa9f7f9e54a46ea81708d9c5b2Daniel Dunbarstatic cl::opt<std::string> 123606e8ad796f72824f5509e2657c44eca025d4bafDaniel DunbarMatchPrefix("match-prefix", cl::init(""), 124606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar cl::desc("Only match instructions with the given prefix")); 12520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 12620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbarnamespace { 127828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilsonclass AsmMatcherInfo; 12854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbarstruct SubtargetFeatureInfo; 12954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 13003f9197d62dddfb70e70acb5563518f589d29251Tim Northover// Register sets are used as keys in some second-order sets TableGen creates 13103f9197d62dddfb70e70acb5563518f589d29251Tim Northover// when generating its data structures. This means that the order of two 13203f9197d62dddfb70e70acb5563518f589d29251Tim Northover// RegisterSets can be seen in the outputted AsmMatcher tables occasionally, and 13303f9197d62dddfb70e70acb5563518f589d29251Tim Northover// can even affect compiler output (at least seen in diagnostics produced when 13403f9197d62dddfb70e70acb5563518f589d29251Tim Northover// all matches fail). So we use a type that sorts them consistently. 13503f9197d62dddfb70e70acb5563518f589d29251Tim Northovertypedef std::set<Record*, LessRecordByID> RegisterSet; 13603f9197d62dddfb70e70acb5563518f589d29251Tim Northover 1376f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenclass AsmMatcherEmitter { 1386f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen RecordKeeper &Records; 1396f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenpublic: 1406f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen AsmMatcherEmitter(RecordKeeper &R) : Records(R) {} 1416f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 1426f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen void run(raw_ostream &o); 1436f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen}; 1446f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 145a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar/// ClassInfo - Helper class for storing the information about a particular 146a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar/// class of operands which can be matched. 147a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarstruct ClassInfo { 148606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar enum ClassInfoKind { 149ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// Invalid kind, for use as a sentinel value. 150ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar Invalid = 0, 151ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 152ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// The class for a particular token. 153ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar Token, 154ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 155ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// The (first) register class, subsequent register classes are 156ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// RegisterClass0+1, and so on. 157ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar RegisterClass0, 158ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 159ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// The (first) user defined class, subsequent user defined classes are 160ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// UserClass0+1, and so on. 161ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar UserClass0 = 1<<16 162606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar }; 163606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 164606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar /// Kind - The class kind, which is either a predefined kind, or (UserClass0 + 165606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar /// N) for the Nth user defined class. 166606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar unsigned Kind; 167a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 168ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// SuperClasses - The super classes of this class. Note that for simplicities 169ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// sake user operands only record their immediate super class, while register 170ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// operands include all superclasses. 171ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar std::vector<ClassInfo*> SuperClasses; 1725fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar 1736745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar /// Name - The full class name, suitable for use in an enum. 174a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::string Name; 175a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1766745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar /// ClassName - The unadorned generic name for this class (e.g., Token). 1776745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar std::string ClassName; 1786745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar 179a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// ValueName - The name of the value this class represents; for a token this 180a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// is the literal token string, for an operand it is the TableGen class (or 181a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// empty if this is a derived class). 182a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::string ValueName; 183a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 184a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// PredicateMethod - The name of the operand method to test whether the 185ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// operand matches this class; this is not valid for Token or register kinds. 186a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::string PredicateMethod; 187a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 188a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// RenderMethod - The name of the operand method to add this operand to an 189ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// MCInst; this is not valid for Token or register kinds. 190a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::string RenderMethod; 191606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 192e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes /// ParserMethod - The name of the operand method to do a target specific 193e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes /// parsing on the operand. 194e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes std::string ParserMethod; 195e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 196dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines /// For register classes: the records for all the registers in this class. 19703f9197d62dddfb70e70acb5563518f589d29251Tim Northover RegisterSet Registers; 1988409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar 199dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines /// For custom match classes: the diagnostic kind for when the predicate fails. 2004dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach std::string DiagnosticType; 2018409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbarpublic: 202ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// isRegisterClass() - Check if this is a register class. 203ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar bool isRegisterClass() const { 204ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar return Kind >= RegisterClass0 && Kind < UserClass0; 205ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 206ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 2075fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar /// isUserClass() - Check if this is a user defined class. 2085fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar bool isUserClass() const { 2095fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar return Kind >= UserClass0; 2105fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar } 2115fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar 2124e0ae44b3a1b5f7157351764fd125c7c85959797Dmitri Gribenko /// isRelatedTo - Check whether this class is "related" to \p RHS. Classes 213ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// are related if they are in the same class hierarchy. 214ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar bool isRelatedTo(const ClassInfo &RHS) const { 215ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Tokens are only related to tokens. 216ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (Kind == Token || RHS.Kind == Token) 217ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar return Kind == Token && RHS.Kind == Token; 218ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 2198409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar // Registers classes are only related to registers classes, and only if 2208409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar // their intersection is non-empty. 2218409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar if (isRegisterClass() || RHS.isRegisterClass()) { 2228409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar if (!isRegisterClass() || !RHS.isRegisterClass()) 2238409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar return false; 2248409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar 22503f9197d62dddfb70e70acb5563518f589d29251Tim Northover RegisterSet Tmp; 22603f9197d62dddfb70e70acb5563518f589d29251Tim Northover std::insert_iterator<RegisterSet> II(Tmp, Tmp.begin()); 227a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach std::set_intersection(Registers.begin(), Registers.end(), 2288409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar RHS.Registers.begin(), RHS.Registers.end(), 22903f9197d62dddfb70e70acb5563518f589d29251Tim Northover II, LessRecordByID()); 2308409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar 2318409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar return !Tmp.empty(); 2328409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar } 233ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 234ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Otherwise we have two users operands; they are related if they are in the 235ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // same class hierarchy. 2368409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar // 2378409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar // FIXME: This is an oversimplification, they should only be related if they 2388409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar // intersect, however we don't have that information. 239ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar assert(isUserClass() && RHS.isUserClass() && "Unexpected class!"); 240ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar const ClassInfo *Root = this; 241ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar while (!Root->SuperClasses.empty()) 242ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar Root = Root->SuperClasses.front(); 243ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 2448409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar const ClassInfo *RHSRoot = &RHS; 245ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar while (!RHSRoot->SuperClasses.empty()) 246ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar RHSRoot = RHSRoot->SuperClasses.front(); 247a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 248ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar return Root == RHSRoot; 249ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 250ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 2514e0ae44b3a1b5f7157351764fd125c7c85959797Dmitri Gribenko /// isSubsetOf - Test whether this class is a subset of \p RHS. 252ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar bool isSubsetOf(const ClassInfo &RHS) const { 253ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // This is a subset of RHS if it is the same class... 254ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (this == &RHS) 255ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar return true; 256ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 257ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // ... or if any of its super classes are a subset of RHS. 258ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar for (std::vector<ClassInfo*>::const_iterator it = SuperClasses.begin(), 259ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ie = SuperClasses.end(); it != ie; ++it) 260ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if ((*it)->isSubsetOf(RHS)) 261ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar return true; 262ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 263ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar return false; 2645fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar } 2655fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar 266606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar /// operator< - Compare two classes. 267606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar bool operator<(const ClassInfo &RHS) const { 268368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar if (this == &RHS) 269368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar return false; 270368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar 271ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Unrelated classes can be ordered by kind. 272ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (!isRelatedTo(RHS)) 273606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar return Kind < RHS.Kind; 274606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 275606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar switch (Kind) { 2766745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar case Invalid: 277655b8de7b2ab773a977e0c524307e71354d8af29Craig Topper llvm_unreachable("Invalid kind!"); 278606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 279606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar default: 2807a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // This class precedes the RHS if it is a proper subset of the RHS. 281368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar if (isSubsetOf(RHS)) 2823472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands return true; 283368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar if (RHS.isSubsetOf(*this)) 2843472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands return false; 285368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar 286368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar // Otherwise, order by name to ensure we have a total ordering. 287368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar return ValueName < RHS.ValueName; 288606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar } 289606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar } 290a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar}; 291a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 29222bc5c4184a497353e33195dd12541a4f08b008aChris Lattner/// MatchableInfo - Helper class for storing the necessary information for an 29322bc5c4184a497353e33195dd12541a4f08b008aChris Lattner/// instruction or alias which is capable of being matched. 29422bc5c4184a497353e33195dd12541a4f08b008aChris Lattnerstruct MatchableInfo { 295c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner struct AsmOperand { 296d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner /// Token - This is the token that the operand came from. 297d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner StringRef Token; 298828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 299a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// The unique class instance this operand should match. 300a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar ClassInfo *Class; 301a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 302567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner /// The operand name this is, if anything. 303567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner StringRef SrcOpName; 304a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson 305a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson /// The suboperand index within SrcOpName, or -1 for the entire operand. 306a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson int SubOpIdx; 307828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 30863faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel /// Register record if this token is singleton register. 30963faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel Record *SingletonReg; 31063faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel 311dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines explicit AsmOperand(StringRef T) : Token(T), Class(nullptr), SubOpIdx(-1), 312dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SingletonReg(nullptr) {} 31320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar }; 314828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 3151d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// ResOperand - This represents a single operand in the result instruction 3161d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// generated by the match. In cases (like addressing modes) where a single 3171d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// assembler operand expands to multiple MCOperands, this represents the 3181d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// single assembler operand, not the MCOperand. 3191d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner struct ResOperand { 3201d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner enum { 3211d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// RenderAsmOperand - This represents an operand result that is 3221d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// generated by calling the render method on the assembly operand. The 3231d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// corresponding AsmOperand is specified by AsmOperandNum. 3241d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner RenderAsmOperand, 325828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 3261d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// TiedOperand - This represents a result operand that is a duplicate of 3271d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// a previous result operand. 32898c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner TiedOperand, 329828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 33098c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner /// ImmOperand - This represents an immediate value that is dumped into 33198c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner /// the operand. 33290fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner ImmOperand, 333828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 33490fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner /// RegOperand - This represents a fixed register that is dumped in. 33590fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner RegOperand 3361d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner } Kind; 337828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 3381d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner union { 3391d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// This is the operand # in the AsmOperands list that this should be 3401d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// copied from. 3411d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner unsigned AsmOperandNum; 342828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 3431d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// TiedOperandNum - This is the (earlier) result operand that should be 3441d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// copied from. 3451d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner unsigned TiedOperandNum; 346828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 34798c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner /// ImmVal - This is the immediate value added to the instruction. 34898c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner int64_t ImmVal; 349828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 35090fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner /// Register - This is the register record. 35190fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner Record *Register; 3521d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner }; 353828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 354a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson /// MINumOperands - The number of MCInst operands populated by this 355a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson /// operand. 356a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson unsigned MINumOperands; 357828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 358a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson static ResOperand getRenderedOp(unsigned AsmOpNum, unsigned NumOperands) { 3591d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner ResOperand X; 3601d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner X.Kind = RenderAsmOperand; 3611d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner X.AsmOperandNum = AsmOpNum; 362a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson X.MINumOperands = NumOperands; 3631d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner return X; 3641d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner } 365828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 366a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson static ResOperand getTiedOp(unsigned TiedOperandNum) { 3671d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner ResOperand X; 3681d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner X.Kind = TiedOperand; 3691d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner X.TiedOperandNum = TiedOperandNum; 370a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson X.MINumOperands = 1; 3711d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner return X; 3721d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner } 373828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 374a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson static ResOperand getImmOp(int64_t Val) { 37598c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner ResOperand X; 37698c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner X.Kind = ImmOperand; 37798c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner X.ImmVal = Val; 378a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson X.MINumOperands = 1; 37998c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner return X; 38098c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner } 381828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 382a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson static ResOperand getRegOp(Record *Reg) { 38390fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner ResOperand X; 38490fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner X.Kind = RegOperand; 38590fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner X.Register = Reg; 386a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson X.MINumOperands = 1; 38790fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner return X; 38890fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner } 3891d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner }; 39020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 39156315d319c104dc96187444e1e19711a1c801166Devang Patel /// AsmVariantID - Target's assembly syntax variant no. 39256315d319c104dc96187444e1e19711a1c801166Devang Patel int AsmVariantID; 39356315d319c104dc96187444e1e19711a1c801166Devang Patel 3943b5aec67ef174c74ff6620ddd71ad3b0cb39030cChris Lattner /// TheDef - This is the definition of the instruction or InstAlias that this 3953b5aec67ef174c74ff6620ddd71ad3b0cb39030cChris Lattner /// matchable came from. 3965bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner Record *const TheDef; 397828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 398c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner /// DefRec - This is the definition that it came from. 399c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner PointerUnion<const CodeGenInstruction*, const CodeGenInstAlias*> DefRec; 400828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 401662e5a30e864e71111b885d3da3cdd184772035dChris Lattner const CodeGenInstruction *getResultInst() const { 402662e5a30e864e71111b885d3da3cdd184772035dChris Lattner if (DefRec.is<const CodeGenInstruction*>()) 403662e5a30e864e71111b885d3da3cdd184772035dChris Lattner return DefRec.get<const CodeGenInstruction*>(); 404662e5a30e864e71111b885d3da3cdd184772035dChris Lattner return DefRec.get<const CodeGenInstAlias*>()->ResultInst; 405662e5a30e864e71111b885d3da3cdd184772035dChris Lattner } 406828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 4071d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// ResOperands - This is the operand list that should be built for the result 4081d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner /// MCInst. 409b423d18a00eed4968d6df7415449259b09b7d67eJim Grosbach SmallVector<ResOperand, 8> ResOperands; 41020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 41120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar /// AsmString - The assembly string for this instruction (with variants 4123b5aec67ef174c74ff6620ddd71ad3b0cb39030cChris Lattner /// removed), e.g. "movsx $src, $dst". 41320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar std::string AsmString; 41420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 415d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner /// Mnemonic - This is the first token of the matched instruction, its 416d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner /// mnemonic. 417d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner StringRef Mnemonic; 418828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 4193116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner /// AsmOperands - The textual operands that this instruction matches, 4203b5aec67ef174c74ff6620ddd71ad3b0cb39030cChris Lattner /// annotated with a class and where in the OperandList they were defined. 4213b5aec67ef174c74ff6620ddd71ad3b0cb39030cChris Lattner /// This directly corresponds to the tokenized AsmString after the mnemonic is 4223b5aec67ef174c74ff6620ddd71ad3b0cb39030cChris Lattner /// removed. 423b423d18a00eed4968d6df7415449259b09b7d67eJim Grosbach SmallVector<AsmOperand, 8> AsmOperands; 42420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 42554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar /// Predicates - The required subtarget features to match this instruction. 42654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar SmallVector<SubtargetFeatureInfo*, 4> RequiredFeatures; 42754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 428b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar /// ConversionFnKind - The enum value which is passed to the generated 42990e11f8c95146c2d3718e9b3de71ee6628347b05Chad Rosier /// convertToMCInst to convert parsed operands into an MCInst for this 430b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar /// function. 431b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar std::string ConversionFnKind; 432828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 433715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly /// If this instruction is deprecated in some form. 434715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly bool HasDeprecation; 435715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly 43622bc5c4184a497353e33195dd12541a4f08b008aChris Lattner MatchableInfo(const CodeGenInstruction &CGI) 437f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach : AsmVariantID(0), TheDef(CGI.TheDef), DefRec(&CGI), 43856315d319c104dc96187444e1e19711a1c801166Devang Patel AsmString(CGI.AsmString) { 4395bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner } 4405bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner 44122bc5c4184a497353e33195dd12541a4f08b008aChris Lattner MatchableInfo(const CodeGenInstAlias *Alias) 442f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach : AsmVariantID(0), TheDef(Alias->TheDef), DefRec(Alias), 44356315d319c104dc96187444e1e19711a1c801166Devang Patel AsmString(Alias->AsmString) { 444c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner } 445828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 446c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach // Two-operand aliases clone from the main matchable, but mark the second 447c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach // operand as a tied operand of the first for purposes of the assembler. 448c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach void formTwoOperandAlias(StringRef Constraint); 449c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach 4508caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach void initialize(const AsmMatcherInfo &Info, 451f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach SmallPtrSet<Record*, 16> &SingletonRegisters, 45211fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach int AsmVariantNo, std::string &RegisterPrefix); 453828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 4548caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach /// validate - Return true if this matchable is a valid thing to match against 45522bc5c4184a497353e33195dd12541a4f08b008aChris Lattner /// and perform a bunch of validity checking. 4568caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach bool validate(StringRef CommentDelimiter, bool Hack) const; 457828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 458f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach /// extractSingletonRegisterForAsmOperand - Extract singleton register, 45963faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel /// if present, from specified token. 46063faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel void 46163faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel extractSingletonRegisterForAsmOperand(unsigned i, const AsmMatcherInfo &Info, 46263faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel std::string &RegisterPrefix); 46320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 4648caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach /// findAsmOperand - Find the AsmOperand with the specified name and 465a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson /// suboperand index. 4668caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach int findAsmOperand(StringRef N, int SubOpIdx) const { 467a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) 468a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson if (N == AsmOperands[i].SrcOpName && 469a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson SubOpIdx == AsmOperands[i].SubOpIdx) 470a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson return i; 471a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson return -1; 472a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson } 473828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 4748caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach /// findAsmOperandNamed - Find the first AsmOperand with the specified name. 475a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson /// This does not check the suboperand index. 4768caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach int findAsmOperandNamed(StringRef N) const { 477ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) 478ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner if (N == AsmOperands[i].SrcOpName) 479ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner return i; 480ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner return -1; 481ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner } 482828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 4838caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach void buildInstructionResultOperands(); 4848caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach void buildAliasResultOperands(); 4851d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner 48622bc5c4184a497353e33195dd12541a4f08b008aChris Lattner /// operator< - Compare two matchables. 48722bc5c4184a497353e33195dd12541a4f08b008aChris Lattner bool operator<(const MatchableInfo &RHS) const { 488e206fcf0e9c7e79c7f42ff2151f3fb58cba70674Chris Lattner // The primary comparator is the instruction mnemonic. 489d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner if (Mnemonic != RHS.Mnemonic) 490d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner return Mnemonic < RHS.Mnemonic; 491a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 4923116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner if (AsmOperands.size() != RHS.AsmOperands.size()) 4933116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner return AsmOperands.size() < RHS.AsmOperands.size(); 4942b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar 495db2ddb5dc57319eff249144f1d9a553a3278d2e0Daniel Dunbar // Compare lexicographically by operand. The matcher validates that other 4968caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach // orderings wouldn't be ambiguous using \see couldMatchAmbiguouslyWith(). 4973116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) { 4983116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner if (*AsmOperands[i].Class < *RHS.AsmOperands[i].Class) 4992b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar return true; 5003116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner if (*RHS.AsmOperands[i].Class < *AsmOperands[i].Class) 501db2ddb5dc57319eff249144f1d9a553a3278d2e0Daniel Dunbar return false; 502db2ddb5dc57319eff249144f1d9a553a3278d2e0Daniel Dunbar } 503db2ddb5dc57319eff249144f1d9a553a3278d2e0Daniel Dunbar 5042b70dfaaebcc436c53b2c86cd8a9574baba47253Andrew Trick // Give matches that require more features higher precedence. This is useful 5052b70dfaaebcc436c53b2c86cd8a9574baba47253Andrew Trick // because we cannot define AssemblerPredicates with the negation of 5062b70dfaaebcc436c53b2c86cd8a9574baba47253Andrew Trick // processor features. For example, ARM v6 "nop" may be either a HINT or 5072b70dfaaebcc436c53b2c86cd8a9574baba47253Andrew Trick // MOV. With v6, we want to match HINT. The assembler has no way to 5082b70dfaaebcc436c53b2c86cd8a9574baba47253Andrew Trick // predicate MOV under "NoV6", but HINT will always match first because it 5092b70dfaaebcc436c53b2c86cd8a9574baba47253Andrew Trick // requires V6 while MOV does not. 5102b70dfaaebcc436c53b2c86cd8a9574baba47253Andrew Trick if (RequiredFeatures.size() != RHS.RequiredFeatures.size()) 5112b70dfaaebcc436c53b2c86cd8a9574baba47253Andrew Trick return RequiredFeatures.size() > RHS.RequiredFeatures.size(); 5122b70dfaaebcc436c53b2c86cd8a9574baba47253Andrew Trick 5132b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar return false; 5142b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar } 515606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 5168caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach /// couldMatchAmbiguouslyWith - Check whether this matchable could 5174e0ae44b3a1b5f7157351764fd125c7c85959797Dmitri Gribenko /// ambiguously match the same set of operands as \p RHS (without being a 5182b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar /// strictly superior match). 5198caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach bool couldMatchAmbiguouslyWith(const MatchableInfo &RHS) { 520e66b7ebfb426c7ed9bc911e9708321e2d8510b41Chris Lattner // The primary comparator is the instruction mnemonic. 521d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner if (Mnemonic != RHS.Mnemonic) 522e66b7ebfb426c7ed9bc911e9708321e2d8510b41Chris Lattner return false; 523828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 5242b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar // The number of operands is unambiguous. 5253116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner if (AsmOperands.size() != RHS.AsmOperands.size()) 5262b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar return false; 527606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 5281402f0b2cac017ab997f71ab4909a2ccfea7be4bDaniel Dunbar // Otherwise, make sure the ordering of the two instructions is unambiguous 5291402f0b2cac017ab997f71ab4909a2ccfea7be4bDaniel Dunbar // by checking that either (a) a token or operand kind discriminates them, 5301402f0b2cac017ab997f71ab4909a2ccfea7be4bDaniel Dunbar // or (b) the ordering among equivalent kinds is consistent. 5311402f0b2cac017ab997f71ab4909a2ccfea7be4bDaniel Dunbar 5322b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar // Tokens and operand kinds are unambiguous (assuming a correct target 5332b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar // specific parser). 5343116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) 5353116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner if (AsmOperands[i].Class->Kind != RHS.AsmOperands[i].Class->Kind || 5363116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner AsmOperands[i].Class->Kind == ClassInfo::Token) 5373116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner if (*AsmOperands[i].Class < *RHS.AsmOperands[i].Class || 5383116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner *RHS.AsmOperands[i].Class < *AsmOperands[i].Class) 5392b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar return false; 540a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 5412b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar // Otherwise, this operand could commute if all operands are equivalent, or 5422b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar // there is a pair of operands that compare less than and a pair that 5432b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar // compare greater than. 5442b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar bool HasLT = false, HasGT = false; 5453116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) { 5463116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner if (*AsmOperands[i].Class < *RHS.AsmOperands[i].Class) 5472b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar HasLT = true; 5483116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner if (*RHS.AsmOperands[i].Class < *AsmOperands[i].Class) 5492b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar HasGT = true; 5502b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar } 551606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 5522b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar return !(HasLT ^ HasGT); 553606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar } 554606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 55520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar void dump(); 556828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 557d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattnerprivate: 5588caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach void tokenizeAsmString(const AsmMatcherInfo &Info); 55920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar}; 56020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 56154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar/// SubtargetFeatureInfo - Helper class for storing information on a subtarget 56254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar/// feature which participates in instruction matching. 56354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbarstruct SubtargetFeatureInfo { 56454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar /// \brief The predicate record for this feature. 56554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar Record *TheDef; 56654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 56754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar /// \brief An unique index assigned to represent this feature. 56854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar unsigned Index; 56954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 5700aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner SubtargetFeatureInfo(Record *D, unsigned Idx) : TheDef(D), Index(Idx) {} 571828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 57254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar /// \brief The name of the enumerated constant identifying this feature. 5730aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner std::string getEnumName() const { 5740aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner return "Feature_" + TheDef->getName(); 5750aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner } 576dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 577dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void dump() { 578dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines errs() << getEnumName() << " " << Index << "\n"; 579dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines TheDef->dump(); 580dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 58154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar}; 58254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 583e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopesstruct OperandMatchEntry { 584e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes unsigned OperandMask; 585e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes MatchableInfo* MI; 586e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes ClassInfo *CI; 587e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 5888caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach static OperandMatchEntry create(MatchableInfo* mi, ClassInfo *ci, 589e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes unsigned opMask) { 590e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OperandMatchEntry X; 591e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes X.OperandMask = opMask; 592e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes X.CI = ci; 593e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes X.MI = mi; 594e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes return X; 595e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes } 596e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes}; 597e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 598e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 599a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarclass AsmMatcherInfo { 600a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarpublic: 60167db883487fca3472fdde51e931657e22d4d0495Chris Lattner /// Tracked Records 6029c6b60eb28d2717008f8d6ff52f7666ebc81113dChris Lattner RecordKeeper &Records; 60367db883487fca3472fdde51e931657e22d4d0495Chris Lattner 60459fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar /// The tablegen AsmParser record. 60559fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar Record *AsmParser; 60659fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar 60702bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner /// Target - The target information. 60802bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner CodeGenTarget &Target; 60902bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner 610a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// The classes which are needed for matching. 611a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::vector<ClassInfo*> Classes; 612a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 61322bc5c4184a497353e33195dd12541a4f08b008aChris Lattner /// The information on the matchables to match. 61422bc5c4184a497353e33195dd12541a4f08b008aChris Lattner std::vector<MatchableInfo*> Matchables; 615a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 616e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes /// Info for custom matching operands by user defined methods. 617e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes std::vector<OperandMatchEntry> OperandMatchInfo; 618e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 619ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// Map of Register records to their class information. 620decfdf548b43c80c3dd81ff1cc3639b80ed33a3eSean Silva typedef std::map<Record*, ClassInfo*, LessRecordByID> RegisterClassesTy; 621decfdf548b43c80c3dd81ff1cc3639b80ed33a3eSean Silva RegisterClassesTy RegisterClasses; 622ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 62354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar /// Map of Predicate records to their subtarget information. 6246dd670af758ee111593f81f355325e1b5960b870Tim Northover std::map<Record*, SubtargetFeatureInfo*, LessRecordByID> SubtargetFeatures; 625828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 6264dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach /// Map of AsmOperandClass records to their class information. 6274dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach std::map<Record*, ClassInfo*> AsmOperandClasses; 6284dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach 629a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarprivate: 630a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// Map of token to class information which has already been constructed. 631a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::map<std::string, ClassInfo*> TokenClasses; 632a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 633ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// Map of RegisterClass records to their class information. 634ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar std::map<Record*, ClassInfo*> RegisterClassClasses; 635a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 636a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarprivate: 637a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// getTokenClass - Lookup or create the class for the given token. 638b8d6e98e566724f58344d275a4bd675249bb713aChris Lattner ClassInfo *getTokenClass(StringRef Token); 639a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 640a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// getOperandClass - Lookup or create the class for the given operand. 641a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson ClassInfo *getOperandClass(const CGIOperandList::OperandInfo &OI, 64248c1f84b104fd32109d809a56f5ebbf461c0910cJim Grosbach int SubOpIdx); 64348c1f84b104fd32109d809a56f5ebbf461c0910cJim Grosbach ClassInfo *getOperandClass(Record *Rec, int SubOpIdx); 644a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 6458caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach /// buildRegisterClasses - Build the ClassInfo* instances for register 646ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// classes. 6478caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach void buildRegisterClasses(SmallPtrSet<Record*, 16> &SingletonRegisters); 648ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 6498caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach /// buildOperandClasses - Build the ClassInfo* instances for user defined 650ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// operand classes. 6518caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach void buildOperandClasses(); 652ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 6538caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach void buildInstructionOperandReference(MatchableInfo *II, StringRef OpName, 654a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson unsigned AsmOpIdx); 6558caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach void buildAliasOperandReference(MatchableInfo *II, StringRef OpName, 656c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner MatchableInfo::AsmOperand &Op); 657828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 658a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarpublic: 659828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson AsmMatcherInfo(Record *AsmParser, 660828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson CodeGenTarget &Target, 6619c6b60eb28d2717008f8d6ff52f7666ebc81113dChris Lattner RecordKeeper &Records); 66259fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar 6638caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach /// buildInfo - Construct the various tables used during matching. 6648caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach void buildInfo(); 665828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 6668caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach /// buildOperandMatchInfo - Build the necessary information to handle user 667e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes /// defined operand parsing methods. 6688caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach void buildOperandMatchInfo(); 669e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 6706fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner /// getSubtargetFeature - Lookup or create the subtarget feature info for the 6716fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner /// given operand. 6726fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner SubtargetFeatureInfo *getSubtargetFeature(Record *Def) const { 6736fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner assert(Def->isSubClassOf("Predicate") && "Invalid predicate type!"); 6746dd670af758ee111593f81f355325e1b5960b870Tim Northover std::map<Record*, SubtargetFeatureInfo*, LessRecordByID>::const_iterator I = 6756fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner SubtargetFeatures.find(Def); 676dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return I == SubtargetFeatures.end() ? nullptr : I->second; 6776fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner } 67867db883487fca3472fdde51e931657e22d4d0495Chris Lattner 6799c6b60eb28d2717008f8d6ff52f7666ebc81113dChris Lattner RecordKeeper &getRecords() const { 6809c6b60eb28d2717008f8d6ff52f7666ebc81113dChris Lattner return Records; 68167db883487fca3472fdde51e931657e22d4d0495Chris Lattner } 682a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar}; 683a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 6846f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End anonymous namespace 68520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 68622bc5c4184a497353e33195dd12541a4f08b008aChris Lattnervoid MatchableInfo::dump() { 6875abd1ebcb380664ae5010395b217e01f7190046cChris Lattner errs() << TheDef->getName() << " -- " << "flattened:\"" << AsmString <<"\"\n"; 688a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 6893116fef7b970eb7dbc2aa7daa9ea01e96c401bbfChris Lattner for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) { 690c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner AsmOperand &Op = AsmOperands[i]; 6916745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar errs() << " op[" << i << "] = " << Op.Class->ClassName << " - "; 6920bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner errs() << '\"' << Op.Token << "\"\n"; 69320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 69420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar} 695a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 696c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbachstatic std::pair<StringRef, StringRef> 697376a8a773e38fdcd9102a40e08ab1e0661d645d9Jakob Stoklund OlesenparseTwoOperandConstraint(StringRef S, ArrayRef<SMLoc> Loc) { 698c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach // Split via the '='. 699c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach std::pair<StringRef, StringRef> Ops = S.split('='); 700c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach if (Ops.second == "") 70161131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger PrintFatalError(Loc, "missing '=' in two-operand alias constraint"); 702c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach // Trim whitespace and the leading '$' on the operand names. 703c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach size_t start = Ops.first.find_first_of('$'); 704c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach if (start == std::string::npos) 70561131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger PrintFatalError(Loc, "expected '$' prefix on asm operand name"); 706c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach Ops.first = Ops.first.slice(start + 1, std::string::npos); 707c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach size_t end = Ops.first.find_last_of(" \t"); 708c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach Ops.first = Ops.first.slice(0, end); 709c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach // Now the second operand. 710c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach start = Ops.second.find_first_of('$'); 711c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach if (start == std::string::npos) 71261131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger PrintFatalError(Loc, "expected '$' prefix on asm operand name"); 713c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach Ops.second = Ops.second.slice(start + 1, std::string::npos); 714c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach end = Ops.second.find_last_of(" \t"); 715c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach Ops.first = Ops.first.slice(0, end); 716c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach return Ops; 717c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach} 718c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach 719c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbachvoid MatchableInfo::formTwoOperandAlias(StringRef Constraint) { 720c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach // Figure out which operands are aliased and mark them as tied. 721c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach std::pair<StringRef, StringRef> Ops = 722c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach parseTwoOperandConstraint(Constraint, TheDef->getLoc()); 723c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach 724c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach // Find the AsmOperands that refer to the operands we're aliasing. 725c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach int SrcAsmOperand = findAsmOperandNamed(Ops.first); 726c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach int DstAsmOperand = findAsmOperandNamed(Ops.second); 727c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach if (SrcAsmOperand == -1) 72861131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger PrintFatalError(TheDef->getLoc(), 72936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "unknown source two-operand alias operand '" + Ops.first + 73036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "'."); 731c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach if (DstAsmOperand == -1) 73261131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger PrintFatalError(TheDef->getLoc(), 73336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "unknown destination two-operand alias operand '" + 73436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Ops.second + "'."); 735c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach 736c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach // Find the ResOperand that refers to the operand we're aliasing away 737c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach // and update it to refer to the combined operand instead. 738c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach for (unsigned i = 0, e = ResOperands.size(); i != e; ++i) { 739c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach ResOperand &Op = ResOperands[i]; 740c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach if (Op.Kind == ResOperand::RenderAsmOperand && 741c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach Op.AsmOperandNum == (unsigned)SrcAsmOperand) { 742c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach Op.AsmOperandNum = DstAsmOperand; 743c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach break; 744c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach } 745c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach } 746c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach // Remove the AsmOperand for the alias operand. 747c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach AsmOperands.erase(AsmOperands.begin() + SrcAsmOperand); 748c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach // Adjust the ResOperand references to any AsmOperands that followed 749c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach // the one we just deleted. 750c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach for (unsigned i = 0, e = ResOperands.size(); i != e; ++i) { 751c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach ResOperand &Op = ResOperands[i]; 752c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach switch(Op.Kind) { 753c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach default: 754c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach // Nothing to do for operands that don't reference AsmOperands. 755c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach break; 756c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach case ResOperand::RenderAsmOperand: 757c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach if (Op.AsmOperandNum > (unsigned)SrcAsmOperand) 758c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach --Op.AsmOperandNum; 759c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach break; 760c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach case ResOperand::TiedOperand: 761c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach if (Op.TiedOperandNum > (unsigned)SrcAsmOperand) 762c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach --Op.TiedOperandNum; 763c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach break; 764c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach } 765c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach } 766c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach} 767c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach 7688caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachvoid MatchableInfo::initialize(const AsmMatcherInfo &Info, 76963faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel SmallPtrSet<Record*, 16> &SingletonRegisters, 77063faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel int AsmVariantNo, std::string &RegisterPrefix) { 77156315d319c104dc96187444e1e19711a1c801166Devang Patel AsmVariantID = AsmVariantNo; 772f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach AsmString = 77363faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel CodeGenInstruction::FlattenAsmStringVariants(AsmString, AsmVariantNo); 774828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 7758caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach tokenizeAsmString(Info); 776828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 777c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner // Compute the require features. 778c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner std::vector<Record*> Predicates =TheDef->getValueAsListOfDefs("Predicates"); 779c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner for (unsigned i = 0, e = Predicates.size(); i != e; ++i) 780c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner if (SubtargetFeatureInfo *Feature = 781c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner Info.getSubtargetFeature(Predicates[i])) 782c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner RequiredFeatures.push_back(Feature); 783828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 784c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner // Collect singleton registers, if used. 785d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) { 78663faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel extractSingletonRegisterForAsmOperand(i, Info, RegisterPrefix); 78763faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel if (Record *Reg = AsmOperands[i].SingletonReg) 788c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner SingletonRegisters.insert(Reg); 789c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner } 790715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly 791715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly const RecordVal *DepMask = TheDef->getValue("DeprecatedFeatureMask"); 792715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly if (!DepMask) 793715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly DepMask = TheDef->getValue("ComplexDeprecationPredicate"); 794715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly 795715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly HasDeprecation = 796715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly DepMask ? !DepMask->getValue()->getAsUnquotedString().empty() : false; 797c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner} 798c2d67bbf806486984d4c9551abfd66c7f766c45bChris Lattner 7998caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach/// tokenizeAsmString - Tokenize a simplified assembly string. 8008caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachvoid MatchableInfo::tokenizeAsmString(const AsmMatcherInfo &Info) { 801d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner StringRef String = AsmString; 802d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner unsigned Prev = 0; 803d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner bool InTok = true; 804d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner for (unsigned i = 0, e = String.size(); i != e; ++i) { 805d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner switch (String[i]) { 806d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner case '[': 807d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner case ']': 808d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner case '*': 809d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner case '!': 810d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner case ' ': 811d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner case '\t': 812d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner case ',': 813d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner if (InTok) { 814c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner AsmOperands.push_back(AsmOperand(String.slice(Prev, i))); 815d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner InTok = false; 816d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner } 817d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner if (!isspace(String[i]) && String[i] != ',') 818c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner AsmOperands.push_back(AsmOperand(String.substr(i, 1))); 819d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner Prev = i + 1; 820d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner break; 821d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner 822d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner case '\\': 823d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner if (InTok) { 824c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner AsmOperands.push_back(AsmOperand(String.slice(Prev, i))); 825d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner InTok = false; 826d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner } 827d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner ++i; 828d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner assert(i != String.size() && "Invalid quoted character"); 829c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner AsmOperands.push_back(AsmOperand(String.substr(i, 1))); 830d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner Prev = i + 1; 831d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner break; 832d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner 833d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner case '$': { 8347ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner if (InTok) { 8357ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner AsmOperands.push_back(AsmOperand(String.slice(Prev, i))); 8367ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner InTok = false; 8377ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner } 838828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 839d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner // If this isn't "${", treat like a normal token. 840d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner if (i + 1 == String.size() || String[i + 1] != '{') { 841d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner Prev = i; 842d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner break; 843d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner } 844d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner 845d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner StringRef::iterator End = std::find(String.begin() + i, String.end(),'}'); 846d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner assert(End != String.end() && "Missing brace in operand reference!"); 847d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner size_t EndPos = End - String.begin(); 848c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner AsmOperands.push_back(AsmOperand(String.slice(i, EndPos+1))); 849d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner Prev = EndPos + 1; 850d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner i = EndPos; 851d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner break; 852d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner } 853d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner 854d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner case '.': 855588f408b95c83e9b59c0777925d2ae70ac445faeVladimir Medic if (!Info.AsmParser->getValueAsBit("MnemonicContainsDot")) { 8569273151c3bbc96c9b2911caffe3e1a724261cd06Vladimir Medic if (InTok) 8579273151c3bbc96c9b2911caffe3e1a724261cd06Vladimir Medic AsmOperands.push_back(AsmOperand(String.slice(Prev, i))); 8589273151c3bbc96c9b2911caffe3e1a724261cd06Vladimir Medic Prev = i; 8599273151c3bbc96c9b2911caffe3e1a724261cd06Vladimir Medic } 860d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner InTok = true; 861d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner break; 862d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner 863d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner default: 864d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner InTok = true; 865d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner } 866d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner } 867d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner if (InTok && Prev != String.size()) 868c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner AsmOperands.push_back(AsmOperand(String.substr(Prev))); 869828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 870d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner // The first token of the instruction is the mnemonic, which must be a 871d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner // simple string, not a $foo variable or a singleton register. 8724a2242cea0e9fdb36276807b1d4ddd7cd1a15bd4Jim Grosbach if (AsmOperands.empty()) 87361131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger PrintFatalError(TheDef->getLoc(), 8744a2242cea0e9fdb36276807b1d4ddd7cd1a15bd4Jim Grosbach "Instruction '" + TheDef->getName() + "' has no tokens"); 875d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner Mnemonic = AsmOperands[0].Token; 8768e27c9615938298bd03a7884964a0f5e0e80542dJim Grosbach if (Mnemonic.empty()) 87761131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger PrintFatalError(TheDef->getLoc(), 8788e27c9615938298bd03a7884964a0f5e0e80542dJim Grosbach "Missing instruction mnemonic"); 87963faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel // FIXME : Check and raise an error if it is a register. 880b78307fc58025713fd98c8414fa8f29720f37a76Devang Patel if (Mnemonic[0] == '$') 88161131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger PrintFatalError(TheDef->getLoc(), 88236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "Invalid instruction mnemonic '" + Mnemonic + "'!"); 883828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 884d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner // Remove the first operand, it is tracked in the mnemonic field. 885d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner AsmOperands.erase(AsmOperands.begin()); 886d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner} 887d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner 8888caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachbool MatchableInfo::validate(StringRef CommentDelimiter, bool Hack) const { 88922bc5c4184a497353e33195dd12541a4f08b008aChris Lattner // Reject matchables with no .s string. 8905bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner if (AsmString.empty()) 89161131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger PrintFatalError(TheDef->getLoc(), "instruction with empty asm string"); 892828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 89322bc5c4184a497353e33195dd12541a4f08b008aChris Lattner // Reject any matchables with a newline in them, they should be marked 8945bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner // isCodeGenOnly if they are pseudo instructions. 8955bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner if (AsmString.find('\n') != std::string::npos) 89661131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger PrintFatalError(TheDef->getLoc(), 8975bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner "multiline instruction is not valid for the asmparser, " 8985bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner "mark it isCodeGenOnly"); 899828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 9004164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner // Remove comments from the asm string. We know that the asmstring only 9014164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner // has one line. 9024164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner if (!CommentDelimiter.empty() && 9034164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner StringRef(AsmString).find(CommentDelimiter) != StringRef::npos) 90461131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger PrintFatalError(TheDef->getLoc(), 9054164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner "asmstring for instruction has comment character in it, " 9064164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner "mark it isCodeGenOnly"); 907828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 90822bc5c4184a497353e33195dd12541a4f08b008aChris Lattner // Reject matchables with operand modifiers, these aren't something we can 909906bc368bc0fe18682edc0743ada41f62e436383Bob Wilson // handle, the target should be refactored to use operands instead of 910906bc368bc0fe18682edc0743ada41f62e436383Bob Wilson // modifiers. 9115bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner // 9125bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner // Also, check for instructions which reference the operand multiple times; 9135bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner // this implies a constraint we would not honor. 9145bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner std::set<std::string> OperandNames; 915d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) { 916d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner StringRef Tok = AsmOperands[i].Token; 917d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner if (Tok[0] == '$' && Tok.find(':') != StringRef::npos) 91861131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger PrintFatalError(TheDef->getLoc(), 91936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "matchable with operand modifier '" + Tok + 92036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "' not supported by asm matcher. Mark isCodeGenOnly!"); 921828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 92222bc5c4184a497353e33195dd12541a4f08b008aChris Lattner // Verify that any operand is only mentioned once. 923d51257a4368d52e2340073bc7ccd83f3c3f1c04dChris Lattner // We reject aliases and ignore instructions for now. 924d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner if (Tok[0] == '$' && !OperandNames.insert(Tok).second) { 92522bc5c4184a497353e33195dd12541a4f08b008aChris Lattner if (!Hack) 92661131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger PrintFatalError(TheDef->getLoc(), 92736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "ERROR: matchable with tied operand '" + Tok + 92836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "' can never be matched!"); 92922bc5c4184a497353e33195dd12541a4f08b008aChris Lattner // FIXME: Should reject these. The ARM backend hits this with $lane in a 93022bc5c4184a497353e33195dd12541a4f08b008aChris Lattner // bunch of instructions. It is unclear what the right answer is. 9315bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner DEBUG({ 9325abd1ebcb380664ae5010395b217e01f7190046cChris Lattner errs() << "warning: '" << TheDef->getName() << "': " 93322bc5c4184a497353e33195dd12541a4f08b008aChris Lattner << "ignoring instruction with tied operand '" 93436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << Tok << "'\n"; 9355bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner }); 9365bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner return false; 9375bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner } 9385bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner } 939828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 9405bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner return true; 9415bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner} 9425bc93878069b7d9c567c8a04ebfa329636822c5eChris Lattner 943f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach/// extractSingletonRegisterForAsmOperand - Extract singleton register, 944d06b01c038e00f6af50a1b6d4c71389037e00212Devang Patel/// if present, from specified token. 94563faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patelvoid MatchableInfo:: 946f35307ceac57194094f207f0920fbd22231f5331Jim GrosbachextractSingletonRegisterForAsmOperand(unsigned OperandNo, 947d06b01c038e00f6af50a1b6d4c71389037e00212Devang Patel const AsmMatcherInfo &Info, 94811fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach std::string &RegisterPrefix) { 949d06b01c038e00f6af50a1b6d4c71389037e00212Devang Patel StringRef Tok = AsmOperands[OperandNo].Token; 95063faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel if (RegisterPrefix.empty()) { 951d06b01c038e00f6af50a1b6d4c71389037e00212Devang Patel std::string LoweredTok = Tok.lower(); 952d06b01c038e00f6af50a1b6d4c71389037e00212Devang Patel if (const CodeGenRegister *Reg = Info.Target.getRegisterByName(LoweredTok)) 953d06b01c038e00f6af50a1b6d4c71389037e00212Devang Patel AsmOperands[OperandNo].SingletonReg = Reg->TheDef; 95463faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel return; 955f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach } 95663faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel 95763faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel if (!Tok.startswith(RegisterPrefix)) 95863faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel return; 959828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 96063faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel StringRef RegName = Tok.substr(RegisterPrefix.size()); 961ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner if (const CodeGenRegister *Reg = Info.Target.getRegisterByName(RegName)) 962d06b01c038e00f6af50a1b6d4c71389037e00212Devang Patel AsmOperands[OperandNo].SingletonReg = Reg->TheDef; 963828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 9641de88235781c45c0afc0c7500d65b59775196c4cChris Lattner // If there is no register prefix (i.e. "%" in "%eax"), then this may 9651de88235781c45c0afc0c7500d65b59775196c4cChris Lattner // be some random non-register token, just ignore it. 96663faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel return; 96702bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner} 96802bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner 969b8d6e98e566724f58344d275a4bd675249bb713aChris Lattnerstatic std::string getEnumNameForToken(StringRef Str) { 970a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::string Res; 971a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 972a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar for (StringRef::iterator it = Str.begin(), ie = Str.end(); it != ie; ++it) { 973a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar switch (*it) { 974a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar case '*': Res += "_STAR_"; break; 975a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar case '%': Res += "_PCT_"; break; 976a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar case ':': Res += "_COLON_"; break; 977bd9c77bc9ad384d046a7967d160ad96f61916d9dBill Wendling case '!': Res += "_EXCLAIM_"; break; 9780ef755d9051a79680326d6144a2401660fc93e57Bill Wendling case '.': Res += "_DOT_"; break; 97912da505d938ecfbc49b203e454bada99eda950e3Tim Northover case '<': Res += "_LT_"; break; 98012da505d938ecfbc49b203e454bada99eda950e3Tim Northover case '>': Res += "_GT_"; break; 981a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar default: 98212da505d938ecfbc49b203e454bada99eda950e3Tim Northover if ((*it >= 'A' && *it <= 'Z') || 98312da505d938ecfbc49b203e454bada99eda950e3Tim Northover (*it >= 'a' && *it <= 'z') || 98412da505d938ecfbc49b203e454bada99eda950e3Tim Northover (*it >= '0' && *it <= '9')) 985a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Res += *it; 98639ee036f407bd0c94cb993cf9b97348843cfafa4Chris Lattner else 987a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Res += "_" + utostr((unsigned) *it) + "_"; 988a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 989a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 99020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 991a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar return Res; 992a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar} 993a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 994b8d6e98e566724f58344d275a4bd675249bb713aChris LattnerClassInfo *AsmMatcherInfo::getTokenClass(StringRef Token) { 995a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar ClassInfo *&Entry = TokenClasses[Token]; 996a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 997a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar if (!Entry) { 998a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Entry = new ClassInfo(); 999a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Entry->Kind = ClassInfo::Token; 10006745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar Entry->ClassName = "Token"; 1001a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Entry->Name = "MCK_" + getEnumNameForToken(Token); 1002a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Entry->ValueName = Token; 1003a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Entry->PredicateMethod = "<invalid>"; 1004a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Entry->RenderMethod = "<invalid>"; 1005e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes Entry->ParserMethod = ""; 10064dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach Entry->DiagnosticType = ""; 1007a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Classes.push_back(Entry); 1008a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 1009a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1010a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar return Entry; 1011a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar} 1012a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1013a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel DunbarClassInfo * 1014a49c7dfb360154070c08b8eb94ad31711d1babaeBob WilsonAsmMatcherInfo::getOperandClass(const CGIOperandList::OperandInfo &OI, 1015a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson int SubOpIdx) { 1016a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson Record *Rec = OI.Rec; 1017a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson if (SubOpIdx != -1) 10183f7b7f8ce0b050fc6a0100839d9c5a84198b2aedSean Silva Rec = cast<DefInit>(OI.MIOperandInfo->getArg(SubOpIdx))->getDef(); 101948c1f84b104fd32109d809a56f5ebbf461c0910cJim Grosbach return getOperandClass(Rec, SubOpIdx); 102048c1f84b104fd32109d809a56f5ebbf461c0910cJim Grosbach} 1021a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson 102248c1f84b104fd32109d809a56f5ebbf461c0910cJim GrosbachClassInfo * 102348c1f84b104fd32109d809a56f5ebbf461c0910cJim GrosbachAsmMatcherInfo::getOperandClass(Record *Rec, int SubOpIdx) { 1024bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson if (Rec->isSubClassOf("RegisterOperand")) { 1025bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson // RegisterOperand may have an associated ParserMatchClass. If it does, 1026bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson // use it, else just fall back to the underlying register class. 1027bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson const RecordVal *R = Rec->getValue("ParserMatchClass"); 1028dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!R || !R->getValue()) 102961131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger PrintFatalError("Record `" + Rec->getName() + 103061131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger "' does not have a ParserMatchClass!\n"); 1031bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson 10326cfc806a6b82b60a3e923b6b89f2b4da62cdb50bSean Silva if (DefInit *DI= dyn_cast<DefInit>(R->getValue())) { 1033bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson Record *MatchClass = DI->getDef(); 1034bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson if (ClassInfo *CI = AsmOperandClasses[MatchClass]) 1035bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson return CI; 1036bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson } 1037bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson 1038bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson // No custom match class. Just use the register class. 1039bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson Record *ClassRec = Rec->getValueAsDef("RegClass"); 1040bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson if (!ClassRec) 104161131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger PrintFatalError(Rec->getLoc(), "RegisterOperand `" + Rec->getName() + 1042bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson "' has no associated register class!\n"); 1043bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson if (ClassInfo *CI = RegisterClassClasses[ClassRec]) 1044bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson return CI; 104561131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger PrintFatalError(Rec->getLoc(), "register class has no class info!"); 1046bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson } 1047bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson 1048bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson 1049a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson if (Rec->isSubClassOf("RegisterClass")) { 1050a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson if (ClassInfo *CI = RegisterClassClasses[Rec]) 1051ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner return CI; 105261131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger PrintFatalError(Rec->getLoc(), "register class has no class info!"); 1053ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 1054338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar 1055a562dc7228990797a259f4fef4acb95a83b23e0dJim Grosbach if (!Rec->isSubClassOf("Operand")) 105661131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger PrintFatalError(Rec->getLoc(), "Operand `" + Rec->getName() + 1057a562dc7228990797a259f4fef4acb95a83b23e0dJim Grosbach "' does not derive from class Operand!\n"); 1058a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson Record *MatchClass = Rec->getValueAsDef("ParserMatchClass"); 1059ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner if (ClassInfo *CI = AsmOperandClasses[MatchClass]) 1060ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner return CI; 1061a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 106261131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger PrintFatalError(Rec->getLoc(), "operand has no match class!"); 1063338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar} 1064338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar 106503f9197d62dddfb70e70acb5563518f589d29251Tim Northoverstruct LessRegisterSet { 1066107cfa2169299fe67caebe7d1f0d405ce727e420Tim Northover bool operator() (const RegisterSet &LHS, const RegisterSet & RHS) const { 106703f9197d62dddfb70e70acb5563518f589d29251Tim Northover // std::set<T> defines its own compariso "operator<", but it 106803f9197d62dddfb70e70acb5563518f589d29251Tim Northover // performs a lexicographical comparison by T's innate comparison 106903f9197d62dddfb70e70acb5563518f589d29251Tim Northover // for some reason. We don't want non-deterministic pointer 107003f9197d62dddfb70e70acb5563518f589d29251Tim Northover // comparisons so use this instead. 107103f9197d62dddfb70e70acb5563518f589d29251Tim Northover return std::lexicographical_compare(LHS.begin(), LHS.end(), 107203f9197d62dddfb70e70acb5563518f589d29251Tim Northover RHS.begin(), RHS.end(), 107303f9197d62dddfb70e70acb5563518f589d29251Tim Northover LessRecordByID()); 107403f9197d62dddfb70e70acb5563518f589d29251Tim Northover } 107503f9197d62dddfb70e70acb5563518f589d29251Tim Northover}; 107603f9197d62dddfb70e70acb5563518f589d29251Tim Northover 10771de88235781c45c0afc0c7500d65b59775196c4cChris Lattnervoid AsmMatcherInfo:: 10788caecdea56c830f3fc80ed67fff121c83de0e364Jim GrosbachbuildRegisterClasses(SmallPtrSet<Record*, 16> &SingletonRegisters) { 1079abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen const std::vector<CodeGenRegister*> &Registers = 1080abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen Target.getRegBank().getRegisters(); 108129f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen ArrayRef<CodeGenRegisterClass*> RegClassList = 108229f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen Target.getRegBank().getRegClasses(); 1083338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar 108403f9197d62dddfb70e70acb5563518f589d29251Tim Northover typedef std::set<RegisterSet, LessRegisterSet> RegisterSetSet; 108503f9197d62dddfb70e70acb5563518f589d29251Tim Northover 1086ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // The register sets used for matching. 108703f9197d62dddfb70e70acb5563518f589d29251Tim Northover RegisterSetSet RegisterSets; 1088ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 1089a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach // Gather the defined sets. 109029f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen for (ArrayRef<CodeGenRegisterClass*>::const_iterator it = 109103f9197d62dddfb70e70acb5563518f589d29251Tim Northover RegClassList.begin(), ie = RegClassList.end(); it != ie; ++it) 109203f9197d62dddfb70e70acb5563518f589d29251Tim Northover RegisterSets.insert(RegisterSet( 109329f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen (*it)->getOrder().begin(), (*it)->getOrder().end())); 10941095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 10951095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar // Add any required singleton sets. 10961de88235781c45c0afc0c7500d65b59775196c4cChris Lattner for (SmallPtrSet<Record*, 16>::iterator it = SingletonRegisters.begin(), 10971de88235781c45c0afc0c7500d65b59775196c4cChris Lattner ie = SingletonRegisters.end(); it != ie; ++it) { 10981de88235781c45c0afc0c7500d65b59775196c4cChris Lattner Record *Rec = *it; 109903f9197d62dddfb70e70acb5563518f589d29251Tim Northover RegisterSets.insert(RegisterSet(&Rec, &Rec + 1)); 11001de88235781c45c0afc0c7500d65b59775196c4cChris Lattner } 1101a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 1102ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Introduce derived sets where necessary (when a register does not determine 1103ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // a unique register set class), and build the mapping of registers to the set 1104ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // they should classify to. 110503f9197d62dddfb70e70acb5563518f589d29251Tim Northover std::map<Record*, RegisterSet> RegisterMap; 1106abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen for (std::vector<CodeGenRegister*>::const_iterator it = Registers.begin(), 1107ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ie = Registers.end(); it != ie; ++it) { 1108abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen const CodeGenRegister &CGR = **it; 1109ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Compute the intersection of all sets containing this register. 111003f9197d62dddfb70e70acb5563518f589d29251Tim Northover RegisterSet ContainingSet; 1111a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 111203f9197d62dddfb70e70acb5563518f589d29251Tim Northover for (RegisterSetSet::iterator it = RegisterSets.begin(), 1113ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ie = RegisterSets.end(); it != ie; ++it) { 1114ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (!it->count(CGR.TheDef)) 1115ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar continue; 1116ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 1117ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (ContainingSet.empty()) { 1118ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ContainingSet = *it; 1119ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner continue; 1120ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 1121828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 112203f9197d62dddfb70e70acb5563518f589d29251Tim Northover RegisterSet Tmp; 1123ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner std::swap(Tmp, ContainingSet); 112403f9197d62dddfb70e70acb5563518f589d29251Tim Northover std::insert_iterator<RegisterSet> II(ContainingSet, 112503f9197d62dddfb70e70acb5563518f589d29251Tim Northover ContainingSet.begin()); 112603f9197d62dddfb70e70acb5563518f589d29251Tim Northover std::set_intersection(Tmp.begin(), Tmp.end(), it->begin(), it->end(), II, 112703f9197d62dddfb70e70acb5563518f589d29251Tim Northover LessRecordByID()); 1128ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 1129ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 1130ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (!ContainingSet.empty()) { 1131ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar RegisterSets.insert(ContainingSet); 1132ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar RegisterMap.insert(std::make_pair(CGR.TheDef, ContainingSet)); 1133ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 1134ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 1135ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 1136ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Construct the register classes. 113703f9197d62dddfb70e70acb5563518f589d29251Tim Northover std::map<RegisterSet, ClassInfo*, LessRegisterSet> RegisterSetClasses; 1138ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar unsigned Index = 0; 113903f9197d62dddfb70e70acb5563518f589d29251Tim Northover for (RegisterSetSet::iterator it = RegisterSets.begin(), 1140ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ie = RegisterSets.end(); it != ie; ++it, ++Index) { 1141ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ClassInfo *CI = new ClassInfo(); 1142ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->Kind = ClassInfo::RegisterClass0 + Index; 1143ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->ClassName = "Reg" + utostr(Index); 1144ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->Name = "MCK_Reg" + utostr(Index); 1145ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->ValueName = ""; 1146ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->PredicateMethod = ""; // unused 1147ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->RenderMethod = "addRegOperands"; 11488409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar CI->Registers = *it; 11494dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach // FIXME: diagnostic type. 11504dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach CI->DiagnosticType = ""; 1151ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar Classes.push_back(CI); 1152ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar RegisterSetClasses.insert(std::make_pair(*it, CI)); 1153ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 1154ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 1155ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Find the superclasses; we could compute only the subgroup lattice edges, 1156ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // but there isn't really a point. 115703f9197d62dddfb70e70acb5563518f589d29251Tim Northover for (RegisterSetSet::iterator it = RegisterSets.begin(), 1158ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ie = RegisterSets.end(); it != ie; ++it) { 1159ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ClassInfo *CI = RegisterSetClasses[*it]; 116003f9197d62dddfb70e70acb5563518f589d29251Tim Northover for (RegisterSetSet::iterator it2 = RegisterSets.begin(), 1161ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ie2 = RegisterSets.end(); it2 != ie2; ++it2) 1162a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach if (*it != *it2 && 116303f9197d62dddfb70e70acb5563518f589d29251Tim Northover std::includes(it2->begin(), it2->end(), it->begin(), it->end(), 116403f9197d62dddfb70e70acb5563518f589d29251Tim Northover LessRecordByID())) 1165ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->SuperClasses.push_back(RegisterSetClasses[*it2]); 1166ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 1167ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 1168ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Name the register classes which correspond to a user defined RegisterClass. 116929f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen for (ArrayRef<CodeGenRegisterClass*>::const_iterator 1170ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner it = RegClassList.begin(), ie = RegClassList.end(); it != ie; ++it) { 117129f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen const CodeGenRegisterClass &RC = **it; 11726fea31e7300fe012b0b2984d6bc0338d02b054d3Jakob Stoklund Olesen // Def will be NULL for non-user defined register classes. 11736fea31e7300fe012b0b2984d6bc0338d02b054d3Jakob Stoklund Olesen Record *Def = RC.getDef(); 11746fea31e7300fe012b0b2984d6bc0338d02b054d3Jakob Stoklund Olesen if (!Def) 11756fea31e7300fe012b0b2984d6bc0338d02b054d3Jakob Stoklund Olesen continue; 117603f9197d62dddfb70e70acb5563518f589d29251Tim Northover ClassInfo *CI = RegisterSetClasses[RegisterSet(RC.getOrder().begin(), 117703f9197d62dddfb70e70acb5563518f589d29251Tim Northover RC.getOrder().end())]; 1178ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (CI->ValueName.empty()) { 117929f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen CI->ClassName = RC.getName(); 118029f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen CI->Name = "MCK_" + RC.getName(); 118129f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen CI->ValueName = RC.getName(); 1182ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } else 118329f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen CI->ValueName = CI->ValueName + "," + RC.getName(); 1184ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 11856fea31e7300fe012b0b2984d6bc0338d02b054d3Jakob Stoklund Olesen RegisterClassClasses.insert(std::make_pair(Def, CI)); 1186ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 1187ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 1188ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Populate the map for individual registers. 118903f9197d62dddfb70e70acb5563518f589d29251Tim Northover for (std::map<Record*, RegisterSet>::iterator it = RegisterMap.begin(), 1190ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ie = RegisterMap.end(); it != ie; ++it) 1191ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner RegisterClasses[it->first] = RegisterSetClasses[it->second]; 11921095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 11931095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar // Name the register classes which correspond to singleton registers. 11941de88235781c45c0afc0c7500d65b59775196c4cChris Lattner for (SmallPtrSet<Record*, 16>::iterator it = SingletonRegisters.begin(), 11951de88235781c45c0afc0c7500d65b59775196c4cChris Lattner ie = SingletonRegisters.end(); it != ie; ++it) { 11961de88235781c45c0afc0c7500d65b59775196c4cChris Lattner Record *Rec = *it; 1197ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner ClassInfo *CI = RegisterClasses[Rec]; 11981de88235781c45c0afc0c7500d65b59775196c4cChris Lattner assert(CI && "Missing singleton register class info!"); 11991de88235781c45c0afc0c7500d65b59775196c4cChris Lattner 12001de88235781c45c0afc0c7500d65b59775196c4cChris Lattner if (CI->ValueName.empty()) { 12011de88235781c45c0afc0c7500d65b59775196c4cChris Lattner CI->ClassName = Rec->getName(); 12021de88235781c45c0afc0c7500d65b59775196c4cChris Lattner CI->Name = "MCK_" + Rec->getName(); 12031de88235781c45c0afc0c7500d65b59775196c4cChris Lattner CI->ValueName = Rec->getName(); 12041de88235781c45c0afc0c7500d65b59775196c4cChris Lattner } else 12051de88235781c45c0afc0c7500d65b59775196c4cChris Lattner CI->ValueName = CI->ValueName + "," + Rec->getName(); 12061095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar } 1207ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar} 1208ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 12098caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachvoid AsmMatcherInfo::buildOperandClasses() { 1210e66b7ebfb426c7ed9bc911e9708321e2d8510b41Chris Lattner std::vector<Record*> AsmOperands = 1211e66b7ebfb426c7ed9bc911e9708321e2d8510b41Chris Lattner Records.getAllDerivedDefinitions("AsmOperandClass"); 1212a2f5e00347641d1b46ce4f65bf9378fecce9be14Daniel Dunbar 1213a2f5e00347641d1b46ce4f65bf9378fecce9be14Daniel Dunbar // Pre-populate AsmOperandClasses map. 1214a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach for (std::vector<Record*>::iterator it = AsmOperands.begin(), 1215a2f5e00347641d1b46ce4f65bf9378fecce9be14Daniel Dunbar ie = AsmOperands.end(); it != ie; ++it) 1216a2f5e00347641d1b46ce4f65bf9378fecce9be14Daniel Dunbar AsmOperandClasses[*it] = new ClassInfo(); 1217a2f5e00347641d1b46ce4f65bf9378fecce9be14Daniel Dunbar 1218338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar unsigned Index = 0; 1219a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach for (std::vector<Record*>::iterator it = AsmOperands.begin(), 1220338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar ie = AsmOperands.end(); it != ie; ++it, ++Index) { 1221a2f5e00347641d1b46ce4f65bf9378fecce9be14Daniel Dunbar ClassInfo *CI = AsmOperandClasses[*it]; 1222338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar CI->Kind = ClassInfo::UserClass0 + Index; 1223338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar 122405bce0beee87512e52428d4b80f5a8e79a949576David Greene ListInit *Supers = (*it)->getValueAsListInit("SuperClasses"); 122554ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar for (unsigned i = 0, e = Supers->getSize(); i != e; ++i) { 12266cfc806a6b82b60a3e923b6b89f2b4da62cdb50bSean Silva DefInit *DI = dyn_cast<DefInit>(Supers->getElement(i)); 122754ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar if (!DI) { 122854ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar PrintError((*it)->getLoc(), "Invalid super class reference!"); 122954ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar continue; 123054ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar } 123154ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar 1232ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ClassInfo *SC = AsmOperandClasses[DI->getDef()]; 1233ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (!SC) 1234338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar PrintError((*it)->getLoc(), "Invalid super class reference!"); 1235ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar else 1236ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->SuperClasses.push_back(SC); 1237a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 1238338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar CI->ClassName = (*it)->getValueAsString("Name"); 1239338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar CI->Name = "MCK_" + CI->ClassName; 1240338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar CI->ValueName = (*it)->getName(); 12415c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar 12425c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar // Get or construct the predicate method name. 124305bce0beee87512e52428d4b80f5a8e79a949576David Greene Init *PMName = (*it)->getValueInit("PredicateMethod"); 12446cfc806a6b82b60a3e923b6b89f2b4da62cdb50bSean Silva if (StringInit *SI = dyn_cast<StringInit>(PMName)) { 12455c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar CI->PredicateMethod = SI->getValue(); 12465c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar } else { 12473f7b7f8ce0b050fc6a0100839d9c5a84198b2aedSean Silva assert(isa<UnsetInit>(PMName) && "Unexpected PredicateMethod field!"); 12485c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar CI->PredicateMethod = "is" + CI->ClassName; 12495c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar } 12505c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar 12515c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar // Get or construct the render method name. 125205bce0beee87512e52428d4b80f5a8e79a949576David Greene Init *RMName = (*it)->getValueInit("RenderMethod"); 12536cfc806a6b82b60a3e923b6b89f2b4da62cdb50bSean Silva if (StringInit *SI = dyn_cast<StringInit>(RMName)) { 12545c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar CI->RenderMethod = SI->getValue(); 12555c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar } else { 12563f7b7f8ce0b050fc6a0100839d9c5a84198b2aedSean Silva assert(isa<UnsetInit>(RMName) && "Unexpected RenderMethod field!"); 12575c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar CI->RenderMethod = "add" + CI->ClassName + "Operands"; 12585c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar } 12595c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar 1260e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes // Get the parse method name or leave it as empty. 126105bce0beee87512e52428d4b80f5a8e79a949576David Greene Init *PRMName = (*it)->getValueInit("ParserMethod"); 12626cfc806a6b82b60a3e923b6b89f2b4da62cdb50bSean Silva if (StringInit *SI = dyn_cast<StringInit>(PRMName)) 1263e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes CI->ParserMethod = SI->getValue(); 1264e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 12654dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach // Get the diagnostic type or leave it as empty. 12664dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach // Get the parse method name or leave it as empty. 12674dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach Init *DiagnosticType = (*it)->getValueInit("DiagnosticType"); 12686cfc806a6b82b60a3e923b6b89f2b4da62cdb50bSean Silva if (StringInit *SI = dyn_cast<StringInit>(DiagnosticType)) 12694dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach CI->DiagnosticType = SI->getValue(); 12704dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach 1271338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar AsmOperandClasses[*it] = CI; 1272338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar Classes.push_back(CI); 1273a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 1274ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar} 1275ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 1276828295bb301d6cd3683751c2da1c2dd22ec6423fBob WilsonAsmMatcherInfo::AsmMatcherInfo(Record *asmParser, 1277828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson CodeGenTarget &target, 12789c6b60eb28d2717008f8d6ff52f7666ebc81113dChris Lattner RecordKeeper &records) 127963faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel : Records(records), AsmParser(asmParser), Target(target) { 128059fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar} 128159fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar 12828caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach/// buildOperandMatchInfo - Build the necessary information to handle user 1283e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes/// defined operand parsing methods. 12848caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachvoid AsmMatcherInfo::buildOperandMatchInfo() { 1285e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 1286d4824fc8aa1df5501600dd2a73c6da823f3b02dbJim Grosbach /// Map containing a mask with all operands indices that can be found for 1287e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes /// that class inside a instruction. 128836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines typedef std::map<ClassInfo *, unsigned, less_ptr<ClassInfo>> OpClassMaskTy; 1289b2df610b44902124c22f3661a39bffd5341da62dSean Silva OpClassMaskTy OpClassMask; 1290e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 1291e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes for (std::vector<MatchableInfo*>::const_iterator it = 1292e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes Matchables.begin(), ie = Matchables.end(); 1293e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes it != ie; ++it) { 1294e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes MatchableInfo &II = **it; 1295e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OpClassMask.clear(); 1296e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 1297e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes // Keep track of all operands of this instructions which belong to the 1298e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes // same class. 1299e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes for (unsigned i = 0, e = II.AsmOperands.size(); i != e; ++i) { 1300e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes MatchableInfo::AsmOperand &Op = II.AsmOperands[i]; 1301e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes if (Op.Class->ParserMethod.empty()) 1302e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes continue; 1303e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes unsigned &OperandMask = OpClassMask[Op.Class]; 1304e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OperandMask |= (1 << i); 1305e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes } 1306e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 1307e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes // Generate operand match info for each mnemonic/operand class pair. 1308b2df610b44902124c22f3661a39bffd5341da62dSean Silva for (OpClassMaskTy::iterator iit = OpClassMask.begin(), 1309e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes iie = OpClassMask.end(); iit != iie; ++iit) { 1310e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes unsigned OpMask = iit->second; 1311e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes ClassInfo *CI = iit->first; 13128caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach OperandMatchInfo.push_back(OperandMatchEntry::create(&II, CI, OpMask)); 1313e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes } 1314e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes } 1315e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes} 1316e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 13178caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachvoid AsmMatcherInfo::buildInfo() { 13180aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner // Build information about all of the AssemblerPredicates. 13190aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner std::vector<Record*> AllPredicates = 13200aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner Records.getAllDerivedDefinitions("Predicate"); 13210aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner for (unsigned i = 0, e = AllPredicates.size(); i != e; ++i) { 13220aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner Record *Pred = AllPredicates[i]; 13230aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner // Ignore predicates that are not intended for the assembler. 13240aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner if (!Pred->getValueAsBit("AssemblerMatcherPredicate")) 13250aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner continue; 1326828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 13274164f6bbbf4ebce676e8a6c0a0cf7a78ef46a0f3Chris Lattner if (Pred->getName().empty()) 132861131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger PrintFatalError(Pred->getLoc(), "Predicate has no name!"); 1329828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 13300aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner unsigned FeatureNo = SubtargetFeatures.size(); 13310aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner SubtargetFeatures[Pred] = new SubtargetFeatureInfo(Pred, FeatureNo); 1332dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DEBUG(SubtargetFeatures[Pred]->dump()); 13330aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner assert(FeatureNo < 32 && "Too many subtarget features!"); 13340aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner } 1335a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 133639ee036f407bd0c94cb993cf9b97348843cfafa4Chris Lattner // Parse the instructions; we need to do this first so that we can gather the 133739ee036f407bd0c94cb993cf9b97348843cfafa4Chris Lattner // singleton register classes. 13381de88235781c45c0afc0c7500d65b59775196c4cChris Lattner SmallPtrSet<Record*, 16> SingletonRegisters; 13390dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel unsigned VariantCount = Target.getAsmParserVariantCount(); 13400dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel for (unsigned VC = 0; VC != VariantCount; ++VC) { 13410dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel Record *AsmVariant = Target.getAsmParserVariant(VC); 134265da6fc8af561e77620bd86b83be8ca50acfdd30Jim Grosbach std::string CommentDelimiter = 134365da6fc8af561e77620bd86b83be8ca50acfdd30Jim Grosbach AsmVariant->getValueAsString("CommentDelimiter"); 13440dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel std::string RegisterPrefix = AsmVariant->getValueAsString("RegisterPrefix"); 13450dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel int AsmVariantNo = AsmVariant->getValueAsInt("Variant"); 1346f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach 13470dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel for (CodeGenTarget::inst_iterator I = Target.inst_begin(), 134811fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach E = Target.inst_end(); I != E; ++I) { 13490dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel const CodeGenInstruction &CGI = **I; 1350f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach 13510dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel // If the tblgen -match-prefix option is specified (for tblgen hackers), 13520dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel // filter the set of instructions we consider. 13530dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel if (!StringRef(CGI.TheDef->getName()).startswith(MatchPrefix)) 135411fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach continue; 1355f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach 13560dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel // Ignore "codegen only" instructions. 13570dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel if (CGI.TheDef->getValueAsBit("isCodeGenOnly")) 135811fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach continue; 1359f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach 136036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<MatchableInfo> II(new MatchableInfo(CGI)); 1361f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach 13628caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach II->initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix); 1363f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach 13640dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel // Ignore instructions which shouldn't be matched and diagnose invalid 13650dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel // instruction definitions with an error. 13668caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach if (!II->validate(CommentDelimiter, true)) 136711fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach continue; 1368f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach 13690dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel // Ignore "Int_*" and "*_Int" instructions, which are internal aliases. 13700dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel // 13710dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel // FIXME: This is a total hack. 13720dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel if (StringRef(II->TheDef->getName()).startswith("Int_") || 137311fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach StringRef(II->TheDef->getName()).endswith("_Int")) 137411fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach continue; 1375f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach 137636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Matchables.push_back(II.release()); 13770dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel } 1378f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach 13790dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel // Parse all of the InstAlias definitions and stick them in the list of 13800dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel // matchables. 13810dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel std::vector<Record*> AllInstAliases = 13820dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel Records.getAllDerivedDefinitions("InstAlias"); 13830dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel for (unsigned i = 0, e = AllInstAliases.size(); i != e; ++i) { 1384dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines CodeGenInstAlias *Alias = 1385dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines new CodeGenInstAlias(AllInstAliases[i], AsmVariantNo, Target); 1386f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach 13870dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel // If the tblgen -match-prefix option is specified (for tblgen hackers), 13880dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel // filter the set of instruction aliases we consider, based on the target 13890dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel // instruction. 139065da6fc8af561e77620bd86b83be8ca50acfdd30Jim Grosbach if (!StringRef(Alias->ResultInst->TheDef->getName()) 139165da6fc8af561e77620bd86b83be8ca50acfdd30Jim Grosbach .startswith( MatchPrefix)) 139211fc6467e6a7bbd39037ec488d1138c5518fd17eJim Grosbach continue; 1393f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach 139436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<MatchableInfo> II(new MatchableInfo(Alias)); 1395f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach 13968caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach II->initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix); 1397f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach 13980dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel // Validate the alias definitions. 13998caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach II->validate(CommentDelimiter, false); 1400f35307ceac57194094f207f0920fbd22231f5331Jim Grosbach 140136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Matchables.push_back(II.release()); 14021d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner } 1403c76e80ded753b78a72be0db40fcdba543435d818Chris Lattner } 1404c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner 14051095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar // Build info for the register classes. 14068caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach buildRegisterClasses(SingletonRegisters); 14071095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 14081095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar // Build info for the user defined assembly operand classes. 14098caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach buildOperandClasses(); 14101095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 14110bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner // Build the information about matchables, now that we have fully formed 14120bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner // classes. 1413c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach std::vector<MatchableInfo*> NewMatchables; 141422bc5c4184a497353e33195dd12541a4f08b008aChris Lattner for (std::vector<MatchableInfo*>::iterator it = Matchables.begin(), 141522bc5c4184a497353e33195dd12541a4f08b008aChris Lattner ie = Matchables.end(); it != ie; ++it) { 141622bc5c4184a497353e33195dd12541a4f08b008aChris Lattner MatchableInfo *II = *it; 1417a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 1418e206fcf0e9c7e79c7f42ff2151f3fb58cba70674Chris Lattner // Parse the tokens after the mnemonic. 14198caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach // Note: buildInstructionOperandReference may insert new AsmOperands, so 1420a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson // don't precompute the loop bound. 1421a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson for (unsigned i = 0; i != II->AsmOperands.size(); ++i) { 1422c0b14a250b61beb78d75d10c3124bbfd5355905cChris Lattner MatchableInfo::AsmOperand &Op = II->AsmOperands[i]; 1423d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner StringRef Token = Op.Token; 142420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 14251095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar // Check for singleton registers. 142663faf82d0377f0a878d643ca2aacc02c35811b3eDevang Patel if (Record *RegRecord = II->AsmOperands[i].SingletonReg) { 1427d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner Op.Class = RegisterClasses[RegRecord]; 142802bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner assert(Op.Class && Op.Class->Registers.size() == 1 && 142902bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner "Unexpected class for singleton register"); 143002bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner continue; 14311095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar } 14321095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 143320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // Check for simple tokens. 143420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (Token[0] != '$') { 1435d19ec05e0785152e7a520ffd4a88da4459a380aaChris Lattner Op.Class = getTokenClass(Token); 143620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar continue; 143720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 1438a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 14397ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner if (Token.size() > 1 && isdigit(Token[1])) { 14407ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner Op.Class = getTokenClass(Token); 14417ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner continue; 14427ad3147f98eb4e84c24629e88a7d8bb1e04df3d4Chris Lattner } 1443828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 1444c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner // Otherwise this is an operand reference. 14455f4280cd2d2d1aeb527c8b161acaa1870cf6ee82Chris Lattner StringRef OperandName; 14465f4280cd2d2d1aeb527c8b161acaa1870cf6ee82Chris Lattner if (Token[1] == '{') 14475f4280cd2d2d1aeb527c8b161acaa1870cf6ee82Chris Lattner OperandName = Token.substr(2, Token.size() - 3); 14485f4280cd2d2d1aeb527c8b161acaa1870cf6ee82Chris Lattner else 14495f4280cd2d2d1aeb527c8b161acaa1870cf6ee82Chris Lattner OperandName = Token.substr(1); 1450828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 1451c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner if (II->DefRec.is<const CodeGenInstruction*>()) 14528caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach buildInstructionOperandReference(II, OperandName, i); 1453c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner else 14548caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach buildAliasOperandReference(II, OperandName, Op); 145553a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar } 1456828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 1457c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach if (II->DefRec.is<const CodeGenInstruction*>()) { 14588caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach II->buildInstructionResultOperands(); 1459c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach // If the instruction has a two-operand alias, build up the 1460c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach // matchable here. We'll add them in bulk at the end to avoid 1461c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach // confusing this loop. 1462c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach std::string Constraint = 1463c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach II->TheDef->getValueAsString("TwoOperandAliasConstraint"); 1464c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach if (Constraint != "") { 1465c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach // Start by making a copy of the original matchable. 146636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<MatchableInfo> AliasII(new MatchableInfo(*II)); 1467c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach 1468c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach // Adjust it to be a two-operand alias. 1469c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach AliasII->formTwoOperandAlias(Constraint); 1470c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach 1471c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach // Add the alias to the matchables list. 147236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines NewMatchables.push_back(AliasII.release()); 1473c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach } 1474c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach } else 14758caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach II->buildAliasResultOperands(); 147620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 1477c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach if (!NewMatchables.empty()) 1478c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach Matchables.insert(Matchables.end(), NewMatchables.begin(), 1479c1922c72adedadb414a3d19c3f150bfe1bc755a5Jim Grosbach NewMatchables.end()); 14805fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar 1481a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach // Process token alias definitions and set up the associated superclass 1482a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach // information. 1483a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach std::vector<Record*> AllTokenAliases = 1484a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach Records.getAllDerivedDefinitions("TokenAlias"); 1485a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach for (unsigned i = 0, e = AllTokenAliases.size(); i != e; ++i) { 1486a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach Record *Rec = AllTokenAliases[i]; 1487a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach ClassInfo *FromClass = getTokenClass(Rec->getValueAsString("FromToken")); 1488a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach ClassInfo *ToClass = getTokenClass(Rec->getValueAsString("ToToken")); 148967cd20d0396a68e61858736b7943dd352f1b0d0bJim Grosbach if (FromClass == ToClass) 149061131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger PrintFatalError(Rec->getLoc(), 149167cd20d0396a68e61858736b7943dd352f1b0d0bJim Grosbach "error: Destination value identical to source value."); 1492a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach FromClass->SuperClasses.push_back(ToClass); 1493a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach } 1494a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach 14957a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // Reorder classes so that classes precede super classes. 14965fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar std::sort(Classes.begin(), Classes.end(), less_ptr<ClassInfo>()); 149720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar} 1498a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 14998caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach/// buildInstructionOperandReference - The specified operand is a reference to a 15000bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner/// named operand such as $src. Resolve the Class and OperandInfo pointers. 15010bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattnervoid AsmMatcherInfo:: 15028caecdea56c830f3fc80ed67fff121c83de0e364Jim GrosbachbuildInstructionOperandReference(MatchableInfo *II, 15035f4280cd2d2d1aeb527c8b161acaa1870cf6ee82Chris Lattner StringRef OperandName, 1504a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson unsigned AsmOpIdx) { 1505c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner const CodeGenInstruction &CGI = *II->DefRec.get<const CodeGenInstruction*>(); 1506c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner const CGIOperandList &Operands = CGI.Operands; 1507a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson MatchableInfo::AsmOperand *Op = &II->AsmOperands[AsmOpIdx]; 1508828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 1509662e5a30e864e71111b885d3da3cdd184772035dChris Lattner // Map this token to an operand. 15100bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner unsigned Idx; 15110bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner if (!Operands.hasOperandNamed(OperandName, Idx)) 151236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines PrintFatalError(II->TheDef->getLoc(), 151336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "error: unable to find operand: '" + OperandName + "'"); 1514ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner 1515a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson // If the instruction operand has multiple suboperands, but the parser 1516a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson // match class for the asm operand is still the default "ImmAsmOperand", 1517a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson // then handle each suboperand separately. 1518a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson if (Op->SubOpIdx == -1 && Operands[Idx].MINumOperands > 1) { 1519a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson Record *Rec = Operands[Idx].Rec; 1520a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson assert(Rec->isSubClassOf("Operand") && "Unexpected operand!"); 1521a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson Record *MatchClass = Rec->getValueAsDef("ParserMatchClass"); 1522a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson if (MatchClass && MatchClass->getValueAsString("Name") == "Imm") { 1523a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson // Insert remaining suboperands after AsmOpIdx in II->AsmOperands. 1524a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson StringRef Token = Op->Token; // save this in case Op gets moved 1525a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson for (unsigned SI = 1, SE = Operands[Idx].MINumOperands; SI != SE; ++SI) { 1526a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson MatchableInfo::AsmOperand NewAsmOp(Token); 1527a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson NewAsmOp.SubOpIdx = SI; 1528a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson II->AsmOperands.insert(II->AsmOperands.begin()+AsmOpIdx+SI, NewAsmOp); 1529a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson } 1530a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson // Replace Op with first suboperand. 1531a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson Op = &II->AsmOperands[AsmOpIdx]; // update the pointer in case it moved 1532a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson Op->SubOpIdx = 0; 1533a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson } 1534a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson } 1535a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson 1536ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner // Set up the operand class. 1537a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson Op->Class = getOperandClass(Operands[Idx], Op->SubOpIdx); 1538ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner 1539ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner // If the named operand is tied, canonicalize it to the untied operand. 1540ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner // For example, something like: 1541ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner // (outs GPR:$dst), (ins GPR:$src) 1542ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner // with an asmstring of 1543ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner // "inc $src" 1544ba3b5b638287e374d0c98fc5efdf866a3cee33b6Chris Lattner // we want to canonicalize to: 1545c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner // "inc $dst" 1546c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner // so that we know how to provide the $dst operand when filling in the result. 1547d999062f31b5e0a2f12d70a54ffdb02be8363657Ulrich Weigand int OITied = -1; 1548d999062f31b5e0a2f12d70a54ffdb02be8363657Ulrich Weigand if (Operands[Idx].MINumOperands == 1) 1549d999062f31b5e0a2f12d70a54ffdb02be8363657Ulrich Weigand OITied = Operands[Idx].getTiedRegister(); 1550c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner if (OITied != -1) { 1551c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner // The tied operand index is an MIOperand index, find the operand that 1552c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner // contains it. 1553a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson std::pair<unsigned, unsigned> Idx = Operands.getSubOperandNumber(OITied); 1554a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson OperandName = Operands[Idx.first].Name; 1555a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson Op->SubOpIdx = Idx.second; 1556c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner } 1557828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 1558a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson Op->SrcOpName = OperandName; 1559c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner} 1560c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner 15618caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach/// buildAliasOperandReference - When parsing an operand reference out of the 15623f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner/// matching string (e.g. "movsx $src, $dst"), determine what the class of the 15633f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner/// operand reference is by looking it up in the result pattern definition. 15648caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachvoid AsmMatcherInfo::buildAliasOperandReference(MatchableInfo *II, 1565c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner StringRef OperandName, 1566c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner MatchableInfo::AsmOperand &Op) { 1567c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner const CodeGenInstAlias &CGA = *II->DefRec.get<const CodeGenInstAlias*>(); 1568828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 1569c07bd40a649991d46c95cf6afe2c4ada4ac49f13Chris Lattner // Set up the operand class. 15703f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner for (unsigned i = 0, e = CGA.ResultOperands.size(); i != e; ++i) 157198c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner if (CGA.ResultOperands[i].isRecord() && 157298c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner CGA.ResultOperands[i].getName() == OperandName) { 1573662e5a30e864e71111b885d3da3cdd184772035dChris Lattner // It's safe to go with the first one we find, because CodeGenInstAlias 1574662e5a30e864e71111b885d3da3cdd184772035dChris Lattner // validates that all operands with the same name have the same record. 1575a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson Op.SubOpIdx = CGA.ResultInstOperandIndex[i].second; 157648c1f84b104fd32109d809a56f5ebbf461c0910cJim Grosbach // Use the match class from the Alias definition, not the 157748c1f84b104fd32109d809a56f5ebbf461c0910cJim Grosbach // destination instruction, as we may have an immediate that's 157848c1f84b104fd32109d809a56f5ebbf461c0910cJim Grosbach // being munged by the match class. 157948c1f84b104fd32109d809a56f5ebbf461c0910cJim Grosbach Op.Class = getOperandClass(CGA.ResultOperands[i].getRecord(), 1580a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson Op.SubOpIdx); 15813f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner Op.SrcOpName = OperandName; 15823f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner return; 15830bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner } 15843f2c8e474b8775aa1f3c2c0cb817b7f9f564e068Chris Lattner 158536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines PrintFatalError(II->TheDef->getLoc(), 158636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "error: unable to find operand: '" + OperandName + "'"); 15870bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner} 15880bb780c0e0cea50e6076fcb44c08caa50b7ecba7Chris Lattner 15898caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachvoid MatchableInfo::buildInstructionResultOperands() { 1590662e5a30e864e71111b885d3da3cdd184772035dChris Lattner const CodeGenInstruction *ResultInst = getResultInst(); 1591828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 1592662e5a30e864e71111b885d3da3cdd184772035dChris Lattner // Loop over all operands of the result instruction, determining how to 1593662e5a30e864e71111b885d3da3cdd184772035dChris Lattner // populate them. 1594662e5a30e864e71111b885d3da3cdd184772035dChris Lattner for (unsigned i = 0, e = ResultInst->Operands.size(); i != e; ++i) { 1595662e5a30e864e71111b885d3da3cdd184772035dChris Lattner const CGIOperandList::OperandInfo &OpInfo = ResultInst->Operands[i]; 1596567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner 1597567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner // If this is a tied operand, just copy from the previously handled operand. 1598d999062f31b5e0a2f12d70a54ffdb02be8363657Ulrich Weigand int TiedOp = -1; 1599d999062f31b5e0a2f12d70a54ffdb02be8363657Ulrich Weigand if (OpInfo.MINumOperands == 1) 1600d999062f31b5e0a2f12d70a54ffdb02be8363657Ulrich Weigand TiedOp = OpInfo.getTiedRegister(); 1601567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner if (TiedOp != -1) { 1602a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson ResOperands.push_back(ResOperand::getTiedOp(TiedOp)); 1603567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner continue; 1604567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner } 1605828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 1606a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson // Find out what operand from the asmparser this MCInst operand comes from. 16078caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach int SrcOperand = findAsmOperandNamed(OpInfo.Name); 1608d999062f31b5e0a2f12d70a54ffdb02be8363657Ulrich Weigand if (OpInfo.Name.empty() || SrcOperand == -1) { 1609d999062f31b5e0a2f12d70a54ffdb02be8363657Ulrich Weigand // This may happen for operands that are tied to a suboperand of a 1610d999062f31b5e0a2f12d70a54ffdb02be8363657Ulrich Weigand // complex operand. Simply use a dummy value here; nobody should 1611d999062f31b5e0a2f12d70a54ffdb02be8363657Ulrich Weigand // use this operand slot. 1612d999062f31b5e0a2f12d70a54ffdb02be8363657Ulrich Weigand // FIXME: The long term goal is for the MCOperand list to not contain 1613d999062f31b5e0a2f12d70a54ffdb02be8363657Ulrich Weigand // tied operands at all. 1614d999062f31b5e0a2f12d70a54ffdb02be8363657Ulrich Weigand ResOperands.push_back(ResOperand::getImmOp(0)); 1615d999062f31b5e0a2f12d70a54ffdb02be8363657Ulrich Weigand continue; 1616d999062f31b5e0a2f12d70a54ffdb02be8363657Ulrich Weigand } 1617567820c1e0454935ca5415ed419da63b84684cb7Chris Lattner 1618a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson // Check if the one AsmOperand populates the entire operand. 1619a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson unsigned NumOperands = OpInfo.MINumOperands; 1620a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson if (AsmOperands[SrcOperand].SubOpIdx == -1) { 1621a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson ResOperands.push_back(ResOperand::getRenderedOp(SrcOperand, NumOperands)); 16221d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner continue; 16231d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner } 1624a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson 1625a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson // Add a separate ResOperand for each suboperand. 1626a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson for (unsigned AI = 0; AI < NumOperands; ++AI) { 1627a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson assert(AsmOperands[SrcOperand+AI].SubOpIdx == (int)AI && 1628a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson AsmOperands[SrcOperand+AI].SrcOpName == OpInfo.Name && 1629a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson "unexpected AsmOperands for suboperands"); 1630a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson ResOperands.push_back(ResOperand::getRenderedOp(SrcOperand + AI, 1)); 1631a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson } 16321d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner } 16331d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner} 16341d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner 16358caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachvoid MatchableInfo::buildAliasResultOperands() { 1636414098571b19fc248fda2be194082cfd012d2729Chris Lattner const CodeGenInstAlias &CGA = *DefRec.get<const CodeGenInstAlias*>(); 1637414098571b19fc248fda2be194082cfd012d2729Chris Lattner const CodeGenInstruction *ResultInst = getResultInst(); 1638828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 1639414098571b19fc248fda2be194082cfd012d2729Chris Lattner // Loop over all operands of the result instruction, determining how to 1640414098571b19fc248fda2be194082cfd012d2729Chris Lattner // populate them. 1641414098571b19fc248fda2be194082cfd012d2729Chris Lattner unsigned AliasOpNo = 0; 1642a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson unsigned LastOpNo = CGA.ResultInstOperandIndex.size(); 1643414098571b19fc248fda2be194082cfd012d2729Chris Lattner for (unsigned i = 0, e = ResultInst->Operands.size(); i != e; ++i) { 1644a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson const CGIOperandList::OperandInfo *OpInfo = &ResultInst->Operands[i]; 1645828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 1646414098571b19fc248fda2be194082cfd012d2729Chris Lattner // If this is a tied operand, just copy from the previously handled operand. 1647d999062f31b5e0a2f12d70a54ffdb02be8363657Ulrich Weigand int TiedOp = -1; 1648d999062f31b5e0a2f12d70a54ffdb02be8363657Ulrich Weigand if (OpInfo->MINumOperands == 1) 1649d999062f31b5e0a2f12d70a54ffdb02be8363657Ulrich Weigand TiedOp = OpInfo->getTiedRegister(); 1650414098571b19fc248fda2be194082cfd012d2729Chris Lattner if (TiedOp != -1) { 1651a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson ResOperands.push_back(ResOperand::getTiedOp(TiedOp)); 165290fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner continue; 165390fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner } 165490fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner 1655a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson // Handle all the suboperands for this operand. 1656a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson const std::string &OpName = OpInfo->Name; 1657a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson for ( ; AliasOpNo < LastOpNo && 1658a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson CGA.ResultInstOperandIndex[AliasOpNo].first == i; ++AliasOpNo) { 1659a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson int SubIdx = CGA.ResultInstOperandIndex[AliasOpNo].second; 1660a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson 1661a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson // Find out what operand from the asmparser that this MCInst operand 1662a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson // comes from. 1663a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson switch (CGA.ResultOperands[AliasOpNo].Kind) { 1664a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson case CodeGenInstAlias::ResultOperand::K_Record: { 1665a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson StringRef Name = CGA.ResultOperands[AliasOpNo].getName(); 16668caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach int SrcOperand = findAsmOperand(Name, SubIdx); 1667a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson if (SrcOperand == -1) 166861131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger PrintFatalError(TheDef->getLoc(), "Instruction '" + 1669a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson TheDef->getName() + "' has operand '" + OpName + 1670a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson "' that doesn't appear in asm string!"); 1671a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson unsigned NumOperands = (SubIdx == -1 ? OpInfo->MINumOperands : 1); 1672a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson ResOperands.push_back(ResOperand::getRenderedOp(SrcOperand, 1673a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson NumOperands)); 1674a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson break; 1675a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson } 1676a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson case CodeGenInstAlias::ResultOperand::K_Imm: { 1677a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson int64_t ImmVal = CGA.ResultOperands[AliasOpNo].getImm(); 1678a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson ResOperands.push_back(ResOperand::getImmOp(ImmVal)); 1679a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson break; 1680a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson } 1681a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson case CodeGenInstAlias::ResultOperand::K_Reg: { 1682a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson Record *Reg = CGA.ResultOperands[AliasOpNo].getRegister(); 1683a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson ResOperands.push_back(ResOperand::getRegOp(Reg)); 1684a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson break; 1685a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson } 1686a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson } 168790fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner } 1688414098571b19fc248fda2be194082cfd012d2729Chris Lattner } 1689414098571b19fc248fda2be194082cfd012d2729Chris Lattner} 16901d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner 1691c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbachstatic unsigned getConverterOperandID(const std::string &Name, 1692c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach SetVector<std::string> &Table, 1693c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach bool &IsNew) { 1694c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach IsNew = Table.insert(Name); 1695c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach 1696c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach unsigned ID = IsNew ? Table.size() - 1 : 1697c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach std::find(Table.begin(), Table.end(), Name) - Table.begin(); 1698c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach 1699c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach assert(ID < Table.size()); 1700c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach 1701c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach return ID; 1702c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach} 1703c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach 1704c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach 170522685876ed7231f32f7d1698c00acab22825b74cChad Rosierstatic void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName, 170622685876ed7231f32f7d1698c00acab22825b74cChad Rosier std::vector<MatchableInfo*> &Infos, 170722685876ed7231f32f7d1698c00acab22825b74cChad Rosier raw_ostream &OS) { 1708c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach SetVector<std::string> OperandConversionKinds; 1709c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach SetVector<std::string> InstructionConversionKinds; 1710c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach std::vector<std::vector<uint8_t> > ConversionTable; 1711c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach size_t MaxRowLength = 2; // minimum is custom converter plus terminator. 1712c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach 1713c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach // TargetOperandClass - This is the target's operand class, like X86Operand. 1714c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach std::string TargetOperandClass = Target.getName() + "Operand"; 1715c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach 1716b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar // Write the convert function to a separate stream, so we can drop it after 1717c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach // the enum. We'll build up the conversion handlers for the individual 1718c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach // operand types opportunistically as we encounter them. 1719b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar std::string ConvertFnBody; 1720b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar raw_string_ostream CvtOS(ConvertFnBody); 1721b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar // Start the unified conversion function. 1722359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosier CvtOS << "void " << Target.getName() << ClassName << "::\n" 172390e11f8c95146c2d3718e9b3de71ee6628347b05Chad Rosier << "convertToMCInst(unsigned Kind, MCInst &Inst, " 1724b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar << "unsigned Opcode,\n" 1725cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << " const OperandVector" 1726cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << " &Operands) {\n" 1727359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosier << " assert(Kind < CVT_NUM_SIGNATURES && \"Invalid signature!\");\n" 1728b198f5c8979d46d75a08c1710a160f8e102b9ba8Craig Topper << " const uint8_t *Converter = ConversionTable[Kind];\n" 1729c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach << " Inst.setOpcode(Opcode);\n" 1730b198f5c8979d46d75a08c1710a160f8e102b9ba8Craig Topper << " for (const uint8_t *p = Converter; *p; p+= 2) {\n" 1731c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach << " switch (*p) {\n" 1732c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach << " default: llvm_unreachable(\"invalid conversion entry!\");\n" 1733c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach << " case CVT_Reg:\n" 1734c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach << " static_cast<" << TargetOperandClass 1735cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << "&>(*Operands[*(p + 1)]).addRegOperands(Inst, 1);\n" 1736c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach << " break;\n" 1737c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach << " case CVT_Tied:\n" 1738c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach << " Inst.addOperand(Inst.getOperand(*(p + 1)));\n" 1739c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach << " break;\n"; 1740c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach 174162316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier std::string OperandFnBody; 174262316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier raw_string_ostream OpOS(OperandFnBody); 174362316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier // Start the operand number lookup function. 174422685876ed7231f32f7d1698c00acab22825b74cChad Rosier OpOS << "void " << Target.getName() << ClassName << "::\n" 174522685876ed7231f32f7d1698c00acab22825b74cChad Rosier << "convertToMapAndConstraints(unsigned Kind,\n"; 1746c69bb70deb5b596941bb1de180d1554f9a411062Chad Rosier OpOS.indent(27); 1747cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines OpOS << "const OperandVector &Operands) {\n" 1748359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosier << " assert(Kind < CVT_NUM_SIGNATURES && \"Invalid signature!\");\n" 174922685876ed7231f32f7d1698c00acab22825b74cChad Rosier << " unsigned NumMCOperands = 0;\n" 1750b198f5c8979d46d75a08c1710a160f8e102b9ba8Craig Topper << " const uint8_t *Converter = ConversionTable[Kind];\n" 1751b198f5c8979d46d75a08c1710a160f8e102b9ba8Craig Topper << " for (const uint8_t *p = Converter; *p; p+= 2) {\n" 175262316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier << " switch (*p) {\n" 175362316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier << " default: llvm_unreachable(\"invalid conversion entry!\");\n" 175462316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier << " case CVT_Reg:\n" 17556e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier << " Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);\n" 17561c99a7f4892a24eb227802e042917d05d8cd415fChad Rosier << " Operands[*(p + 1)]->setConstraint(\"r\");\n" 17576e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier << " ++NumMCOperands;\n" 17586e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier << " break;\n" 175962316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier << " case CVT_Tied:\n" 176022685876ed7231f32f7d1698c00acab22825b74cChad Rosier << " ++NumMCOperands;\n" 176162316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier << " break;\n"; 1762c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach 1763c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach // Pre-populate the operand conversion kinds with the standard always 1764c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach // available entries. 1765c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach OperandConversionKinds.insert("CVT_Done"); 1766c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach OperandConversionKinds.insert("CVT_Reg"); 1767c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach OperandConversionKinds.insert("CVT_Tied"); 1768c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach enum { CVT_Done, CVT_Reg, CVT_Tied }; 1769a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 177022bc5c4184a497353e33195dd12541a4f08b008aChris Lattner for (std::vector<MatchableInfo*>::const_iterator it = Infos.begin(), 177120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar ie = Infos.end(); it != ie; ++it) { 177222bc5c4184a497353e33195dd12541a4f08b008aChris Lattner MatchableInfo &II = **it; 177320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 1774cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar // Check if we have a custom match function. 177527b83d4ff2264d9a0e2367d92543efe4c0148931Daniel Dunbar std::string AsmMatchConverter = 177627b83d4ff2264d9a0e2367d92543efe4c0148931Daniel Dunbar II.getResultInst()->TheDef->getValueAsString("AsmMatchConverter"); 1777cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar if (!AsmMatchConverter.empty()) { 177827b83d4ff2264d9a0e2367d92543efe4c0148931Daniel Dunbar std::string Signature = "ConvertCustom_" + AsmMatchConverter; 1779cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar II.ConversionFnKind = Signature; 1780cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar 1781cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar // Check if we have already generated this signature. 1782c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach if (!InstructionConversionKinds.insert(Signature)) 1783cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar continue; 1784cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar 1785c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach // Remember this converter for the kind enum. 1786c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach unsigned KindID = OperandConversionKinds.size(); 178712da505d938ecfbc49b203e454bada99eda950e3Tim Northover OperandConversionKinds.insert("CVT_" + 178812da505d938ecfbc49b203e454bada99eda950e3Tim Northover getEnumNameForToken(AsmMatchConverter)); 1789c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach 1790c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach // Add the converter row for this instruction. 1791c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach ConversionTable.push_back(std::vector<uint8_t>()); 1792c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach ConversionTable.back().push_back(KindID); 1793c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach ConversionTable.back().push_back(CVT_Done); 1794cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar 1795c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach // Add the handler to the conversion driver function. 179612da505d938ecfbc49b203e454bada99eda950e3Tim Northover CvtOS << " case CVT_" 179712da505d938ecfbc49b203e454bada99eda950e3Tim Northover << getEnumNameForToken(AsmMatchConverter) << ":\n" 1798756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad Rosier << " " << AsmMatchConverter << "(Inst, Operands);\n" 1799359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosier << " break;\n"; 1800c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach 180162316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier // FIXME: Handle the operand number lookup for custom match functions. 1802cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar continue; 1803cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar } 1804cf12067ae08dc7911c860070eaf2830dc1dc4ff7Daniel Dunbar 180520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // Build the conversion function signature. 180620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar std::string Signature = "Convert"; 1807c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach 1808c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach std::vector<uint8_t> ConversionRow; 1809828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 1810dda855de8b3c60bce5d1d0d9eb11470c9710e30fChris Lattner // Compute the convert enum and the case body. 1811c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach MaxRowLength = std::max(MaxRowLength, II.ResOperands.size()*2 + 1 ); 1812c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach 18131d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner for (unsigned i = 0, e = II.ResOperands.size(); i != e; ++i) { 18141d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner const MatchableInfo::ResOperand &OpInfo = II.ResOperands[i]; 18151d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner 18161d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner // Generate code to populate each result operand. 18171d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner switch (OpInfo.Kind) { 18181d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner case MatchableInfo::ResOperand::RenderAsmOperand: { 18191d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner // This comes from something we parsed. 18201d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner MatchableInfo::AsmOperand &Op = II.AsmOperands[OpInfo.AsmOperandNum]; 1821828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 18229b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner // Registers are always converted the same, don't duplicate the 18239b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner // conversion function based on them. 18249b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner Signature += "__"; 1825c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach std::string Class; 1826c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach Class = Op.Class->isRegisterClass() ? "Reg" : Op.Class->ClassName; 1827c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach Signature += Class; 1828a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson Signature += utostr(OpInfo.MINumOperands); 18291d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner Signature += "_" + itostr(OpInfo.AsmOperandNum); 1830828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 1831c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach // Add the conversion kind, if necessary, and get the associated ID 1832c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach // the index of its entry in the vector). 1833c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach std::string Name = "CVT_" + (Op.Class->isRegisterClass() ? "Reg" : 1834c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach Op.Class->RenderMethod); 183512da505d938ecfbc49b203e454bada99eda950e3Tim Northover Name = getEnumNameForToken(Name); 1836c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach 1837c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach bool IsNewConverter = false; 1838c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach unsigned ID = getConverterOperandID(Name, OperandConversionKinds, 1839c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach IsNewConverter); 1840c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach 1841c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach // Add the operand entry to the instruction kind conversion row. 1842c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach ConversionRow.push_back(ID); 1843c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach ConversionRow.push_back(OpInfo.AsmOperandNum + 1); 1844c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach 1845c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach if (!IsNewConverter) 1846c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach break; 1847c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach 1848c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach // This is a new operand kind. Add a handler for it to the 1849c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach // converter driver. 1850c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach CvtOS << " case " << Name << ":\n" 1851c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach << " static_cast<" << TargetOperandClass 1852cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << "&>(*Operands[*(p + 1)])." << Op.Class->RenderMethod 1853cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << "(Inst, " << OpInfo.MINumOperands << ");\n" 1854c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach << " break;\n"; 185562316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier 185662316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier // Add a handler for the operand number lookup. 185762316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier OpOS << " case " << Name << ":\n" 18581c99a7f4892a24eb227802e042917d05d8cd415fChad Rosier << " Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);\n"; 18591c99a7f4892a24eb227802e042917d05d8cd415fChad Rosier 18601c99a7f4892a24eb227802e042917d05d8cd415fChad Rosier if (Op.Class->isRegisterClass()) 18611c99a7f4892a24eb227802e042917d05d8cd415fChad Rosier OpOS << " Operands[*(p + 1)]->setConstraint(\"r\");\n"; 18621c99a7f4892a24eb227802e042917d05d8cd415fChad Rosier else 18631c99a7f4892a24eb227802e042917d05d8cd415fChad Rosier OpOS << " Operands[*(p + 1)]->setConstraint(\"m\");\n"; 18641c99a7f4892a24eb227802e042917d05d8cd415fChad Rosier OpOS << " NumMCOperands += " << OpInfo.MINumOperands << ";\n" 186562316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier << " break;\n"; 18661d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner break; 18671d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner } 18681d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner case MatchableInfo::ResOperand::TiedOperand: { 18691d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner // If this operand is tied to a previous one, just copy the MCInst 18701d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner // operand from the earlier one.We can only tie single MCOperand values. 1871d999062f31b5e0a2f12d70a54ffdb02be8363657Ulrich Weigand assert(OpInfo.MINumOperands == 1 && "Not a singular MCOperand"); 18721d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner unsigned TiedOp = OpInfo.TiedOperandNum; 18737a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner assert(i > TiedOp && "Tied operand precedes its target!"); 18741d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner Signature += "__Tie" + utostr(TiedOp); 1875c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach ConversionRow.push_back(CVT_Tied); 1876c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach ConversionRow.push_back(TiedOp); 18771d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner break; 18781d13bda737bad3e0cea28cbd65a221ab27abdb9bChris Lattner } 187998c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner case MatchableInfo::ResOperand::ImmOperand: { 188098c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner int64_t Val = OpInfo.ImmVal; 1881c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach std::string Ty = "imm_" + itostr(Val); 1882c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach Signature += "__" + Ty; 1883c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach 1884c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach std::string Name = "CVT_" + Ty; 1885c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach bool IsNewConverter = false; 1886c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach unsigned ID = getConverterOperandID(Name, OperandConversionKinds, 1887c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach IsNewConverter); 1888c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach // Add the operand entry to the instruction kind conversion row. 1889c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach ConversionRow.push_back(ID); 1890c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach ConversionRow.push_back(0); 1891c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach 1892c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach if (!IsNewConverter) 1893c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach break; 1894c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach 1895c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach CvtOS << " case " << Name << ":\n" 1896c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach << " Inst.addOperand(MCOperand::CreateImm(" << Val << "));\n" 1897c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach << " break;\n"; 1898c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach 189962316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier OpOS << " case " << Name << ":\n" 19006e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier << " Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);\n" 19016e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier << " Operands[*(p + 1)]->setConstraint(\"\");\n" 190222685876ed7231f32f7d1698c00acab22825b74cChad Rosier << " ++NumMCOperands;\n" 190362316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier << " break;\n"; 190498c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner break; 190598c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner } 190690fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner case MatchableInfo::ResOperand::RegOperand: { 1907c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach std::string Reg, Name; 1908dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!OpInfo.Register) { 1909c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach Name = "reg0"; 1910c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach Reg = "0"; 1911dc1a2bd3aa199693413f39dd723cc14a77e9f131Bob Wilson } else { 1912c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach Reg = getQualifiedName(OpInfo.Register); 1913c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach Name = "reg" + OpInfo.Register->getName(); 1914dc1a2bd3aa199693413f39dd723cc14a77e9f131Bob Wilson } 1915c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach Signature += "__" + Name; 1916c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach Name = "CVT_" + Name; 1917c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach bool IsNewConverter = false; 1918c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach unsigned ID = getConverterOperandID(Name, OperandConversionKinds, 1919c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach IsNewConverter); 1920c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach // Add the operand entry to the instruction kind conversion row. 1921c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach ConversionRow.push_back(ID); 1922c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach ConversionRow.push_back(0); 1923c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach 1924c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach if (!IsNewConverter) 1925c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach break; 1926c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach CvtOS << " case " << Name << ":\n" 1927c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach << " Inst.addOperand(MCOperand::CreateReg(" << Reg << "));\n" 1928c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach << " break;\n"; 192962316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier 193062316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier OpOS << " case " << Name << ":\n" 19316e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier << " Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);\n" 19326e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier << " Operands[*(p + 1)]->setConstraint(\"m\");\n" 193322685876ed7231f32f7d1698c00acab22825b74cChad Rosier << " ++NumMCOperands;\n" 193462316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier << " break;\n"; 1935828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson } 1936af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar } 19379b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner } 1938828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 1939c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach // If there were no operands, add to the signature to that effect 1940c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach if (Signature == "Convert") 1941c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach Signature += "_NoOperands"; 1942c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach 1943b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar II.ConversionFnKind = Signature; 1944a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 1945c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach // Save the signature. If we already have it, don't add a new row 1946c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach // to the table. 1947c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach if (!InstructionConversionKinds.insert(Signature)) 194820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar continue; 1949a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 1950c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach // Add the row to the table. 1951c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach ConversionTable.push_back(ConversionRow); 1952a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar } 1953b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 1954c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach // Finish up the converter driver function. 1955ad2d3e637a3a9eb368e71a1672331ee5e7809fe8Chad Rosier CvtOS << " }\n }\n}\n\n"; 1956b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 195762316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier // Finish up the operand number lookup function. 195822685876ed7231f32f7d1698c00acab22825b74cChad Rosier OpOS << " }\n }\n}\n\n"; 195962316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier 1960c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach OS << "namespace {\n"; 1961b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 1962c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach // Output the operand conversion kind enum. 1963c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach OS << "enum OperatorConversionKind {\n"; 1964c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach for (unsigned i = 0, e = OperandConversionKinds.size(); i != e; ++i) 1965c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach OS << " " << OperandConversionKinds[i] << ",\n"; 1966c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach OS << " CVT_NUM_CONVERTERS\n"; 1967c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach OS << "};\n\n"; 1968b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 1969c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach // Output the instruction conversion kind enum. 1970c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach OS << "enum InstructionConversionKind {\n"; 1971c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach for (SetVector<std::string>::const_iterator 1972c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach i = InstructionConversionKinds.begin(), 1973c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach e = InstructionConversionKinds.end(); i != e; ++i) 1974c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach OS << " " << *i << ",\n"; 1975c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach OS << " CVT_NUM_SIGNATURES\n"; 1976b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar OS << "};\n\n"; 1977a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 1978c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach 1979c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach OS << "} // end anonymous namespace\n\n"; 1980c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach 1981c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach // Output the conversion table. 1982b198f5c8979d46d75a08c1710a160f8e102b9ba8Craig Topper OS << "static const uint8_t ConversionTable[CVT_NUM_SIGNATURES][" 1983c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach << MaxRowLength << "] = {\n"; 1984c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach 1985c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach for (unsigned Row = 0, ERow = ConversionTable.size(); Row != ERow; ++Row) { 1986c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach assert(ConversionTable[Row].size() % 2 == 0 && "bad conversion row!"); 1987c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach OS << " // " << InstructionConversionKinds[Row] << "\n"; 1988c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach OS << " { "; 1989c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach for (unsigned i = 0, e = ConversionTable[Row].size(); i != e; i += 2) 1990c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach OS << OperandConversionKinds[ConversionTable[Row][i]] << ", " 1991c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach << (unsigned)(ConversionTable[Row][i + 1]) << ", "; 1992c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach OS << "CVT_Done },\n"; 1993c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach } 1994c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach 1995c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach OS << "};\n\n"; 1996c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach 1997c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach // Spit out the conversion driver function. 1998b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar OS << CvtOS.str(); 1999c8f267f66931c4358f11a2934e8b6234d9b7f0bdJim Grosbach 200062316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier // Spit out the operand number lookup function. 200162316fa00a342bdb618e4c020c8e8606f541db92Chad Rosier OS << OpOS.str(); 200220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar} 200320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 20048caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach/// emitMatchClassEnumeration - Emit the enumeration for match class kinds. 20058caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachstatic void emitMatchClassEnumeration(CodeGenTarget &Target, 2006a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::vector<ClassInfo*> &Infos, 2007a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar raw_ostream &OS) { 2008a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "namespace {\n\n"; 2009a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 2010a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "/// MatchClassKind - The kinds of classes which participate in\n" 2011a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar << "/// instruction matching.\n"; 2012a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "enum MatchClassKind {\n"; 2013a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " InvalidMatchClass = 0,\n"; 2014a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach for (std::vector<ClassInfo*>::iterator it = Infos.begin(), 2015a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar ie = Infos.end(); it != ie; ++it) { 2016a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar ClassInfo &CI = **it; 2017a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " " << CI.Name << ", // "; 2018a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar if (CI.Kind == ClassInfo::Token) { 2019a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "'" << CI.ValueName << "'\n"; 2020ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } else if (CI.isRegisterClass()) { 2021a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar if (!CI.ValueName.empty()) 2022a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "register class '" << CI.ValueName << "'\n"; 2023a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar else 2024a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "derived register class\n"; 2025a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } else { 2026a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "user defined class '" << CI.ValueName << "'\n"; 2027a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 2028a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 2029a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " NumMatchClassKinds\n"; 2030a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "};\n\n"; 2031a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 2032a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "}\n\n"; 2033a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar} 2034a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 20358caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach/// emitValidateOperandClass - Emit the function to validate an operand class. 20368caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachstatic void emitValidateOperandClass(AsmMatcherInfo &Info, 2037b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach raw_ostream &OS) { 2038cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines OS << "static unsigned validateOperandClass(MCParsedAsmOperand &GOp, " 2039b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach << "MatchClassKind Kind) {\n"; 2040cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines OS << " " << Info.Target.getName() << "Operand &Operand = (" 2041cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << Info.Target.getName() << "Operand&)GOp;\n"; 2042ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 2043893818347e9d7b34ea99ae9c984934c9b6bf92daKevin Enderby // The InvalidMatchClass is not to match any operand. 2044893818347e9d7b34ea99ae9c984934c9b6bf92daKevin Enderby OS << " if (Kind == InvalidMatchClass)\n"; 20454dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach OS << " return MCTargetAsmParser::Match_InvalidOperand;\n\n"; 2046893818347e9d7b34ea99ae9c984934c9b6bf92daKevin Enderby 2047b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach // Check for Token operands first. 20484dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach // FIXME: Use a more specific diagnostic type. 2049a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " if (Operand.isToken())\n"; 20504dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach OS << " return isSubclass(matchTokenString(Operand.getToken()), Kind) ?\n" 20514dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach << " MCTargetAsmParser::Match_Success :\n" 20524dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach << " MCTargetAsmParser::Match_InvalidOperand;\n\n"; 2053ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 2054b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach // Check the user classes. We don't care what order since we're only 2055b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach // actually matching against one of them. 2056a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach for (std::vector<ClassInfo*>::iterator it = Info.Classes.begin(), 2057ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ie = Info.Classes.end(); it != ie; ++it) { 2058a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar ClassInfo &CI = **it; 2059a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 2060ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (!CI.isUserClass()) 2061ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar continue; 2062828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 2063b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach OS << " // '" << CI.ClassName << "' class\n"; 20644dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach OS << " if (Kind == " << CI.Name << ") {\n"; 20654dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach OS << " if (Operand." << CI.PredicateMethod << "())\n"; 20664dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach OS << " return MCTargetAsmParser::Match_Success;\n"; 20674dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach if (!CI.DiagnosticType.empty()) 20684dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach OS << " return " << Info.Target.getName() << "AsmParser::Match_" 20694dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach << CI.DiagnosticType << ";\n"; 2070ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " }\n\n"; 2071a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 2072828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 2073b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson // Check for register operands, including sub-classes. 2074b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson OS << " if (Operand.isReg()) {\n"; 2075b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson OS << " MatchClassKind OpKind;\n"; 2076b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson OS << " switch (Operand.getReg()) {\n"; 2077b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson OS << " default: OpKind = InvalidMatchClass; break;\n"; 2078decfdf548b43c80c3dd81ff1cc3639b80ed33a3eSean Silva for (AsmMatcherInfo::RegisterClassesTy::iterator 2079b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson it = Info.RegisterClasses.begin(), ie = Info.RegisterClasses.end(); 2080b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson it != ie; ++it) 2081b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson OS << " case " << Info.Target.getName() << "::" 2082b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson << it->first->getName() << ": OpKind = " << it->second->Name 2083b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson << "; break;\n"; 2084b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson OS << " }\n"; 2085b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson OS << " return isSubclass(OpKind, Kind) ? " 2086b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson << "MCTargetAsmParser::Match_Success :\n " 2087b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson << " MCTargetAsmParser::Match_InvalidOperand;\n }\n\n"; 2088b885dc8d39fd5ffe4be01059ca6d8977374db02fOwen Anderson 20894dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach // Generic fallthrough match failure case for operands that don't have 20904dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach // specialized diagnostic types. 20914dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach OS << " return MCTargetAsmParser::Match_InvalidOperand;\n"; 2092a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "}\n\n"; 2093a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar} 2094a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 20958caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach/// emitIsSubclass - Emit the subclass predicate function. 20968caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachstatic void emitIsSubclass(CodeGenTarget &Target, 2097fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar std::vector<ClassInfo*> &Infos, 2098fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar raw_ostream &OS) { 20994e0ae44b3a1b5f7157351764fd125c7c85959797Dmitri Gribenko OS << "/// isSubclass - Compute whether \\p A is a subclass of \\p B.\n"; 21003d5d8f6b768619ed65f79606d5c981c1e056c7e8Jim Grosbach OS << "static bool isSubclass(MatchClassKind A, MatchClassKind B) {\n"; 2101fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar OS << " if (A == B)\n"; 2102fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar OS << " return true;\n\n"; 2103fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar 210447cfec02842f885b46ea0d3c812793e660691640Reid Kleckner std::string OStr; 210547cfec02842f885b46ea0d3c812793e660691640Reid Kleckner raw_string_ostream SS(OStr); 210654911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman unsigned Count = 0; 210754911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman SS << " switch (A) {\n"; 210854911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman SS << " default:\n"; 210954911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman SS << " return false;\n"; 2110a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach for (std::vector<ClassInfo*>::iterator it = Infos.begin(), 2111fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar ie = Infos.end(); it != ie; ++it) { 2112fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar ClassInfo &A = **it; 2113fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar 2114a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach std::vector<StringRef> SuperClasses; 2115a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach for (std::vector<ClassInfo*>::iterator it = Infos.begin(), 2116a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach ie = Infos.end(); it != ie; ++it) { 2117a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach ClassInfo &B = **it; 2118fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar 2119a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach if (&A != &B && A.isSubsetOf(B)) 2120a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach SuperClasses.push_back(B.Name); 2121a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach } 2122fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar 2123a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach if (SuperClasses.empty()) 2124a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach continue; 212554911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman ++Count; 2126fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar 212754911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman SS << "\n case " << A.Name << ":\n"; 2128fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar 2129a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach if (SuperClasses.size() == 1) { 213054911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman SS << " return B == " << SuperClasses.back().str() << ";\n"; 2131a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach continue; 2132fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar } 2133a66512e59142f36ae653460891c058d5e78e07e3Jim Grosbach 213454911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman if (!SuperClasses.empty()) { 213554911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman SS << " switch (B) {\n"; 213654911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman SS << " default: return false;\n"; 213754911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i) 213854911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman SS << " case " << SuperClasses[i].str() << ": return true;\n"; 213954911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman SS << " }\n"; 214054911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman } else { 214154911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman // No case statement to emit 214254911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman SS << " return false;\n"; 214354911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman } 2144fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar } 214554911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman SS << " }\n"; 214654911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman 214754911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman // If there were case statements emitted into the string stream, write them 214854911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman // to the output stream, otherwise write the default. 214954911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman if (Count) 215054911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman OS << SS.str(); 215154911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman else 215254911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman OS << " return false;\n"; 215354911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman 2154fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar OS << "}\n\n"; 2155fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar} 2156fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar 21578caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach/// emitMatchTokenString - Emit the function to match a token string to the 2158245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar/// appropriate match class value. 21598caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachstatic void emitMatchTokenString(CodeGenTarget &Target, 2160245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar std::vector<ClassInfo*> &Infos, 2161245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar raw_ostream &OS) { 2162245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar // Construct the match list. 21635845e5c62b42d025557765006515156691a6a8b1Chris Lattner std::vector<StringMatcher::StringPair> Matches; 2164a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach for (std::vector<ClassInfo*>::iterator it = Infos.begin(), 2165245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar ie = Infos.end(); it != ie; ++it) { 2166245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar ClassInfo &CI = **it; 2167245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar 2168245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar if (CI.Kind == ClassInfo::Token) 21695845e5c62b42d025557765006515156691a6a8b1Chris Lattner Matches.push_back(StringMatcher::StringPair(CI.ValueName, 21705845e5c62b42d025557765006515156691a6a8b1Chris Lattner "return " + CI.Name + ";")); 2171245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar } 2172245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar 21733d5d8f6b768619ed65f79606d5c981c1e056c7e8Jim Grosbach OS << "static MatchClassKind matchTokenString(StringRef Name) {\n"; 2174245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar 21755845e5c62b42d025557765006515156691a6a8b1Chris Lattner StringMatcher("Name", Matches, OS).Emit(); 2176245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar 2177245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar OS << " return InvalidMatchClass;\n"; 2178245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar OS << "}\n\n"; 2179245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar} 218070add884e4967f511e2cbb35c61534186b9b418aChris Lattner 21818caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach/// emitMatchRegisterName - Emit the function to match a string to the target 21822234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar/// specific register enum. 21838caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachstatic void emitMatchRegisterName(CodeGenTarget &Target, Record *AsmParser, 21842234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar raw_ostream &OS) { 2185245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar // Construct the match list. 21865845e5c62b42d025557765006515156691a6a8b1Chris Lattner std::vector<StringMatcher::StringPair> Matches; 2187abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen const std::vector<CodeGenRegister*> &Regs = 2188abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen Target.getRegBank().getRegisters(); 2189abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen for (unsigned i = 0, e = Regs.size(); i != e; ++i) { 2190abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen const CodeGenRegister *Reg = Regs[i]; 2191abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen if (Reg->TheDef->getValueAsString("AsmName").empty()) 219220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar continue; 219320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 21945845e5c62b42d025557765006515156691a6a8b1Chris Lattner Matches.push_back(StringMatcher::StringPair( 2195abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen Reg->TheDef->getValueAsString("AsmName"), 2196abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen "return " + utostr(Reg->EnumValue) + ";")); 219720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 2198a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 2199b8d6e98e566724f58344d275a4bd675249bb713aChris Lattner OS << "static unsigned MatchRegisterName(StringRef Name) {\n"; 2200245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar 22015845e5c62b42d025557765006515156691a6a8b1Chris Lattner StringMatcher("Name", Matches, OS).Emit(); 2202a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 2203245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar OS << " return 0;\n"; 220420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar OS << "}\n\n"; 22052234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar} 22062234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar 2207dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic const char *getMinimalTypeForRange(uint64_t Range) { 2208dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines assert(Range <= 0xFFFFFFFFULL && "Enum too large"); 2209dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Range > 0xFFFF) 2210dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return "uint32_t"; 2211dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Range > 0xFF) 2212dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return "uint16_t"; 2213dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return "uint8_t"; 2214dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 2215dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 2216dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic const char *getMinimalRequiredFeaturesType(const AsmMatcherInfo &Info) { 2217dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t MaxIndex = Info.SubtargetFeatures.size(); 2218dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (MaxIndex > 0) 2219dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MaxIndex--; 2220dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return getMinimalTypeForRange(1ULL << MaxIndex); 2221dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 2222dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 22238caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach/// emitSubtargetFeatureFlagEnumeration - Emit the subtarget feature flag 222454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar/// definitions. 22258caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachstatic void emitSubtargetFeatureFlagEnumeration(AsmMatcherInfo &Info, 222654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar raw_ostream &OS) { 222754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << "// Flags for subtarget features that participate in " 222854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar << "instruction matching.\n"; 2229dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OS << "enum SubtargetFeatureFlag : " << getMinimalRequiredFeaturesType(Info) 2230dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << " {\n"; 22316dd670af758ee111593f81f355325e1b5960b870Tim Northover for (std::map<Record*, SubtargetFeatureInfo*, LessRecordByID>::const_iterator 223254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar it = Info.SubtargetFeatures.begin(), 223354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar ie = Info.SubtargetFeatures.end(); it != ie; ++it) { 223454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar SubtargetFeatureInfo &SFI = *it->second; 2235dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OS << " " << SFI.getEnumName() << " = (1U << " << SFI.Index << "),\n"; 223654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar } 223754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << " Feature_None = 0\n"; 223854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << "};\n\n"; 223954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar} 224054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 22414dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach/// emitOperandDiagnosticTypes - Emit the operand matching diagnostic types. 22424dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbachstatic void emitOperandDiagnosticTypes(AsmMatcherInfo &Info, raw_ostream &OS) { 22434dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach // Get the set of diagnostic types from all of the operand classes. 22444dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach std::set<StringRef> Types; 22454dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach for (std::map<Record*, ClassInfo*>::const_iterator 22464dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach I = Info.AsmOperandClasses.begin(), 22474dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach E = Info.AsmOperandClasses.end(); I != E; ++I) { 22484dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach if (!I->second->DiagnosticType.empty()) 22494dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach Types.insert(I->second->DiagnosticType); 22504dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach } 22514dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach 22524dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach if (Types.empty()) return; 22534dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach 22544dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach // Now emit the enum entries. 22554dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach for (std::set<StringRef>::const_iterator I = Types.begin(), E = Types.end(); 22564dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach I != E; ++I) 22574dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach OS << " Match_" << *I << ",\n"; 22584dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach OS << " END_OPERAND_DIAGNOSTIC_TYPES\n"; 22594dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach} 22604dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach 226114ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach/// emitGetSubtargetFeatureName - Emit the helper function to get the 226214ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach/// user-level name for a subtarget feature. 226314ce6fac242228dacc5c08040e544141a96880e5Jim Grosbachstatic void emitGetSubtargetFeatureName(AsmMatcherInfo &Info, raw_ostream &OS) { 226414ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach OS << "// User-level names for subtarget features that participate in\n" 226514ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach << "// instruction matching.\n" 226654911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman << "static const char *getSubtargetFeatureName(unsigned Val) {\n"; 226754911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman if (!Info.SubtargetFeatures.empty()) { 226854911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman OS << " switch(Val) {\n"; 22696dd670af758ee111593f81f355325e1b5960b870Tim Northover typedef std::map<Record*, SubtargetFeatureInfo*, LessRecordByID> RecFeatMap; 22706dd670af758ee111593f81f355325e1b5960b870Tim Northover for (RecFeatMap::const_iterator it = Info.SubtargetFeatures.begin(), 22716dd670af758ee111593f81f355325e1b5960b870Tim Northover ie = Info.SubtargetFeatures.end(); it != ie; ++it) { 227254911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman SubtargetFeatureInfo &SFI = *it->second; 227354911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman // FIXME: Totally just a placeholder name to get the algorithm working. 227454911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman OS << " case " << SFI.getEnumName() << ": return \"" 227554911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman << SFI.TheDef->getValueAsString("PredicateName") << "\";\n"; 227654911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman } 227754911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman OS << " default: return \"(unknown)\";\n"; 227854911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman OS << " }\n"; 227954911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman } else { 228054911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman // Nothing to emit, so skip the switch 228154911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman OS << " return \"(unknown)\";\n"; 228214ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach } 228354911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman OS << "}\n\n"; 228414ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach} 228514ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach 22868caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach/// emitComputeAvailableFeatures - Emit the function to compute the list of 228754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar/// available features given a subtarget. 22888caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachstatic void emitComputeAvailableFeatures(AsmMatcherInfo &Info, 228954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar raw_ostream &OS) { 229054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar std::string ClassName = 229154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar Info.AsmParser->getValueAsString("AsmParserClassName"); 229254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 229302bcbc97fbf55803c660729aa9d2c154a2101331Chris Lattner OS << "unsigned " << Info.Target.getName() << ClassName << "::\n" 2294ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng << "ComputeAvailableFeatures(uint64_t FB) const {\n"; 229554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << " unsigned Features = 0;\n"; 22966dd670af758ee111593f81f355325e1b5960b870Tim Northover for (std::map<Record*, SubtargetFeatureInfo*, LessRecordByID>::const_iterator 229754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar it = Info.SubtargetFeatures.begin(), 229854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar ie = Info.SubtargetFeatures.end(); it != ie; ++it) { 229954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar SubtargetFeatureInfo &SFI = *it->second; 2300ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 2301ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng OS << " if ("; 230265da6fc8af561e77620bd86b83be8ca50acfdd30Jim Grosbach std::string CondStorage = 230365da6fc8af561e77620bd86b83be8ca50acfdd30Jim Grosbach SFI.TheDef->getValueAsString("AssemblerCondString"); 2304fbc38d2c16bc2fb923efdbbd6035ec8233fb4856Evan Cheng StringRef Conds = CondStorage; 2305ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng std::pair<StringRef,StringRef> Comma = Conds.split(','); 2306ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng bool First = true; 2307ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng do { 2308ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng if (!First) 2309ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng OS << " && "; 2310ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 2311ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng bool Neg = false; 2312ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng StringRef Cond = Comma.first; 2313ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng if (Cond[0] == '!') { 2314ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng Neg = true; 2315ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng Cond = Cond.substr(1); 2316ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 2317ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 2318ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng OS << "((FB & " << Info.Target.getName() << "::" << Cond << ")"; 2319ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng if (Neg) 2320ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng OS << " == 0"; 2321ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng else 2322ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng OS << " != 0"; 2323ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng OS << ")"; 2324ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 2325ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng if (Comma.second.empty()) 2326ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng break; 2327ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 2328ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng First = false; 2329ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng Comma = Comma.second.split(','); 2330ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } while (true); 2331ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 2332ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng OS << ")\n"; 23330aed1e770149301af473ce05a83f73be01c06fe0Chris Lattner OS << " Features |= " << SFI.getEnumName() << ";\n"; 233454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar } 233554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << " return Features;\n"; 233654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << "}\n\n"; 233754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar} 233854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 23396fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattnerstatic std::string GetAliasRequiredFeatures(Record *R, 23406fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner const AsmMatcherInfo &Info) { 2341693173feefaa326fad0e386470846fb3199ba381Chris Lattner std::vector<Record*> ReqFeatures = R->getValueAsListOfDefs("Predicates"); 2342693173feefaa326fad0e386470846fb3199ba381Chris Lattner std::string Result; 2343693173feefaa326fad0e386470846fb3199ba381Chris Lattner unsigned NumFeatures = 0; 2344693173feefaa326fad0e386470846fb3199ba381Chris Lattner for (unsigned i = 0, e = ReqFeatures.size(); i != e; ++i) { 23454a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner SubtargetFeatureInfo *F = Info.getSubtargetFeature(ReqFeatures[i]); 2346828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 2347dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!F) 234861131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger PrintFatalError(R->getLoc(), "Predicate '" + ReqFeatures[i]->getName() + 23494a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner "' is not marked as an AssemblerPredicate!"); 2350828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 23514a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner if (NumFeatures) 23524a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner Result += '|'; 2353828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 23544a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner Result += F->getEnumName(); 23554a74ee7203d119232d9c6df33946c01611e433f8Chris Lattner ++NumFeatures; 2356693173feefaa326fad0e386470846fb3199ba381Chris Lattner } 2357828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 2358693173feefaa326fad0e386470846fb3199ba381Chris Lattner if (NumFeatures > 1) 2359693173feefaa326fad0e386470846fb3199ba381Chris Lattner Result = '(' + Result + ')'; 2360693173feefaa326fad0e386470846fb3199ba381Chris Lattner return Result; 2361693173feefaa326fad0e386470846fb3199ba381Chris Lattner} 2362693173feefaa326fad0e386470846fb3199ba381Chris Lattner 236388eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosierstatic void emitMnemonicAliasVariant(raw_ostream &OS,const AsmMatcherInfo &Info, 236488eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier std::vector<Record*> &Aliases, 236588eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier unsigned Indent = 0, 236688eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier StringRef AsmParserVariantName = StringRef()){ 23674fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner // Keep track of all the aliases from a mnemonic. Use an std::map so that the 23684fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner // iteration order of the map is stable. 23694fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner std::map<std::string, std::vector<Record*> > AliasesFromMnemonic; 2370828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 2371674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner for (unsigned i = 0, e = Aliases.size(); i != e; ++i) { 2372674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner Record *R = Aliases[i]; 237388eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier // FIXME: Allow AssemblerVariantName to be a comma separated list. 237488eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier std::string AsmVariantName = R->getValueAsString("AsmVariantName"); 237588eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier if (AsmVariantName != AsmParserVariantName) 237688eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier continue; 23774fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner AliasesFromMnemonic[R->getValueAsString("FromMnemonic")].push_back(R); 23784fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner } 237988eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier if (AliasesFromMnemonic.empty()) 238088eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier return; 23819273151c3bbc96c9b2911caffe3e1a724261cd06Vladimir Medic 23824fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner // Process each alias a "from" mnemonic at a time, building the code executed 23834fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner // by the string remapper. 23844fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner std::vector<StringMatcher::StringPair> Cases; 23854fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner for (std::map<std::string, std::vector<Record*> >::iterator 23864fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner I = AliasesFromMnemonic.begin(), E = AliasesFromMnemonic.end(); 23874fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner I != E; ++I) { 23884fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner const std::vector<Record*> &ToVec = I->second; 2389693173feefaa326fad0e386470846fb3199ba381Chris Lattner 2390693173feefaa326fad0e386470846fb3199ba381Chris Lattner // Loop through each alias and emit code that handles each case. If there 2391693173feefaa326fad0e386470846fb3199ba381Chris Lattner // are two instructions without predicates, emit an error. If there is one, 2392693173feefaa326fad0e386470846fb3199ba381Chris Lattner // emit it last. 2393693173feefaa326fad0e386470846fb3199ba381Chris Lattner std::string MatchCode; 2394693173feefaa326fad0e386470846fb3199ba381Chris Lattner int AliasWithNoPredicate = -1; 2395828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 2396693173feefaa326fad0e386470846fb3199ba381Chris Lattner for (unsigned i = 0, e = ToVec.size(); i != e; ++i) { 2397693173feefaa326fad0e386470846fb3199ba381Chris Lattner Record *R = ToVec[i]; 23986fa152c8fb3f36456955fbdf9e95e365f3e21ec8Chris Lattner std::string FeatureMask = GetAliasRequiredFeatures(R, Info); 2399828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 2400693173feefaa326fad0e386470846fb3199ba381Chris Lattner // If this unconditionally matches, remember it for later and diagnose 2401693173feefaa326fad0e386470846fb3199ba381Chris Lattner // duplicates. 2402693173feefaa326fad0e386470846fb3199ba381Chris Lattner if (FeatureMask.empty()) { 2403693173feefaa326fad0e386470846fb3199ba381Chris Lattner if (AliasWithNoPredicate != -1) { 2404693173feefaa326fad0e386470846fb3199ba381Chris Lattner // We can't have two aliases from the same mnemonic with no predicate. 2405693173feefaa326fad0e386470846fb3199ba381Chris Lattner PrintError(ToVec[AliasWithNoPredicate]->getLoc(), 2406693173feefaa326fad0e386470846fb3199ba381Chris Lattner "two MnemonicAliases with the same 'from' mnemonic!"); 240761131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger PrintFatalError(R->getLoc(), "this is the other MnemonicAlias."); 2408693173feefaa326fad0e386470846fb3199ba381Chris Lattner } 2409828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 2410693173feefaa326fad0e386470846fb3199ba381Chris Lattner AliasWithNoPredicate = i; 2411693173feefaa326fad0e386470846fb3199ba381Chris Lattner continue; 2412693173feefaa326fad0e386470846fb3199ba381Chris Lattner } 24136ef6ceda6883d0ee543d8da86d16b0fcdcecab96Joerg Sonnenberger if (R->getValueAsString("ToMnemonic") == I->first) 241461131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger PrintFatalError(R->getLoc(), "MnemonicAlias to the same string"); 2415828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 24168cf8bcc40c977713e51fb85fb9f24a0ecfbde24bChris Lattner if (!MatchCode.empty()) 24178cf8bcc40c977713e51fb85fb9f24a0ecfbde24bChris Lattner MatchCode += "else "; 2418693173feefaa326fad0e386470846fb3199ba381Chris Lattner MatchCode += "if ((Features & " + FeatureMask + ") == "+FeatureMask+")\n"; 2419693173feefaa326fad0e386470846fb3199ba381Chris Lattner MatchCode += " Mnemonic = \"" +R->getValueAsString("ToMnemonic")+"\";\n"; 2420693173feefaa326fad0e386470846fb3199ba381Chris Lattner } 2421828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 2422693173feefaa326fad0e386470846fb3199ba381Chris Lattner if (AliasWithNoPredicate != -1) { 2423693173feefaa326fad0e386470846fb3199ba381Chris Lattner Record *R = ToVec[AliasWithNoPredicate]; 24248cf8bcc40c977713e51fb85fb9f24a0ecfbde24bChris Lattner if (!MatchCode.empty()) 24258cf8bcc40c977713e51fb85fb9f24a0ecfbde24bChris Lattner MatchCode += "else\n "; 24268cf8bcc40c977713e51fb85fb9f24a0ecfbde24bChris Lattner MatchCode += "Mnemonic = \"" + R->getValueAsString("ToMnemonic")+"\";\n"; 24274fd32c66481c107a4f32cbec0c3017d9c6154a93Chris Lattner } 2428828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 2429693173feefaa326fad0e386470846fb3199ba381Chris Lattner MatchCode += "return;"; 2430693173feefaa326fad0e386470846fb3199ba381Chris Lattner 2431693173feefaa326fad0e386470846fb3199ba381Chris Lattner Cases.push_back(std::make_pair(I->first, MatchCode)); 2432674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner } 243388eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier StringMatcher("Mnemonic", Cases, OS).Emit(Indent); 243488eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier} 243588eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier 243688eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier/// emitMnemonicAliases - If the target has any MnemonicAlias<> definitions, 243788eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier/// emit a function for them and return true, otherwise return false. 243888eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosierstatic bool emitMnemonicAliases(raw_ostream &OS, const AsmMatcherInfo &Info, 243988eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier CodeGenTarget &Target) { 244088eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier // Ignore aliases when match-prefix is set. 244188eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier if (!MatchPrefix.empty()) 244288eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier return false; 244388eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier 244488eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier std::vector<Record*> Aliases = 244588eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier Info.getRecords().getAllDerivedDefinitions("MnemonicAlias"); 244688eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier if (Aliases.empty()) return false; 244788eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier 244888eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier OS << "static void applyMnemonicAliases(StringRef &Mnemonic, " 244988eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier "unsigned Features, unsigned VariantID) {\n"; 245088eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier OS << " switch (VariantID) {\n"; 245188eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier unsigned VariantCount = Target.getAsmParserVariantCount(); 245288eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier for (unsigned VC = 0; VC != VariantCount; ++VC) { 245388eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier Record *AsmVariant = Target.getAsmParserVariant(VC); 245488eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier int AsmParserVariantNo = AsmVariant->getValueAsInt("Variant"); 245588eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier std::string AsmParserVariantName = AsmVariant->getValueAsString("Name"); 245688eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier OS << " case " << AsmParserVariantNo << ":\n"; 245788eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier emitMnemonicAliasVariant(OS, Info, Aliases, /*Indent=*/2, 245888eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier AsmParserVariantName); 245988eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier OS << " break;\n"; 246088eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier } 246188eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier OS << " }\n"; 246288eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier 246388eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier // Emit aliases that apply to all variants. 246488eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier emitMnemonicAliasVariant(OS, Info, Aliases); 2465828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 246655b5e85643b189636758188f11b598c45178407fDaniel Dunbar OS << "}\n\n"; 2467828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 24687fd4489de11bdf06f6c852d42abafea013b76f28Chris Lattner return true; 2469674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner} 2470674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner 24718caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbachstatic void emitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target, 24723a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper const AsmMatcherInfo &Info, StringRef ClassName, 24733a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper StringToOffsetTable &StringTable, 24743a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper unsigned MaxMnemonicIndex) { 24753a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper unsigned MaxMask = 0; 24763a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper for (std::vector<OperandMatchEntry>::const_iterator it = 24773a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper Info.OperandMatchInfo.begin(), ie = Info.OperandMatchInfo.end(); 24783a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper it != ie; ++it) { 24793a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper MaxMask |= it->OperandMask; 24803a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper } 24813a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper 2482e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes // Emit the static custom operand parsing table; 2483e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << "namespace {\n"; 2484e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " struct OperandMatchEntry {\n"; 2485dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OS << " " << getMinimalRequiredFeaturesType(Info) 2486fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper << " RequiredFeatures;\n"; 24873a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper OS << " " << getMinimalTypeForRange(MaxMnemonicIndex) 24883a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper << " Mnemonic;\n"; 2489fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper OS << " " << getMinimalTypeForRange(Info.Classes.size()) 24903a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper << " Class;\n"; 24913a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper OS << " " << getMinimalTypeForRange(MaxMask) 24923a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper << " OperandMask;\n\n"; 2493b08bb34a6f49c79e963aac52030c0cbeb0526f86Benjamin Kramer OS << " StringRef getMnemonic() const {\n"; 2494b08bb34a6f49c79e963aac52030c0cbeb0526f86Benjamin Kramer OS << " return StringRef(MnemonicTable + Mnemonic + 1,\n"; 2495b08bb34a6f49c79e963aac52030c0cbeb0526f86Benjamin Kramer OS << " MnemonicTable[Mnemonic]);\n"; 2496b08bb34a6f49c79e963aac52030c0cbeb0526f86Benjamin Kramer OS << " }\n"; 2497e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " };\n\n"; 2498e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2499e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " // Predicate for searching for an opcode.\n"; 2500e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " struct LessOpcodeOperand {\n"; 2501e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " bool operator()(const OperandMatchEntry &LHS, StringRef RHS) {\n"; 2502b08bb34a6f49c79e963aac52030c0cbeb0526f86Benjamin Kramer OS << " return LHS.getMnemonic() < RHS;\n"; 2503e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " }\n"; 2504e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " bool operator()(StringRef LHS, const OperandMatchEntry &RHS) {\n"; 2505b08bb34a6f49c79e963aac52030c0cbeb0526f86Benjamin Kramer OS << " return LHS < RHS.getMnemonic();\n"; 2506e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " }\n"; 2507e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " bool operator()(const OperandMatchEntry &LHS,"; 2508e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " const OperandMatchEntry &RHS) {\n"; 2509b08bb34a6f49c79e963aac52030c0cbeb0526f86Benjamin Kramer OS << " return LHS.getMnemonic() < RHS.getMnemonic();\n"; 2510e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " }\n"; 2511e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " };\n"; 2512e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2513e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << "} // end anonymous namespace.\n\n"; 2514e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2515e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << "static const OperandMatchEntry OperandMatchTable[" 2516e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes << Info.OperandMatchInfo.size() << "] = {\n"; 2517e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2518b08bb34a6f49c79e963aac52030c0cbeb0526f86Benjamin Kramer OS << " /* Operand List Mask, Mnemonic, Operand Class, Features */\n"; 2519e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes for (std::vector<OperandMatchEntry>::const_iterator it = 2520e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes Info.OperandMatchInfo.begin(), ie = Info.OperandMatchInfo.end(); 2521e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes it != ie; ++it) { 2522e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes const OperandMatchEntry &OMI = *it; 2523e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes const MatchableInfo &II = *OMI.MI; 2524e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 25253a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper OS << " { "; 25263a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper 25273a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper // Write the required features mask. 25283a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper if (!II.RequiredFeatures.empty()) { 25293a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper for (unsigned i = 0, e = II.RequiredFeatures.size(); i != e; ++i) { 25303a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper if (i) OS << "|"; 25313a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper OS << II.RequiredFeatures[i]->getEnumName(); 25323a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper } 25333a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper } else 25343a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper OS << "0"; 25353a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper 25363a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper // Store a pascal-style length byte in the mnemonic. 25373a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper std::string LenMnemonic = char(II.Mnemonic.size()) + II.Mnemonic.str(); 25383a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper OS << ", " << StringTable.GetOrAddStringOffset(LenMnemonic, false) 25393a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper << " /* " << II.Mnemonic << " */, "; 25403a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper 25413a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper OS << OMI.CI->Name; 2542e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 25433a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper OS << ", " << OMI.OperandMask; 2544e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " /* "; 2545e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes bool printComma = false; 2546e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes for (int i = 0, e = 31; i !=e; ++i) 2547e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes if (OMI.OperandMask & (1 << i)) { 2548e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes if (printComma) 2549e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << ", "; 2550e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << i; 2551e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes printComma = true; 2552e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes } 2553e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " */"; 2554e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2555e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " },\n"; 2556e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes } 2557e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << "};\n\n"; 2558e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2559e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes // Emit the operand class switch to call the correct custom parser for 2560e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes // the found operand class. 2561f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OS << Target.getName() << ClassName << "::OperandMatchResultTy " 2562f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach << Target.getName() << ClassName << "::\n" 2563cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << "tryCustomParseOperand(OperandVector" 2564e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes << " &Operands,\n unsigned MCK) {\n\n" 2565e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes << " switch(MCK) {\n"; 2566e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2567e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes for (std::vector<ClassInfo*>::const_iterator it = Info.Classes.begin(), 2568e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes ie = Info.Classes.end(); it != ie; ++it) { 2569e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes ClassInfo *CI = *it; 2570e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes if (CI->ParserMethod.empty()) 2571e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes continue; 2572e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " case " << CI->Name << ":\n" 2573e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes << " return " << CI->ParserMethod << "(Operands);\n"; 2574e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes } 2575e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2576e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " default:\n"; 2577f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OS << " return MatchOperand_NoMatch;\n"; 2578e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " }\n"; 2579f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OS << " return MatchOperand_NoMatch;\n"; 2580e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << "}\n\n"; 2581e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2582e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes // Emit the static custom operand parser. This code is very similar with 2583e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes // the other matcher. Also use MatchResultTy here just in case we go for 2584e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes // a better error handling. 2585f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OS << Target.getName() << ClassName << "::OperandMatchResultTy " 2586e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes << Target.getName() << ClassName << "::\n" 2587cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << "MatchOperandParserImpl(OperandVector" 2588e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes << " &Operands,\n StringRef Mnemonic) {\n"; 2589e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2590e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes // Emit code to get the available features. 2591e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " // Get the current feature set.\n"; 2592e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " unsigned AvailableFeatures = getAvailableFeatures();\n\n"; 2593e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2594e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " // Get the next operand index.\n"; 2595e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " unsigned NextOpNum = Operands.size()-1;\n"; 2596e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2597e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes // Emit code to search the table. 2598e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " // Search the table.\n"; 2599e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " std::pair<const OperandMatchEntry*, const OperandMatchEntry*>"; 2600e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " MnemonicRange =\n"; 2601e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " std::equal_range(OperandMatchTable, OperandMatchTable+" 2602e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes << Info.OperandMatchInfo.size() << ", Mnemonic,\n" 2603e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes << " LessOpcodeOperand());\n\n"; 2604e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2605e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " if (MnemonicRange.first == MnemonicRange.second)\n"; 2606f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OS << " return MatchOperand_NoMatch;\n\n"; 2607e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2608e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " for (const OperandMatchEntry *it = MnemonicRange.first,\n" 2609e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes << " *ie = MnemonicRange.second; it != ie; ++it) {\n"; 2610e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2611e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " // equal_range guarantees that instruction mnemonic matches.\n"; 2612b08bb34a6f49c79e963aac52030c0cbeb0526f86Benjamin Kramer OS << " assert(Mnemonic == it->getMnemonic());\n\n"; 2613e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2614e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes // Emit check that the required features are available. 2615e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " // check if the available features match\n"; 2616e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " if ((AvailableFeatures & it->RequiredFeatures) " 2617e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes << "!= it->RequiredFeatures) {\n"; 2618e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " continue;\n"; 2619e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " }\n\n"; 2620e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2621e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes // Emit check to ensure the operand number matches. 2622e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " // check if the operand in question has a custom parser.\n"; 2623e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " if (!(it->OperandMask & (1 << NextOpNum)))\n"; 2624e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " continue;\n\n"; 2625e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2626e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes // Emit call to the custom parser method 2627e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " // call custom parse method to handle the operand\n"; 2628f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OS << " OperandMatchResultTy Result = "; 26293d5d8f6b768619ed65f79606d5c981c1e056c7e8Jim Grosbach OS << "tryCustomParseOperand(Operands, it->Class);\n"; 2630f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OS << " if (Result != MatchOperand_NoMatch)\n"; 2631f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OS << " return Result;\n"; 2632e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " }\n\n"; 2633e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2634f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OS << " // Okay, we had no match.\n"; 2635f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OS << " return MatchOperand_NoMatch;\n"; 2636e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << "}\n\n"; 2637e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes} 2638e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 26392234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbarvoid AsmMatcherEmitter::run(raw_ostream &OS) { 264067db883487fca3472fdde51e931657e22d4d0495Chris Lattner CodeGenTarget Target(Records); 26412234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar Record *AsmParser = Target.getAsmParser(); 26422234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar std::string ClassName = AsmParser->getValueAsString("AsmParserClassName"); 26432234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar 2644a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // Compute the information on the instructions to match. 264567db883487fca3472fdde51e931657e22d4d0495Chris Lattner AsmMatcherInfo Info(AsmParser, Target, Records); 26468caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach Info.buildInfo(); 264720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 2648e1f6de3fbd892ea3f918a26912660cf316866fc1Daniel Dunbar // Sort the instruction table using the partial order on classes. We use 2649e1f6de3fbd892ea3f918a26912660cf316866fc1Daniel Dunbar // stable_sort to ensure that ambiguous instructions are still 2650e1f6de3fbd892ea3f918a26912660cf316866fc1Daniel Dunbar // deterministically ordered. 265122bc5c4184a497353e33195dd12541a4f08b008aChris Lattner std::stable_sort(Info.Matchables.begin(), Info.Matchables.end(), 265222bc5c4184a497353e33195dd12541a4f08b008aChris Lattner less_ptr<MatchableInfo>()); 2653a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 2654b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar DEBUG_WITH_TYPE("instruction_info", { 265522bc5c4184a497353e33195dd12541a4f08b008aChris Lattner for (std::vector<MatchableInfo*>::iterator 265622bc5c4184a497353e33195dd12541a4f08b008aChris Lattner it = Info.Matchables.begin(), ie = Info.Matchables.end(); 2657a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar it != ie; ++it) 265820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar (*it)->dump(); 265920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar }); 266020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 266122bc5c4184a497353e33195dd12541a4f08b008aChris Lattner // Check for ambiguous matchables. 2662fa0d74d58e6c70ef032afb5f83680276dc4d7370Chris Lattner DEBUG_WITH_TYPE("ambiguous_instrs", { 2663fa0d74d58e6c70ef032afb5f83680276dc4d7370Chris Lattner unsigned NumAmbiguous = 0; 266422bc5c4184a497353e33195dd12541a4f08b008aChris Lattner for (unsigned i = 0, e = Info.Matchables.size(); i != e; ++i) { 266587410368e1bd50408e787f6ece0e58d94c53c1e1Chris Lattner for (unsigned j = i + 1; j != e; ++j) { 266622bc5c4184a497353e33195dd12541a4f08b008aChris Lattner MatchableInfo &A = *Info.Matchables[i]; 266722bc5c4184a497353e33195dd12541a4f08b008aChris Lattner MatchableInfo &B = *Info.Matchables[j]; 2668a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 26698caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach if (A.couldMatchAmbiguouslyWith(B)) { 267022bc5c4184a497353e33195dd12541a4f08b008aChris Lattner errs() << "warning: ambiguous matchables:\n"; 2671fa0d74d58e6c70ef032afb5f83680276dc4d7370Chris Lattner A.dump(); 2672fa0d74d58e6c70ef032afb5f83680276dc4d7370Chris Lattner errs() << "\nis incomparable with:\n"; 2673fa0d74d58e6c70ef032afb5f83680276dc4d7370Chris Lattner B.dump(); 2674fa0d74d58e6c70ef032afb5f83680276dc4d7370Chris Lattner errs() << "\n\n"; 267587410368e1bd50408e787f6ece0e58d94c53c1e1Chris Lattner ++NumAmbiguous; 267687410368e1bd50408e787f6ece0e58d94c53c1e1Chris Lattner } 26772b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar } 2678606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar } 267987410368e1bd50408e787f6ece0e58d94c53c1e1Chris Lattner if (NumAmbiguous) 2680a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach errs() << "warning: " << NumAmbiguous 268122bc5c4184a497353e33195dd12541a4f08b008aChris Lattner << " ambiguous matchables!\n"; 2682fa0d74d58e6c70ef032afb5f83680276dc4d7370Chris Lattner }); 2683606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 2684e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes // Compute the information on the custom operand parsing. 26858caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach Info.buildOperandMatchInfo(); 2686e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 26871095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar // Write the output. 26881095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 26890692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner // Information for the class declaration. 26900692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner OS << "\n#ifdef GET_ASSEMBLER_HEADER\n"; 26910692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner OS << "#undef GET_ASSEMBLER_HEADER\n"; 269284cb033bf30b6f93ae2fbea71513970147e08dc2Jim Grosbach OS << " // This should be included into the middle of the declaration of\n"; 269394b9550a32d189704a8eae55505edf62662c0534Evan Cheng OS << " // your subclasses implementation of MCTargetAsmParser.\n"; 2694ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng OS << " unsigned ComputeAvailableFeatures(uint64_t FeatureBits) const;\n"; 269590e11f8c95146c2d3718e9b3de71ee6628347b05Chad Rosier OS << " void convertToMCInst(unsigned Kind, MCInst &Inst, " 26965c228a945fe3e25a12d0f7e2e9b26b548d6f29f5Daniel Dunbar << "unsigned Opcode,\n" 2697cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << " const OperandVector " 26985c228a945fe3e25a12d0f7e2e9b26b548d6f29f5Daniel Dunbar << "&Operands);\n"; 2699c69bb70deb5b596941bb1de180d1554f9a411062Chad Rosier OS << " void convertToMapAndConstraints(unsigned Kind,\n "; 2700cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines OS << " const OperandVector &Operands) override;\n"; 270136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << " bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) override;\n"; 27029ba9d4d76bfa8de2b05cbce02a5a3ff7d46cb331Chad Rosier OS << " unsigned MatchInstructionImpl(\n"; 27039ba9d4d76bfa8de2b05cbce02a5a3ff7d46cb331Chad Rosier OS.indent(27); 2704cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines OS << "const OperandVector &Operands,\n" 27056e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier << " MCInst &Inst,\n" 2706c69bb70deb5b596941bb1de180d1554f9a411062Chad Rosier << " unsigned &ErrorInfo," 2707c69bb70deb5b596941bb1de180d1554f9a411062Chad Rosier << " bool matchingInlineAsm,\n" 2708c69bb70deb5b596941bb1de180d1554f9a411062Chad Rosier << " unsigned VariantID = 0);\n"; 2709e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 2710e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes if (Info.OperandMatchInfo.size()) { 2711f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OS << "\n enum OperandMatchResultTy {\n"; 2712f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OS << " MatchOperand_Success, // operand matched successfully\n"; 2713f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OS << " MatchOperand_NoMatch, // operand did not match\n"; 2714f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OS << " MatchOperand_ParseFail // operand matched but had errors\n"; 2715f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OS << " };\n"; 2716f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OS << " OperandMatchResultTy MatchOperandParserImpl(\n"; 2717cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines OS << " OperandVector &Operands,\n"; 2718e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " StringRef Mnemonic);\n"; 2719e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 27203d5d8f6b768619ed65f79606d5c981c1e056c7e8Jim Grosbach OS << " OperandMatchResultTy tryCustomParseOperand(\n"; 2721cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines OS << " OperandVector &Operands,\n"; 2722e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " unsigned MCK);\n\n"; 2723e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes } 2724e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 27250692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner OS << "#endif // GET_ASSEMBLER_HEADER_INFO\n\n"; 27260692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner 27274dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach // Emit the operand match diagnostic enum names. 27284dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach OS << "\n#ifdef GET_OPERAND_DIAGNOSTIC_TYPES\n"; 27294dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach OS << "#undef GET_OPERAND_DIAGNOSTIC_TYPES\n\n"; 27304dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach emitOperandDiagnosticTypes(Info, OS); 27314dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach OS << "#endif // GET_OPERAND_DIAGNOSTIC_TYPES\n\n"; 27324dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach 27334dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach 27340692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner OS << "\n#ifdef GET_REGISTER_MATCHER\n"; 27350692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner OS << "#undef GET_REGISTER_MATCHER\n\n"; 27360692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner 273754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar // Emit the subtarget feature enumeration. 27388caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach emitSubtargetFeatureFlagEnumeration(Info, OS); 273954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 27401095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar // Emit the function to match a register name to number. 274172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka // This should be omitted for Mips target 274272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka if (AsmParser->getValueAsBit("ShouldEmitMatchRegisterName")) 274372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka emitMatchRegisterName(Target, AsmParser, OS); 27440692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner 27450692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner OS << "#endif // GET_REGISTER_MATCHER\n\n"; 2746a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 27478030e1a0df630ec6ed1cd5ec673f6472558a4dbeCraig Topper OS << "\n#ifdef GET_SUBTARGET_FEATURE_NAME\n"; 27488030e1a0df630ec6ed1cd5ec673f6472558a4dbeCraig Topper OS << "#undef GET_SUBTARGET_FEATURE_NAME\n\n"; 27491095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 275014ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach // Generate the helper function to get the names for subtarget features. 275114ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach emitGetSubtargetFeatureName(Info, OS); 275214ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach 27538030e1a0df630ec6ed1cd5ec673f6472558a4dbeCraig Topper OS << "#endif // GET_SUBTARGET_FEATURE_NAME\n\n"; 27548030e1a0df630ec6ed1cd5ec673f6472558a4dbeCraig Topper 27558030e1a0df630ec6ed1cd5ec673f6472558a4dbeCraig Topper OS << "\n#ifdef GET_MATCHER_IMPLEMENTATION\n"; 27568030e1a0df630ec6ed1cd5ec673f6472558a4dbeCraig Topper OS << "#undef GET_MATCHER_IMPLEMENTATION\n\n"; 27578030e1a0df630ec6ed1cd5ec673f6472558a4dbeCraig Topper 27587fd4489de11bdf06f6c852d42abafea013b76f28Chris Lattner // Generate the function that remaps for mnemonic aliases. 275988eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier bool HasMnemonicAliases = emitMnemonicAliases(OS, Info, Target); 2760828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 276122685876ed7231f32f7d1698c00acab22825b74cChad Rosier // Generate the convertToMCInst function to convert operands into an MCInst. 276222685876ed7231f32f7d1698c00acab22825b74cChad Rosier // Also, generate the convertToMapAndConstraints function for MS-style inline 276322685876ed7231f32f7d1698c00acab22825b74cChad Rosier // assembly. The latter doesn't actually generate a MCInst. 276422685876ed7231f32f7d1698c00acab22825b74cChad Rosier emitConvertFuncs(Target, ClassName, Info.Matchables, OS); 2765a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 2766a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // Emit the enumeration for classes which participate in matching. 27678caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach emitMatchClassEnumeration(Target, Info.Classes, OS); 276820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 2769a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // Emit the routine to match token strings to their match class. 27708caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach emitMatchTokenString(Target, Info.Classes, OS); 277120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 2772fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar // Emit the subclass predicate routine. 27738caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach emitIsSubclass(Target, Info.Classes, OS); 2774fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar 2775b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach // Emit the routine to validate an operand against a match class. 27768caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach emitValidateOperandClass(Info, OS); 2777b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach 277854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar // Emit the available features compute function. 27798caecdea56c830f3fc80ed67fff121c83de0e364Jim Grosbach emitComputeAvailableFeatures(Info, OS); 278054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 2781a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 2782fee7f01d1e193266b9ca88ef6b5466d543e4cec4Craig Topper StringToOffsetTable StringTable; 2783fee7f01d1e193266b9ca88ef6b5466d543e4cec4Craig Topper 2784a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar size_t MaxNumOperands = 0; 2785fee7f01d1e193266b9ca88ef6b5466d543e4cec4Craig Topper unsigned MaxMnemonicIndex = 0; 2786715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly bool HasDeprecation = false; 278722bc5c4184a497353e33195dd12541a4f08b008aChris Lattner for (std::vector<MatchableInfo*>::const_iterator it = 278822bc5c4184a497353e33195dd12541a4f08b008aChris Lattner Info.Matchables.begin(), ie = Info.Matchables.end(); 2789fee7f01d1e193266b9ca88ef6b5466d543e4cec4Craig Topper it != ie; ++it) { 2790fee7f01d1e193266b9ca88ef6b5466d543e4cec4Craig Topper MatchableInfo &II = **it; 2791fee7f01d1e193266b9ca88ef6b5466d543e4cec4Craig Topper MaxNumOperands = std::max(MaxNumOperands, II.AsmOperands.size()); 2792715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly HasDeprecation |= II.HasDeprecation; 2793fee7f01d1e193266b9ca88ef6b5466d543e4cec4Craig Topper 2794fee7f01d1e193266b9ca88ef6b5466d543e4cec4Craig Topper // Store a pascal-style length byte in the mnemonic. 2795fee7f01d1e193266b9ca88ef6b5466d543e4cec4Craig Topper std::string LenMnemonic = char(II.Mnemonic.size()) + II.Mnemonic.str(); 2796fee7f01d1e193266b9ca88ef6b5466d543e4cec4Craig Topper MaxMnemonicIndex = std::max(MaxMnemonicIndex, 2797fee7f01d1e193266b9ca88ef6b5466d543e4cec4Craig Topper StringTable.GetOrAddStringOffset(LenMnemonic, false)); 2798fee7f01d1e193266b9ca88ef6b5466d543e4cec4Craig Topper } 2799a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 28003a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper OS << "static const char *const MnemonicTable =\n"; 28013a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper StringTable.EmitString(OS); 28023a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper OS << ";\n\n"; 28033a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper 2804a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // Emit the static match table; unused classes get initalized to 0 which is 2805a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // guaranteed to be InvalidMatchClass. 2806a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // 2807a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // FIXME: We can reduce the size of this table very easily. First, we change 2808a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // it so that store the kinds in separate bit-fields for each index, which 2809a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // only needs to be the max width used for classes at that index (we also need 2810a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // to reject based on this during classification). If we then make sure to 2811a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // order the match kinds appropriately (putting mnemonics last), then we 2812a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // should only end up using a few bits for each class, especially the ones 2813a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // following the mnemonic. 281496352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner OS << "namespace {\n"; 281596352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner OS << " struct MatchEntry {\n"; 2816fee7f01d1e193266b9ca88ef6b5466d543e4cec4Craig Topper OS << " " << getMinimalTypeForRange(MaxMnemonicIndex) 2817fee7f01d1e193266b9ca88ef6b5466d543e4cec4Craig Topper << " Mnemonic;\n"; 2818a4c5ecfb1bc0101c1b42a4d81bb427482b52cecfBenjamin Kramer OS << " uint16_t Opcode;\n"; 2819af482cf301cf35eebb3a67a3540e16b102b92246Benjamin Kramer OS << " " << getMinimalTypeForRange(Info.Matchables.size()) 2820af482cf301cf35eebb3a67a3540e16b102b92246Benjamin Kramer << " ConvertFn;\n"; 2821dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OS << " " << getMinimalRequiredFeaturesType(Info) 2822af482cf301cf35eebb3a67a3540e16b102b92246Benjamin Kramer << " RequiredFeatures;\n"; 2823fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper OS << " " << getMinimalTypeForRange(Info.Classes.size()) 2824fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper << " Classes[" << MaxNumOperands << "];\n"; 2825a4c5ecfb1bc0101c1b42a4d81bb427482b52cecfBenjamin Kramer OS << " StringRef getMnemonic() const {\n"; 2826a4c5ecfb1bc0101c1b42a4d81bb427482b52cecfBenjamin Kramer OS << " return StringRef(MnemonicTable + Mnemonic + 1,\n"; 2827a4c5ecfb1bc0101c1b42a4d81bb427482b52cecfBenjamin Kramer OS << " MnemonicTable[Mnemonic]);\n"; 2828a4c5ecfb1bc0101c1b42a4d81bb427482b52cecfBenjamin Kramer OS << " }\n"; 28292b1f943444d1853204725c7b45b1e1032be39958Chris Lattner OS << " };\n\n"; 2830a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 2831e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes OS << " // Predicate for searching for an opcode.\n"; 28322b1f943444d1853204725c7b45b1e1032be39958Chris Lattner OS << " struct LessOpcode {\n"; 28332b1f943444d1853204725c7b45b1e1032be39958Chris Lattner OS << " bool operator()(const MatchEntry &LHS, StringRef RHS) {\n"; 2834a4c5ecfb1bc0101c1b42a4d81bb427482b52cecfBenjamin Kramer OS << " return LHS.getMnemonic() < RHS;\n"; 28352b1f943444d1853204725c7b45b1e1032be39958Chris Lattner OS << " }\n"; 28362b1f943444d1853204725c7b45b1e1032be39958Chris Lattner OS << " bool operator()(StringRef LHS, const MatchEntry &RHS) {\n"; 2837a4c5ecfb1bc0101c1b42a4d81bb427482b52cecfBenjamin Kramer OS << " return LHS < RHS.getMnemonic();\n"; 28382b1f943444d1853204725c7b45b1e1032be39958Chris Lattner OS << " }\n"; 283932c685cb67ff7701f4970ef61765cae7a50f255cChris Lattner OS << " bool operator()(const MatchEntry &LHS, const MatchEntry &RHS) {\n"; 2840a4c5ecfb1bc0101c1b42a4d81bb427482b52cecfBenjamin Kramer OS << " return LHS.getMnemonic() < RHS.getMnemonic();\n"; 284132c685cb67ff7701f4970ef61765cae7a50f255cChris Lattner OS << " }\n"; 284296352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner OS << " };\n"; 2843a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 284496352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner OS << "} // end anonymous namespace.\n\n"; 2845a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 2846f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper unsigned VariantCount = Target.getAsmParserVariantCount(); 2847f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper for (unsigned VC = 0; VC != VariantCount; ++VC) { 2848f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper Record *AsmVariant = Target.getAsmParserVariant(VC); 2849f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper int AsmVariantNo = AsmVariant->getValueAsInt("Variant"); 2850a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 2851f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper OS << "static const MatchEntry MatchTable" << VC << "[] = {\n"; 2852a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 2853f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper for (std::vector<MatchableInfo*>::const_iterator it = 2854f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper Info.Matchables.begin(), ie = Info.Matchables.end(); 2855f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper it != ie; ++it) { 2856f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper MatchableInfo &II = **it; 2857f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper if (II.AsmVariantID != AsmVariantNo) 2858f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper continue; 2859a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 2860f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper // Store a pascal-style length byte in the mnemonic. 2861f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper std::string LenMnemonic = char(II.Mnemonic.size()) + II.Mnemonic.str(); 2862f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper OS << " { " << StringTable.GetOrAddStringOffset(LenMnemonic, false) 2863f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper << " /* " << II.Mnemonic << " */, " 2864f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper << Target.getName() << "::" 2865f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper << II.getResultInst()->TheDef->getName() << ", " 2866f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper << II.ConversionFnKind << ", "; 2867f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper 2868f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper // Write the required features mask. 2869f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper if (!II.RequiredFeatures.empty()) { 2870f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper for (unsigned i = 0, e = II.RequiredFeatures.size(); i != e; ++i) { 2871f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper if (i) OS << "|"; 2872f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper OS << II.RequiredFeatures[i]->getEnumName(); 2873f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper } 2874f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper } else 2875f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper OS << "0"; 2876fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper 2877f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper OS << ", { "; 2878f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper for (unsigned i = 0, e = II.AsmOperands.size(); i != e; ++i) { 2879f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper MatchableInfo::AsmOperand &Op = II.AsmOperands[i]; 2880fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper 2881f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper if (i) OS << ", "; 2882f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper OS << Op.Class->Name; 2883f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper } 2884f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper OS << " }, },\n"; 2885fab3f7ee6f2adca5037f597ce4f28c5acdcbd852Craig Topper } 2886a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 2887f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper OS << "};\n\n"; 2888f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper } 2889a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 28901fe3aa15e9cdc4981d7a125d87eaf257c1d75af1Bob Wilson // A method to determine if a mnemonic is in the list. 28911fe3aa15e9cdc4981d7a125d87eaf257c1d75af1Bob Wilson OS << "bool " << Target.getName() << ClassName << "::\n" 2892f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper << "mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) {\n"; 2893f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper OS << " // Find the appropriate table for this asm variant.\n"; 2894f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper OS << " const MatchEntry *Start, *End;\n"; 2895f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper OS << " switch (VariantID) {\n"; 2896f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper OS << " default: // unreachable\n"; 2897f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper for (unsigned VC = 0; VC != VariantCount; ++VC) { 2898f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper Record *AsmVariant = Target.getAsmParserVariant(VC); 2899f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper int AsmVariantNo = AsmVariant->getValueAsInt("Variant"); 2900dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OS << " case " << AsmVariantNo << ": Start = std::begin(MatchTable" << VC 2901dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << "); End = std::end(MatchTable" << VC << "); break;\n"; 2902f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper } 2903f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper OS << " }\n"; 29041fe3aa15e9cdc4981d7a125d87eaf257c1d75af1Bob Wilson OS << " // Search the table.\n"; 29051fe3aa15e9cdc4981d7a125d87eaf257c1d75af1Bob Wilson OS << " std::pair<const MatchEntry*, const MatchEntry*> MnemonicRange =\n"; 2906f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper OS << " std::equal_range(Start, End, Mnemonic, LessOpcode());\n"; 29071fe3aa15e9cdc4981d7a125d87eaf257c1d75af1Bob Wilson OS << " return MnemonicRange.first != MnemonicRange.second;\n"; 29081fe3aa15e9cdc4981d7a125d87eaf257c1d75af1Bob Wilson OS << "}\n\n"; 29091fe3aa15e9cdc4981d7a125d87eaf257c1d75af1Bob Wilson 291096352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner // Finally, build the match function. 2911cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines OS << "unsigned " << Target.getName() << ClassName << "::\n" 2912cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << "MatchInstructionImpl(const OperandVector" 291396352e5ceb9a2fee7b6e67384afd77493b5c6e5bChris Lattner << " &Operands,\n"; 29146e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier OS << " MCInst &Inst,\n" 291522685876ed7231f32f7d1698c00acab22825b74cChad Rosier << "unsigned &ErrorInfo, bool matchingInlineAsm, unsigned VariantID) {\n"; 291654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 29170bad086d6dd2ee2d4ab8269ace959f7fb9cb3b9dChad Rosier OS << " // Eliminate obvious mismatches.\n"; 29180bad086d6dd2ee2d4ab8269ace959f7fb9cb3b9dChad Rosier OS << " if (Operands.size() > " << (MaxNumOperands+1) << ") {\n"; 29190bad086d6dd2ee2d4ab8269ace959f7fb9cb3b9dChad Rosier OS << " ErrorInfo = " << (MaxNumOperands+1) << ";\n"; 29200bad086d6dd2ee2d4ab8269ace959f7fb9cb3b9dChad Rosier OS << " return Match_InvalidOperand;\n"; 29210bad086d6dd2ee2d4ab8269ace959f7fb9cb3b9dChad Rosier OS << " }\n\n"; 29220bad086d6dd2ee2d4ab8269ace959f7fb9cb3b9dChad Rosier 292354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar // Emit code to get the available features. 292454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << " // Get the current feature set.\n"; 292554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << " unsigned AvailableFeatures = getAvailableFeatures();\n\n"; 292654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 2927674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner OS << " // Get the instruction mnemonic, which is the first token.\n"; 2928674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner OS << " StringRef Mnemonic = ((" << Target.getName() 2929cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << "Operand&)*Operands[0]).getToken();\n\n"; 2930674c1dcca21f5edf9f7380902971fc5471c0bd4aChris Lattner 29317fd4489de11bdf06f6c852d42abafea013b76f28Chris Lattner if (HasMnemonicAliases) { 29327fd4489de11bdf06f6c852d42abafea013b76f28Chris Lattner OS << " // Process all MnemonicAliases to remap the mnemonic.\n"; 293388eb89b89f9426feb7be9b19d1a664b37c590bdbChad Rosier OS << " applyMnemonicAliases(Mnemonic, AvailableFeatures, VariantID);\n\n"; 29347fd4489de11bdf06f6c852d42abafea013b76f28Chris Lattner } 2935828295bb301d6cd3683751c2da1c2dd22ec6423fBob Wilson 2936a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // Emit code to compute the class list for this operand vector. 29379bb9fa19a5e121b83866867ad1d8f7bf2618c1a0Chris Lattner OS << " // Some state to try to produce better error messages.\n"; 293819cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach OS << " bool HadMatchOtherThanFeatures = false;\n"; 2939578071a08734a4eb76484ba0a8d9f10b6e322184Jim Grosbach OS << " bool HadMatchOtherThanPredicate = false;\n"; 294019cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach OS << " unsigned RetCode = Match_InvalidOperand;\n"; 2941325bd661ff57787efddc6b302230f22e9c187655Jim Grosbach OS << " unsigned MissingFeatures = ~0U;\n"; 294284cb033bf30b6f93ae2fbea71513970147e08dc2Jim Grosbach OS << " // Set ErrorInfo to the operand that mismatches if it is\n"; 29439bb9fa19a5e121b83866867ad1d8f7bf2618c1a0Chris Lattner OS << " // wrong for all instances of the instruction.\n"; 29449bb9fa19a5e121b83866867ad1d8f7bf2618c1a0Chris Lattner OS << " ErrorInfo = ~0U;\n"; 29452b1f943444d1853204725c7b45b1e1032be39958Chris Lattner 2946a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // Emit code to search the table. 2947f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper OS << " // Find the appropriate table for this asm variant.\n"; 2948f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper OS << " const MatchEntry *Start, *End;\n"; 2949f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper OS << " switch (VariantID) {\n"; 2950f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper OS << " default: // unreachable\n"; 2951f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper for (unsigned VC = 0; VC != VariantCount; ++VC) { 2952f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper Record *AsmVariant = Target.getAsmParserVariant(VC); 2953f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper int AsmVariantNo = AsmVariant->getValueAsInt("Variant"); 2954dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OS << " case " << AsmVariantNo << ": Start = std::begin(MatchTable" << VC 2955dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << "); End = std::end(MatchTable" << VC << "); break;\n"; 2956f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper } 2957f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper OS << " }\n"; 2958a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " // Search the table.\n"; 29592b1f943444d1853204725c7b45b1e1032be39958Chris Lattner OS << " std::pair<const MatchEntry*, const MatchEntry*> MnemonicRange =\n"; 2960f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper OS << " std::equal_range(Start, End, Mnemonic, LessOpcode());\n\n"; 2961a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 2962a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner OS << " // Return a more specific error code if no mnemonics match.\n"; 2963a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner OS << " if (MnemonicRange.first == MnemonicRange.second)\n"; 2964a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner OS << " return Match_MnemonicFail;\n\n"; 2965a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 29662b1f943444d1853204725c7b45b1e1032be39958Chris Lattner OS << " for (const MatchEntry *it = MnemonicRange.first, " 296780db4e51d2a44bc623b5892bed2351406890b9aaChris Lattner << "*ie = MnemonicRange.second;\n"; 29682b1f943444d1853204725c7b45b1e1032be39958Chris Lattner OS << " it != ie; ++it) {\n"; 296954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 2970e53ee3b112810068b8ca229aff211fc497069273Gabor Greif OS << " // equal_range guarantees that instruction mnemonic matches.\n"; 2971a4c5ecfb1bc0101c1b42a4d81bb427482b52cecfBenjamin Kramer OS << " assert(Mnemonic == it->getMnemonic());\n"; 2972a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 297354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar // Emit check that the subclasses match. 2974ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " bool OperandsValid = true;\n"; 2975ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " for (unsigned i = 0; i != " << MaxNumOperands << "; ++i) {\n"; 2976b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach OS << " if (i + 1 >= Operands.size()) {\n"; 2977b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach OS << " OperandsValid = (it->Classes[i] == " <<"InvalidMatchClass);\n"; 2978087642f8638b08bf236b2cf8f0feb4df34c568f4Bill Wendling OS << " if (!OperandsValid) ErrorInfo = i + 1;\n"; 2979b9d5af05fdc0867ed772c4bbfe3f3acc9fb3d628Jim Grosbach OS << " break;\n"; 2980b9db0c50d84b06b4b567c29375b7db92b5dab077Jim Grosbach OS << " }\n"; 2981cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines OS << " unsigned Diag = validateOperandClass(*Operands[i+1],\n"; 29824dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach OS.indent(43); 29834dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach OS << "(MatchClassKind)it->Classes[i]);\n"; 29844dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach OS << " if (Diag == Match_Success)\n"; 2985ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " continue;\n"; 2986fa05def52c6bb8266d856a9af2de6fa066d93d44Jim Grosbach OS << " // If the generic handler indicates an invalid operand\n"; 2987fa05def52c6bb8266d856a9af2de6fa066d93d44Jim Grosbach OS << " // failure, check for a special case.\n"; 2988fa05def52c6bb8266d856a9af2de6fa066d93d44Jim Grosbach OS << " if (Diag == Match_InvalidOperand) {\n"; 2989cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines OS << " Diag = validateTargetOperandClass(*Operands[i+1],\n"; 2990fa05def52c6bb8266d856a9af2de6fa066d93d44Jim Grosbach OS.indent(43); 2991fa05def52c6bb8266d856a9af2de6fa066d93d44Jim Grosbach OS << "(MatchClassKind)it->Classes[i]);\n"; 2992fa05def52c6bb8266d856a9af2de6fa066d93d44Jim Grosbach OS << " if (Diag == Match_Success)\n"; 2993fa05def52c6bb8266d856a9af2de6fa066d93d44Jim Grosbach OS << " continue;\n"; 2994fa05def52c6bb8266d856a9af2de6fa066d93d44Jim Grosbach OS << " }\n"; 29959bb9fa19a5e121b83866867ad1d8f7bf2618c1a0Chris Lattner OS << " // If this operand is broken for all of the instances of this\n"; 29969bb9fa19a5e121b83866867ad1d8f7bf2618c1a0Chris Lattner OS << " // mnemonic, keep track of it so we can report loc info.\n"; 29974dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach OS << " // If we already had a match that only failed due to a\n"; 29984dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach OS << " // target predicate, that diagnostic is preferred.\n"; 29994dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach OS << " if (!HadMatchOtherThanPredicate &&\n"; 30004dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach OS << " (it == MnemonicRange.first || ErrorInfo <= i+1)) {\n"; 3001ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " ErrorInfo = i+1;\n"; 3002ef970c10918dde1e84b8e14a28dc7cf0a93c7c95Jim Grosbach OS << " // InvalidOperand is the default. Prefer specificity.\n"; 3003ef970c10918dde1e84b8e14a28dc7cf0a93c7c95Jim Grosbach OS << " if (Diag != Match_InvalidOperand)\n"; 3004ef970c10918dde1e84b8e14a28dc7cf0a93c7c95Jim Grosbach OS << " RetCode = Diag;\n"; 30054dbfdfba6c92b6224bf58364371569f5780844d3Jim Grosbach OS << " }\n"; 3006ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " // Otherwise, just reject this instance of the mnemonic.\n"; 3007ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " OperandsValid = false;\n"; 3008ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " break;\n"; 3009ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " }\n\n"; 3010a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 3011ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner OS << " if (!OperandsValid) continue;\n"; 3012ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner 3013ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner // Emit check that the required features are available. 3014ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner OS << " if ((AvailableFeatures & it->RequiredFeatures) " 3015ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner << "!= it->RequiredFeatures) {\n"; 3016ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner OS << " HadMatchOtherThanFeatures = true;\n"; 3017325bd661ff57787efddc6b302230f22e9c187655Jim Grosbach OS << " unsigned NewMissingFeatures = it->RequiredFeatures & " 3018325bd661ff57787efddc6b302230f22e9c187655Jim Grosbach "~AvailableFeatures;\n"; 30190bad086d6dd2ee2d4ab8269ace959f7fb9cb3b9dChad Rosier OS << " if (CountPopulation_32(NewMissingFeatures) <=\n" 30200bad086d6dd2ee2d4ab8269ace959f7fb9cb3b9dChad Rosier " CountPopulation_32(MissingFeatures))\n"; 3021325bd661ff57787efddc6b302230f22e9c187655Jim Grosbach OS << " MissingFeatures = NewMissingFeatures;\n"; 3022ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner OS << " continue;\n"; 3023ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner OS << " }\n"; 3024a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "\n"; 302522685876ed7231f32f7d1698c00acab22825b74cChad Rosier OS << " if (matchingInlineAsm) {\n"; 302622685876ed7231f32f7d1698c00acab22825b74cChad Rosier OS << " Inst.setOpcode(it->Opcode);\n"; 30276e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier OS << " convertToMapAndConstraints(it->ConvertFn, Operands);\n"; 302822685876ed7231f32f7d1698c00acab22825b74cChad Rosier OS << " return Match_Success;\n"; 302922685876ed7231f32f7d1698c00acab22825b74cChad Rosier OS << " }\n\n"; 3030b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar OS << " // We have selected a definite instruction, convert the parsed\n" 3031b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar << " // operands into the appropriate MCInst.\n"; 303290e11f8c95146c2d3718e9b3de71ee6628347b05Chad Rosier OS << " convertToMCInst(it->ConvertFn, Inst, it->Opcode, Operands);\n"; 3033b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar OS << "\n"; 30348cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar 303519cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach // Verify the instruction with the target-specific match predicate function. 303619cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach OS << " // We have a potential match. Check the target predicate to\n" 303719cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach << " // handle any context sensitive constraints.\n" 303819cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach << " unsigned MatchResult;\n" 303919cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach << " if ((MatchResult = checkTargetMatchPredicate(Inst)) !=" 304019cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach << " Match_Success) {\n" 304119cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach << " Inst.clear();\n" 304219cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach << " RetCode = MatchResult;\n" 3043578071a08734a4eb76484ba0a8d9f10b6e322184Jim Grosbach << " HadMatchOtherThanPredicate = true;\n" 304419cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach << " continue;\n" 304519cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach << " }\n\n"; 304619cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach 30478cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar // Call the post-processing function, if used. 30488cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar std::string InsnCleanupFn = 30498cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar AsmParser->getValueAsString("AsmParserInstCleanup"); 30508cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar if (!InsnCleanupFn.empty()) 30518cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar OS << " " << InsnCleanupFn << "(Inst);\n"; 30528cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar 3053715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly if (HasDeprecation) { 3054715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly OS << " std::string Info;\n"; 3055715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly OS << " if (MII.get(Inst.getOpcode()).getDeprecatedInfo(Inst, STI, Info)) {\n"; 3056cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines OS << " SMLoc Loc = ((" << Target.getName() 3057cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << "Operand&)*Operands[0]).getStartLoc();\n"; 3058715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly OS << " Parser.Warning(Loc, Info, None);\n"; 3059715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly OS << " }\n"; 3060715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly } 3061715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly 306279ed3f77e8b87615b80054ca6e4e3ba5e07445bdChris Lattner OS << " return Match_Success;\n"; 3063a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " }\n\n"; 3064a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 3065ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner OS << " // Okay, we had no match. Try to return a useful error code.\n"; 30664c1d2baa7c3303302fec9a15ebc4021bd5d45002Chad Rosier OS << " if (HadMatchOtherThanPredicate || !HadMatchOtherThanFeatures)\n"; 30674c1d2baa7c3303302fec9a15ebc4021bd5d45002Chad Rosier OS << " return RetCode;\n\n"; 3068325bd661ff57787efddc6b302230f22e9c187655Jim Grosbach OS << " // Missing feature matches return which features were missing\n"; 3069325bd661ff57787efddc6b302230f22e9c187655Jim Grosbach OS << " ErrorInfo = MissingFeatures;\n"; 3070578071a08734a4eb76484ba0a8d9f10b6e322184Jim Grosbach OS << " return Match_MissingFeature;\n"; 3071a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar OS << "}\n\n"; 3072a7c78220c4ce0c79801044774355b97b731bcedaJim Grosbach 3073e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes if (Info.OperandMatchInfo.size()) 30743a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper emitCustomOperandParsing(OS, Target, Info, ClassName, StringTable, 30753a3644436695d835bb4e1e2a0c7f3cc82a2807c2Craig Topper MaxMnemonicIndex); 3076e7a54520b3435c006c4f97c56fe970350981ea3cBruno Cardoso Lopes 30770692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner OS << "#endif // GET_MATCHER_IMPLEMENTATION\n\n"; 3078d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar} 30796f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 30806f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesennamespace llvm { 30816f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 30826f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenvoid EmitAsmMatcher(RecordKeeper &RK, raw_ostream &OS) { 30836f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen emitSourceFileHeader("Assembly Matcher Source Fragment", OS); 30846f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen AsmMatcherEmitter(RK).run(OS); 30856f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} 30866f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 30876f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End llvm namespace 3088