AsmMatcherEmitter.cpp revision ec6789f4f97ca1701c163132b6e3388366463090
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" 795845e5c62b42d025557765006515156691a6a8b1Chris Lattner#include "StringMatcher.h" 8020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar#include "llvm/ADT/OwningPtr.h" 81a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar#include "llvm/ADT/SmallVector.h" 82606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar#include "llvm/ADT/STLExtras.h" 8320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar#include "llvm/ADT/StringExtras.h" 8420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar#include "llvm/Support/CommandLine.h" 85a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar#include "llvm/Support/Debug.h" 86a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar#include <list> 87b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar#include <map> 88b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar#include <set> 89d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbarusing namespace llvm; 90d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar 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 95a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar/// FlattenVariants - Flatten an .td file assembly string by selecting the 96a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar/// variant at index \arg N. 97a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbarstatic std::string FlattenVariants(const std::string &AsmString, 98a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar unsigned N) { 99a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar StringRef Cur = AsmString; 100a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar std::string Res = ""; 101a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 102a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar for (;;) { 10353a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar // Find the start of the next variant string. 10453a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar size_t VariantsStart = 0; 10553a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar for (size_t e = Cur.size(); VariantsStart != e; ++VariantsStart) 10653a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar if (Cur[VariantsStart] == '{' && 10720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar (VariantsStart == 0 || (Cur[VariantsStart-1] != '$' && 10820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Cur[VariantsStart-1] != '\\'))) 10953a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar break; 11053a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar 11153a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar // Add the prefix to the result. 11253a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar Res += Cur.slice(0, VariantsStart); 11353a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar if (VariantsStart == Cur.size()) 114a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar break; 115a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 11653a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar ++VariantsStart; // Skip the '{'. 11753a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar 11853a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar // Scan to the end of the variants string. 11953a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar size_t VariantsEnd = VariantsStart; 12053a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar unsigned NestedBraces = 1; 12153a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar for (size_t e = Cur.size(); VariantsEnd != e; ++VariantsEnd) { 12220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (Cur[VariantsEnd] == '}' && Cur[VariantsEnd-1] != '\\') { 12353a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar if (--NestedBraces == 0) 12453a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar break; 12553a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar } else if (Cur[VariantsEnd] == '{') 12653a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar ++NestedBraces; 12753a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar } 128a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 129a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar // Select the Nth variant (or empty). 13053a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar StringRef Selection = Cur.slice(VariantsStart, VariantsEnd); 131a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar for (unsigned i = 0; i != N; ++i) 132a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar Selection = Selection.split('|').second; 133a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar Res += Selection.split('|').first; 134a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 13553a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar assert(VariantsEnd != Cur.size() && 13653a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar "Unterminated variants in assembly string!"); 13753a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar Cur = Cur.substr(VariantsEnd + 1); 138a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar } 139a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 140a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar return Res; 141a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar} 142a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 143a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar/// TokenizeAsmString - Tokenize a simplified assembly string. 144b8d6e98e566724f58344d275a4bd675249bb713aChris Lattnerstatic void TokenizeAsmString(StringRef AsmString, 145a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar SmallVectorImpl<StringRef> &Tokens) { 146a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar unsigned Prev = 0; 147a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar bool InTok = true; 148a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar for (unsigned i = 0, e = AsmString.size(); i != e; ++i) { 149a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar switch (AsmString[i]) { 15020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar case '[': 15120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar case ']': 152a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar case '*': 153a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar case '!': 154a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar case ' ': 155a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar case '\t': 156a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar case ',': 157a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar if (InTok) { 15820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Tokens.push_back(AsmString.slice(Prev, i)); 159a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar InTok = false; 160a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar } 16120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (!isspace(AsmString[i]) && AsmString[i] != ',') 16220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Tokens.push_back(AsmString.substr(i, 1)); 163a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar Prev = i + 1; 164a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar break; 16520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 16620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar case '\\': 16720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (InTok) { 16820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Tokens.push_back(AsmString.slice(Prev, i)); 16920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar InTok = false; 17020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 17120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar ++i; 17220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar assert(i != AsmString.size() && "Invalid quoted character"); 17320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Tokens.push_back(AsmString.substr(i, 1)); 17420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Prev = i + 1; 17520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar break; 17620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 17720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar case '$': { 17820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // If this isn't "${", treat like a normal token. 17920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (i + 1 == AsmString.size() || AsmString[i + 1] != '{') { 18020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (InTok) { 18120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Tokens.push_back(AsmString.slice(Prev, i)); 18220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar InTok = false; 18320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 18420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Prev = i; 18520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar break; 18620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 18720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 18820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (InTok) { 18920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Tokens.push_back(AsmString.slice(Prev, i)); 19020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar InTok = false; 19120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 19220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 19320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar StringRef::iterator End = 19420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar std::find(AsmString.begin() + i, AsmString.end(), '}'); 19520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar assert(End != AsmString.end() && "Missing brace in operand reference!"); 19620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar size_t EndPos = End - AsmString.begin(); 19720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Tokens.push_back(AsmString.slice(i, EndPos+1)); 19820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Prev = EndPos + 1; 19920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar i = EndPos; 20020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar break; 20120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 202a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 2034d39b6728dcdcf131bc0739f4ee0f90c836bf94fDaniel Dunbar case '.': 2044d39b6728dcdcf131bc0739f4ee0f90c836bf94fDaniel Dunbar if (InTok) { 2054d39b6728dcdcf131bc0739f4ee0f90c836bf94fDaniel Dunbar Tokens.push_back(AsmString.slice(Prev, i)); 2064d39b6728dcdcf131bc0739f4ee0f90c836bf94fDaniel Dunbar } 2074d39b6728dcdcf131bc0739f4ee0f90c836bf94fDaniel Dunbar Prev = i; 2084d39b6728dcdcf131bc0739f4ee0f90c836bf94fDaniel Dunbar InTok = true; 2094d39b6728dcdcf131bc0739f4ee0f90c836bf94fDaniel Dunbar break; 2104d39b6728dcdcf131bc0739f4ee0f90c836bf94fDaniel Dunbar 211a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar default: 212a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar InTok = true; 213a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar } 214a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar } 215a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar if (InTok && Prev != AsmString.size()) 21620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Tokens.push_back(AsmString.substr(Prev)); 217a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar} 218a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 219b8d6e98e566724f58344d275a4bd675249bb713aChris Lattnerstatic bool IsAssemblerInstruction(StringRef Name, 22020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar const CodeGenInstruction &CGI, 22120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar const SmallVectorImpl<StringRef> &Tokens) { 2227417b761c2d88335bd77d38911ff8d323fc4a4f2Daniel Dunbar // Ignore "codegen only" instructions. 2237417b761c2d88335bd77d38911ff8d323fc4a4f2Daniel Dunbar if (CGI.TheDef->getValueAsBit("isCodeGenOnly")) 2247417b761c2d88335bd77d38911ff8d323fc4a4f2Daniel Dunbar return false; 2257417b761c2d88335bd77d38911ff8d323fc4a4f2Daniel Dunbar 2267417b761c2d88335bd77d38911ff8d323fc4a4f2Daniel Dunbar // Ignore pseudo ops. 22720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // 2287417b761c2d88335bd77d38911ff8d323fc4a4f2Daniel Dunbar // FIXME: This is a hack; can we convert these instructions to set the 2297417b761c2d88335bd77d38911ff8d323fc4a4f2Daniel Dunbar // "codegen only" bit instead? 23020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (const RecordVal *Form = CGI.TheDef->getValue("Form")) 23120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (Form->getValue()->getAsString() == "Pseudo") 23220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar return false; 23320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 23472fa87f0cfe22faa575280dbac8dbc9225dfb12dDaniel Dunbar // Ignore "Int_*" and "*_Int" instructions, which are internal aliases. 23572fa87f0cfe22faa575280dbac8dbc9225dfb12dDaniel Dunbar // 23672fa87f0cfe22faa575280dbac8dbc9225dfb12dDaniel Dunbar // FIXME: This is a total hack. 23772fa87f0cfe22faa575280dbac8dbc9225dfb12dDaniel Dunbar if (StringRef(Name).startswith("Int_") || StringRef(Name).endswith("_Int")) 23872fa87f0cfe22faa575280dbac8dbc9225dfb12dDaniel Dunbar return false; 23972fa87f0cfe22faa575280dbac8dbc9225dfb12dDaniel Dunbar 24020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // Ignore instructions with no .s string. 24120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // 24220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // FIXME: What are these? 24320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (CGI.AsmString.empty()) 24420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar return false; 24520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 24620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // FIXME: Hack; ignore any instructions with a newline in them. 24720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (std::find(CGI.AsmString.begin(), 24820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar CGI.AsmString.end(), '\n') != CGI.AsmString.end()) 24920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar return false; 25020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 25120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // Ignore instructions with attributes, these are always fake instructions for 25220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // simplifying codegen. 25320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // 25420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // FIXME: Is this true? 25520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // 2567417b761c2d88335bd77d38911ff8d323fc4a4f2Daniel Dunbar // Also, check for instructions which reference the operand multiple times; 2577417b761c2d88335bd77d38911ff8d323fc4a4f2Daniel Dunbar // this implies a constraint we would not honor. 25820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar std::set<std::string> OperandNames; 25920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar for (unsigned i = 1, e = Tokens.size(); i < e; ++i) { 26020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (Tokens[i][0] == '$' && 26120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar std::find(Tokens[i].begin(), 26220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Tokens[i].end(), ':') != Tokens[i].end()) { 26320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar DEBUG({ 26420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar errs() << "warning: '" << Name << "': " 26520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar << "ignoring instruction; operand with attribute '" 2667417b761c2d88335bd77d38911ff8d323fc4a4f2Daniel Dunbar << Tokens[i] << "'\n"; 26720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar }); 26820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar return false; 26920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 27022be5225ff88ffaab83c36fa133e70586b91166dDaniel Dunbar 27120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (Tokens[i][0] == '$' && !OperandNames.insert(Tokens[i]).second) { 272a9ba5fe2bde747fadcb57c5304bc4700fc155704Daniel Dunbar DEBUG({ 273a9ba5fe2bde747fadcb57c5304bc4700fc155704Daniel Dunbar errs() << "warning: '" << Name << "': " 274a9ba5fe2bde747fadcb57c5304bc4700fc155704Daniel Dunbar << "ignoring instruction with tied operand '" 275a9ba5fe2bde747fadcb57c5304bc4700fc155704Daniel Dunbar << Tokens[i].str() << "'\n"; 276a9ba5fe2bde747fadcb57c5304bc4700fc155704Daniel Dunbar }); 277a9ba5fe2bde747fadcb57c5304bc4700fc155704Daniel Dunbar return false; 27820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 27920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 28022be5225ff88ffaab83c36fa133e70586b91166dDaniel Dunbar 28120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar return true; 28220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar} 28322be5225ff88ffaab83c36fa133e70586b91166dDaniel Dunbar 28420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbarnamespace { 28522be5225ff88ffaab83c36fa133e70586b91166dDaniel Dunbar 28654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbarstruct SubtargetFeatureInfo; 28754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 288a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar/// ClassInfo - Helper class for storing the information about a particular 289a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar/// class of operands which can be matched. 290a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarstruct ClassInfo { 291606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar enum ClassInfoKind { 292ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// Invalid kind, for use as a sentinel value. 293ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar Invalid = 0, 294ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 295ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// The class for a particular token. 296ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar Token, 297ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 298ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// The (first) register class, subsequent register classes are 299ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// RegisterClass0+1, and so on. 300ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar RegisterClass0, 301ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 302ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// The (first) user defined class, subsequent user defined classes are 303ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// UserClass0+1, and so on. 304ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar UserClass0 = 1<<16 305606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar }; 306606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 307606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar /// Kind - The class kind, which is either a predefined kind, or (UserClass0 + 308606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar /// N) for the Nth user defined class. 309606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar unsigned Kind; 310a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 311ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// SuperClasses - The super classes of this class. Note that for simplicities 312ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// sake user operands only record their immediate super class, while register 313ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// operands include all superclasses. 314ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar std::vector<ClassInfo*> SuperClasses; 3155fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar 3166745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar /// Name - The full class name, suitable for use in an enum. 317a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::string Name; 318a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 3196745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar /// ClassName - The unadorned generic name for this class (e.g., Token). 3206745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar std::string ClassName; 3216745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar 322a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// ValueName - The name of the value this class represents; for a token this 323a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// is the literal token string, for an operand it is the TableGen class (or 324a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// empty if this is a derived class). 325a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::string ValueName; 326a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 327a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// PredicateMethod - The name of the operand method to test whether the 328ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// operand matches this class; this is not valid for Token or register kinds. 329a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::string PredicateMethod; 330a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 331a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// RenderMethod - The name of the operand method to add this operand to an 332ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// MCInst; this is not valid for Token or register kinds. 333a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::string RenderMethod; 334606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 3358409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar /// For register classes, the records for all the registers in this class. 3368409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar std::set<Record*> Registers; 3378409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar 3388409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbarpublic: 339ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// isRegisterClass() - Check if this is a register class. 340ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar bool isRegisterClass() const { 341ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar return Kind >= RegisterClass0 && Kind < UserClass0; 342ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 343ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 3445fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar /// isUserClass() - Check if this is a user defined class. 3455fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar bool isUserClass() const { 3465fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar return Kind >= UserClass0; 3475fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar } 3485fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar 349ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// isRelatedTo - Check whether this class is "related" to \arg RHS. Classes 350ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// are related if they are in the same class hierarchy. 351ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar bool isRelatedTo(const ClassInfo &RHS) const { 352ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Tokens are only related to tokens. 353ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (Kind == Token || RHS.Kind == Token) 354ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar return Kind == Token && RHS.Kind == Token; 355ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 3568409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar // Registers classes are only related to registers classes, and only if 3578409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar // their intersection is non-empty. 3588409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar if (isRegisterClass() || RHS.isRegisterClass()) { 3598409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar if (!isRegisterClass() || !RHS.isRegisterClass()) 3608409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar return false; 3618409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar 3628409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar std::set<Record*> Tmp; 3638409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar std::insert_iterator< std::set<Record*> > II(Tmp, Tmp.begin()); 3648409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar std::set_intersection(Registers.begin(), Registers.end(), 3658409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar RHS.Registers.begin(), RHS.Registers.end(), 3668409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar II); 3678409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar 3688409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar return !Tmp.empty(); 3698409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar } 370ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 371ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Otherwise we have two users operands; they are related if they are in the 372ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // same class hierarchy. 3738409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar // 3748409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar // FIXME: This is an oversimplification, they should only be related if they 3758409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar // intersect, however we don't have that information. 376ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar assert(isUserClass() && RHS.isUserClass() && "Unexpected class!"); 377ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar const ClassInfo *Root = this; 378ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar while (!Root->SuperClasses.empty()) 379ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar Root = Root->SuperClasses.front(); 380ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 3818409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar const ClassInfo *RHSRoot = &RHS; 382ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar while (!RHSRoot->SuperClasses.empty()) 383ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar RHSRoot = RHSRoot->SuperClasses.front(); 384ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 385ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar return Root == RHSRoot; 386ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 387ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 388ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// isSubsetOf - Test whether this class is a subset of \arg RHS; 389ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar bool isSubsetOf(const ClassInfo &RHS) const { 390ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // This is a subset of RHS if it is the same class... 391ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (this == &RHS) 392ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar return true; 393ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 394ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // ... or if any of its super classes are a subset of RHS. 395ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar for (std::vector<ClassInfo*>::const_iterator it = SuperClasses.begin(), 396ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ie = SuperClasses.end(); it != ie; ++it) 397ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if ((*it)->isSubsetOf(RHS)) 398ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar return true; 399ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 400ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar return false; 4015fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar } 4025fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar 403606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar /// operator< - Compare two classes. 404606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar bool operator<(const ClassInfo &RHS) const { 405368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar if (this == &RHS) 406368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar return false; 407368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar 408ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Unrelated classes can be ordered by kind. 409ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (!isRelatedTo(RHS)) 410606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar return Kind < RHS.Kind; 411606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 412606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar switch (Kind) { 4136745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar case Invalid: 4146745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar assert(0 && "Invalid kind!"); 415606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar case Token: 4165fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar // Tokens are comparable by value. 417606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar // 418606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar // FIXME: Compare by enum value. 419606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar return ValueName < RHS.ValueName; 420606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 421606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar default: 422ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // This class preceeds the RHS if it is a proper subset of the RHS. 423368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar if (isSubsetOf(RHS)) 4243472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands return true; 425368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar if (RHS.isSubsetOf(*this)) 4263472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands return false; 427368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar 428368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar // Otherwise, order by name to ensure we have a total ordering. 429368a4565034b907943f5c0173574eb47939b74bfDaniel Dunbar return ValueName < RHS.ValueName; 430606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar } 431606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar } 432a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar}; 433a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 434b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar/// InstructionInfo - Helper class for storing the necessary information for an 435b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar/// instruction which is capable of being matched. 43620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbarstruct InstructionInfo { 43720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar struct Operand { 438a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// The unique class instance this operand should match. 439a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar ClassInfo *Class; 440a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 441a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// The original operand this corresponds to, if any. 442fa1165abb8fec9383d640b0696a9f397b9153bafBenjamin Kramer const CodeGenInstruction::OperandInfo *OperandInfo; 44320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar }; 44420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 44520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar /// InstrName - The target name for this instruction. 44620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar std::string InstrName; 44720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 44820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar /// Instr - The instruction this matches. 44920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar const CodeGenInstruction *Instr; 45020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 45120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar /// AsmString - The assembly string for this instruction (with variants 45220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar /// removed). 45320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar std::string AsmString; 45420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 45520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar /// Tokens - The tokenized assembly pattern that this instruction matches. 45620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar SmallVector<StringRef, 4> Tokens; 45720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 45820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar /// Operands - The operands that this instruction matches. 45920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar SmallVector<Operand, 4> Operands; 46020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 46154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar /// Predicates - The required subtarget features to match this instruction. 46254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar SmallVector<SubtargetFeatureInfo*, 4> RequiredFeatures; 46354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 464b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar /// ConversionFnKind - The enum value which is passed to the generated 465b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar /// ConvertToMCInst to convert parsed operands into an MCInst for this 466b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar /// function. 467b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar std::string ConversionFnKind; 46820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 469606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar /// operator< - Compare two instructions. 470606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar bool operator<(const InstructionInfo &RHS) const { 471606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar if (Operands.size() != RHS.Operands.size()) 472606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar return Operands.size() < RHS.Operands.size(); 4732b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar 474db2ddb5dc57319eff249144f1d9a553a3278d2e0Daniel Dunbar // Compare lexicographically by operand. The matcher validates that other 475db2ddb5dc57319eff249144f1d9a553a3278d2e0Daniel Dunbar // orderings wouldn't be ambiguous using \see CouldMatchAmiguouslyWith(). 476db2ddb5dc57319eff249144f1d9a553a3278d2e0Daniel Dunbar for (unsigned i = 0, e = Operands.size(); i != e; ++i) { 4772b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar if (*Operands[i].Class < *RHS.Operands[i].Class) 4782b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar return true; 479db2ddb5dc57319eff249144f1d9a553a3278d2e0Daniel Dunbar if (*RHS.Operands[i].Class < *Operands[i].Class) 480db2ddb5dc57319eff249144f1d9a553a3278d2e0Daniel Dunbar return false; 481db2ddb5dc57319eff249144f1d9a553a3278d2e0Daniel Dunbar } 482db2ddb5dc57319eff249144f1d9a553a3278d2e0Daniel Dunbar 4832b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar return false; 4842b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar } 485606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 4862b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar /// CouldMatchAmiguouslyWith - Check whether this instruction could 4872b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar /// ambiguously match the same set of operands as \arg RHS (without being a 4882b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar /// strictly superior match). 4892b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar bool CouldMatchAmiguouslyWith(const InstructionInfo &RHS) { 4902b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar // The number of operands is unambiguous. 4912b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar if (Operands.size() != RHS.Operands.size()) 4922b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar return false; 493606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 4941402f0b2cac017ab997f71ab4909a2ccfea7be4bDaniel Dunbar // Otherwise, make sure the ordering of the two instructions is unambiguous 4951402f0b2cac017ab997f71ab4909a2ccfea7be4bDaniel Dunbar // by checking that either (a) a token or operand kind discriminates them, 4961402f0b2cac017ab997f71ab4909a2ccfea7be4bDaniel Dunbar // or (b) the ordering among equivalent kinds is consistent. 4971402f0b2cac017ab997f71ab4909a2ccfea7be4bDaniel Dunbar 4982b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar // Tokens and operand kinds are unambiguous (assuming a correct target 4992b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar // specific parser). 500606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar for (unsigned i = 0, e = Operands.size(); i != e; ++i) 5012b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar if (Operands[i].Class->Kind != RHS.Operands[i].Class->Kind || 5022b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar Operands[i].Class->Kind == ClassInfo::Token) 5032b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar if (*Operands[i].Class < *RHS.Operands[i].Class || 5042b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar *RHS.Operands[i].Class < *Operands[i].Class) 5052b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar return false; 5062b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar 5072b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar // Otherwise, this operand could commute if all operands are equivalent, or 5082b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar // there is a pair of operands that compare less than and a pair that 5092b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar // compare greater than. 5102b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar bool HasLT = false, HasGT = false; 5112b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar for (unsigned i = 0, e = Operands.size(); i != e; ++i) { 512606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar if (*Operands[i].Class < *RHS.Operands[i].Class) 5132b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar HasLT = true; 5142b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar if (*RHS.Operands[i].Class < *Operands[i].Class) 5152b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar HasGT = true; 5162b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar } 517606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 5182b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar return !(HasLT ^ HasGT); 519606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar } 520606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 52120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbarpublic: 52220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar void dump(); 52320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar}; 52420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 52554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar/// SubtargetFeatureInfo - Helper class for storing information on a subtarget 52654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar/// feature which participates in instruction matching. 52754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbarstruct SubtargetFeatureInfo { 52854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar /// \brief The predicate record for this feature. 52954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar Record *TheDef; 53054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 53154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar /// \brief An unique index assigned to represent this feature. 53254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar unsigned Index; 53354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 53454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar /// \brief The name of the enumerated constant identifying this feature. 53554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar std::string EnumName; 53654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar}; 53754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 538a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarclass AsmMatcherInfo { 539a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarpublic: 54059fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar /// The tablegen AsmParser record. 54159fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar Record *AsmParser; 54259fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar 54359fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar /// The AsmParser "CommentDelimiter" value. 54459fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar std::string CommentDelimiter; 54559fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar 54659fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar /// The AsmParser "RegisterPrefix" value. 54759fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar std::string RegisterPrefix; 54859fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar 549a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// The classes which are needed for matching. 550a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::vector<ClassInfo*> Classes; 551a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 552a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// The information on the instruction to match. 553a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::vector<InstructionInfo*> Instructions; 554a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 555ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// Map of Register records to their class information. 556ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar std::map<Record*, ClassInfo*> RegisterClasses; 557ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 55854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar /// Map of Predicate records to their subtarget information. 55954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar std::map<Record*, SubtargetFeatureInfo*> SubtargetFeatures; 56054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 561a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarprivate: 562a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// Map of token to class information which has already been constructed. 563a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::map<std::string, ClassInfo*> TokenClasses; 564a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 565ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// Map of RegisterClass records to their class information. 566ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar std::map<Record*, ClassInfo*> RegisterClassClasses; 567a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 568338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar /// Map of AsmOperandClass records to their class information. 569338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar std::map<Record*, ClassInfo*> AsmOperandClasses; 5706745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar 571a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarprivate: 572a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// getTokenClass - Lookup or create the class for the given token. 573b8d6e98e566724f58344d275a4bd675249bb713aChris Lattner ClassInfo *getTokenClass(StringRef Token); 574a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 575a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// getOperandClass - Lookup or create the class for the given operand. 576b8d6e98e566724f58344d275a4bd675249bb713aChris Lattner ClassInfo *getOperandClass(StringRef Token, 577a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar const CodeGenInstruction::OperandInfo &OI); 578a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 57954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar /// getSubtargetFeature - Lookup or create the subtarget feature info for the 58054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar /// given operand. 58154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar SubtargetFeatureInfo *getSubtargetFeature(Record *Def) { 58254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar assert(Def->isSubClassOf("Predicate") && "Invalid predicate type!"); 58354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 58454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar SubtargetFeatureInfo *&Entry = SubtargetFeatures[Def]; 58554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar if (!Entry) { 58654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar Entry = new SubtargetFeatureInfo; 58754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar Entry->TheDef = Def; 58854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar Entry->Index = SubtargetFeatures.size() - 1; 58954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar Entry->EnumName = "Feature_" + Def->getName(); 59054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar assert(Entry->Index < 32 && "Too many subtarget features!"); 59154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar } 59254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 59354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar return Entry; 59454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar } 59554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 596ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// BuildRegisterClasses - Build the ClassInfo* instances for register 597ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// classes. 5981095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar void BuildRegisterClasses(CodeGenTarget &Target, 5991095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar std::set<std::string> &SingletonRegisterNames); 600ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 601ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// BuildOperandClasses - Build the ClassInfo* instances for user defined 602ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar /// operand classes. 603ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar void BuildOperandClasses(CodeGenTarget &Target); 604ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 605a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarpublic: 60659fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar AsmMatcherInfo(Record *_AsmParser); 60759fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar 608a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar /// BuildInfo - Construct the various tables used during matching. 609a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar void BuildInfo(CodeGenTarget &Target); 610a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar}; 611a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 61220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar} 61320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 61420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbarvoid InstructionInfo::dump() { 61520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar errs() << InstrName << " -- " << "flattened:\"" << AsmString << '\"' 61620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar << ", tokens:["; 61720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar for (unsigned i = 0, e = Tokens.size(); i != e; ++i) { 61820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar errs() << Tokens[i]; 61920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (i + 1 != e) 62020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar errs() << ", "; 62122be5225ff88ffaab83c36fa133e70586b91166dDaniel Dunbar } 62220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar errs() << "]\n"; 623a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 62420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar for (unsigned i = 0, e = Operands.size(); i != e; ++i) { 62520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Operand &Op = Operands[i]; 6266745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar errs() << " op[" << i << "] = " << Op.Class->ClassName << " - "; 627a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar if (Op.Class->Kind == ClassInfo::Token) { 62820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar errs() << '\"' << Tokens[i] << "\"\n"; 62920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar continue; 63020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 631a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 6321095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar if (!Op.OperandInfo) { 6331095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar errs() << "(singleton register)\n"; 6341095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar continue; 6351095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar } 6361095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 637fa1165abb8fec9383d640b0696a9f397b9153bafBenjamin Kramer const CodeGenInstruction::OperandInfo &OI = *Op.OperandInfo; 63820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar errs() << OI.Name << " " << OI.Rec->getName() 63920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar << " (" << OI.MIOperandNo << ", " << OI.MINumOperands << ")\n"; 64020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 64120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar} 642a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 643b8d6e98e566724f58344d275a4bd675249bb713aChris Lattnerstatic std::string getEnumNameForToken(StringRef Str) { 644a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::string Res; 645a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 646a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar for (StringRef::iterator it = Str.begin(), ie = Str.end(); it != ie; ++it) { 647a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar switch (*it) { 648a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar case '*': Res += "_STAR_"; break; 649a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar case '%': Res += "_PCT_"; break; 650a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar case ':': Res += "_COLON_"; break; 651a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 652a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar default: 653a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar if (isalnum(*it)) { 654a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Res += *it; 655a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } else { 656a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Res += "_" + utostr((unsigned) *it) + "_"; 657a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 658a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 659a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 66020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 661a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar return Res; 662a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar} 663a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 6641095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar/// getRegisterRecord - Get the register record for \arg name, or 0. 665b8d6e98e566724f58344d275a4bd675249bb713aChris Lattnerstatic Record *getRegisterRecord(CodeGenTarget &Target, StringRef Name) { 6661095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar for (unsigned i = 0, e = Target.getRegisters().size(); i != e; ++i) { 6671095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar const CodeGenRegister &Reg = Target.getRegisters()[i]; 6681095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar if (Name == Reg.TheDef->getValueAsString("AsmName")) 6691095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar return Reg.TheDef; 6701095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar } 6711095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 6721095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar return 0; 6731095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar} 6741095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 675b8d6e98e566724f58344d275a4bd675249bb713aChris LattnerClassInfo *AsmMatcherInfo::getTokenClass(StringRef Token) { 676a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar ClassInfo *&Entry = TokenClasses[Token]; 677a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 678a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar if (!Entry) { 679a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Entry = new ClassInfo(); 680a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Entry->Kind = ClassInfo::Token; 6816745d42e8e51ba6b9546d6fa62e0c1b1e0f3982aDaniel Dunbar Entry->ClassName = "Token"; 682a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Entry->Name = "MCK_" + getEnumNameForToken(Token); 683a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Entry->ValueName = Token; 684a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Entry->PredicateMethod = "<invalid>"; 685a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Entry->RenderMethod = "<invalid>"; 686a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Classes.push_back(Entry); 687a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 688a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 689a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar return Entry; 690a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar} 691a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 692a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel DunbarClassInfo * 693b8d6e98e566724f58344d275a4bd675249bb713aChris LattnerAsmMatcherInfo::getOperandClass(StringRef Token, 694a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar const CodeGenInstruction::OperandInfo &OI) { 695ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (OI.Rec->isSubClassOf("RegisterClass")) { 696ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ClassInfo *CI = RegisterClassClasses[OI.Rec]; 697ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 698ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (!CI) { 699ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar PrintError(OI.Rec->getLoc(), "register class has no class info!"); 700ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar throw std::string("ERROR: Missing register class!"); 701ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 702ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 703ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar return CI; 704ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 705338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar 706338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar assert(OI.Rec->isSubClassOf("Operand") && "Unexpected operand!"); 707338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar Record *MatchClass = OI.Rec->getValueAsDef("ParserMatchClass"); 708338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar ClassInfo *CI = AsmOperandClasses[MatchClass]; 7095fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar 710338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar if (!CI) { 711338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar PrintError(OI.Rec->getLoc(), "operand has no match class!"); 712338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar throw std::string("ERROR: Missing match class!"); 713a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 714a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 715338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar return CI; 716338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar} 717338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar 7181095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbarvoid AsmMatcherInfo::BuildRegisterClasses(CodeGenTarget &Target, 7191095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar std::set<std::string> 7201095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar &SingletonRegisterNames) { 721ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar std::vector<CodeGenRegisterClass> RegisterClasses; 722ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar std::vector<CodeGenRegister> Registers; 723338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar 724ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar RegisterClasses = Target.getRegisterClasses(); 725ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar Registers = Target.getRegisters(); 726338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar 727ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // The register sets used for matching. 728ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar std::set< std::set<Record*> > RegisterSets; 729ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 730ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Gather the defined sets. 731ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar for (std::vector<CodeGenRegisterClass>::iterator it = RegisterClasses.begin(), 732ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ie = RegisterClasses.end(); it != ie; ++it) 733ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar RegisterSets.insert(std::set<Record*>(it->Elements.begin(), 734ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar it->Elements.end())); 7351095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 7361095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar // Add any required singleton sets. 7371095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar for (std::set<std::string>::iterator it = SingletonRegisterNames.begin(), 7381095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar ie = SingletonRegisterNames.end(); it != ie; ++it) 7391095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar if (Record *Rec = getRegisterRecord(Target, *it)) 7401095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar RegisterSets.insert(std::set<Record*>(&Rec, &Rec + 1)); 7411095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 742ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Introduce derived sets where necessary (when a register does not determine 743ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // a unique register set class), and build the mapping of registers to the set 744ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // they should classify to. 745ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar std::map<Record*, std::set<Record*> > RegisterMap; 746ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar for (std::vector<CodeGenRegister>::iterator it = Registers.begin(), 747ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ie = Registers.end(); it != ie; ++it) { 748ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CodeGenRegister &CGR = *it; 749ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Compute the intersection of all sets containing this register. 750ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar std::set<Record*> ContainingSet; 751ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 752ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar for (std::set< std::set<Record*> >::iterator it = RegisterSets.begin(), 753ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ie = RegisterSets.end(); it != ie; ++it) { 754ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (!it->count(CGR.TheDef)) 755ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar continue; 756ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 757ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (ContainingSet.empty()) { 758ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ContainingSet = *it; 759ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } else { 760ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar std::set<Record*> Tmp; 761ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar std::swap(Tmp, ContainingSet); 762ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar std::insert_iterator< std::set<Record*> > II(ContainingSet, 763ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ContainingSet.begin()); 764ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar std::set_intersection(Tmp.begin(), Tmp.end(), it->begin(), it->end(), 765ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar II); 766ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 767ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 768ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 769ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (!ContainingSet.empty()) { 770ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar RegisterSets.insert(ContainingSet); 771ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar RegisterMap.insert(std::make_pair(CGR.TheDef, ContainingSet)); 772ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 773ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 774ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 775ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Construct the register classes. 776ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar std::map<std::set<Record*>, ClassInfo*> RegisterSetClasses; 777ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar unsigned Index = 0; 778ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar for (std::set< std::set<Record*> >::iterator it = RegisterSets.begin(), 779ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ie = RegisterSets.end(); it != ie; ++it, ++Index) { 780ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ClassInfo *CI = new ClassInfo(); 781ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->Kind = ClassInfo::RegisterClass0 + Index; 782ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->ClassName = "Reg" + utostr(Index); 783ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->Name = "MCK_Reg" + utostr(Index); 784ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->ValueName = ""; 785ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->PredicateMethod = ""; // unused 786ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->RenderMethod = "addRegOperands"; 7878409bfbbc306bc051fbd8b049804103ca7df2f63Daniel Dunbar CI->Registers = *it; 788ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar Classes.push_back(CI); 789ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar RegisterSetClasses.insert(std::make_pair(*it, CI)); 790ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 791ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 792ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Find the superclasses; we could compute only the subgroup lattice edges, 793ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // but there isn't really a point. 794ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar for (std::set< std::set<Record*> >::iterator it = RegisterSets.begin(), 795ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ie = RegisterSets.end(); it != ie; ++it) { 796ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ClassInfo *CI = RegisterSetClasses[*it]; 797ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar for (std::set< std::set<Record*> >::iterator it2 = RegisterSets.begin(), 798ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ie2 = RegisterSets.end(); it2 != ie2; ++it2) 799ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (*it != *it2 && 800ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar std::includes(it2->begin(), it2->end(), it->begin(), it->end())) 801ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->SuperClasses.push_back(RegisterSetClasses[*it2]); 802ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 803ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 804ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Name the register classes which correspond to a user defined RegisterClass. 805ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar for (std::vector<CodeGenRegisterClass>::iterator it = RegisterClasses.begin(), 806ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ie = RegisterClasses.end(); it != ie; ++it) { 807ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ClassInfo *CI = RegisterSetClasses[std::set<Record*>(it->Elements.begin(), 808ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar it->Elements.end())]; 809ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (CI->ValueName.empty()) { 810ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->ClassName = it->getName(); 811ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->Name = "MCK_" + it->getName(); 812ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->ValueName = it->getName(); 813ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } else 814ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->ValueName = CI->ValueName + "," + it->getName(); 815ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 816ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar RegisterClassClasses.insert(std::make_pair(it->TheDef, CI)); 817ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 818ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 819ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Populate the map for individual registers. 820ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar for (std::map<Record*, std::set<Record*> >::iterator it = RegisterMap.begin(), 821ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ie = RegisterMap.end(); it != ie; ++it) 822ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar this->RegisterClasses[it->first] = RegisterSetClasses[it->second]; 8231095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 8241095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar // Name the register classes which correspond to singleton registers. 8251095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar for (std::set<std::string>::iterator it = SingletonRegisterNames.begin(), 8261095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar ie = SingletonRegisterNames.end(); it != ie; ++it) { 8271095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar if (Record *Rec = getRegisterRecord(Target, *it)) { 8281095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar ClassInfo *CI = this->RegisterClasses[Rec]; 8291095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar assert(CI && "Missing singleton register class info!"); 8301095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 8311095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar if (CI->ValueName.empty()) { 8321095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar CI->ClassName = Rec->getName(); 8331095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar CI->Name = "MCK_" + Rec->getName(); 8341095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar CI->ValueName = Rec->getName(); 8351095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar } else 8361095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar CI->ValueName = CI->ValueName + "," + Rec->getName(); 8371095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar } 8381095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar } 839ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar} 840ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 841ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbarvoid AsmMatcherInfo::BuildOperandClasses(CodeGenTarget &Target) { 842338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar std::vector<Record*> AsmOperands; 843338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar AsmOperands = Records.getAllDerivedDefinitions("AsmOperandClass"); 844a2f5e00347641d1b46ce4f65bf9378fecce9be14Daniel Dunbar 845a2f5e00347641d1b46ce4f65bf9378fecce9be14Daniel Dunbar // Pre-populate AsmOperandClasses map. 846a2f5e00347641d1b46ce4f65bf9378fecce9be14Daniel Dunbar for (std::vector<Record*>::iterator it = AsmOperands.begin(), 847a2f5e00347641d1b46ce4f65bf9378fecce9be14Daniel Dunbar ie = AsmOperands.end(); it != ie; ++it) 848a2f5e00347641d1b46ce4f65bf9378fecce9be14Daniel Dunbar AsmOperandClasses[*it] = new ClassInfo(); 849a2f5e00347641d1b46ce4f65bf9378fecce9be14Daniel Dunbar 850338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar unsigned Index = 0; 851338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar for (std::vector<Record*>::iterator it = AsmOperands.begin(), 852338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar ie = AsmOperands.end(); it != ie; ++it, ++Index) { 853a2f5e00347641d1b46ce4f65bf9378fecce9be14Daniel Dunbar ClassInfo *CI = AsmOperandClasses[*it]; 854338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar CI->Kind = ClassInfo::UserClass0 + Index; 855338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar 85654ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar ListInit *Supers = (*it)->getValueAsListInit("SuperClasses"); 85754ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar for (unsigned i = 0, e = Supers->getSize(); i != e; ++i) { 85854ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar DefInit *DI = dynamic_cast<DefInit*>(Supers->getElement(i)); 85954ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar if (!DI) { 86054ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar PrintError((*it)->getLoc(), "Invalid super class reference!"); 86154ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar continue; 86254ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar } 86354ddf3d9c756881021afcb869a6ec892a21aef5bDaniel Dunbar 864ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ClassInfo *SC = AsmOperandClasses[DI->getDef()]; 865ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (!SC) 866338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar PrintError((*it)->getLoc(), "Invalid super class reference!"); 867ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar else 868ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar CI->SuperClasses.push_back(SC); 869a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 870338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar CI->ClassName = (*it)->getValueAsString("Name"); 871338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar CI->Name = "MCK_" + CI->ClassName; 872338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar CI->ValueName = (*it)->getName(); 8735c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar 8745c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar // Get or construct the predicate method name. 8755c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar Init *PMName = (*it)->getValueInit("PredicateMethod"); 8765c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar if (StringInit *SI = dynamic_cast<StringInit*>(PMName)) { 8775c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar CI->PredicateMethod = SI->getValue(); 8785c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar } else { 8795c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar assert(dynamic_cast<UnsetInit*>(PMName) && 8805c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar "Unexpected PredicateMethod field!"); 8815c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar CI->PredicateMethod = "is" + CI->ClassName; 8825c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar } 8835c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar 8845c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar // Get or construct the render method name. 8855c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar Init *RMName = (*it)->getValueInit("RenderMethod"); 8865c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar if (StringInit *SI = dynamic_cast<StringInit*>(RMName)) { 8875c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar CI->RenderMethod = SI->getValue(); 8885c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar } else { 8895c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar assert(dynamic_cast<UnsetInit*>(RMName) && 8905c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar "Unexpected RenderMethod field!"); 8915c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar CI->RenderMethod = "add" + CI->ClassName + "Operands"; 8925c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar } 8935c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar 894338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar AsmOperandClasses[*it] = CI; 895338825c1928b956b2cbcc2c165a60afddd100398Daniel Dunbar Classes.push_back(CI); 896a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 897ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar} 898ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 89959fc42debd571bbafc52c20bc418fdc3f4d00188Daniel DunbarAsmMatcherInfo::AsmMatcherInfo(Record *_AsmParser) 90059fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar : AsmParser(_AsmParser), 90159fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar CommentDelimiter(AsmParser->getValueAsString("CommentDelimiter")), 90259fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar RegisterPrefix(AsmParser->getValueAsString("RegisterPrefix")) 90359fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar{ 90459fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar} 90559fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar 906ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbarvoid AsmMatcherInfo::BuildInfo(CodeGenTarget &Target) { 9071095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar // Parse the instructions; we need to do this first so that we can gather the 9081095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar // singleton register classes. 9091095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar std::set<std::string> SingletonRegisterNames; 910b61e09de6d0cd7241ddc6dee3efef416552eec3bChris Lattner 911f65027842e82027dd6e8020586a299aaa548e355Chris Lattner const std::vector<const CodeGenInstruction*> &InstrList = 912f65027842e82027dd6e8020586a299aaa548e355Chris Lattner Target.getInstructionsByEnumValue(); 913b61e09de6d0cd7241ddc6dee3efef416552eec3bChris Lattner 914b61e09de6d0cd7241ddc6dee3efef416552eec3bChris Lattner for (unsigned i = 0, e = InstrList.size(); i != e; ++i) { 915b61e09de6d0cd7241ddc6dee3efef416552eec3bChris Lattner const CodeGenInstruction &CGI = *InstrList[i]; 916a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 917b61e09de6d0cd7241ddc6dee3efef416552eec3bChris Lattner if (!StringRef(CGI.TheDef->getName()).startswith(MatchPrefix)) 91853a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar continue; 91953a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar 920b61e09de6d0cd7241ddc6dee3efef416552eec3bChris Lattner OwningPtr<InstructionInfo> II(new InstructionInfo()); 92120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 922b61e09de6d0cd7241ddc6dee3efef416552eec3bChris Lattner II->InstrName = CGI.TheDef->getName(); 923b61e09de6d0cd7241ddc6dee3efef416552eec3bChris Lattner II->Instr = &CGI; 92420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar II->AsmString = FlattenVariants(CGI.AsmString, 0); 92520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 92659fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar // Remove comments from the asm string. 92759fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar if (!CommentDelimiter.empty()) { 92859fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar size_t Idx = StringRef(II->AsmString).find(CommentDelimiter); 92959fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar if (Idx != StringRef::npos) 93059fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar II->AsmString = II->AsmString.substr(0, Idx); 93159fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar } 93259fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar 93320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar TokenizeAsmString(II->AsmString, II->Tokens); 934a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 93520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // Ignore instructions which shouldn't be matched. 936b61e09de6d0cd7241ddc6dee3efef416552eec3bChris Lattner if (!IsAssemblerInstruction(CGI.TheDef->getName(), CGI, II->Tokens)) 937a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar continue; 938a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 9391095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar // Collect singleton registers, if used. 9401095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar if (!RegisterPrefix.empty()) { 9411095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar for (unsigned i = 0, e = II->Tokens.size(); i != e; ++i) { 9421095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar if (II->Tokens[i].startswith(RegisterPrefix)) { 9431095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar StringRef RegName = II->Tokens[i].substr(RegisterPrefix.size()); 9441095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar Record *Rec = getRegisterRecord(Target, RegName); 9451095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 9461095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar if (!Rec) { 9471095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar std::string Err = "unable to find register for '" + RegName.str() + 9481095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar "' (which matches register prefix)"; 9491095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar throw TGError(CGI.TheDef->getLoc(), Err); 9501095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar } 9511095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 9521095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar SingletonRegisterNames.insert(RegName); 9531095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar } 9541095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar } 9551095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar } 95654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 95754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar // Compute the require features. 95854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar ListInit *Predicates = CGI.TheDef->getValueAsListInit("Predicates"); 95954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar for (unsigned i = 0, e = Predicates->getSize(); i != e; ++i) { 96054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar if (DefInit *Pred = dynamic_cast<DefInit*>(Predicates->getElement(i))) { 96154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar // Ignore OptForSize and OptForSpeed, they aren't really requirements, 96254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar // rather they are hints to isel. 96354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar // 96454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar // FIXME: Find better way to model this. 96554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar if (Pred->getDef()->getName() == "OptForSize" || 96654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar Pred->getDef()->getName() == "OptForSpeed") 96754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar continue; 96854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 96954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar // FIXME: Total hack; for now, we just limit ourselves to In32BitMode 97054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar // and In64BitMode, because we aren't going to have the right feature 97154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar // masks for SSE and friends. We need to decide what we are going to do 97254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar // about CPU subtypes to implement this the right way. 97354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar if (Pred->getDef()->getName() != "In32BitMode" && 97454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar Pred->getDef()->getName() != "In64BitMode") 97554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar continue; 97654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 97754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar II->RequiredFeatures.push_back(getSubtargetFeature(Pred->getDef())); 97854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar } 97954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar } 98054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 9811095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar Instructions.push_back(II.take()); 9821095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar } 9831095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 9841095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar // Build info for the register classes. 9851095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar BuildRegisterClasses(Target, SingletonRegisterNames); 9861095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 9871095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar // Build info for the user defined assembly operand classes. 9881095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar BuildOperandClasses(Target); 9891095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 9901095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar // Build the instruction information. 9911095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar for (std::vector<InstructionInfo*>::iterator it = Instructions.begin(), 9921095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar ie = Instructions.end(); it != ie; ++it) { 9931095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar InstructionInfo *II = *it; 9941095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 99520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar for (unsigned i = 0, e = II->Tokens.size(); i != e; ++i) { 99620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar StringRef Token = II->Tokens[i]; 99720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 9981095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar // Check for singleton registers. 9991095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar if (!RegisterPrefix.empty() && Token.startswith(RegisterPrefix)) { 10001095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar StringRef RegName = II->Tokens[i].substr(RegisterPrefix.size()); 10011095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar InstructionInfo::Operand Op; 10021095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar Op.Class = RegisterClasses[getRegisterRecord(Target, RegName)]; 10031095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar Op.OperandInfo = 0; 10041095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar assert(Op.Class && Op.Class->Registers.size() == 1 && 10051095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar "Unexpected class for singleton register"); 10061095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar II->Operands.push_back(Op); 10071095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar continue; 10081095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar } 10091095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 101020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // Check for simple tokens. 101120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (Token[0] != '$') { 101220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar InstructionInfo::Operand Op; 1013a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Op.Class = getTokenClass(Token); 1014fa1165abb8fec9383d640b0696a9f397b9153bafBenjamin Kramer Op.OperandInfo = 0; 101520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar II->Operands.push_back(Op); 101620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar continue; 101720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 1018a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 101920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // Otherwise this is an operand reference. 102020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar StringRef OperandName; 102120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (Token[1] == '{') 102220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar OperandName = Token.substr(2, Token.size() - 3); 102320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar else 102420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar OperandName = Token.substr(1); 102520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 102620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // Map this token to an operand. FIXME: Move elsewhere. 102720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar unsigned Idx; 102820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar try { 10291095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar Idx = II->Instr->getOperandNamed(OperandName); 103020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } catch(...) { 10311095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar throw std::string("error: unable to find operand: '" + 10321095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar OperandName.str() + "'"); 103320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 1034a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 1035af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar // FIXME: This is annoying, the named operand may be tied (e.g., 1036af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar // XCHG8rm). What we want is the untied operand, which we now have to 1037af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar // grovel for. Only worry about this for single entry operands, we have to 1038af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar // clean this up anyway. 1039af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar const CodeGenInstruction::OperandInfo *OI = &II->Instr->OperandList[Idx]; 1040af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar if (OI->Constraints[0].isTied()) { 1041af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar unsigned TiedOp = OI->Constraints[0].getTiedOperand(); 1042af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar 1043af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar // The tied operand index is an MIOperand index, find the operand that 1044af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar // contains it. 1045af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar for (unsigned i = 0, e = II->Instr->OperandList.size(); i != e; ++i) { 1046af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar if (II->Instr->OperandList[i].MIOperandNo == TiedOp) { 1047af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar OI = &II->Instr->OperandList[i]; 1048af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar break; 1049af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar } 1050af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar } 1051af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar 1052af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar assert(OI && "Unable to find tied operand target!"); 1053af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar } 1054af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar 1055a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar InstructionInfo::Operand Op; 1056af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar Op.Class = getOperandClass(Token, *OI); 1057af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar Op.OperandInfo = OI; 105820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar II->Operands.push_back(Op); 105953a7f16dcc96de71fa46f641c59470586548081eDaniel Dunbar } 106020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 10615fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar 10625fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar // Reorder classes so that classes preceed super classes. 10635fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar std::sort(Classes.begin(), Classes.end(), less_ptr<ClassInfo>()); 106420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar} 1065a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 10663b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbarstatic std::pair<unsigned, unsigned> * 10673b6910dcd466bf091b386bb136f42522c89473f7Daniel DunbarGetTiedOperandAtIndex(SmallVectorImpl<std::pair<unsigned, unsigned> > &List, 10683b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar unsigned Index) { 10693b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar for (unsigned i = 0, e = List.size(); i != e; ++i) 10703b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar if (Index == List[i].first) 10713b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar return &List[i]; 10723b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar 10733b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar return 0; 10743b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar} 10753b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar 1076606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbarstatic void EmitConvertToMCInst(CodeGenTarget &Target, 1077606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar std::vector<InstructionInfo*> &Infos, 1078606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar raw_ostream &OS) { 1079b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar // Write the convert function to a separate stream, so we can drop it after 1080b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar // the enum. 1081b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar std::string ConvertFnBody; 1082b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar raw_string_ostream CvtOS(ConvertFnBody); 1083b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 108420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // Function we have already generated. 108520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar std::set<std::string> GeneratedFns; 108620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 1087b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar // Start the unified conversion function. 1088b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 10898cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar CvtOS << "static void ConvertToMCInst(ConversionKind Kind, MCInst &Inst, " 1090b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar << "unsigned Opcode,\n" 10919898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner << " const SmallVectorImpl<MCParsedAsmOperand*" 10929898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner << "> &Operands) {\n"; 1093b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar CvtOS << " Inst.setOpcode(Opcode);\n"; 1094b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar CvtOS << " switch (Kind) {\n"; 1095b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar CvtOS << " default:\n"; 1096b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 1097b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar // Start the enum, which we will generate inline. 1098b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 1099b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar OS << "// Unified function for converting operants to MCInst instances.\n\n"; 1100b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar OS << "enum ConversionKind {\n"; 1101b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 11029898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner // TargetOperandClass - This is the target's operand class, like X86Operand. 11039898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner std::string TargetOperandClass = Target.getName() + "Operand"; 11049898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner 110520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar for (std::vector<InstructionInfo*>::const_iterator it = Infos.begin(), 110620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar ie = Infos.end(); it != ie; ++it) { 110720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar InstructionInfo &II = **it; 110820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 110920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // Order the (class) operands by the order to convert them into an MCInst. 111020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar SmallVector<std::pair<unsigned, unsigned>, 4> MIOperandList; 111120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar for (unsigned i = 0, e = II.Operands.size(); i != e; ++i) { 111220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar InstructionInfo::Operand &Op = II.Operands[i]; 1113fa1165abb8fec9383d640b0696a9f397b9153bafBenjamin Kramer if (Op.OperandInfo) 1114fa1165abb8fec9383d640b0696a9f397b9153bafBenjamin Kramer MIOperandList.push_back(std::make_pair(Op.OperandInfo->MIOperandNo, i)); 111520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 1116af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar 1117af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar // Find any tied operands. 1118af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar SmallVector<std::pair<unsigned, unsigned>, 4> TiedOperands; 1119af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar for (unsigned i = 0, e = II.Instr->OperandList.size(); i != e; ++i) { 1120af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar const CodeGenInstruction::OperandInfo &OpInfo = II.Instr->OperandList[i]; 1121af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar for (unsigned j = 0, e = OpInfo.Constraints.size(); j != e; ++j) { 1122af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar const CodeGenInstruction::ConstraintInfo &CI = OpInfo.Constraints[j]; 1123af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar if (CI.isTied()) 1124af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar TiedOperands.push_back(std::make_pair(OpInfo.MIOperandNo + j, 1125af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar CI.getTiedOperand())); 1126af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar } 1127af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar } 1128af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar 112920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar std::sort(MIOperandList.begin(), MIOperandList.end()); 1130a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 113120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // Compute the total number of operands. 1132a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar unsigned NumMIOperands = 0; 113320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar for (unsigned i = 0, e = II.Instr->OperandList.size(); i != e; ++i) { 113420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar const CodeGenInstruction::OperandInfo &OI = II.Instr->OperandList[i]; 1135a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar NumMIOperands = std::max(NumMIOperands, 1136a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar OI.MIOperandNo + OI.MINumOperands); 1137a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar } 1138a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 113920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // Build the conversion function signature. 114020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar std::string Signature = "Convert"; 114120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar unsigned CurIndex = 0; 114220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar for (unsigned i = 0, e = MIOperandList.size(); i != e; ++i) { 114320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar InstructionInfo::Operand &Op = II.Operands[MIOperandList[i].second]; 1144fa1165abb8fec9383d640b0696a9f397b9153bafBenjamin Kramer assert(CurIndex <= Op.OperandInfo->MIOperandNo && 114520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar "Duplicate match for instruction operand!"); 114620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 114720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // Skip operands which weren't matched by anything, this occurs when the 114820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // .td file encodes "implicit" operands as explicit ones. 114920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // 115020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // FIXME: This should be removed from the MCInst structure. 1151af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar for (; CurIndex != Op.OperandInfo->MIOperandNo; ++CurIndex) { 11523b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar std::pair<unsigned, unsigned> *Tie = GetTiedOperandAtIndex(TiedOperands, 11533b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar CurIndex); 11543b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar if (!Tie) 1155af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar Signature += "__Imp"; 1156af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar else 11573b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar Signature += "__Tie" + utostr(Tie->second); 1158af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar } 1159af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar 1160af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar Signature += "__"; 1161a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 1162ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Registers are always converted the same, don't duplicate the conversion 1163ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // function based on them. 1164ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // 1165ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // FIXME: We could generalize this based on the render method, if it 1166ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // mattered. 1167ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (Op.Class->isRegisterClass()) 1168ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar Signature += "Reg"; 1169ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar else 1170ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar Signature += Op.Class->ClassName; 1171fa1165abb8fec9383d640b0696a9f397b9153bafBenjamin Kramer Signature += utostr(Op.OperandInfo->MINumOperands); 1172b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar Signature += "_" + utostr(MIOperandList[i].second); 1173b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 1174fa1165abb8fec9383d640b0696a9f397b9153bafBenjamin Kramer CurIndex += Op.OperandInfo->MINumOperands; 117520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 1176a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 117720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // Add any trailing implicit operands. 11783b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar for (; CurIndex != NumMIOperands; ++CurIndex) { 11793b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar std::pair<unsigned, unsigned> *Tie = GetTiedOperandAtIndex(TiedOperands, 11803b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar CurIndex); 11813b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar if (!Tie) 11823b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar Signature += "__Imp"; 11833b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar else 11843b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar Signature += "__Tie" + utostr(Tie->second); 11853b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar } 1186a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 1187b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar II.ConversionFnKind = Signature; 1188a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 1189b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar // Check if we have already generated this signature. 119020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (!GeneratedFns.insert(Signature).second) 119120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar continue; 1192a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 119320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // If not, emit it now. 1194b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 1195b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar // Add to the enum list. 1196b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar OS << " " << Signature << ",\n"; 1197b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 1198b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar // And to the convert function. 1199b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar CvtOS << " case " << Signature << ":\n"; 120020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar CurIndex = 0; 120120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar for (unsigned i = 0, e = MIOperandList.size(); i != e; ++i) { 120220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar InstructionInfo::Operand &Op = II.Operands[MIOperandList[i].second]; 120320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 120420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // Add the implicit operands. 1205af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar for (; CurIndex != Op.OperandInfo->MIOperandNo; ++CurIndex) { 1206af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar // See if this is a tied operand. 12073b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar std::pair<unsigned, unsigned> *Tie = GetTiedOperandAtIndex(TiedOperands, 12083b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar CurIndex); 1209af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar 12103b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar if (!Tie) { 1211af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar // If not, this is some implicit operand. Just assume it is a register 1212af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar // for now. 1213af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar CvtOS << " Inst.addOperand(MCOperand::CreateReg(0));\n"; 1214af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar } else { 1215af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar // Copy the tied operand. 12163b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar assert(Tie->first>Tie->second && "Tied operand preceeds its target!"); 1217af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar CvtOS << " Inst.addOperand(Inst.getOperand(" 12183b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar << Tie->second << "));\n"; 1219af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar } 1220af61681cedb42a0e9f84560316d74f4ddeb2d2b6Daniel Dunbar } 122120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 12229898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner CvtOS << " ((" << TargetOperandClass << "*)Operands[" 12239898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner << MIOperandList[i].second 12249898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner << "])->" << Op.Class->RenderMethod 1225fa1165abb8fec9383d640b0696a9f397b9153bafBenjamin Kramer << "(Inst, " << Op.OperandInfo->MINumOperands << ");\n"; 1226fa1165abb8fec9383d640b0696a9f397b9153bafBenjamin Kramer CurIndex += Op.OperandInfo->MINumOperands; 1227a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar } 122820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 122920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // And add trailing implicit operands. 12303b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar for (; CurIndex != NumMIOperands; ++CurIndex) { 12313b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar std::pair<unsigned, unsigned> *Tie = GetTiedOperandAtIndex(TiedOperands, 12323b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar CurIndex); 12333b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar 12343b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar if (!Tie) { 12353b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar // If not, this is some implicit operand. Just assume it is a register 12363b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar // for now. 12373b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar CvtOS << " Inst.addOperand(MCOperand::CreateReg(0));\n"; 12383b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar } else { 12393b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar // Copy the tied operand. 12403b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar assert(Tie->first>Tie->second && "Tied operand preceeds its target!"); 12413b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar CvtOS << " Inst.addOperand(Inst.getOperand(" 12423b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar << Tie->second << "));\n"; 12433b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar } 12443b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar } 12453b6910dcd466bf091b386bb136f42522c89473f7Daniel Dunbar 12468cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar CvtOS << " return;\n"; 1247a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar } 1248b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 1249b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar // Finish the convert function. 1250b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 1251b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar CvtOS << " }\n"; 1252b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar CvtOS << "}\n\n"; 1253b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 1254b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar // Finish the enum, and drop the convert function after it. 1255b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 1256b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar OS << " NumConversionVariants\n"; 1257b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar OS << "};\n\n"; 1258b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar 1259b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar OS << CvtOS.str(); 126020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar} 126120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 1262a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar/// EmitMatchClassEnumeration - Emit the enumeration for match class kinds. 1263a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarstatic void EmitMatchClassEnumeration(CodeGenTarget &Target, 1264a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar std::vector<ClassInfo*> &Infos, 1265a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar raw_ostream &OS) { 1266a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "namespace {\n\n"; 1267a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1268a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "/// MatchClassKind - The kinds of classes which participate in\n" 1269a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar << "/// instruction matching.\n"; 1270a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "enum MatchClassKind {\n"; 1271a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " InvalidMatchClass = 0,\n"; 1272a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar for (std::vector<ClassInfo*>::iterator it = Infos.begin(), 1273a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar ie = Infos.end(); it != ie; ++it) { 1274a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar ClassInfo &CI = **it; 1275a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " " << CI.Name << ", // "; 1276a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar if (CI.Kind == ClassInfo::Token) { 1277a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "'" << CI.ValueName << "'\n"; 1278ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } else if (CI.isRegisterClass()) { 1279a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar if (!CI.ValueName.empty()) 1280a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "register class '" << CI.ValueName << "'\n"; 1281a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar else 1282a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "derived register class\n"; 1283a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } else { 1284a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "user defined class '" << CI.ValueName << "'\n"; 1285a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 1286a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 1287a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " NumMatchClassKinds\n"; 1288a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "};\n\n"; 1289a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1290a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "}\n\n"; 1291a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar} 1292a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1293a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar/// EmitClassifyOperand - Emit the function to classify an operand. 1294a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbarstatic void EmitClassifyOperand(CodeGenTarget &Target, 1295ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar AsmMatcherInfo &Info, 1296a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar raw_ostream &OS) { 12979898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner OS << "static MatchClassKind ClassifyOperand(MCParsedAsmOperand *GOp) {\n" 12989898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner << " " << Target.getName() << "Operand &Operand = *(" 12999898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner << Target.getName() << "Operand*)GOp;\n"; 1300ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 1301ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Classify tokens. 1302a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " if (Operand.isToken())\n"; 1303a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " return MatchTokenString(Operand.getToken());\n\n"; 1304ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 1305ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Classify registers. 1306ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // 1307ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // FIXME: Don't hardcode isReg, getReg. 1308ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " if (Operand.isReg()) {\n"; 1309ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " switch (Operand.getReg()) {\n"; 1310ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " default: return InvalidMatchClass;\n"; 1311ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar for (std::map<Record*, ClassInfo*>::iterator 1312ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar it = Info.RegisterClasses.begin(), ie = Info.RegisterClasses.end(); 1313ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar it != ie; ++it) 1314ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " case " << Target.getName() << "::" 1315ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar << it->first->getName() << ": return " << it->second->Name << ";\n"; 1316ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " }\n"; 1317ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " }\n\n"; 1318ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 1319ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Classify user defined operands. 1320ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar for (std::vector<ClassInfo*>::iterator it = Info.Classes.begin(), 1321ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar ie = Info.Classes.end(); it != ie; ++it) { 1322a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar ClassInfo &CI = **it; 1323a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1324ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (!CI.isUserClass()) 1325ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar continue; 1326ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 1327ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " // '" << CI.ClassName << "' class"; 1328ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (!CI.SuperClasses.empty()) { 1329ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << ", subclass of "; 1330ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar for (unsigned i = 0, e = CI.SuperClasses.size(); i != e; ++i) { 1331ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (i) OS << ", "; 1332ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << "'" << CI.SuperClasses[i]->ClassName << "'"; 1333ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar assert(CI < *CI.SuperClasses[i] && "Invalid class relation!"); 13345fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar } 1335ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar } 1336ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << "\n"; 13375fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar 1338ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " if (Operand." << CI.PredicateMethod << "()) {\n"; 13395fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar 1340ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar // Validate subclass relationships. 1341ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (!CI.SuperClasses.empty()) { 1342ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar for (unsigned i = 0, e = CI.SuperClasses.size(); i != e; ++i) 1343ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " assert(Operand." << CI.SuperClasses[i]->PredicateMethod 13445fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar << "() && \"Invalid class relationship!\");\n"; 1345a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 1346ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar 1347ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " return " << CI.Name << ";\n"; 1348ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " }\n\n"; 1349a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 1350a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " return InvalidMatchClass;\n"; 1351a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "}\n\n"; 1352a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar} 1353a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1354fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar/// EmitIsSubclass - Emit the subclass predicate function. 1355fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbarstatic void EmitIsSubclass(CodeGenTarget &Target, 1356fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar std::vector<ClassInfo*> &Infos, 1357fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar raw_ostream &OS) { 1358fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar OS << "/// IsSubclass - Compute whether \\arg A is a subclass of \\arg B.\n"; 1359fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar OS << "static bool IsSubclass(MatchClassKind A, MatchClassKind B) {\n"; 1360fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar OS << " if (A == B)\n"; 1361fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar OS << " return true;\n\n"; 1362fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar 1363fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar OS << " switch (A) {\n"; 1364fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar OS << " default:\n"; 1365fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar OS << " return false;\n"; 1366fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar for (std::vector<ClassInfo*>::iterator it = Infos.begin(), 1367fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar ie = Infos.end(); it != ie; ++it) { 1368fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar ClassInfo &A = **it; 1369fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar 1370fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar if (A.Kind != ClassInfo::Token) { 1371fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar std::vector<StringRef> SuperClasses; 1372fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar for (std::vector<ClassInfo*>::iterator it = Infos.begin(), 1373fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar ie = Infos.end(); it != ie; ++it) { 1374fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar ClassInfo &B = **it; 1375fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar 1376ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar if (&A != &B && A.isSubsetOf(B)) 1377fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar SuperClasses.push_back(B.Name); 1378fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar } 1379fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar 1380fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar if (SuperClasses.empty()) 1381fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar continue; 1382fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar 1383fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar OS << "\n case " << A.Name << ":\n"; 1384fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar 1385fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar if (SuperClasses.size() == 1) { 1386ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " return B == " << SuperClasses.back() << ";\n"; 1387fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar continue; 1388fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar } 1389fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar 1390ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " switch (B) {\n"; 1391ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " default: return false;\n"; 1392fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i) 1393ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " case " << SuperClasses[i] << ": return true;\n"; 1394ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar OS << " }\n"; 1395fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar } 1396fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar } 1397fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar OS << " }\n"; 1398fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar OS << "}\n\n"; 1399fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar} 1400fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar 140170add884e4967f511e2cbb35c61534186b9b418aChris Lattner 140270add884e4967f511e2cbb35c61534186b9b418aChris Lattner 1403245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar/// EmitMatchTokenString - Emit the function to match a token string to the 1404245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar/// appropriate match class value. 1405245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbarstatic void EmitMatchTokenString(CodeGenTarget &Target, 1406245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar std::vector<ClassInfo*> &Infos, 1407245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar raw_ostream &OS) { 1408245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar // Construct the match list. 14095845e5c62b42d025557765006515156691a6a8b1Chris Lattner std::vector<StringMatcher::StringPair> Matches; 1410245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar for (std::vector<ClassInfo*>::iterator it = Infos.begin(), 1411245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar ie = Infos.end(); it != ie; ++it) { 1412245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar ClassInfo &CI = **it; 1413245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar 1414245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar if (CI.Kind == ClassInfo::Token) 14155845e5c62b42d025557765006515156691a6a8b1Chris Lattner Matches.push_back(StringMatcher::StringPair(CI.ValueName, 14165845e5c62b42d025557765006515156691a6a8b1Chris Lattner "return " + CI.Name + ";")); 1417245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar } 1418245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar 1419b8d6e98e566724f58344d275a4bd675249bb713aChris Lattner OS << "static MatchClassKind MatchTokenString(StringRef Name) {\n"; 1420245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar 14215845e5c62b42d025557765006515156691a6a8b1Chris Lattner StringMatcher("Name", Matches, OS).Emit(); 1422245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar 1423245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar OS << " return InvalidMatchClass;\n"; 1424245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar OS << "}\n\n"; 1425245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar} 142670add884e4967f511e2cbb35c61534186b9b418aChris Lattner 14272234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar/// EmitMatchRegisterName - Emit the function to match a string to the target 14282234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar/// specific register enum. 14292234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbarstatic void EmitMatchRegisterName(CodeGenTarget &Target, Record *AsmParser, 14302234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar raw_ostream &OS) { 1431245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar // Construct the match list. 14325845e5c62b42d025557765006515156691a6a8b1Chris Lattner std::vector<StringMatcher::StringPair> Matches; 1433245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar for (unsigned i = 0, e = Target.getRegisters().size(); i != e; ++i) { 1434245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar const CodeGenRegister &Reg = Target.getRegisters()[i]; 143520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (Reg.TheDef->getValueAsString("AsmName").empty()) 143620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar continue; 143720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 14385845e5c62b42d025557765006515156691a6a8b1Chris Lattner Matches.push_back(StringMatcher::StringPair( 14395845e5c62b42d025557765006515156691a6a8b1Chris Lattner Reg.TheDef->getValueAsString("AsmName"), 14405845e5c62b42d025557765006515156691a6a8b1Chris Lattner "return " + utostr(i + 1) + ";")); 144120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 144270add884e4967f511e2cbb35c61534186b9b418aChris Lattner 1443b8d6e98e566724f58344d275a4bd675249bb713aChris Lattner OS << "static unsigned MatchRegisterName(StringRef Name) {\n"; 1444245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar 14455845e5c62b42d025557765006515156691a6a8b1Chris Lattner StringMatcher("Name", Matches, OS).Emit(); 144670add884e4967f511e2cbb35c61534186b9b418aChris Lattner 1447245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar OS << " return 0;\n"; 144820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar OS << "}\n\n"; 14492234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar} 14502234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar 145154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar/// EmitSubtargetFeatureFlagEnumeration - Emit the subtarget feature flag 145254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar/// definitions. 145354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbarstatic void EmitSubtargetFeatureFlagEnumeration(CodeGenTarget &Target, 145454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar AsmMatcherInfo &Info, 145554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar raw_ostream &OS) { 145654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << "// Flags for subtarget features that participate in " 145754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar << "instruction matching.\n"; 145854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << "enum SubtargetFeatureFlag {\n"; 145954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar for (std::map<Record*, SubtargetFeatureInfo*>::const_iterator 146054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar it = Info.SubtargetFeatures.begin(), 146154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar ie = Info.SubtargetFeatures.end(); it != ie; ++it) { 146254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar SubtargetFeatureInfo &SFI = *it->second; 146354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << " " << SFI.EnumName << " = (1 << " << SFI.Index << "),\n"; 146454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar } 146554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << " Feature_None = 0\n"; 146654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << "};\n\n"; 146754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar} 146854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 146954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar/// EmitComputeAvailableFeatures - Emit the function to compute the list of 147054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar/// available features given a subtarget. 147154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbarstatic void EmitComputeAvailableFeatures(CodeGenTarget &Target, 147254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar AsmMatcherInfo &Info, 147354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar raw_ostream &OS) { 147454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar std::string ClassName = 147554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar Info.AsmParser->getValueAsString("AsmParserClassName"); 147654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 147754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << "unsigned " << Target.getName() << ClassName << "::\n" 147854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar << "ComputeAvailableFeatures(const " << Target.getName() 147954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar << "Subtarget *Subtarget) const {\n"; 148054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << " unsigned Features = 0;\n"; 148154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar for (std::map<Record*, SubtargetFeatureInfo*>::const_iterator 148254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar it = Info.SubtargetFeatures.begin(), 148354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar ie = Info.SubtargetFeatures.end(); it != ie; ++it) { 148454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar SubtargetFeatureInfo &SFI = *it->second; 148554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << " if (" << SFI.TheDef->getValueAsString("CondString") 148654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar << ")\n"; 148754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << " Features |= " << SFI.EnumName << ";\n"; 148854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar } 148954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << " return Features;\n"; 149054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << "}\n\n"; 149154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar} 149254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 14932234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbarvoid AsmMatcherEmitter::run(raw_ostream &OS) { 14942234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar CodeGenTarget Target; 14952234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar Record *AsmParser = Target.getAsmParser(); 14962234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar std::string ClassName = AsmParser->getValueAsString("AsmParserClassName"); 14972234e5eee6d196594d42e6f2be51e176bf5e5f6eDaniel Dunbar 1498a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // Compute the information on the instructions to match. 149959fc42debd571bbafc52c20bc418fdc3f4d00188Daniel Dunbar AsmMatcherInfo Info(AsmParser); 1500a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Info.BuildInfo(Target); 150120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 1502e1f6de3fbd892ea3f918a26912660cf316866fc1Daniel Dunbar // Sort the instruction table using the partial order on classes. We use 1503e1f6de3fbd892ea3f918a26912660cf316866fc1Daniel Dunbar // stable_sort to ensure that ambiguous instructions are still 1504e1f6de3fbd892ea3f918a26912660cf316866fc1Daniel Dunbar // deterministically ordered. 1505e1f6de3fbd892ea3f918a26912660cf316866fc1Daniel Dunbar std::stable_sort(Info.Instructions.begin(), Info.Instructions.end(), 1506e1f6de3fbd892ea3f918a26912660cf316866fc1Daniel Dunbar less_ptr<InstructionInfo>()); 1507606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 1508b7479c035534b1c240117cd0aea8342393160da8Daniel Dunbar DEBUG_WITH_TYPE("instruction_info", { 1509a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar for (std::vector<InstructionInfo*>::iterator 1510a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar it = Info.Instructions.begin(), ie = Info.Instructions.end(); 1511a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar it != ie; ++it) 151220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar (*it)->dump(); 151320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar }); 151420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 1515606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar // Check for ambiguous instructions. 1516606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar unsigned NumAmbiguous = 0; 15172b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar for (unsigned i = 0, e = Info.Instructions.size(); i != e; ++i) { 15182b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar for (unsigned j = i + 1; j != e; ++j) { 15192b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar InstructionInfo &A = *Info.Instructions[i]; 15202b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar InstructionInfo &B = *Info.Instructions[j]; 1521606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 15222b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar if (A.CouldMatchAmiguouslyWith(B)) { 15232b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar DEBUG_WITH_TYPE("ambiguous_instrs", { 15242b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar errs() << "warning: ambiguous instruction match:\n"; 15252b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar A.dump(); 15262b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar errs() << "\nis incomparable with:\n"; 15272b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar B.dump(); 15282b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar errs() << "\n\n"; 15292b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar }); 15302b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar ++NumAmbiguous; 15312b54481a77696d47dc9220cd7a36155599750904Daniel Dunbar } 1532606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar } 1533606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar } 1534606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar if (NumAmbiguous) 1535606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar DEBUG_WITH_TYPE("ambiguous_instrs", { 1536606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar errs() << "warning: " << NumAmbiguous 1537606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar << " ambiguous instructions!\n"; 1538606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar }); 1539606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar 15401095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar // Write the output. 15411095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 15421095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar EmitSourceFileHeader("Assembly Matcher Source Fragment", OS); 15431095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 15440692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner // Information for the class declaration. 15450692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner OS << "\n#ifdef GET_ASSEMBLER_HEADER\n"; 15460692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner OS << "#undef GET_ASSEMBLER_HEADER\n"; 154779ed3f77e8b87615b80054ca6e4e3ba5e07445bdChris Lattner OS << " // This should be included into the middle of the declaration of \n"; 154879ed3f77e8b87615b80054ca6e4e3ba5e07445bdChris Lattner OS << " // your subclasses implementation of TargetAsmParser.\n"; 15490692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner OS << " unsigned ComputeAvailableFeatures(const " << 15500692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner Target.getName() << "Subtarget *Subtarget) const;\n"; 155179ed3f77e8b87615b80054ca6e4e3ba5e07445bdChris Lattner OS << " enum MatchResultTy {\n"; 1552ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner OS << " Match_Success, Match_Fail, Match_MissingFeature\n"; 155379ed3f77e8b87615b80054ca6e4e3ba5e07445bdChris Lattner OS << " };\n"; 155479ed3f77e8b87615b80054ca6e4e3ba5e07445bdChris Lattner OS << " MatchResultTy MatchInstructionImpl(const SmallVectorImpl<MCParsedAsmOperand*>" 15550692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner << " &Operands, MCInst &Inst);\n\n"; 15560692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner OS << "#endif // GET_ASSEMBLER_HEADER_INFO\n\n"; 15570692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner 15580692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner 15590692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner 15600692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner 15610692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner OS << "\n#ifdef GET_REGISTER_MATCHER\n"; 15620692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner OS << "#undef GET_REGISTER_MATCHER\n\n"; 15630692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner 156454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar // Emit the subtarget feature enumeration. 156554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar EmitSubtargetFeatureFlagEnumeration(Target, Info, OS); 156654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 15671095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar // Emit the function to match a register name to number. 15681095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar EmitMatchRegisterName(Target, AsmParser, OS); 15690692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner 15700692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner OS << "#endif // GET_REGISTER_MATCHER\n\n"; 1571e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan 15720692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner 15730692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner OS << "\n#ifdef GET_MATCHER_IMPLEMENTATION\n"; 15740692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner OS << "#undef GET_MATCHER_IMPLEMENTATION\n\n"; 15751095f2ae261d231a63d329b0ebbf6eaf566ff429Daniel Dunbar 1576606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar // Generate the unified function to convert operands into an MCInst. 1577606e8ad796f72824f5509e2657c44eca025d4bafDaniel Dunbar EmitConvertToMCInst(Target, Info.Instructions, OS); 1578a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1579a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // Emit the enumeration for classes which participate in matching. 1580a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar EmitMatchClassEnumeration(Target, Info.Classes, OS); 158120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 1582a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // Emit the routine to match token strings to their match class. 1583a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar EmitMatchTokenString(Target, Info.Classes, OS); 158420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 1585a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // Emit the routine to classify an operand. 1586ea6408f8cd17b065e414611e01a7133d118429e9Daniel Dunbar EmitClassifyOperand(Target, Info, OS); 1587a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1588fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar // Emit the subclass predicate routine. 1589fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar EmitIsSubclass(Target, Info.Classes, OS); 1590fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar 159154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar // Emit the available features compute function. 159254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar EmitComputeAvailableFeatures(Target, Info, OS); 159354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 1594a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // Finally, build the match function. 1595a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1596a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar size_t MaxNumOperands = 0; 1597a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar for (std::vector<InstructionInfo*>::const_iterator it = 1598a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Info.Instructions.begin(), ie = Info.Instructions.end(); 1599a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar it != ie; ++it) 1600a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar MaxNumOperands = std::max(MaxNumOperands, (*it)->Operands.size()); 16014f83e73a6d4d96a1a83bfd258b3bf937297c2957Daniel Dunbar 160279ed3f77e8b87615b80054ca6e4e3ba5e07445bdChris Lattner OS << Target.getName() << ClassName << "::MatchResultTy " 160379ed3f77e8b87615b80054ca6e4e3ba5e07445bdChris Lattner << Target.getName() << ClassName << "::\n" 16044f98f834593f0a107268d19a557b63f0da33a751Daniel Dunbar << "MatchInstructionImpl(const SmallVectorImpl<MCParsedAsmOperand*>" 16054f98f834593f0a107268d19a557b63f0da33a751Daniel Dunbar << " &Operands,\n"; 16064f98f834593f0a107268d19a557b63f0da33a751Daniel Dunbar OS << " MCInst &Inst) {\n"; 160720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 1608a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // Emit the static match table; unused classes get initalized to 0 which is 1609a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // guaranteed to be InvalidMatchClass. 1610a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // 1611a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // FIXME: We can reduce the size of this table very easily. First, we change 1612a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // it so that store the kinds in separate bit-fields for each index, which 1613a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // only needs to be the max width used for classes at that index (we also need 1614a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // to reject based on this during classification). If we then make sure to 1615a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // order the match kinds appropriately (putting mnemonics last), then we 1616a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // should only end up using a few bits for each class, especially the ones 1617a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // following the mnemonic. 1618c6049534605af5f13d1b5149488b0a9efd294582Chris Lattner OS << " static const struct MatchEntry {\n"; 1619a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " unsigned Opcode;\n"; 1620a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " ConversionKind ConvertFn;\n"; 1621a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " MatchClassKind Classes[" << MaxNumOperands << "];\n"; 162254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << " unsigned RequiredFeatures;\n"; 1623a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " } MatchTable[" << Info.Instructions.size() << "] = {\n"; 1624a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1625a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar for (std::vector<InstructionInfo*>::const_iterator it = 1626a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar Info.Instructions.begin(), ie = Info.Instructions.end(); 1627a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar it != ie; ++it) { 162820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar InstructionInfo &II = **it; 162920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 1630a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " { " << Target.getName() << "::" << II.InstrName 1631a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar << ", " << II.ConversionFnKind << ", { "; 163220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar for (unsigned i = 0, e = II.Operands.size(); i != e; ++i) { 163320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar InstructionInfo::Operand &Op = II.Operands[i]; 163420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 1635a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar if (i) OS << ", "; 1636a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << Op.Class->Name; 163720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 163854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << " }, "; 163954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 164054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar // Write the required features mask. 164154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar if (!II.RequiredFeatures.empty()) { 164254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar for (unsigned i = 0, e = II.RequiredFeatures.size(); i != e; ++i) { 164354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar if (i) OS << "|"; 164454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << II.RequiredFeatures[i]->EnumName; 164554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar } 164654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar } else 164754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << "0"; 164854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 164954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << "},\n"; 1650a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar } 1651a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1652a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " };\n\n"; 1653a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 165454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 165554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar // Emit code to get the available features. 165654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << " // Get the current feature set.\n"; 165754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar OS << " unsigned AvailableFeatures = getAvailableFeatures();\n\n"; 165854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 1659a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // Emit code to compute the class list for this operand vector. 1660a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " // Eliminate obvious mismatches.\n"; 1661a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " if (Operands.size() > " << MaxNumOperands << ")\n"; 166279ed3f77e8b87615b80054ca6e4e3ba5e07445bdChris Lattner OS << " return Match_Fail;\n\n"; 1663a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1664a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " // Compute the class list for this operand vector.\n"; 1665a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " MatchClassKind Classes[" << MaxNumOperands << "];\n"; 1666a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " for (unsigned i = 0, e = Operands.size(); i != e; ++i) {\n"; 1667a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " Classes[i] = ClassifyOperand(Operands[i]);\n\n"; 1668a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1669a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " // Check for invalid operands before matching.\n"; 1670a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " if (Classes[i] == InvalidMatchClass)\n"; 167179ed3f77e8b87615b80054ca6e4e3ba5e07445bdChris Lattner OS << " return Match_Fail;\n"; 1672a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " }\n\n"; 1673a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1674a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " // Mark unused classes.\n"; 1675a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " for (unsigned i = Operands.size(), e = " << MaxNumOperands << "; " 1676a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar << "i != e; ++i)\n"; 1677a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " Classes[i] = InvalidMatchClass;\n\n"; 1678a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar 1679a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar // Emit code to search the table. 1680a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " // Search the table.\n"; 1681ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner OS << " bool HadMatchOtherThanFeatures = false;\n"; 1682d39bd3aa5c795e55c0e2c4a5c72dab58ce1a1576Chris Lattner OS << " for (const MatchEntry *it = MatchTable, " 1683a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar << "*ie = MatchTable + " << Info.Instructions.size() 1684a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar << "; it != ie; ++it) {\n"; 168554074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar 168654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar // Emit check that the subclasses match. 1687a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar for (unsigned i = 0; i != MaxNumOperands; ++i) { 1688fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar OS << " if (!IsSubclass(Classes[" 1689fdb1f493ab6bcfb5603b9f497195492d92aceacbDaniel Dunbar << i << "], it->Classes[" << i << "]))\n"; 1690a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " continue;\n"; 1691a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar } 1692ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner 1693ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner // Emit check that the required features are available. 1694ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner OS << " if ((AvailableFeatures & it->RequiredFeatures) " 1695ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner << "!= it->RequiredFeatures) {\n"; 1696ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner OS << " HadMatchOtherThanFeatures = true;\n"; 1697ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner OS << " continue;\n"; 1698ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner OS << " }\n"; 16990692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner 1700a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << "\n"; 17018cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar OS << " ConvertToMCInst(it->ConvertFn, Inst, it->Opcode, Operands);\n"; 17028cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar 17038cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar // Call the post-processing function, if used. 17048cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar std::string InsnCleanupFn = 17058cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar AsmParser->getValueAsString("AsmParserInstCleanup"); 17068cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar if (!InsnCleanupFn.empty()) 17078cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar OS << " " << InsnCleanupFn << "(Inst);\n"; 17088cc9c0c487128c4d675d45803a0711c3e43534afDaniel Dunbar 170979ed3f77e8b87615b80054ca6e4e3ba5e07445bdChris Lattner OS << " return Match_Success;\n"; 1710a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar OS << " }\n\n"; 1711a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 1712ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner OS << " // Okay, we had no match. Try to return a useful error code.\n"; 1713ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner OS << " if (HadMatchOtherThanFeatures) return Match_MissingFeature;\n"; 171479ed3f77e8b87615b80054ca6e4e3ba5e07445bdChris Lattner OS << " return Match_Fail;\n"; 1715a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar OS << "}\n\n"; 1716e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan 17170692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner OS << "#endif // GET_MATCHER_IMPLEMENTATION\n\n"; 1718d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar} 1719