AsmMatcherEmitter.cpp revision 606e8ad796f72824f5509e2657c44eca025d4baf
1d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar//===- AsmMatcherEmitter.cpp - Generate an assembly matcher ---------------===// 2d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar// 3d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar// The LLVM Compiler Infrastructure 4d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar// 5d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar// This file is distributed under the University of Illinois Open Source 6d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar// License. See LICENSE.TXT for details. 7d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar// 8d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar//===----------------------------------------------------------------------===// 9d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar// 10d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar// This tablegen backend emits a target specifier matcher for converting parsed 11d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar// assembly operands in the MCInst structures. 12d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar// 1320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// The input to the target specific matcher is a list of literal tokens and 1420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// operands. The target specific parser should generally eliminate any syntax 1520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// which is not relevant for matching; for example, comma tokens should have 1620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// already been consumed and eliminated by the parser. Most instructions will 1720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// end up with a single literal token (the instruction name) and some number of 1820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// operands. 1920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 2020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// Some example inputs, for X86: 2120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 'addl' (immediate ...) (register ...) 2220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 'add' (immediate ...) (memory ...) 2320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 'call' '*' %epc 2420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 2520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// The assembly matcher is responsible for converting this input into a precise 2620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// machine instruction (i.e., an instruction with a well defined encoding). This 2720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// mapping has several properties which complicate matching: 2820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 2920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// - It may be ambiguous; many architectures can legally encode particular 3020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// variants of an instruction in different ways (for example, using a smaller 3120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// encoding for small immediates). Such ambiguities should never be 3220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// arbitrarily resolved by the assembler, the assembler is always responsible 3320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// for choosing the "best" available instruction. 3420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 3520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// - It may depend on the subtarget or the assembler context. Instructions 3620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// which are invalid for the current mode, but otherwise unambiguous (e.g., 3720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// an SSE instruction in a file being assembled for i486) should be accepted 3820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// and rejected by the assembler front end. However, if the proper encoding 3920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// for an instruction is dependent on the assembler context then the matcher 4020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// is responsible for selecting the correct machine instruction for the 4120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// current mode. 4220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 4320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// The core matching algorithm attempts to exploit the regularity in most 4420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// instruction sets to quickly determine the set of possibly matching 4520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// instructions, and the simplify the generated code. Additionally, this helps 4620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// to ensure that the ambiguities are intentionally resolved by the user. 4720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 4820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// The matching is divided into two distinct phases: 4920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 5020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 1. Classification: Each operand is mapped to the unique set which (a) 5120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// contains it, and (b) is the largest such subset for which a single 5220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// instruction could match all members. 5320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 5420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// For register classes, we can generate these subgroups automatically. For 5520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// arbitrary operands, we expect the user to define the classes and their 5620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// relations to one another (for example, 8-bit signed immediates as a 5720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// subset of 32-bit immediates). 5820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 5920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// By partitioning the operands in this way, we guarantee that for any 6020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// tuple of classes, any single instruction must match either all or none 6120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// of the sets of operands which could classify to that tuple. 6220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 6320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// In addition, the subset relation amongst classes induces a partial order 6420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// on such tuples, which we use to resolve ambiguities. 6520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 6620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// FIXME: What do we do if a crazy case shows up where this is the wrong 6720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// resolution? 6820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 6920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 2. The input can now be treated as a tuple of classes (static tokens are 7020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// simple singleton sets). Each such tuple should generally map to a single 7120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// instruction (we currently ignore cases where this isn't true, whee!!!), 7220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// which we can emit a simple matcher for. 7320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar// 74d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar//===----------------------------------------------------------------------===// 75d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar 76d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar#include "AsmMatcherEmitter.h" 77d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar#include "CodeGenTarget.h" 78d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar#include "Record.h" 7920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar#include "llvm/ADT/OwningPtr.h" 80a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar#include "llvm/ADT/SmallVector.h" 81606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar#include "llvm/ADT/STLExtras.h" 8220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar#include "llvm/ADT/StringExtras.h" 8320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar#include "llvm/Support/CommandLine.h" 84a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar#include "llvm/Support/Debug.h" 85a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar#include <list> 86b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar#include <map> 87b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar#include <set> 88d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbarusing namespace llvm; 89d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar 9020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbarnamespace { 912724915c171b08fa9f7f9e54a46ea81708d9c5b2Daniel Dunbarstatic cl::opt<std::string> 92606e8ad796f72824f5509e2657c44eca025d4bafDaniel DunbarMatchPrefix("match-prefix", cl::init(""), 93606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar cl::desc("Only match instructions with the given prefix")); 9420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar} 9520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 96a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar/// FlattenVariants - Flatten an .td file assembly string by selecting the 97a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar/// variant at index \arg N. 98a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbarstatic std::string FlattenVariants(const std::string &AsmString, 99a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar unsigned N) { 100a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar StringRef Cur = AsmString; 101a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar std::string Res = ""; 102a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 103a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar for (;;) { 10453a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar // Find the start of the next variant string. 10553a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar size_t VariantsStart = 0; 10653a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar for (size_t e = Cur.size(); VariantsStart != e; ++VariantsStart) 10753a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar if (Cur[VariantsStart] == '{' && 10820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar (VariantsStart == 0 || (Cur[VariantsStart-1] != '$' && 10920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Cur[VariantsStart-1] != '\\'))) 11053a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar break; 11153a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar 11253a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar // Add the prefix to the result. 11353a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar Res += Cur.slice(0, VariantsStart); 11453a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar if (VariantsStart == Cur.size()) 115a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar break; 116a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 11753a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar ++VariantsStart; // Skip the '{'. 11853a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar 11953a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar // Scan to the end of the variants string. 12053a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar size_t VariantsEnd = VariantsStart; 12153a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar unsigned NestedBraces = 1; 12253a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar for (size_t e = Cur.size(); VariantsEnd != e; ++VariantsEnd) { 12320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (Cur[VariantsEnd] == '}' && Cur[VariantsEnd-1] != '\\') { 12453a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar if (--NestedBraces == 0) 12553a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar break; 12653a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar } else if (Cur[VariantsEnd] == '{') 12753a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar ++NestedBraces; 12853a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar } 129a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 130a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar // Select the Nth variant (or empty). 13153a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar StringRef Selection = Cur.slice(VariantsStart, VariantsEnd); 132a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar for (unsigned i = 0; i != N; ++i) 133a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar Selection = Selection.split('|').second; 134a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar Res += Selection.split('|').first; 135a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 13653a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar assert(VariantsEnd != Cur.size() && 13753a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar "Unterminated variants in assembly string!"); 13853a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar Cur = Cur.substr(VariantsEnd + 1); 139a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar } 140a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 141a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar return Res; 142a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar} 143a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 144a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar/// TokenizeAsmString - Tokenize a simplified assembly string. 14520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbarstatic void TokenizeAsmString(const StringRef &AsmString, 146a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar SmallVectorImpl<StringRef> &Tokens) { 147a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar unsigned Prev = 0; 148a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar bool InTok = true; 149a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar for (unsigned i = 0, e = AsmString.size(); i != e; ++i) { 150a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar switch (AsmString[i]) { 15120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar case '[': 15220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar case ']': 153a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar case '*': 154a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar case '!': 155a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar case ' ': 156a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar case '\t': 157a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar case ',': 158a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar if (InTok) { 15920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Tokens.push_back(AsmString.slice(Prev, i)); 160a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar InTok = false; 161a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar } 16220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (!isspace(AsmString[i]) && AsmString[i] != ',') 16320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Tokens.push_back(AsmString.substr(i, 1)); 164a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar Prev = i + 1; 165a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar break; 16620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 16720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar case '\\': 16820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (InTok) { 16920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Tokens.push_back(AsmString.slice(Prev, i)); 17020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar InTok = false; 17120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 17220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar ++i; 17320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar assert(i != AsmString.size() && "Invalid quoted character"); 17420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Tokens.push_back(AsmString.substr(i, 1)); 17520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Prev = i + 1; 17620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar break; 17720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 17820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar case '$': { 17920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // If this isn't "${", treat like a normal token. 18020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (i + 1 == AsmString.size() || AsmString[i + 1] != '{') { 18120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (InTok) { 18220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Tokens.push_back(AsmString.slice(Prev, i)); 18320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar InTok = false; 18420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 18520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Prev = i; 18620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar break; 18720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 18820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 18920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (InTok) { 19020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Tokens.push_back(AsmString.slice(Prev, i)); 19120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar InTok = false; 19220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 19320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 19420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar StringRef::iterator End = 19520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar std::find(AsmString.begin() + i, AsmString.end(), '}'); 19620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar assert(End != AsmString.end() && "Missing brace in operand reference!"); 19720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar size_t EndPos = End - AsmString.begin(); 19820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Tokens.push_back(AsmString.slice(i, EndPos+1)); 19920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Prev = EndPos + 1; 20020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar i = EndPos; 20120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar break; 20220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 203a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 204a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar default: 205a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar InTok = true; 206a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar } 207a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar } 208a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar if (InTok && Prev != AsmString.size()) 20920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Tokens.push_back(AsmString.substr(Prev)); 210a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar} 211a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 21220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbarstatic bool IsAssemblerInstruction(const StringRef &Name, 21320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar const CodeGenInstruction &CGI, 21420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar const SmallVectorImpl<StringRef> &Tokens) { 21520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // Ignore psuedo ops. 21620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // 21720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // FIXME: This is a hack. 21820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (const RecordVal *Form = CGI.TheDef->getValue("Form")) 21920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (Form->getValue()->getAsString() == "Pseudo") 22020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar return false; 22120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 22220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // Ignore "PHI" node. 22320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // 22420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // FIXME: This is also a hack. 22520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (Name == "PHI") 22620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar return false; 22720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 22820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // Ignore instructions with no .s string. 22920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // 23020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // FIXME: What are these? 23120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (CGI.AsmString.empty()) 23220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar return false; 23320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 23420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // FIXME: Hack; ignore any instructions with a newline in them. 23520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (std::find(CGI.AsmString.begin(), 23620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar CGI.AsmString.end(), '\n') != CGI.AsmString.end()) 23720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar return false; 23820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 23920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // Ignore instructions with attributes, these are always fake instructions for 24020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // simplifying codegen. 24120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // 24220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // FIXME: Is this true? 24320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // 24420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // Also, we ignore instructions which reference the operand multiple times; 24520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // this implies a constraint we would not currently honor. These are 24620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // currently always fake instructions for simplifying codegen. 24720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // 24820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // FIXME: Encode this assumption in the .td, so we can error out here. 24920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar std::set<std::string> OperandNames; 25020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar for (unsigned i = 1, e = Tokens.size(); i < e; ++i) { 25120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (Tokens[i][0] == '$' && 25220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar std::find(Tokens[i].begin(), 25320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Tokens[i].end(), ':') != Tokens[i].end()) { 25420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar DEBUG({ 25520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar errs() << "warning: '" << Name << "': " 25620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar << "ignoring instruction; operand with attribute '" 25720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar << Tokens[i] << "', \n"; 25820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar }); 25920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar return false; 26020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 26122be5225ff88ffaab83c36fa133e70586b91166dDaniel Dunbar 26220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (Tokens[i][0] == '$' && !OperandNames.insert(Tokens[i]).second) { 26320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar DEBUG({ 26420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar errs() << "warning: '" << Name << "': " 26520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar << "ignoring instruction; tied operand '" 26620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar << Tokens[i] << "', \n"; 26720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar }); 26820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar return false; 26920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 27020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 27122be5225ff88ffaab83c36fa133e70586b91166dDaniel Dunbar 27220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar return true; 27320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar} 27422be5225ff88ffaab83c36fa133e70586b91166dDaniel Dunbar 27520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbarnamespace { 27622be5225ff88ffaab83c36fa133e70586b91166dDaniel Dunbar 277a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar/// ClassInfo - Helper class for storing the information about a particular 278a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar/// class of operands which can be matched. 279a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarstruct ClassInfo { 280606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar enum ClassInfoKind { 281a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Token, ///< The class for a particular token. 282a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Register, ///< A register class. 283606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar UserClass0 ///< The (first) user defined class, subsequent user defined 284606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar /// classes are UserClass0+1, and so on. 285606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar }; 286606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 287606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar /// Kind - The class kind, which is either a predefined kind, or (UserClass0 + 288606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar /// N) for the Nth user defined class. 289606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar unsigned Kind; 290a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 291a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// Name - The class name, suitable for use as an enum. 292a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::string Name; 293a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 294a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// ValueName - The name of the value this class represents; for a token this 295a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// is the literal token string, for an operand it is the TableGen class (or 296a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// empty if this is a derived class). 297a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::string ValueName; 298a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 299a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// PredicateMethod - The name of the operand method to test whether the 300a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// operand matches this class; this is not valid for Token kinds. 301a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::string PredicateMethod; 302a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 303a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// RenderMethod - The name of the operand method to add this operand to an 304a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// MCInst; this is not valid for Token kinds. 305a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::string RenderMethod; 306606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 307606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar /// operator< - Compare two classes. 308606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar bool operator<(const ClassInfo &RHS) const { 309606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar // Incompatible kinds are comparable. 310606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar if (Kind != RHS.Kind) 311606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar return Kind < RHS.Kind; 312606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 313606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar switch (Kind) { 314606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar case Token: 315606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar // Tokens are always comparable. 316606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar // 317606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar // FIXME: Compare by enum value. 318606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar return ValueName < RHS.ValueName; 319606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 320606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar case Register: 321606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar // FIXME: Compare by subset relation. 322606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar return false; 323606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 324606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar default: 325606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar // FIXME: Allow user defined relation. 326606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar return false; 327606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar } 328606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar } 329a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar}; 330a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 331b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar/// InstructionInfo - Helper class for storing the necessary information for an 332b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar/// instruction which is capable of being matched. 33320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbarstruct InstructionInfo { 33420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar struct Operand { 335a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// The unique class instance this operand should match. 336a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar ClassInfo *Class; 337a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 338a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// The original operand this corresponds to, if any. 339fa1165abb8fec9383d640b0696a9f397b9153bafBenjamin Kramer const CodeGenInstruction::OperandInfo *OperandInfo; 34020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar }; 34120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 34220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar /// InstrName - The target name for this instruction. 34320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar std::string InstrName; 34420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 34520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar /// Instr - The instruction this matches. 34620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar const CodeGenInstruction *Instr; 34720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 34820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar /// AsmString - The assembly string for this instruction (with variants 34920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar /// removed). 35020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar std::string AsmString; 35120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 35220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar /// Tokens - The tokenized assembly pattern that this instruction matches. 35320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar SmallVector<StringRef, 4> Tokens; 35420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 35520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar /// Operands - The operands that this instruction matches. 35620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar SmallVector<Operand, 4> Operands; 35720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 358b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar /// ConversionFnKind - The enum value which is passed to the generated 359b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar /// ConvertToMCInst to convert parsed operands into an MCInst for this 360b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar /// function. 361b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar std::string ConversionFnKind; 36220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 363606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar /// operator< - Compare two instructions. 364606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar bool operator<(const InstructionInfo &RHS) const { 365606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar // Order first by the number of operands (which is unambiguous). 366606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar if (Operands.size() != RHS.Operands.size()) 367606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar return Operands.size() < RHS.Operands.size(); 368606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 369606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar // Otherwise, order by lexicographic comparison of tokens and operand kinds 370606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar // (these can never be ambiguous). 371606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar for (unsigned i = 0, e = Operands.size(); i != e; ++i) 372606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar if (Operands[i].Class->Kind != RHS.Operands[i].Class->Kind || 373606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar Operands[i].Class->Kind == ClassInfo::Token) 374606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar if (*Operands[i].Class < *RHS.Operands[i].Class) 375606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar return true; 376606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 377606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar // Finally, order by the component wise comparison of operand classes. We 378606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar // don't want to rely on the lexigraphic ordering of elements, so we define 379606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar // only define the ordering when it is unambiguous. That is, when some pair 380606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar // compares less than and no pair compares greater than. 381606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 382606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar // Check that no pair compares greater than. 383606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar for (unsigned i = 0, e = Operands.size(); i != e; ++i) 384606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar if (*RHS.Operands[i].Class < *Operands[i].Class) 385606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar return false; 386606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 387606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar // Otherwise, return true if some pair compares less than. 388606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar for (unsigned i = 0, e = Operands.size(); i != e; ++i) 389606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar if (*Operands[i].Class < *RHS.Operands[i].Class) 390606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar return true; 391606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 392606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar return false; 393606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar } 394606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 39520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbarpublic: 39620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar void dump(); 39720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar}; 39820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 399a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarclass AsmMatcherInfo { 400a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarpublic: 401a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// The classes which are needed for matching. 402a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::vector<ClassInfo*> Classes; 403a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 404a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// The information on the instruction to match. 405a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::vector<InstructionInfo*> Instructions; 406a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 407a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarprivate: 408a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// Map of token to class information which has already been constructed. 409a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::map<std::string, ClassInfo*> TokenClasses; 410a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 411a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// Map of operand name to class information which has already been 412a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// constructed. 413a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::map<std::string, ClassInfo*> OperandClasses; 414a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 415a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarprivate: 416a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// getTokenClass - Lookup or create the class for the given token. 417a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar ClassInfo *getTokenClass(const StringRef &Token); 418a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 419a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// getOperandClass - Lookup or create the class for the given operand. 420a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar ClassInfo *getOperandClass(const StringRef &Token, 421a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar const CodeGenInstruction::OperandInfo &OI); 422a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 423a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarpublic: 424a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// BuildInfo - Construct the various tables used during matching. 425a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar void BuildInfo(CodeGenTarget &Target); 426a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar}; 427a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 42820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar} 42920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 43020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbarvoid InstructionInfo::dump() { 43120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar errs() << InstrName << " -- " << "flattened:\"" << AsmString << '\"' 43220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar << ", tokens:["; 43320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar for (unsigned i = 0, e = Tokens.size(); i != e; ++i) { 43420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar errs() << Tokens[i]; 43520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (i + 1 != e) 43620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar errs() << ", "; 43722be5225ff88ffaab83c36fa133e70586b91166dDaniel Dunbar } 43820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar errs() << "]\n"; 439a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 44020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar for (unsigned i = 0, e = Operands.size(); i != e; ++i) { 44120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Operand &Op = Operands[i]; 44220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar errs() << " op[" << i << "] = "; 443a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar if (Op.Class->Kind == ClassInfo::Token) { 44420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar errs() << '\"' << Tokens[i] << "\"\n"; 44520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar continue; 44620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 447a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 448fa1165abb8fec9383d640b0696a9f397b9153bafBenjamin Kramer const CodeGenInstruction::OperandInfo &OI = *Op.OperandInfo; 44920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar errs() << OI.Name << " " << OI.Rec->getName() 45020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar << " (" << OI.MIOperandNo << ", " << OI.MINumOperands << ")\n"; 45120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 45220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar} 453a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 454a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarstatic std::string getEnumNameForToken(const StringRef &Str) { 455a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::string Res; 456a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 457a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar for (StringRef::iterator it = Str.begin(), ie = Str.end(); it != ie; ++it) { 458a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar switch (*it) { 459a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar case '*': Res += "_STAR_"; break; 460a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar case '%': Res += "_PCT_"; break; 461a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar case ':': Res += "_COLON_"; break; 462a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 463a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar default: 464a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar if (isalnum(*it)) { 465a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Res += *it; 466a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } else { 467a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Res += "_" + utostr((unsigned) *it) + "_"; 468a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 469a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 470a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 47120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 472a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar return Res; 473a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar} 474a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 475a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel DunbarClassInfo *AsmMatcherInfo::getTokenClass(const StringRef &Token) { 476a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar ClassInfo *&Entry = TokenClasses[Token]; 477a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 478a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar if (!Entry) { 479a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Entry = new ClassInfo(); 480a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Entry->Kind = ClassInfo::Token; 481a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Entry->Name = "MCK_" + getEnumNameForToken(Token); 482a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Entry->ValueName = Token; 483a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Entry->PredicateMethod = "<invalid>"; 484a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Entry->RenderMethod = "<invalid>"; 485a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Classes.push_back(Entry); 486a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 487a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 488a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar return Entry; 489a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar} 490a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 491a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel DunbarClassInfo * 492a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel DunbarAsmMatcherInfo::getOperandClass(const StringRef &Token, 493a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar const CodeGenInstruction::OperandInfo &OI) { 494a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::string ClassName; 495a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar if (OI.Rec->isSubClassOf("RegisterClass")) { 496a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar ClassName = "Reg"; 497a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } else if (OI.Rec->isSubClassOf("Operand")) { 498a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // FIXME: This should not be hard coded. 499a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar const RecordVal *RV = OI.Rec->getValue("Type"); 500a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 501a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // FIXME: Yet another total hack. 502a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar if (RV->getValue()->getAsString() == "iPTR" || 503a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OI.Rec->getName() == "i8mem_NOREX" || 504a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OI.Rec->getName() == "lea32mem" || 505a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OI.Rec->getName() == "lea64mem" || 506a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OI.Rec->getName() == "i128mem" || 507a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OI.Rec->getName() == "sdmem" || 508a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OI.Rec->getName() == "ssmem" || 509a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OI.Rec->getName() == "lea64_32mem") { 510a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar ClassName = "Mem"; 511a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } else { 512a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar ClassName = "Imm"; 513a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 514a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 515a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 516a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar ClassInfo *&Entry = OperandClasses[ClassName]; 517a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 518a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar if (!Entry) { 519a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Entry = new ClassInfo(); 520a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // FIXME: Hack. 521a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar if (ClassName == "Reg") { 522a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Entry->Kind = ClassInfo::Register; 523a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } else { 524606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar if (ClassName == "Mem") 525606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar Entry->Kind = ClassInfo::UserClass0; 526606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar else 527606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar Entry->Kind = ClassInfo::UserClass0 + 1; 528a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 529a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Entry->Name = "MCK_" + ClassName; 530a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Entry->ValueName = OI.Rec->getName(); 531a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Entry->PredicateMethod = "is" + ClassName; 532a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Entry->RenderMethod = "add" + ClassName + "Operands"; 533a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Classes.push_back(Entry); 534a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 535a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 536a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar return Entry; 537a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar} 538a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 539a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarvoid AsmMatcherInfo::BuildInfo(CodeGenTarget &Target) { 540a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar for (std::map<std::string, CodeGenInstruction>::const_iterator 541a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar it = Target.getInstructions().begin(), 542a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar ie = Target.getInstructions().end(); 543a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar it != ie; ++it) { 544a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar const CodeGenInstruction &CGI = it->second; 545a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 546606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar if (!StringRef(it->first).startswith(MatchPrefix)) 54753a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar continue; 54853a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar 54920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar OwningPtr<InstructionInfo> II(new InstructionInfo); 55020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 55120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar II->InstrName = it->first; 55220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar II->Instr = &it->second; 55320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar II->AsmString = FlattenVariants(CGI.AsmString, 0); 55420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 55520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar TokenizeAsmString(II->AsmString, II->Tokens); 556a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 55720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // Ignore instructions which shouldn't be matched. 55820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (!IsAssemblerInstruction(it->first, CGI, II->Tokens)) 559a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar continue; 560a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 56120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar for (unsigned i = 0, e = II->Tokens.size(); i != e; ++i) { 56220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar StringRef Token = II->Tokens[i]; 56320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 56420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // Check for simple tokens. 56520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (Token[0] != '$') { 56620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar InstructionInfo::Operand Op; 567a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Op.Class = getTokenClass(Token); 568fa1165abb8fec9383d640b0696a9f397b9153bafBenjamin Kramer Op.OperandInfo = 0; 56920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar II->Operands.push_back(Op); 57020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar continue; 57120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 572a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 57320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // Otherwise this is an operand reference. 57420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar StringRef OperandName; 57520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (Token[1] == '{') 57620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar OperandName = Token.substr(2, Token.size() - 3); 57720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar else 57820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar OperandName = Token.substr(1); 57920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 58020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // Map this token to an operand. FIXME: Move elsewhere. 58120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar unsigned Idx; 58220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar try { 58320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Idx = CGI.getOperandNamed(OperandName); 58420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } catch(...) { 58520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar errs() << "error: unable to find operand: '" << OperandName << "'!\n"; 58620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar break; 58720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 588a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 58920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar const CodeGenInstruction::OperandInfo &OI = CGI.OperandList[Idx]; 590a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar InstructionInfo::Operand Op; 591a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Op.Class = getOperandClass(Token, OI); 592fa1165abb8fec9383d640b0696a9f397b9153bafBenjamin Kramer Op.OperandInfo = &OI; 59320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar II->Operands.push_back(Op); 59453a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar } 59553a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar 59620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // If we broke out, ignore the instruction. 59720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (II->Operands.size() != II->Tokens.size()) 59853a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar continue; 599a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 600a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Instructions.push_back(II.take()); 60120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 60220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar} 603a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 604606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbarstatic void EmitConvertToMCInst(CodeGenTarget &Target, 605606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar std::vector<InstructionInfo*> &Infos, 606606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar raw_ostream &OS) { 607b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar // Write the convert function to a separate stream, so we can drop it after 608b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar // the enum. 609b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar std::string ConvertFnBody; 610b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar raw_string_ostream CvtOS(ConvertFnBody); 611b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 61220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // Function we have already generated. 61320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar std::set<std::string> GeneratedFns; 61420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 615b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar // Start the unified conversion function. 616b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 617b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar CvtOS << "static bool ConvertToMCInst(ConversionKind Kind, MCInst &Inst, " 618b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar << "unsigned Opcode,\n" 619b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar << " SmallVectorImpl<" 620b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar << Target.getName() << "Operand> &Operands) {\n"; 621b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar CvtOS << " Inst.setOpcode(Opcode);\n"; 622b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar CvtOS << " switch (Kind) {\n"; 623b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar CvtOS << " default:\n"; 624b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 625b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar // Start the enum, which we will generate inline. 626b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 627b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar OS << "// Unified function for converting operants to MCInst instances.\n\n"; 628b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar OS << "enum ConversionKind {\n"; 629b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 63020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar for (std::vector<InstructionInfo*>::const_iterator it = Infos.begin(), 63120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar ie = Infos.end(); it != ie; ++it) { 63220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar InstructionInfo &II = **it; 63320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 63420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // Order the (class) operands by the order to convert them into an MCInst. 63520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar SmallVector<std::pair<unsigned, unsigned>, 4> MIOperandList; 63620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar for (unsigned i = 0, e = II.Operands.size(); i != e; ++i) { 63720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar InstructionInfo::Operand &Op = II.Operands[i]; 638fa1165abb8fec9383d640b0696a9f397b9153bafBenjamin Kramer if (Op.OperandInfo) 639fa1165abb8fec9383d640b0696a9f397b9153bafBenjamin Kramer MIOperandList.push_back(std::make_pair(Op.OperandInfo->MIOperandNo, i)); 64020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 64120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar std::sort(MIOperandList.begin(), MIOperandList.end()); 642a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 64320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // Compute the total number of operands. 644a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar unsigned NumMIOperands = 0; 64520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar for (unsigned i = 0, e = II.Instr->OperandList.size(); i != e; ++i) { 64620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar const CodeGenInstruction::OperandInfo &OI = II.Instr->OperandList[i]; 647a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar NumMIOperands = std::max(NumMIOperands, 648a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar OI.MIOperandNo + OI.MINumOperands); 649a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar } 650a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 65120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // Build the conversion function signature. 65220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar std::string Signature = "Convert"; 65320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar unsigned CurIndex = 0; 65420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar for (unsigned i = 0, e = MIOperandList.size(); i != e; ++i) { 65520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar InstructionInfo::Operand &Op = II.Operands[MIOperandList[i].second]; 656fa1165abb8fec9383d640b0696a9f397b9153bafBenjamin Kramer assert(CurIndex <= Op.OperandInfo->MIOperandNo && 65720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar "Duplicate match for instruction operand!"); 65820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 659b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar Signature += "_"; 660b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 66120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // Skip operands which weren't matched by anything, this occurs when the 66220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // .td file encodes "implicit" operands as explicit ones. 66320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // 66420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // FIXME: This should be removed from the MCInst structure. 665fa1165abb8fec9383d640b0696a9f397b9153bafBenjamin Kramer for (; CurIndex != Op.OperandInfo->MIOperandNo; ++CurIndex) 66620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Signature += "Imp"; 667a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 668a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Signature += Op.Class->Name; 669fa1165abb8fec9383d640b0696a9f397b9153bafBenjamin Kramer Signature += utostr(Op.OperandInfo->MINumOperands); 670b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar Signature += "_" + utostr(MIOperandList[i].second); 671b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 672fa1165abb8fec9383d640b0696a9f397b9153bafBenjamin Kramer CurIndex += Op.OperandInfo->MINumOperands; 67320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 674a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 67520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // Add any trailing implicit operands. 67620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar for (; CurIndex != NumMIOperands; ++CurIndex) 67720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Signature += "Imp"; 678a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 679b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar II.ConversionFnKind = Signature; 680a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 681b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar // Check if we have already generated this signature. 68220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (!GeneratedFns.insert(Signature).second) 68320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar continue; 684a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 68520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // If not, emit it now. 686b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 687b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar // Add to the enum list. 688b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar OS << " " << Signature << ",\n"; 689b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 690b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar // And to the convert function. 691b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar CvtOS << " case " << Signature << ":\n"; 69220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar CurIndex = 0; 69320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar for (unsigned i = 0, e = MIOperandList.size(); i != e; ++i) { 69420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar InstructionInfo::Operand &Op = II.Operands[MIOperandList[i].second]; 69520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 69620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // Add the implicit operands. 697fa1165abb8fec9383d640b0696a9f397b9153bafBenjamin Kramer for (; CurIndex != Op.OperandInfo->MIOperandNo; ++CurIndex) 698b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar CvtOS << " Inst.addOperand(MCOperand::CreateReg(0));\n"; 69920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 700b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar CvtOS << " Operands[" << MIOperandList[i].second 701a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar << "]." << Op.Class->RenderMethod 702fa1165abb8fec9383d640b0696a9f397b9153bafBenjamin Kramer << "(Inst, " << Op.OperandInfo->MINumOperands << ");\n"; 703fa1165abb8fec9383d640b0696a9f397b9153bafBenjamin Kramer CurIndex += Op.OperandInfo->MINumOperands; 704a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar } 70520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 70620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // And add trailing implicit operands. 70720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar for (; CurIndex != NumMIOperands; ++CurIndex) 708b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar CvtOS << " Inst.addOperand(MCOperand::CreateReg(0));\n"; 709b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar CvtOS << " break;\n"; 710a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar } 711b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 712b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar // Finish the convert function. 713b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 714b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar CvtOS << " }\n"; 715b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar CvtOS << " return false;\n"; 716b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar CvtOS << "}\n\n"; 717b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 718b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar // Finish the enum, and drop the convert function after it. 719b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 720b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar OS << " NumConversionVariants\n"; 721b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar OS << "};\n\n"; 722b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 723b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar OS << CvtOS.str(); 72420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar} 72520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 726a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar/// EmitMatchClassEnumeration - Emit the enumeration for match class kinds. 727a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarstatic void EmitMatchClassEnumeration(CodeGenTarget &Target, 728a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::vector<ClassInfo*> &Infos, 729a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar raw_ostream &OS) { 730a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "namespace {\n\n"; 731a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 732a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "/// MatchClassKind - The kinds of classes which participate in\n" 733a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar << "/// instruction matching.\n"; 734a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "enum MatchClassKind {\n"; 735a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " InvalidMatchClass = 0,\n"; 736a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar for (std::vector<ClassInfo*>::iterator it = Infos.begin(), 737a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar ie = Infos.end(); it != ie; ++it) { 738a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar ClassInfo &CI = **it; 739a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " " << CI.Name << ", // "; 740a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar if (CI.Kind == ClassInfo::Token) { 741a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "'" << CI.ValueName << "'\n"; 742a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } else if (CI.Kind == ClassInfo::Register) { 743a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar if (!CI.ValueName.empty()) 744a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "register class '" << CI.ValueName << "'\n"; 745a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar else 746a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "derived register class\n"; 747a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } else { 748a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "user defined class '" << CI.ValueName << "'\n"; 749a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 750a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 751a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " NumMatchClassKinds\n"; 752a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "};\n\n"; 753a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 754a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "}\n\n"; 755a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar} 756a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 757a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar/// EmitClassifyOperand - Emit the function to classify an operand. 758a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarstatic void EmitClassifyOperand(CodeGenTarget &Target, 759a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::vector<ClassInfo*> &Infos, 760a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar raw_ostream &OS) { 761a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "static MatchClassKind ClassifyOperand(" 762a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar << Target.getName() << "Operand &Operand) {\n"; 763a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " if (Operand.isToken())\n"; 764a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " return MatchTokenString(Operand.getToken());\n\n"; 765a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar for (std::vector<ClassInfo*>::iterator it = Infos.begin(), 766a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar ie = Infos.end(); it != ie; ++it) { 767a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar ClassInfo &CI = **it; 768a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 769a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar if (CI.Kind != ClassInfo::Token) { 770a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " if (Operand." << CI.PredicateMethod << "())\n"; 771a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " return " << CI.Name << ";\n\n"; 772a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 773a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 774a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " return InvalidMatchClass;\n"; 775a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "}\n\n"; 776a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar} 777a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 77870add884e4967f511e2cbb35c61534186b9b418aChris Lattnertypedef std::pair<std::string, std::string> StringPair; 77970add884e4967f511e2cbb35c61534186b9b418aChris Lattner 78070add884e4967f511e2cbb35c61534186b9b418aChris Lattner/// FindFirstNonCommonLetter - Find the first character in the keys of the 78170add884e4967f511e2cbb35c61534186b9b418aChris Lattner/// string pairs that is not shared across the whole set of strings. All 78270add884e4967f511e2cbb35c61534186b9b418aChris Lattner/// strings are assumed to have the same length. 78370add884e4967f511e2cbb35c61534186b9b418aChris Lattnerstatic unsigned 78470add884e4967f511e2cbb35c61534186b9b418aChris LattnerFindFirstNonCommonLetter(const std::vector<const StringPair*> &Matches) { 78570add884e4967f511e2cbb35c61534186b9b418aChris Lattner assert(!Matches.empty()); 78670add884e4967f511e2cbb35c61534186b9b418aChris Lattner for (unsigned i = 0, e = Matches[0]->first.size(); i != e; ++i) { 78770add884e4967f511e2cbb35c61534186b9b418aChris Lattner // Check to see if letter i is the same across the set. 78870add884e4967f511e2cbb35c61534186b9b418aChris Lattner char Letter = Matches[0]->first[i]; 78970add884e4967f511e2cbb35c61534186b9b418aChris Lattner 79070add884e4967f511e2cbb35c61534186b9b418aChris Lattner for (unsigned str = 0, e = Matches.size(); str != e; ++str) 79170add884e4967f511e2cbb35c61534186b9b418aChris Lattner if (Matches[str]->first[i] != Letter) 79270add884e4967f511e2cbb35c61534186b9b418aChris Lattner return i; 79370add884e4967f511e2cbb35c61534186b9b418aChris Lattner } 79470add884e4967f511e2cbb35c61534186b9b418aChris Lattner 79570add884e4967f511e2cbb35c61534186b9b418aChris Lattner return Matches[0]->first.size(); 79670add884e4967f511e2cbb35c61534186b9b418aChris Lattner} 79770add884e4967f511e2cbb35c61534186b9b418aChris Lattner 79870add884e4967f511e2cbb35c61534186b9b418aChris Lattner/// EmitStringMatcherForChar - Given a set of strings that are known to be the 79970add884e4967f511e2cbb35c61534186b9b418aChris Lattner/// same length and whose characters leading up to CharNo are the same, emit 80070add884e4967f511e2cbb35c61534186b9b418aChris Lattner/// code to verify that CharNo and later are the same. 80172ffae90ce9750b46b9a7cc84e5c11dae9274ebeDaniel Dunbar/// 80272ffae90ce9750b46b9a7cc84e5c11dae9274ebeDaniel Dunbar/// \return - True if control can leave the emitted code fragment. 80372ffae90ce9750b46b9a7cc84e5c11dae9274ebeDaniel Dunbarstatic bool EmitStringMatcherForChar(const std::string &StrVariableName, 80470add884e4967f511e2cbb35c61534186b9b418aChris Lattner const std::vector<const StringPair*> &Matches, 80570add884e4967f511e2cbb35c61534186b9b418aChris Lattner unsigned CharNo, unsigned IndentCount, 80670add884e4967f511e2cbb35c61534186b9b418aChris Lattner raw_ostream &OS) { 80770add884e4967f511e2cbb35c61534186b9b418aChris Lattner assert(!Matches.empty() && "Must have at least one string to match!"); 80870add884e4967f511e2cbb35c61534186b9b418aChris Lattner std::string Indent(IndentCount*2+4, ' '); 80970add884e4967f511e2cbb35c61534186b9b418aChris Lattner 81070add884e4967f511e2cbb35c61534186b9b418aChris Lattner // If we have verified that the entire string matches, we're done: output the 81170add884e4967f511e2cbb35c61534186b9b418aChris Lattner // matching code. 81270add884e4967f511e2cbb35c61534186b9b418aChris Lattner if (CharNo == Matches[0]->first.size()) { 81370add884e4967f511e2cbb35c61534186b9b418aChris Lattner assert(Matches.size() == 1 && "Had duplicate keys to match on"); 81470add884e4967f511e2cbb35c61534186b9b418aChris Lattner 81570add884e4967f511e2cbb35c61534186b9b418aChris Lattner // FIXME: If Matches[0].first has embeded \n, this will be bad. 81670add884e4967f511e2cbb35c61534186b9b418aChris Lattner OS << Indent << Matches[0]->second << "\t // \"" << Matches[0]->first 81770add884e4967f511e2cbb35c61534186b9b418aChris Lattner << "\"\n"; 81872ffae90ce9750b46b9a7cc84e5c11dae9274ebeDaniel Dunbar return false; 81970add884e4967f511e2cbb35c61534186b9b418aChris Lattner } 82070add884e4967f511e2cbb35c61534186b9b418aChris Lattner 82170add884e4967f511e2cbb35c61534186b9b418aChris Lattner // Bucket the matches by the character we are comparing. 82270add884e4967f511e2cbb35c61534186b9b418aChris Lattner std::map<char, std::vector<const StringPair*> > MatchesByLetter; 82370add884e4967f511e2cbb35c61534186b9b418aChris Lattner 82470add884e4967f511e2cbb35c61534186b9b418aChris Lattner for (unsigned i = 0, e = Matches.size(); i != e; ++i) 82570add884e4967f511e2cbb35c61534186b9b418aChris Lattner MatchesByLetter[Matches[i]->first[CharNo]].push_back(Matches[i]); 82670add884e4967f511e2cbb35c61534186b9b418aChris Lattner 82770add884e4967f511e2cbb35c61534186b9b418aChris Lattner 82870add884e4967f511e2cbb35c61534186b9b418aChris Lattner // If we have exactly one bucket to match, see how many characters are common 82970add884e4967f511e2cbb35c61534186b9b418aChris Lattner // across the whole set and match all of them at once. 83070add884e4967f511e2cbb35c61534186b9b418aChris Lattner if (MatchesByLetter.size() == 1) { 83170add884e4967f511e2cbb35c61534186b9b418aChris Lattner unsigned FirstNonCommonLetter = FindFirstNonCommonLetter(Matches); 83270add884e4967f511e2cbb35c61534186b9b418aChris Lattner unsigned NumChars = FirstNonCommonLetter-CharNo; 83370add884e4967f511e2cbb35c61534186b9b418aChris Lattner 83472ffae90ce9750b46b9a7cc84e5c11dae9274ebeDaniel Dunbar // Emit code to break out if the prefix doesn't match. 83570add884e4967f511e2cbb35c61534186b9b418aChris Lattner if (NumChars == 1) { 83672ffae90ce9750b46b9a7cc84e5c11dae9274ebeDaniel Dunbar // Do the comparison with if (Str[1] != 'f') 83770add884e4967f511e2cbb35c61534186b9b418aChris Lattner // FIXME: Need to escape general characters. 83872ffae90ce9750b46b9a7cc84e5c11dae9274ebeDaniel Dunbar OS << Indent << "if (" << StrVariableName << "[" << CharNo << "] != '" 83972ffae90ce9750b46b9a7cc84e5c11dae9274ebeDaniel Dunbar << Matches[0]->first[CharNo] << "')\n"; 84072ffae90ce9750b46b9a7cc84e5c11dae9274ebeDaniel Dunbar OS << Indent << " break;\n"; 84170add884e4967f511e2cbb35c61534186b9b418aChris Lattner } else { 84272ffae90ce9750b46b9a7cc84e5c11dae9274ebeDaniel Dunbar // Do the comparison with if (Str.substr(1,3) != "foo"). 84370add884e4967f511e2cbb35c61534186b9b418aChris Lattner // FIXME: Need to escape general strings. 84472ffae90ce9750b46b9a7cc84e5c11dae9274ebeDaniel Dunbar OS << Indent << "if (" << StrVariableName << ".substr(" << CharNo << "," 84572ffae90ce9750b46b9a7cc84e5c11dae9274ebeDaniel Dunbar << NumChars << ") != \""; 84672ffae90ce9750b46b9a7cc84e5c11dae9274ebeDaniel Dunbar OS << Matches[0]->first.substr(CharNo, NumChars) << "\")\n"; 847af3e9d43a2d8ba3cf5f65f54bd928846bec3ab67Daniel Dunbar OS << Indent << " break;\n"; 84870add884e4967f511e2cbb35c61534186b9b418aChris Lattner } 84970add884e4967f511e2cbb35c61534186b9b418aChris Lattner 85072ffae90ce9750b46b9a7cc84e5c11dae9274ebeDaniel Dunbar return EmitStringMatcherForChar(StrVariableName, Matches, 85172ffae90ce9750b46b9a7cc84e5c11dae9274ebeDaniel Dunbar FirstNonCommonLetter, IndentCount, OS); 85270add884e4967f511e2cbb35c61534186b9b418aChris Lattner } 85370add884e4967f511e2cbb35c61534186b9b418aChris Lattner 85470add884e4967f511e2cbb35c61534186b9b418aChris Lattner // Otherwise, we have multiple possible things, emit a switch on the 85570add884e4967f511e2cbb35c61534186b9b418aChris Lattner // character. 85670add884e4967f511e2cbb35c61534186b9b418aChris Lattner OS << Indent << "switch (" << StrVariableName << "[" << CharNo << "]) {\n"; 85770add884e4967f511e2cbb35c61534186b9b418aChris Lattner OS << Indent << "default: break;\n"; 85870add884e4967f511e2cbb35c61534186b9b418aChris Lattner 85970add884e4967f511e2cbb35c61534186b9b418aChris Lattner for (std::map<char, std::vector<const StringPair*> >::iterator LI = 86070add884e4967f511e2cbb35c61534186b9b418aChris Lattner MatchesByLetter.begin(), E = MatchesByLetter.end(); LI != E; ++LI) { 86170add884e4967f511e2cbb35c61534186b9b418aChris Lattner // TODO: escape hard stuff (like \n) if we ever care about it. 86270add884e4967f511e2cbb35c61534186b9b418aChris Lattner OS << Indent << "case '" << LI->first << "':\t // " 86370add884e4967f511e2cbb35c61534186b9b418aChris Lattner << LI->second.size() << " strings to match.\n"; 86472ffae90ce9750b46b9a7cc84e5c11dae9274ebeDaniel Dunbar if (EmitStringMatcherForChar(StrVariableName, LI->second, CharNo+1, 86572ffae90ce9750b46b9a7cc84e5c11dae9274ebeDaniel Dunbar IndentCount+1, OS)) 86672ffae90ce9750b46b9a7cc84e5c11dae9274ebeDaniel Dunbar OS << Indent << " break;\n"; 86770add884e4967f511e2cbb35c61534186b9b418aChris Lattner } 86870add884e4967f511e2cbb35c61534186b9b418aChris Lattner 86970add884e4967f511e2cbb35c61534186b9b418aChris Lattner OS << Indent << "}\n"; 87072ffae90ce9750b46b9a7cc84e5c11dae9274ebeDaniel Dunbar return true; 87170add884e4967f511e2cbb35c61534186b9b418aChris Lattner} 87270add884e4967f511e2cbb35c61534186b9b418aChris Lattner 87370add884e4967f511e2cbb35c61534186b9b418aChris Lattner 87470add884e4967f511e2cbb35c61534186b9b418aChris Lattner/// EmitStringMatcher - Given a list of strings and code to execute when they 87572ffae90ce9750b46b9a7cc84e5c11dae9274ebeDaniel Dunbar/// match, output a simple switch tree to classify the input string. 87672ffae90ce9750b46b9a7cc84e5c11dae9274ebeDaniel Dunbar/// 87772ffae90ce9750b46b9a7cc84e5c11dae9274ebeDaniel Dunbar/// If a match is found, the code in Vals[i].second is executed; control must 87872ffae90ce9750b46b9a7cc84e5c11dae9274ebeDaniel Dunbar/// not exit this code fragment. If nothing matches, execution falls through. 87972ffae90ce9750b46b9a7cc84e5c11dae9274ebeDaniel Dunbar/// 88072ffae90ce9750b46b9a7cc84e5c11dae9274ebeDaniel Dunbar/// \param StrVariableName - The name of the variable to test. 88170add884e4967f511e2cbb35c61534186b9b418aChris Lattnerstatic void EmitStringMatcher(const std::string &StrVariableName, 88270add884e4967f511e2cbb35c61534186b9b418aChris Lattner const std::vector<StringPair> &Matches, 88370add884e4967f511e2cbb35c61534186b9b418aChris Lattner raw_ostream &OS) { 88470add884e4967f511e2cbb35c61534186b9b418aChris Lattner // First level categorization: group strings by length. 88570add884e4967f511e2cbb35c61534186b9b418aChris Lattner std::map<unsigned, std::vector<const StringPair*> > MatchesByLength; 88670add884e4967f511e2cbb35c61534186b9b418aChris Lattner 88770add884e4967f511e2cbb35c61534186b9b418aChris Lattner for (unsigned i = 0, e = Matches.size(); i != e; ++i) 88870add884e4967f511e2cbb35c61534186b9b418aChris Lattner MatchesByLength[Matches[i].first.size()].push_back(&Matches[i]); 88970add884e4967f511e2cbb35c61534186b9b418aChris Lattner 89070add884e4967f511e2cbb35c61534186b9b418aChris Lattner // Output a switch statement on length and categorize the elements within each 89170add884e4967f511e2cbb35c61534186b9b418aChris Lattner // bin. 89270add884e4967f511e2cbb35c61534186b9b418aChris Lattner OS << " switch (" << StrVariableName << ".size()) {\n"; 89370add884e4967f511e2cbb35c61534186b9b418aChris Lattner OS << " default: break;\n"; 89470add884e4967f511e2cbb35c61534186b9b418aChris Lattner 89570add884e4967f511e2cbb35c61534186b9b418aChris Lattner for (std::map<unsigned, std::vector<const StringPair*> >::iterator LI = 89670add884e4967f511e2cbb35c61534186b9b418aChris Lattner MatchesByLength.begin(), E = MatchesByLength.end(); LI != E; ++LI) { 89770add884e4967f511e2cbb35c61534186b9b418aChris Lattner OS << " case " << LI->first << ":\t // " << LI->second.size() 89870add884e4967f511e2cbb35c61534186b9b418aChris Lattner << " strings to match.\n"; 89972ffae90ce9750b46b9a7cc84e5c11dae9274ebeDaniel Dunbar if (EmitStringMatcherForChar(StrVariableName, LI->second, 0, 0, OS)) 90072ffae90ce9750b46b9a7cc84e5c11dae9274ebeDaniel Dunbar OS << " break;\n"; 90170add884e4967f511e2cbb35c61534186b9b418aChris Lattner } 90270add884e4967f511e2cbb35c61534186b9b418aChris Lattner 90370add884e4967f511e2cbb35c61534186b9b418aChris Lattner OS << " }\n"; 90470add884e4967f511e2cbb35c61534186b9b418aChris Lattner} 90570add884e4967f511e2cbb35c61534186b9b418aChris Lattner 90670add884e4967f511e2cbb35c61534186b9b418aChris Lattner 907245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar/// EmitMatchTokenString - Emit the function to match a token string to the 908245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar/// appropriate match class value. 909245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbarstatic void EmitMatchTokenString(CodeGenTarget &Target, 910245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar std::vector<ClassInfo*> &Infos, 911245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar raw_ostream &OS) { 912245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar // Construct the match list. 913245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar std::vector<StringPair> Matches; 914245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar for (std::vector<ClassInfo*>::iterator it = Infos.begin(), 915245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar ie = Infos.end(); it != ie; ++it) { 916245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar ClassInfo &CI = **it; 917245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar 918245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar if (CI.Kind == ClassInfo::Token) 919245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar Matches.push_back(StringPair(CI.ValueName, "return " + CI.Name + ";")); 920245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar } 921245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar 922245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar OS << "static MatchClassKind MatchTokenString(const StringRef &Name) {\n"; 923245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar 924245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar EmitStringMatcher("Name", Matches, OS); 925245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar 926245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar OS << " return InvalidMatchClass;\n"; 927245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar OS << "}\n\n"; 928245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar} 92970add884e4967f511e2cbb35c61534186b9b418aChris Lattner 9302234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar/// EmitMatchRegisterName - Emit the function to match a string to the target 9312234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar/// specific register enum. 9322234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbarstatic void EmitMatchRegisterName(CodeGenTarget &Target, Record *AsmParser, 9332234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar raw_ostream &OS) { 934245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar // Construct the match list. 93570add884e4967f511e2cbb35c61534186b9b418aChris Lattner std::vector<StringPair> Matches; 936245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar for (unsigned i = 0, e = Target.getRegisters().size(); i != e; ++i) { 937245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar const CodeGenRegister &Reg = Target.getRegisters()[i]; 93820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (Reg.TheDef->getValueAsString("AsmName").empty()) 93920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar continue; 94020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 94170add884e4967f511e2cbb35c61534186b9b418aChris Lattner Matches.push_back(StringPair(Reg.TheDef->getValueAsString("AsmName"), 942245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar "return " + utostr(i + 1) + ";")); 94320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 94470add884e4967f511e2cbb35c61534186b9b418aChris Lattner 945245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar OS << "unsigned " << Target.getName() 946245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar << AsmParser->getValueAsString("AsmParserClassName") 947245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar << "::MatchRegisterName(const StringRef &Name) {\n"; 948245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar 94970add884e4967f511e2cbb35c61534186b9b418aChris Lattner EmitStringMatcher("Name", Matches, OS); 95070add884e4967f511e2cbb35c61534186b9b418aChris Lattner 951245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar OS << " return 0;\n"; 95220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar OS << "}\n\n"; 9532234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar} 9542234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar 9552234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbarvoid AsmMatcherEmitter::run(raw_ostream &OS) { 9562234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar CodeGenTarget Target; 9572234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar Record *AsmParser = Target.getAsmParser(); 9582234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar std::string ClassName = AsmParser->getValueAsString("AsmParserClassName"); 9592234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar 9602234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar EmitSourceFileHeader("Assembly Matcher Source Fragment", OS); 9612234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar 9622234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar // Emit the function to match a register name to number. 9632234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar EmitMatchRegisterName(Target, AsmParser, OS); 96420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 965a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // Compute the information on the instructions to match. 966a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar AsmMatcherInfo Info; 967a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Info.BuildInfo(Target); 96820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 969606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar // Sort the instruction table using the partial order on classes. 970606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar std::sort(Info.Instructions.begin(), Info.Instructions.end(), 971606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar less_ptr<InstructionInfo>()); 972606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 973b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar DEBUG_WITH_TYPE("instruction_info", { 974a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar for (std::vector<InstructionInfo*>::iterator 975a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar it = Info.Instructions.begin(), ie = Info.Instructions.end(); 976a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar it != ie; ++it) 97720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar (*it)->dump(); 97820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar }); 97920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 980606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar // Check for ambiguous instructions. 981606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar unsigned NumAmbiguous = 0; 982606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar for (std::vector<InstructionInfo*>::const_iterator it = 983606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar Info.Instructions.begin(), ie = Info.Instructions.end() - 1; 984606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar it != ie;) { 985606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar InstructionInfo &II = **it; 986606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar ++it; 98720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 988606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar InstructionInfo &Next = **it; 989606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 990606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar if (!(II < Next)){ 991606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar DEBUG_WITH_TYPE("ambiguous_instrs", { 992606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar errs() << "warning: ambiguous instruction match:\n"; 993606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar II.dump(); 994606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar errs() << "\nis incomparable with:\n"; 995606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar Next.dump(); 996606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar errs() << "\n\n"; 997606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar }); 998606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar ++NumAmbiguous; 999606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar } 1000606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar } 1001606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar if (NumAmbiguous) 1002606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar DEBUG_WITH_TYPE("ambiguous_instrs", { 1003606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar errs() << "warning: " << NumAmbiguous 1004606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar << " ambiguous instructions!\n"; 1005606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar }); 1006606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 1007606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar // Generate the unified function to convert operands into an MCInst. 1008606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar EmitConvertToMCInst(Target, Info.Instructions, OS); 1009a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1010a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // Emit the enumeration for classes which participate in matching. 1011a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar EmitMatchClassEnumeration(Target, Info.Classes, OS); 101220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 1013a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // Emit the routine to match token strings to their match class. 1014a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar EmitMatchTokenString(Target, Info.Classes, OS); 101520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 1016a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // Emit the routine to classify an operand. 1017a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar EmitClassifyOperand(Target, Info.Classes, OS); 1018a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1019a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // Finally, build the match function. 1020a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1021a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar size_t MaxNumOperands = 0; 1022a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar for (std::vector<InstructionInfo*>::const_iterator it = 1023a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Info.Instructions.begin(), ie = Info.Instructions.end(); 1024a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar it != ie; ++it) 1025a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar MaxNumOperands = std::max(MaxNumOperands, (*it)->Operands.size()); 1026a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 102720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar OS << "bool " << Target.getName() << ClassName 102820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar << "::MatchInstruction(" 1029a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar << "SmallVectorImpl<" << Target.getName() << "Operand> &Operands, " 1030a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar << "MCInst &Inst) {\n"; 103120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 1032a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // Emit the static match table; unused classes get initalized to 0 which is 1033a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // guaranteed to be InvalidMatchClass. 1034a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // 1035a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // FIXME: We can reduce the size of this table very easily. First, we change 1036a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // it so that store the kinds in separate bit-fields for each index, which 1037a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // only needs to be the max width used for classes at that index (we also need 1038a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // to reject based on this during classification). If we then make sure to 1039a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // order the match kinds appropriately (putting mnemonics last), then we 1040a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // should only end up using a few bits for each class, especially the ones 1041a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // following the mnemonic. 1042c6049534605af5f13d1b5149488b0a9efd294582Chris Lattner OS << " static const struct MatchEntry {\n"; 1043a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " unsigned Opcode;\n"; 1044a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " ConversionKind ConvertFn;\n"; 1045a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " MatchClassKind Classes[" << MaxNumOperands << "];\n"; 1046a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " } MatchTable[" << Info.Instructions.size() << "] = {\n"; 1047a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1048a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar for (std::vector<InstructionInfo*>::const_iterator it = 1049a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Info.Instructions.begin(), ie = Info.Instructions.end(); 1050a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar it != ie; ++it) { 105120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar InstructionInfo &II = **it; 105220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 1053a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " { " << Target.getName() << "::" << II.InstrName 1054a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar << ", " << II.ConversionFnKind << ", { "; 105520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar for (unsigned i = 0, e = II.Operands.size(); i != e; ++i) { 105620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar InstructionInfo::Operand &Op = II.Operands[i]; 105720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 1058a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar if (i) OS << ", "; 1059a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << Op.Class->Name; 106020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 1061a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " } },\n"; 1062a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 1063a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1064a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " };\n\n"; 1065a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1066a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // Emit code to compute the class list for this operand vector. 1067a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " // Eliminate obvious mismatches.\n"; 1068a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " if (Operands.size() > " << MaxNumOperands << ")\n"; 1069a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " return true;\n\n"; 1070a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1071a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " // Compute the class list for this operand vector.\n"; 1072a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " MatchClassKind Classes[" << MaxNumOperands << "];\n"; 1073a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " for (unsigned i = 0, e = Operands.size(); i != e; ++i) {\n"; 1074a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " Classes[i] = ClassifyOperand(Operands[i]);\n\n"; 1075a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1076a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " // Check for invalid operands before matching.\n"; 1077a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " if (Classes[i] == InvalidMatchClass)\n"; 1078a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " return true;\n"; 1079a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " }\n\n"; 1080a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1081a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " // Mark unused classes.\n"; 1082a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " for (unsigned i = Operands.size(), e = " << MaxNumOperands << "; " 1083a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar << "i != e; ++i)\n"; 1084a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " Classes[i] = InvalidMatchClass;\n\n"; 1085a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1086a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // Emit code to search the table. 1087a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " // Search the table.\n"; 1088d39bd3aa5c795e55c0e2c4a5c72dab58ce1a1576Chris Lattner OS << " for (const MatchEntry *it = MatchTable, " 1089a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar << "*ie = MatchTable + " << Info.Instructions.size() 1090a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar << "; it != ie; ++it) {\n"; 1091a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar for (unsigned i = 0; i != MaxNumOperands; ++i) { 1092a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " if (Classes[" << i << "] != it->Classes[" << i << "])\n"; 1093a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " continue;\n"; 1094a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar } 1095a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "\n"; 1096a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " return ConvertToMCInst(it->ConvertFn, Inst, " 1097a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar << "it->Opcode, Operands);\n"; 1098a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " }\n\n"; 1099a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 1100a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar OS << " return true;\n"; 1101a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar OS << "}\n\n"; 1102d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar} 1103