blob: 5464f8366e0674d0690d58eb0926b58cb789b5a6 [file] [log] [blame]
Daniel Dunbard51ffcf2009-07-11 19:39:44 +00001//===- AsmMatcherEmitter.cpp - Generate an assembly matcher ---------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This tablegen backend emits a target specifier matcher for converting parsed
11// assembly operands in the MCInst structures.
12//
Daniel Dunbar20927f22009-08-07 08:26:05 +000013// The input to the target specific matcher is a list of literal tokens and
14// operands. The target specific parser should generally eliminate any syntax
15// which is not relevant for matching; for example, comma tokens should have
16// already been consumed and eliminated by the parser. Most instructions will
17// end up with a single literal token (the instruction name) and some number of
18// operands.
19//
20// Some example inputs, for X86:
21// 'addl' (immediate ...) (register ...)
22// 'add' (immediate ...) (memory ...)
23// 'call' '*' %epc
24//
25// The assembly matcher is responsible for converting this input into a precise
26// machine instruction (i.e., an instruction with a well defined encoding). This
27// mapping has several properties which complicate matching:
28//
29// - It may be ambiguous; many architectures can legally encode particular
30// variants of an instruction in different ways (for example, using a smaller
31// encoding for small immediates). Such ambiguities should never be
32// arbitrarily resolved by the assembler, the assembler is always responsible
33// for choosing the "best" available instruction.
34//
35// - It may depend on the subtarget or the assembler context. Instructions
36// which are invalid for the current mode, but otherwise unambiguous (e.g.,
37// an SSE instruction in a file being assembled for i486) should be accepted
38// and rejected by the assembler front end. However, if the proper encoding
39// for an instruction is dependent on the assembler context then the matcher
40// is responsible for selecting the correct machine instruction for the
41// current mode.
42//
43// The core matching algorithm attempts to exploit the regularity in most
44// instruction sets to quickly determine the set of possibly matching
45// instructions, and the simplify the generated code. Additionally, this helps
46// to ensure that the ambiguities are intentionally resolved by the user.
47//
48// The matching is divided into two distinct phases:
49//
50// 1. Classification: Each operand is mapped to the unique set which (a)
51// contains it, and (b) is the largest such subset for which a single
52// instruction could match all members.
53//
54// For register classes, we can generate these subgroups automatically. For
55// arbitrary operands, we expect the user to define the classes and their
56// relations to one another (for example, 8-bit signed immediates as a
57// subset of 32-bit immediates).
58//
59// By partitioning the operands in this way, we guarantee that for any
60// tuple of classes, any single instruction must match either all or none
61// of the sets of operands which could classify to that tuple.
62//
63// In addition, the subset relation amongst classes induces a partial order
64// on such tuples, which we use to resolve ambiguities.
65//
66// FIXME: What do we do if a crazy case shows up where this is the wrong
67// resolution?
68//
69// 2. The input can now be treated as a tuple of classes (static tokens are
70// simple singleton sets). Each such tuple should generally map to a single
71// instruction (we currently ignore cases where this isn't true, whee!!!),
72// which we can emit a simple matcher for.
73//
Daniel Dunbard51ffcf2009-07-11 19:39:44 +000074//===----------------------------------------------------------------------===//
75
76#include "AsmMatcherEmitter.h"
77#include "CodeGenTarget.h"
78#include "Record.h"
Daniel Dunbar20927f22009-08-07 08:26:05 +000079#include "llvm/ADT/OwningPtr.h"
Daniel Dunbara027d222009-07-31 02:32:59 +000080#include "llvm/ADT/SmallVector.h"
Daniel Dunbar606e8ad2009-08-09 04:00:06 +000081#include "llvm/ADT/STLExtras.h"
Daniel Dunbar20927f22009-08-07 08:26:05 +000082#include "llvm/ADT/StringExtras.h"
83#include "llvm/Support/CommandLine.h"
Daniel Dunbara027d222009-07-31 02:32:59 +000084#include "llvm/Support/Debug.h"
Daniel Dunbara027d222009-07-31 02:32:59 +000085#include <list>
Daniel Dunbarb7479c02009-08-08 05:24:34 +000086#include <map>
87#include <set>
Daniel Dunbard51ffcf2009-07-11 19:39:44 +000088using namespace llvm;
89
Daniel Dunbar27249152009-08-07 20:33:39 +000090static cl::opt<std::string>
Daniel Dunbar606e8ad2009-08-09 04:00:06 +000091MatchPrefix("match-prefix", cl::init(""),
92 cl::desc("Only match instructions with the given prefix"));
Daniel Dunbar20927f22009-08-07 08:26:05 +000093
Daniel Dunbara027d222009-07-31 02:32:59 +000094/// FlattenVariants - Flatten an .td file assembly string by selecting the
95/// variant at index \arg N.
96static std::string FlattenVariants(const std::string &AsmString,
97 unsigned N) {
98 StringRef Cur = AsmString;
99 std::string Res = "";
100
101 for (;;) {
Daniel Dunbar53a7f162009-08-04 20:36:45 +0000102 // Find the start of the next variant string.
103 size_t VariantsStart = 0;
104 for (size_t e = Cur.size(); VariantsStart != e; ++VariantsStart)
105 if (Cur[VariantsStart] == '{' &&
Daniel Dunbar20927f22009-08-07 08:26:05 +0000106 (VariantsStart == 0 || (Cur[VariantsStart-1] != '$' &&
107 Cur[VariantsStart-1] != '\\')))
Daniel Dunbar53a7f162009-08-04 20:36:45 +0000108 break;
Daniel Dunbara027d222009-07-31 02:32:59 +0000109
Daniel Dunbar53a7f162009-08-04 20:36:45 +0000110 // Add the prefix to the result.
111 Res += Cur.slice(0, VariantsStart);
112 if (VariantsStart == Cur.size())
Daniel Dunbara027d222009-07-31 02:32:59 +0000113 break;
114
Daniel Dunbar53a7f162009-08-04 20:36:45 +0000115 ++VariantsStart; // Skip the '{'.
116
117 // Scan to the end of the variants string.
118 size_t VariantsEnd = VariantsStart;
119 unsigned NestedBraces = 1;
120 for (size_t e = Cur.size(); VariantsEnd != e; ++VariantsEnd) {
Daniel Dunbar20927f22009-08-07 08:26:05 +0000121 if (Cur[VariantsEnd] == '}' && Cur[VariantsEnd-1] != '\\') {
Daniel Dunbar53a7f162009-08-04 20:36:45 +0000122 if (--NestedBraces == 0)
123 break;
124 } else if (Cur[VariantsEnd] == '{')
125 ++NestedBraces;
126 }
Daniel Dunbara027d222009-07-31 02:32:59 +0000127
128 // Select the Nth variant (or empty).
Daniel Dunbar53a7f162009-08-04 20:36:45 +0000129 StringRef Selection = Cur.slice(VariantsStart, VariantsEnd);
Daniel Dunbara027d222009-07-31 02:32:59 +0000130 for (unsigned i = 0; i != N; ++i)
131 Selection = Selection.split('|').second;
132 Res += Selection.split('|').first;
133
Daniel Dunbar53a7f162009-08-04 20:36:45 +0000134 assert(VariantsEnd != Cur.size() &&
135 "Unterminated variants in assembly string!");
136 Cur = Cur.substr(VariantsEnd + 1);
Daniel Dunbara027d222009-07-31 02:32:59 +0000137 }
138
139 return Res;
140}
141
142/// TokenizeAsmString - Tokenize a simplified assembly string.
Chris Lattnerb8d6e982010-02-09 00:34:28 +0000143static void TokenizeAsmString(StringRef AsmString,
Daniel Dunbara027d222009-07-31 02:32:59 +0000144 SmallVectorImpl<StringRef> &Tokens) {
145 unsigned Prev = 0;
146 bool InTok = true;
147 for (unsigned i = 0, e = AsmString.size(); i != e; ++i) {
148 switch (AsmString[i]) {
Daniel Dunbar20927f22009-08-07 08:26:05 +0000149 case '[':
150 case ']':
Daniel Dunbara027d222009-07-31 02:32:59 +0000151 case '*':
152 case '!':
153 case ' ':
154 case '\t':
155 case ',':
156 if (InTok) {
Daniel Dunbar20927f22009-08-07 08:26:05 +0000157 Tokens.push_back(AsmString.slice(Prev, i));
Daniel Dunbara027d222009-07-31 02:32:59 +0000158 InTok = false;
159 }
Daniel Dunbar20927f22009-08-07 08:26:05 +0000160 if (!isspace(AsmString[i]) && AsmString[i] != ',')
161 Tokens.push_back(AsmString.substr(i, 1));
Daniel Dunbara027d222009-07-31 02:32:59 +0000162 Prev = i + 1;
163 break;
Daniel Dunbar20927f22009-08-07 08:26:05 +0000164
165 case '\\':
166 if (InTok) {
167 Tokens.push_back(AsmString.slice(Prev, i));
168 InTok = false;
169 }
170 ++i;
171 assert(i != AsmString.size() && "Invalid quoted character");
172 Tokens.push_back(AsmString.substr(i, 1));
173 Prev = i + 1;
174 break;
175
176 case '$': {
177 // If this isn't "${", treat like a normal token.
178 if (i + 1 == AsmString.size() || AsmString[i + 1] != '{') {
179 if (InTok) {
180 Tokens.push_back(AsmString.slice(Prev, i));
181 InTok = false;
182 }
183 Prev = i;
184 break;
185 }
186
187 if (InTok) {
188 Tokens.push_back(AsmString.slice(Prev, i));
189 InTok = false;
190 }
191
192 StringRef::iterator End =
193 std::find(AsmString.begin() + i, AsmString.end(), '}');
194 assert(End != AsmString.end() && "Missing brace in operand reference!");
195 size_t EndPos = End - AsmString.begin();
196 Tokens.push_back(AsmString.slice(i, EndPos+1));
197 Prev = EndPos + 1;
198 i = EndPos;
199 break;
200 }
Daniel Dunbara027d222009-07-31 02:32:59 +0000201
202 default:
203 InTok = true;
204 }
205 }
206 if (InTok && Prev != AsmString.size())
Daniel Dunbar20927f22009-08-07 08:26:05 +0000207 Tokens.push_back(AsmString.substr(Prev));
208}
209
Chris Lattnerb8d6e982010-02-09 00:34:28 +0000210static bool IsAssemblerInstruction(StringRef Name,
Daniel Dunbar20927f22009-08-07 08:26:05 +0000211 const CodeGenInstruction &CGI,
212 const SmallVectorImpl<StringRef> &Tokens) {
Daniel Dunbar7417b762009-08-11 22:17:52 +0000213 // Ignore "codegen only" instructions.
214 if (CGI.TheDef->getValueAsBit("isCodeGenOnly"))
215 return false;
216
217 // Ignore pseudo ops.
Daniel Dunbar20927f22009-08-07 08:26:05 +0000218 //
Daniel Dunbar7417b762009-08-11 22:17:52 +0000219 // FIXME: This is a hack; can we convert these instructions to set the
220 // "codegen only" bit instead?
Daniel Dunbar20927f22009-08-07 08:26:05 +0000221 if (const RecordVal *Form = CGI.TheDef->getValue("Form"))
222 if (Form->getValue()->getAsString() == "Pseudo")
223 return false;
Daniel Dunbar20927f22009-08-07 08:26:05 +0000224
Daniel Dunbar72fa87f2009-08-09 08:19:00 +0000225 // Ignore "Int_*" and "*_Int" instructions, which are internal aliases.
226 //
227 // FIXME: This is a total hack.
228 if (StringRef(Name).startswith("Int_") || StringRef(Name).endswith("_Int"))
229 return false;
230
Daniel Dunbar20927f22009-08-07 08:26:05 +0000231 // Ignore instructions with no .s string.
232 //
233 // FIXME: What are these?
234 if (CGI.AsmString.empty())
235 return false;
236
237 // FIXME: Hack; ignore any instructions with a newline in them.
238 if (std::find(CGI.AsmString.begin(),
239 CGI.AsmString.end(), '\n') != CGI.AsmString.end())
240 return false;
241
242 // Ignore instructions with attributes, these are always fake instructions for
243 // simplifying codegen.
244 //
245 // FIXME: Is this true?
246 //
Daniel Dunbar7417b762009-08-11 22:17:52 +0000247 // Also, check for instructions which reference the operand multiple times;
248 // this implies a constraint we would not honor.
Daniel Dunbar20927f22009-08-07 08:26:05 +0000249 std::set<std::string> OperandNames;
250 for (unsigned i = 1, e = Tokens.size(); i < e; ++i) {
251 if (Tokens[i][0] == '$' &&
252 std::find(Tokens[i].begin(),
253 Tokens[i].end(), ':') != Tokens[i].end()) {
254 DEBUG({
255 errs() << "warning: '" << Name << "': "
256 << "ignoring instruction; operand with attribute '"
Daniel Dunbar7417b762009-08-11 22:17:52 +0000257 << Tokens[i] << "'\n";
Daniel Dunbar20927f22009-08-07 08:26:05 +0000258 });
259 return false;
260 }
261
262 if (Tokens[i][0] == '$' && !OperandNames.insert(Tokens[i]).second) {
Daniel Dunbara9ba5fe2010-08-11 04:46:08 +0000263 DEBUG({
264 errs() << "warning: '" << Name << "': "
265 << "ignoring instruction with tied operand '"
266 << Tokens[i].str() << "'\n";
267 });
268 return false;
Daniel Dunbar20927f22009-08-07 08:26:05 +0000269 }
270 }
271
272 return true;
273}
274
275namespace {
276
Daniel Dunbar54074b52010-07-19 05:44:09 +0000277struct SubtargetFeatureInfo;
278
Daniel Dunbara3741fa2009-08-08 07:50:56 +0000279/// ClassInfo - Helper class for storing the information about a particular
280/// class of operands which can be matched.
281struct ClassInfo {
Daniel Dunbar606e8ad2009-08-09 04:00:06 +0000282 enum ClassInfoKind {
Daniel Dunbarea6408f2009-08-11 02:59:53 +0000283 /// Invalid kind, for use as a sentinel value.
284 Invalid = 0,
285
286 /// The class for a particular token.
287 Token,
288
289 /// The (first) register class, subsequent register classes are
290 /// RegisterClass0+1, and so on.
291 RegisterClass0,
292
293 /// The (first) user defined class, subsequent user defined classes are
294 /// UserClass0+1, and so on.
295 UserClass0 = 1<<16
Daniel Dunbar606e8ad2009-08-09 04:00:06 +0000296 };
297
298 /// Kind - The class kind, which is either a predefined kind, or (UserClass0 +
299 /// N) for the Nth user defined class.
300 unsigned Kind;
Daniel Dunbara3741fa2009-08-08 07:50:56 +0000301
Daniel Dunbarea6408f2009-08-11 02:59:53 +0000302 /// SuperClasses - The super classes of this class. Note that for simplicities
303 /// sake user operands only record their immediate super class, while register
304 /// operands include all superclasses.
305 std::vector<ClassInfo*> SuperClasses;
Daniel Dunbar5fe63382009-08-09 07:20:21 +0000306
Daniel Dunbar6745d422009-08-09 05:18:30 +0000307 /// Name - The full class name, suitable for use in an enum.
Daniel Dunbara3741fa2009-08-08 07:50:56 +0000308 std::string Name;
309
Daniel Dunbar6745d422009-08-09 05:18:30 +0000310 /// ClassName - The unadorned generic name for this class (e.g., Token).
311 std::string ClassName;
312
Daniel Dunbara3741fa2009-08-08 07:50:56 +0000313 /// ValueName - The name of the value this class represents; for a token this
314 /// is the literal token string, for an operand it is the TableGen class (or
315 /// empty if this is a derived class).
316 std::string ValueName;
317
318 /// PredicateMethod - The name of the operand method to test whether the
Daniel Dunbarea6408f2009-08-11 02:59:53 +0000319 /// operand matches this class; this is not valid for Token or register kinds.
Daniel Dunbara3741fa2009-08-08 07:50:56 +0000320 std::string PredicateMethod;
321
322 /// RenderMethod - The name of the operand method to add this operand to an
Daniel Dunbarea6408f2009-08-11 02:59:53 +0000323 /// MCInst; this is not valid for Token or register kinds.
Daniel Dunbara3741fa2009-08-08 07:50:56 +0000324 std::string RenderMethod;
Daniel Dunbar606e8ad2009-08-09 04:00:06 +0000325
Daniel Dunbar8409bfb2009-08-11 20:10:07 +0000326 /// For register classes, the records for all the registers in this class.
327 std::set<Record*> Registers;
328
329public:
Daniel Dunbarea6408f2009-08-11 02:59:53 +0000330 /// isRegisterClass() - Check if this is a register class.
331 bool isRegisterClass() const {
332 return Kind >= RegisterClass0 && Kind < UserClass0;
333 }
334
Daniel Dunbar5fe63382009-08-09 07:20:21 +0000335 /// isUserClass() - Check if this is a user defined class.
336 bool isUserClass() const {
337 return Kind >= UserClass0;
338 }
339
Daniel Dunbarea6408f2009-08-11 02:59:53 +0000340 /// isRelatedTo - Check whether this class is "related" to \arg RHS. Classes
341 /// are related if they are in the same class hierarchy.
342 bool isRelatedTo(const ClassInfo &RHS) const {
343 // Tokens are only related to tokens.
344 if (Kind == Token || RHS.Kind == Token)
345 return Kind == Token && RHS.Kind == Token;
346
Daniel Dunbar8409bfb2009-08-11 20:10:07 +0000347 // Registers classes are only related to registers classes, and only if
348 // their intersection is non-empty.
349 if (isRegisterClass() || RHS.isRegisterClass()) {
350 if (!isRegisterClass() || !RHS.isRegisterClass())
351 return false;
352
353 std::set<Record*> Tmp;
354 std::insert_iterator< std::set<Record*> > II(Tmp, Tmp.begin());
355 std::set_intersection(Registers.begin(), Registers.end(),
356 RHS.Registers.begin(), RHS.Registers.end(),
357 II);
358
359 return !Tmp.empty();
360 }
Daniel Dunbarea6408f2009-08-11 02:59:53 +0000361
362 // Otherwise we have two users operands; they are related if they are in the
363 // same class hierarchy.
Daniel Dunbar8409bfb2009-08-11 20:10:07 +0000364 //
365 // FIXME: This is an oversimplification, they should only be related if they
366 // intersect, however we don't have that information.
Daniel Dunbarea6408f2009-08-11 02:59:53 +0000367 assert(isUserClass() && RHS.isUserClass() && "Unexpected class!");
368 const ClassInfo *Root = this;
369 while (!Root->SuperClasses.empty())
370 Root = Root->SuperClasses.front();
371
Daniel Dunbar8409bfb2009-08-11 20:10:07 +0000372 const ClassInfo *RHSRoot = &RHS;
Daniel Dunbarea6408f2009-08-11 02:59:53 +0000373 while (!RHSRoot->SuperClasses.empty())
374 RHSRoot = RHSRoot->SuperClasses.front();
375
376 return Root == RHSRoot;
377 }
378
379 /// isSubsetOf - Test whether this class is a subset of \arg RHS;
380 bool isSubsetOf(const ClassInfo &RHS) const {
381 // This is a subset of RHS if it is the same class...
382 if (this == &RHS)
383 return true;
384
385 // ... or if any of its super classes are a subset of RHS.
386 for (std::vector<ClassInfo*>::const_iterator it = SuperClasses.begin(),
387 ie = SuperClasses.end(); it != ie; ++it)
388 if ((*it)->isSubsetOf(RHS))
389 return true;
390
391 return false;
Daniel Dunbar5fe63382009-08-09 07:20:21 +0000392 }
393
Daniel Dunbar606e8ad2009-08-09 04:00:06 +0000394 /// operator< - Compare two classes.
395 bool operator<(const ClassInfo &RHS) const {
Daniel Dunbar368a4562010-05-27 05:31:32 +0000396 if (this == &RHS)
397 return false;
398
Daniel Dunbarea6408f2009-08-11 02:59:53 +0000399 // Unrelated classes can be ordered by kind.
400 if (!isRelatedTo(RHS))
Daniel Dunbar606e8ad2009-08-09 04:00:06 +0000401 return Kind < RHS.Kind;
402
403 switch (Kind) {
Daniel Dunbar6745d422009-08-09 05:18:30 +0000404 case Invalid:
405 assert(0 && "Invalid kind!");
Daniel Dunbar606e8ad2009-08-09 04:00:06 +0000406 case Token:
Daniel Dunbar5fe63382009-08-09 07:20:21 +0000407 // Tokens are comparable by value.
Daniel Dunbar606e8ad2009-08-09 04:00:06 +0000408 //
409 // FIXME: Compare by enum value.
410 return ValueName < RHS.ValueName;
411
Daniel Dunbar606e8ad2009-08-09 04:00:06 +0000412 default:
Daniel Dunbarea6408f2009-08-11 02:59:53 +0000413 // This class preceeds the RHS if it is a proper subset of the RHS.
Daniel Dunbar368a4562010-05-27 05:31:32 +0000414 if (isSubsetOf(RHS))
Duncan Sands34727662010-07-12 08:16:59 +0000415 return true;
Daniel Dunbar368a4562010-05-27 05:31:32 +0000416 if (RHS.isSubsetOf(*this))
Duncan Sands34727662010-07-12 08:16:59 +0000417 return false;
Daniel Dunbar368a4562010-05-27 05:31:32 +0000418
419 // Otherwise, order by name to ensure we have a total ordering.
420 return ValueName < RHS.ValueName;
Daniel Dunbar606e8ad2009-08-09 04:00:06 +0000421 }
422 }
Daniel Dunbara3741fa2009-08-08 07:50:56 +0000423};
424
Daniel Dunbarb7479c02009-08-08 05:24:34 +0000425/// InstructionInfo - Helper class for storing the necessary information for an
426/// instruction which is capable of being matched.
Daniel Dunbar20927f22009-08-07 08:26:05 +0000427struct InstructionInfo {
428 struct Operand {
Daniel Dunbara3741fa2009-08-08 07:50:56 +0000429 /// The unique class instance this operand should match.
430 ClassInfo *Class;
Daniel Dunbar20927f22009-08-07 08:26:05 +0000431
Daniel Dunbara3741fa2009-08-08 07:50:56 +0000432 /// The original operand this corresponds to, if any.
Benjamin Kramerfa1165a2009-08-08 10:06:30 +0000433 const CodeGenInstruction::OperandInfo *OperandInfo;
Daniel Dunbar20927f22009-08-07 08:26:05 +0000434 };
435
436 /// InstrName - The target name for this instruction.
437 std::string InstrName;
438
439 /// Instr - The instruction this matches.
440 const CodeGenInstruction *Instr;
441
442 /// AsmString - The assembly string for this instruction (with variants
443 /// removed).
444 std::string AsmString;
445
446 /// Tokens - The tokenized assembly pattern that this instruction matches.
447 SmallVector<StringRef, 4> Tokens;
448
449 /// Operands - The operands that this instruction matches.
450 SmallVector<Operand, 4> Operands;
451
Daniel Dunbar54074b52010-07-19 05:44:09 +0000452 /// Predicates - The required subtarget features to match this instruction.
453 SmallVector<SubtargetFeatureInfo*, 4> RequiredFeatures;
454
Daniel Dunbarb7479c02009-08-08 05:24:34 +0000455 /// ConversionFnKind - The enum value which is passed to the generated
456 /// ConvertToMCInst to convert parsed operands into an MCInst for this
457 /// function.
458 std::string ConversionFnKind;
Daniel Dunbar20927f22009-08-07 08:26:05 +0000459
Daniel Dunbar606e8ad2009-08-09 04:00:06 +0000460 /// operator< - Compare two instructions.
461 bool operator<(const InstructionInfo &RHS) const {
Daniel Dunbar606e8ad2009-08-09 04:00:06 +0000462 if (Operands.size() != RHS.Operands.size())
463 return Operands.size() < RHS.Operands.size();
Daniel Dunbar606e8ad2009-08-09 04:00:06 +0000464
Daniel Dunbardb2ddb52009-08-09 08:23:23 +0000465 // Compare lexicographically by operand. The matcher validates that other
466 // orderings wouldn't be ambiguous using \see CouldMatchAmiguouslyWith().
467 for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
Daniel Dunbar606e8ad2009-08-09 04:00:06 +0000468 if (*Operands[i].Class < *RHS.Operands[i].Class)
469 return true;
Daniel Dunbardb2ddb52009-08-09 08:23:23 +0000470 if (*RHS.Operands[i].Class < *Operands[i].Class)
471 return false;
472 }
473
Daniel Dunbar606e8ad2009-08-09 04:00:06 +0000474 return false;
475 }
476
Daniel Dunbar2b544812009-08-09 06:05:33 +0000477 /// CouldMatchAmiguouslyWith - Check whether this instruction could
478 /// ambiguously match the same set of operands as \arg RHS (without being a
479 /// strictly superior match).
480 bool CouldMatchAmiguouslyWith(const InstructionInfo &RHS) {
481 // The number of operands is unambiguous.
482 if (Operands.size() != RHS.Operands.size())
483 return false;
484
Daniel Dunbar1402f0b2010-01-23 00:26:16 +0000485 // Otherwise, make sure the ordering of the two instructions is unambiguous
486 // by checking that either (a) a token or operand kind discriminates them,
487 // or (b) the ordering among equivalent kinds is consistent.
488
Daniel Dunbar2b544812009-08-09 06:05:33 +0000489 // Tokens and operand kinds are unambiguous (assuming a correct target
490 // specific parser).
491 for (unsigned i = 0, e = Operands.size(); i != e; ++i)
492 if (Operands[i].Class->Kind != RHS.Operands[i].Class->Kind ||
493 Operands[i].Class->Kind == ClassInfo::Token)
494 if (*Operands[i].Class < *RHS.Operands[i].Class ||
495 *RHS.Operands[i].Class < *Operands[i].Class)
496 return false;
497
498 // Otherwise, this operand could commute if all operands are equivalent, or
499 // there is a pair of operands that compare less than and a pair that
500 // compare greater than.
501 bool HasLT = false, HasGT = false;
502 for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
503 if (*Operands[i].Class < *RHS.Operands[i].Class)
504 HasLT = true;
505 if (*RHS.Operands[i].Class < *Operands[i].Class)
506 HasGT = true;
507 }
508
509 return !(HasLT ^ HasGT);
510 }
511
Daniel Dunbar20927f22009-08-07 08:26:05 +0000512public:
513 void dump();
514};
515
Daniel Dunbar54074b52010-07-19 05:44:09 +0000516/// SubtargetFeatureInfo - Helper class for storing information on a subtarget
517/// feature which participates in instruction matching.
518struct SubtargetFeatureInfo {
519 /// \brief The predicate record for this feature.
520 Record *TheDef;
521
522 /// \brief An unique index assigned to represent this feature.
523 unsigned Index;
524
525 /// \brief The name of the enumerated constant identifying this feature.
526 std::string EnumName;
527};
528
Daniel Dunbara3741fa2009-08-08 07:50:56 +0000529class AsmMatcherInfo {
530public:
Daniel Dunbar59fc42d2009-08-11 20:59:47 +0000531 /// The tablegen AsmParser record.
532 Record *AsmParser;
533
534 /// The AsmParser "CommentDelimiter" value.
535 std::string CommentDelimiter;
536
537 /// The AsmParser "RegisterPrefix" value.
538 std::string RegisterPrefix;
539
Daniel Dunbara3741fa2009-08-08 07:50:56 +0000540 /// The classes which are needed for matching.
541 std::vector<ClassInfo*> Classes;
542
543 /// The information on the instruction to match.
544 std::vector<InstructionInfo*> Instructions;
545
Daniel Dunbarea6408f2009-08-11 02:59:53 +0000546 /// Map of Register records to their class information.
547 std::map<Record*, ClassInfo*> RegisterClasses;
548
Daniel Dunbar54074b52010-07-19 05:44:09 +0000549 /// Map of Predicate records to their subtarget information.
550 std::map<Record*, SubtargetFeatureInfo*> SubtargetFeatures;
551
Daniel Dunbara3741fa2009-08-08 07:50:56 +0000552private:
553 /// Map of token to class information which has already been constructed.
554 std::map<std::string, ClassInfo*> TokenClasses;
555
Daniel Dunbarea6408f2009-08-11 02:59:53 +0000556 /// Map of RegisterClass records to their class information.
557 std::map<Record*, ClassInfo*> RegisterClassClasses;
Daniel Dunbara3741fa2009-08-08 07:50:56 +0000558
Daniel Dunbar338825c2009-08-10 18:41:10 +0000559 /// Map of AsmOperandClass records to their class information.
560 std::map<Record*, ClassInfo*> AsmOperandClasses;
Daniel Dunbar6745d422009-08-09 05:18:30 +0000561
Daniel Dunbara3741fa2009-08-08 07:50:56 +0000562private:
563 /// getTokenClass - Lookup or create the class for the given token.
Chris Lattnerb8d6e982010-02-09 00:34:28 +0000564 ClassInfo *getTokenClass(StringRef Token);
Daniel Dunbara3741fa2009-08-08 07:50:56 +0000565
566 /// getOperandClass - Lookup or create the class for the given operand.
Chris Lattnerb8d6e982010-02-09 00:34:28 +0000567 ClassInfo *getOperandClass(StringRef Token,
Daniel Dunbara3741fa2009-08-08 07:50:56 +0000568 const CodeGenInstruction::OperandInfo &OI);
569
Daniel Dunbar54074b52010-07-19 05:44:09 +0000570 /// getSubtargetFeature - Lookup or create the subtarget feature info for the
571 /// given operand.
572 SubtargetFeatureInfo *getSubtargetFeature(Record *Def) {
573 assert(Def->isSubClassOf("Predicate") && "Invalid predicate type!");
574
575 SubtargetFeatureInfo *&Entry = SubtargetFeatures[Def];
576 if (!Entry) {
577 Entry = new SubtargetFeatureInfo;
578 Entry->TheDef = Def;
579 Entry->Index = SubtargetFeatures.size() - 1;
580 Entry->EnumName = "Feature_" + Def->getName();
581 assert(Entry->Index < 32 && "Too many subtarget features!");
582 }
583
584 return Entry;
585 }
586
Daniel Dunbarea6408f2009-08-11 02:59:53 +0000587 /// BuildRegisterClasses - Build the ClassInfo* instances for register
588 /// classes.
Daniel Dunbar1095f2a2009-08-11 23:23:44 +0000589 void BuildRegisterClasses(CodeGenTarget &Target,
590 std::set<std::string> &SingletonRegisterNames);
Daniel Dunbarea6408f2009-08-11 02:59:53 +0000591
592 /// BuildOperandClasses - Build the ClassInfo* instances for user defined
593 /// operand classes.
594 void BuildOperandClasses(CodeGenTarget &Target);
595
Daniel Dunbara3741fa2009-08-08 07:50:56 +0000596public:
Daniel Dunbar59fc42d2009-08-11 20:59:47 +0000597 AsmMatcherInfo(Record *_AsmParser);
598
Daniel Dunbara3741fa2009-08-08 07:50:56 +0000599 /// BuildInfo - Construct the various tables used during matching.
600 void BuildInfo(CodeGenTarget &Target);
601};
602
Daniel Dunbar20927f22009-08-07 08:26:05 +0000603}
604
605void InstructionInfo::dump() {
606 errs() << InstrName << " -- " << "flattened:\"" << AsmString << '\"'
607 << ", tokens:[";
608 for (unsigned i = 0, e = Tokens.size(); i != e; ++i) {
609 errs() << Tokens[i];
610 if (i + 1 != e)
611 errs() << ", ";
612 }
613 errs() << "]\n";
614
615 for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
616 Operand &Op = Operands[i];
Daniel Dunbar6745d422009-08-09 05:18:30 +0000617 errs() << " op[" << i << "] = " << Op.Class->ClassName << " - ";
Daniel Dunbara3741fa2009-08-08 07:50:56 +0000618 if (Op.Class->Kind == ClassInfo::Token) {
Daniel Dunbar20927f22009-08-07 08:26:05 +0000619 errs() << '\"' << Tokens[i] << "\"\n";
620 continue;
621 }
622
Daniel Dunbar1095f2a2009-08-11 23:23:44 +0000623 if (!Op.OperandInfo) {
624 errs() << "(singleton register)\n";
625 continue;
626 }
627
Benjamin Kramerfa1165a2009-08-08 10:06:30 +0000628 const CodeGenInstruction::OperandInfo &OI = *Op.OperandInfo;
Daniel Dunbar20927f22009-08-07 08:26:05 +0000629 errs() << OI.Name << " " << OI.Rec->getName()
630 << " (" << OI.MIOperandNo << ", " << OI.MINumOperands << ")\n";
631 }
632}
633
Chris Lattnerb8d6e982010-02-09 00:34:28 +0000634static std::string getEnumNameForToken(StringRef Str) {
Daniel Dunbara3741fa2009-08-08 07:50:56 +0000635 std::string Res;
636
637 for (StringRef::iterator it = Str.begin(), ie = Str.end(); it != ie; ++it) {
638 switch (*it) {
639 case '*': Res += "_STAR_"; break;
640 case '%': Res += "_PCT_"; break;
641 case ':': Res += "_COLON_"; break;
Daniel Dunbar20927f22009-08-07 08:26:05 +0000642
Daniel Dunbara3741fa2009-08-08 07:50:56 +0000643 default:
644 if (isalnum(*it)) {
645 Res += *it;
646 } else {
647 Res += "_" + utostr((unsigned) *it) + "_";
648 }
649 }
650 }
651
652 return Res;
653}
654
Daniel Dunbar1095f2a2009-08-11 23:23:44 +0000655/// getRegisterRecord - Get the register record for \arg name, or 0.
Chris Lattnerb8d6e982010-02-09 00:34:28 +0000656static Record *getRegisterRecord(CodeGenTarget &Target, StringRef Name) {
Daniel Dunbar1095f2a2009-08-11 23:23:44 +0000657 for (unsigned i = 0, e = Target.getRegisters().size(); i != e; ++i) {
658 const CodeGenRegister &Reg = Target.getRegisters()[i];
659 if (Name == Reg.TheDef->getValueAsString("AsmName"))
660 return Reg.TheDef;
661 }
662
663 return 0;
664}
665
Chris Lattnerb8d6e982010-02-09 00:34:28 +0000666ClassInfo *AsmMatcherInfo::getTokenClass(StringRef Token) {
Daniel Dunbara3741fa2009-08-08 07:50:56 +0000667 ClassInfo *&Entry = TokenClasses[Token];
668
669 if (!Entry) {
670 Entry = new ClassInfo();
671 Entry->Kind = ClassInfo::Token;
Daniel Dunbar6745d422009-08-09 05:18:30 +0000672 Entry->ClassName = "Token";
Daniel Dunbara3741fa2009-08-08 07:50:56 +0000673 Entry->Name = "MCK_" + getEnumNameForToken(Token);
674 Entry->ValueName = Token;
675 Entry->PredicateMethod = "<invalid>";
676 Entry->RenderMethod = "<invalid>";
677 Classes.push_back(Entry);
678 }
679
680 return Entry;
681}
682
683ClassInfo *
Chris Lattnerb8d6e982010-02-09 00:34:28 +0000684AsmMatcherInfo::getOperandClass(StringRef Token,
Daniel Dunbara3741fa2009-08-08 07:50:56 +0000685 const CodeGenInstruction::OperandInfo &OI) {
Daniel Dunbarea6408f2009-08-11 02:59:53 +0000686 if (OI.Rec->isSubClassOf("RegisterClass")) {
687 ClassInfo *CI = RegisterClassClasses[OI.Rec];
688
689 if (!CI) {
690 PrintError(OI.Rec->getLoc(), "register class has no class info!");
691 throw std::string("ERROR: Missing register class!");
692 }
693
694 return CI;
695 }
Daniel Dunbar5fe63382009-08-09 07:20:21 +0000696
Daniel Dunbar338825c2009-08-10 18:41:10 +0000697 assert(OI.Rec->isSubClassOf("Operand") && "Unexpected operand!");
698 Record *MatchClass = OI.Rec->getValueAsDef("ParserMatchClass");
699 ClassInfo *CI = AsmOperandClasses[MatchClass];
700
701 if (!CI) {
702 PrintError(OI.Rec->getLoc(), "operand has no match class!");
703 throw std::string("ERROR: Missing match class!");
Daniel Dunbara3741fa2009-08-08 07:50:56 +0000704 }
705
Daniel Dunbar338825c2009-08-10 18:41:10 +0000706 return CI;
Daniel Dunbara3741fa2009-08-08 07:50:56 +0000707}
708
Daniel Dunbar1095f2a2009-08-11 23:23:44 +0000709void AsmMatcherInfo::BuildRegisterClasses(CodeGenTarget &Target,
710 std::set<std::string>
711 &SingletonRegisterNames) {
Daniel Dunbarea6408f2009-08-11 02:59:53 +0000712 std::vector<CodeGenRegisterClass> RegisterClasses;
713 std::vector<CodeGenRegister> Registers;
Daniel Dunbar338825c2009-08-10 18:41:10 +0000714
Daniel Dunbarea6408f2009-08-11 02:59:53 +0000715 RegisterClasses = Target.getRegisterClasses();
716 Registers = Target.getRegisters();
Daniel Dunbar338825c2009-08-10 18:41:10 +0000717
Daniel Dunbarea6408f2009-08-11 02:59:53 +0000718 // The register sets used for matching.
719 std::set< std::set<Record*> > RegisterSets;
720
721 // Gather the defined sets.
722 for (std::vector<CodeGenRegisterClass>::iterator it = RegisterClasses.begin(),
723 ie = RegisterClasses.end(); it != ie; ++it)
724 RegisterSets.insert(std::set<Record*>(it->Elements.begin(),
725 it->Elements.end()));
Daniel Dunbar1095f2a2009-08-11 23:23:44 +0000726
727 // Add any required singleton sets.
728 for (std::set<std::string>::iterator it = SingletonRegisterNames.begin(),
729 ie = SingletonRegisterNames.end(); it != ie; ++it)
730 if (Record *Rec = getRegisterRecord(Target, *it))
731 RegisterSets.insert(std::set<Record*>(&Rec, &Rec + 1));
732
Daniel Dunbarea6408f2009-08-11 02:59:53 +0000733 // Introduce derived sets where necessary (when a register does not determine
734 // a unique register set class), and build the mapping of registers to the set
735 // they should classify to.
736 std::map<Record*, std::set<Record*> > RegisterMap;
737 for (std::vector<CodeGenRegister>::iterator it = Registers.begin(),
738 ie = Registers.end(); it != ie; ++it) {
739 CodeGenRegister &CGR = *it;
740 // Compute the intersection of all sets containing this register.
741 std::set<Record*> ContainingSet;
742
743 for (std::set< std::set<Record*> >::iterator it = RegisterSets.begin(),
744 ie = RegisterSets.end(); it != ie; ++it) {
745 if (!it->count(CGR.TheDef))
746 continue;
747
748 if (ContainingSet.empty()) {
749 ContainingSet = *it;
750 } else {
751 std::set<Record*> Tmp;
752 std::swap(Tmp, ContainingSet);
753 std::insert_iterator< std::set<Record*> > II(ContainingSet,
754 ContainingSet.begin());
755 std::set_intersection(Tmp.begin(), Tmp.end(), it->begin(), it->end(),
756 II);
757 }
758 }
759
760 if (!ContainingSet.empty()) {
761 RegisterSets.insert(ContainingSet);
762 RegisterMap.insert(std::make_pair(CGR.TheDef, ContainingSet));
763 }
764 }
765
766 // Construct the register classes.
767 std::map<std::set<Record*>, ClassInfo*> RegisterSetClasses;
768 unsigned Index = 0;
769 for (std::set< std::set<Record*> >::iterator it = RegisterSets.begin(),
770 ie = RegisterSets.end(); it != ie; ++it, ++Index) {
771 ClassInfo *CI = new ClassInfo();
772 CI->Kind = ClassInfo::RegisterClass0 + Index;
773 CI->ClassName = "Reg" + utostr(Index);
774 CI->Name = "MCK_Reg" + utostr(Index);
775 CI->ValueName = "";
776 CI->PredicateMethod = ""; // unused
777 CI->RenderMethod = "addRegOperands";
Daniel Dunbar8409bfb2009-08-11 20:10:07 +0000778 CI->Registers = *it;
Daniel Dunbarea6408f2009-08-11 02:59:53 +0000779 Classes.push_back(CI);
780 RegisterSetClasses.insert(std::make_pair(*it, CI));
781 }
782
783 // Find the superclasses; we could compute only the subgroup lattice edges,
784 // but there isn't really a point.
785 for (std::set< std::set<Record*> >::iterator it = RegisterSets.begin(),
786 ie = RegisterSets.end(); it != ie; ++it) {
787 ClassInfo *CI = RegisterSetClasses[*it];
788 for (std::set< std::set<Record*> >::iterator it2 = RegisterSets.begin(),
789 ie2 = RegisterSets.end(); it2 != ie2; ++it2)
790 if (*it != *it2 &&
791 std::includes(it2->begin(), it2->end(), it->begin(), it->end()))
792 CI->SuperClasses.push_back(RegisterSetClasses[*it2]);
793 }
794
795 // Name the register classes which correspond to a user defined RegisterClass.
796 for (std::vector<CodeGenRegisterClass>::iterator it = RegisterClasses.begin(),
797 ie = RegisterClasses.end(); it != ie; ++it) {
798 ClassInfo *CI = RegisterSetClasses[std::set<Record*>(it->Elements.begin(),
799 it->Elements.end())];
800 if (CI->ValueName.empty()) {
801 CI->ClassName = it->getName();
802 CI->Name = "MCK_" + it->getName();
803 CI->ValueName = it->getName();
804 } else
805 CI->ValueName = CI->ValueName + "," + it->getName();
806
807 RegisterClassClasses.insert(std::make_pair(it->TheDef, CI));
808 }
809
810 // Populate the map for individual registers.
811 for (std::map<Record*, std::set<Record*> >::iterator it = RegisterMap.begin(),
812 ie = RegisterMap.end(); it != ie; ++it)
813 this->RegisterClasses[it->first] = RegisterSetClasses[it->second];
Daniel Dunbar1095f2a2009-08-11 23:23:44 +0000814
815 // Name the register classes which correspond to singleton registers.
816 for (std::set<std::string>::iterator it = SingletonRegisterNames.begin(),
817 ie = SingletonRegisterNames.end(); it != ie; ++it) {
818 if (Record *Rec = getRegisterRecord(Target, *it)) {
819 ClassInfo *CI = this->RegisterClasses[Rec];
820 assert(CI && "Missing singleton register class info!");
821
822 if (CI->ValueName.empty()) {
823 CI->ClassName = Rec->getName();
824 CI->Name = "MCK_" + Rec->getName();
825 CI->ValueName = Rec->getName();
826 } else
827 CI->ValueName = CI->ValueName + "," + Rec->getName();
828 }
829 }
Daniel Dunbarea6408f2009-08-11 02:59:53 +0000830}
831
832void AsmMatcherInfo::BuildOperandClasses(CodeGenTarget &Target) {
Daniel Dunbar338825c2009-08-10 18:41:10 +0000833 std::vector<Record*> AsmOperands;
834 AsmOperands = Records.getAllDerivedDefinitions("AsmOperandClass");
Daniel Dunbara2f5e002010-01-30 01:02:37 +0000835
836 // Pre-populate AsmOperandClasses map.
837 for (std::vector<Record*>::iterator it = AsmOperands.begin(),
838 ie = AsmOperands.end(); it != ie; ++it)
839 AsmOperandClasses[*it] = new ClassInfo();
840
Daniel Dunbar338825c2009-08-10 18:41:10 +0000841 unsigned Index = 0;
842 for (std::vector<Record*>::iterator it = AsmOperands.begin(),
843 ie = AsmOperands.end(); it != ie; ++it, ++Index) {
Daniel Dunbara2f5e002010-01-30 01:02:37 +0000844 ClassInfo *CI = AsmOperandClasses[*it];
Daniel Dunbar338825c2009-08-10 18:41:10 +0000845 CI->Kind = ClassInfo::UserClass0 + Index;
846
Daniel Dunbar54ddf3d2010-05-22 21:02:29 +0000847 ListInit *Supers = (*it)->getValueAsListInit("SuperClasses");
848 for (unsigned i = 0, e = Supers->getSize(); i != e; ++i) {
849 DefInit *DI = dynamic_cast<DefInit*>(Supers->getElement(i));
850 if (!DI) {
851 PrintError((*it)->getLoc(), "Invalid super class reference!");
852 continue;
853 }
854
Daniel Dunbarea6408f2009-08-11 02:59:53 +0000855 ClassInfo *SC = AsmOperandClasses[DI->getDef()];
856 if (!SC)
Daniel Dunbar338825c2009-08-10 18:41:10 +0000857 PrintError((*it)->getLoc(), "Invalid super class reference!");
Daniel Dunbarea6408f2009-08-11 02:59:53 +0000858 else
859 CI->SuperClasses.push_back(SC);
Daniel Dunbar338825c2009-08-10 18:41:10 +0000860 }
861 CI->ClassName = (*it)->getValueAsString("Name");
862 CI->Name = "MCK_" + CI->ClassName;
863 CI->ValueName = (*it)->getName();
Daniel Dunbar5c468e32009-08-10 21:00:45 +0000864
865 // Get or construct the predicate method name.
866 Init *PMName = (*it)->getValueInit("PredicateMethod");
867 if (StringInit *SI = dynamic_cast<StringInit*>(PMName)) {
868 CI->PredicateMethod = SI->getValue();
869 } else {
870 assert(dynamic_cast<UnsetInit*>(PMName) &&
871 "Unexpected PredicateMethod field!");
872 CI->PredicateMethod = "is" + CI->ClassName;
873 }
874
875 // Get or construct the render method name.
876 Init *RMName = (*it)->getValueInit("RenderMethod");
877 if (StringInit *SI = dynamic_cast<StringInit*>(RMName)) {
878 CI->RenderMethod = SI->getValue();
879 } else {
880 assert(dynamic_cast<UnsetInit*>(RMName) &&
881 "Unexpected RenderMethod field!");
882 CI->RenderMethod = "add" + CI->ClassName + "Operands";
883 }
884
Daniel Dunbar338825c2009-08-10 18:41:10 +0000885 AsmOperandClasses[*it] = CI;
886 Classes.push_back(CI);
887 }
Daniel Dunbarea6408f2009-08-11 02:59:53 +0000888}
889
Daniel Dunbar59fc42d2009-08-11 20:59:47 +0000890AsmMatcherInfo::AsmMatcherInfo(Record *_AsmParser)
891 : AsmParser(_AsmParser),
892 CommentDelimiter(AsmParser->getValueAsString("CommentDelimiter")),
893 RegisterPrefix(AsmParser->getValueAsString("RegisterPrefix"))
894{
895}
896
Daniel Dunbarea6408f2009-08-11 02:59:53 +0000897void AsmMatcherInfo::BuildInfo(CodeGenTarget &Target) {
Daniel Dunbar1095f2a2009-08-11 23:23:44 +0000898 // Parse the instructions; we need to do this first so that we can gather the
899 // singleton register classes.
900 std::set<std::string> SingletonRegisterNames;
Chris Lattnerb61e09d2010-03-19 00:18:23 +0000901
Chris Lattnerf6502782010-03-19 00:34:35 +0000902 const std::vector<const CodeGenInstruction*> &InstrList =
903 Target.getInstructionsByEnumValue();
Chris Lattnerb61e09d2010-03-19 00:18:23 +0000904
905 for (unsigned i = 0, e = InstrList.size(); i != e; ++i) {
906 const CodeGenInstruction &CGI = *InstrList[i];
Daniel Dunbar20927f22009-08-07 08:26:05 +0000907
Chris Lattnerb61e09d2010-03-19 00:18:23 +0000908 if (!StringRef(CGI.TheDef->getName()).startswith(MatchPrefix))
Daniel Dunbar20927f22009-08-07 08:26:05 +0000909 continue;
910
Chris Lattnerb61e09d2010-03-19 00:18:23 +0000911 OwningPtr<InstructionInfo> II(new InstructionInfo());
Daniel Dunbar20927f22009-08-07 08:26:05 +0000912
Chris Lattnerb61e09d2010-03-19 00:18:23 +0000913 II->InstrName = CGI.TheDef->getName();
914 II->Instr = &CGI;
Daniel Dunbar20927f22009-08-07 08:26:05 +0000915 II->AsmString = FlattenVariants(CGI.AsmString, 0);
916
Daniel Dunbar59fc42d2009-08-11 20:59:47 +0000917 // Remove comments from the asm string.
918 if (!CommentDelimiter.empty()) {
919 size_t Idx = StringRef(II->AsmString).find(CommentDelimiter);
920 if (Idx != StringRef::npos)
921 II->AsmString = II->AsmString.substr(0, Idx);
922 }
923
Daniel Dunbar20927f22009-08-07 08:26:05 +0000924 TokenizeAsmString(II->AsmString, II->Tokens);
925
926 // Ignore instructions which shouldn't be matched.
Chris Lattnerb61e09d2010-03-19 00:18:23 +0000927 if (!IsAssemblerInstruction(CGI.TheDef->getName(), CGI, II->Tokens))
Daniel Dunbar20927f22009-08-07 08:26:05 +0000928 continue;
929
Daniel Dunbar1095f2a2009-08-11 23:23:44 +0000930 // Collect singleton registers, if used.
931 if (!RegisterPrefix.empty()) {
932 for (unsigned i = 0, e = II->Tokens.size(); i != e; ++i) {
933 if (II->Tokens[i].startswith(RegisterPrefix)) {
934 StringRef RegName = II->Tokens[i].substr(RegisterPrefix.size());
935 Record *Rec = getRegisterRecord(Target, RegName);
936
937 if (!Rec) {
938 std::string Err = "unable to find register for '" + RegName.str() +
939 "' (which matches register prefix)";
940 throw TGError(CGI.TheDef->getLoc(), Err);
941 }
942
943 SingletonRegisterNames.insert(RegName);
944 }
945 }
946 }
Daniel Dunbar54074b52010-07-19 05:44:09 +0000947
948 // Compute the require features.
949 ListInit *Predicates = CGI.TheDef->getValueAsListInit("Predicates");
950 for (unsigned i = 0, e = Predicates->getSize(); i != e; ++i) {
951 if (DefInit *Pred = dynamic_cast<DefInit*>(Predicates->getElement(i))) {
952 // Ignore OptForSize and OptForSpeed, they aren't really requirements,
953 // rather they are hints to isel.
954 //
955 // FIXME: Find better way to model this.
956 if (Pred->getDef()->getName() == "OptForSize" ||
957 Pred->getDef()->getName() == "OptForSpeed")
958 continue;
959
960 // FIXME: Total hack; for now, we just limit ourselves to In32BitMode
961 // and In64BitMode, because we aren't going to have the right feature
962 // masks for SSE and friends. We need to decide what we are going to do
963 // about CPU subtypes to implement this the right way.
964 if (Pred->getDef()->getName() != "In32BitMode" &&
965 Pred->getDef()->getName() != "In64BitMode")
966 continue;
967
968 II->RequiredFeatures.push_back(getSubtargetFeature(Pred->getDef()));
969 }
970 }
971
Daniel Dunbar1095f2a2009-08-11 23:23:44 +0000972 Instructions.push_back(II.take());
973 }
974
975 // Build info for the register classes.
976 BuildRegisterClasses(Target, SingletonRegisterNames);
977
978 // Build info for the user defined assembly operand classes.
979 BuildOperandClasses(Target);
980
981 // Build the instruction information.
982 for (std::vector<InstructionInfo*>::iterator it = Instructions.begin(),
983 ie = Instructions.end(); it != ie; ++it) {
984 InstructionInfo *II = *it;
985
Daniel Dunbar20927f22009-08-07 08:26:05 +0000986 for (unsigned i = 0, e = II->Tokens.size(); i != e; ++i) {
987 StringRef Token = II->Tokens[i];
988
Daniel Dunbar1095f2a2009-08-11 23:23:44 +0000989 // Check for singleton registers.
990 if (!RegisterPrefix.empty() && Token.startswith(RegisterPrefix)) {
991 StringRef RegName = II->Tokens[i].substr(RegisterPrefix.size());
992 InstructionInfo::Operand Op;
993 Op.Class = RegisterClasses[getRegisterRecord(Target, RegName)];
994 Op.OperandInfo = 0;
995 assert(Op.Class && Op.Class->Registers.size() == 1 &&
996 "Unexpected class for singleton register");
997 II->Operands.push_back(Op);
998 continue;
999 }
1000
Daniel Dunbar20927f22009-08-07 08:26:05 +00001001 // Check for simple tokens.
1002 if (Token[0] != '$') {
1003 InstructionInfo::Operand Op;
Daniel Dunbara3741fa2009-08-08 07:50:56 +00001004 Op.Class = getTokenClass(Token);
Benjamin Kramerfa1165a2009-08-08 10:06:30 +00001005 Op.OperandInfo = 0;
Daniel Dunbar20927f22009-08-07 08:26:05 +00001006 II->Operands.push_back(Op);
1007 continue;
1008 }
1009
1010 // Otherwise this is an operand reference.
Daniel Dunbar20927f22009-08-07 08:26:05 +00001011 StringRef OperandName;
1012 if (Token[1] == '{')
1013 OperandName = Token.substr(2, Token.size() - 3);
1014 else
1015 OperandName = Token.substr(1);
1016
1017 // Map this token to an operand. FIXME: Move elsewhere.
1018 unsigned Idx;
1019 try {
Daniel Dunbar1095f2a2009-08-11 23:23:44 +00001020 Idx = II->Instr->getOperandNamed(OperandName);
Daniel Dunbar20927f22009-08-07 08:26:05 +00001021 } catch(...) {
Daniel Dunbar1095f2a2009-08-11 23:23:44 +00001022 throw std::string("error: unable to find operand: '" +
1023 OperandName.str() + "'");
Daniel Dunbar20927f22009-08-07 08:26:05 +00001024 }
1025
Daniel Dunbaraf616812010-02-10 08:15:48 +00001026 // FIXME: This is annoying, the named operand may be tied (e.g.,
1027 // XCHG8rm). What we want is the untied operand, which we now have to
1028 // grovel for. Only worry about this for single entry operands, we have to
1029 // clean this up anyway.
1030 const CodeGenInstruction::OperandInfo *OI = &II->Instr->OperandList[Idx];
1031 if (OI->Constraints[0].isTied()) {
1032 unsigned TiedOp = OI->Constraints[0].getTiedOperand();
1033
1034 // The tied operand index is an MIOperand index, find the operand that
1035 // contains it.
1036 for (unsigned i = 0, e = II->Instr->OperandList.size(); i != e; ++i) {
1037 if (II->Instr->OperandList[i].MIOperandNo == TiedOp) {
1038 OI = &II->Instr->OperandList[i];
1039 break;
1040 }
1041 }
1042
1043 assert(OI && "Unable to find tied operand target!");
1044 }
1045
Daniel Dunbara3741fa2009-08-08 07:50:56 +00001046 InstructionInfo::Operand Op;
Daniel Dunbaraf616812010-02-10 08:15:48 +00001047 Op.Class = getOperandClass(Token, *OI);
1048 Op.OperandInfo = OI;
Daniel Dunbar20927f22009-08-07 08:26:05 +00001049 II->Operands.push_back(Op);
1050 }
Daniel Dunbar20927f22009-08-07 08:26:05 +00001051 }
Daniel Dunbar5fe63382009-08-09 07:20:21 +00001052
Daniel Dunbar5fe63382009-08-09 07:20:21 +00001053 // Reorder classes so that classes preceed super classes.
1054 std::sort(Classes.begin(), Classes.end(), less_ptr<ClassInfo>());
Daniel Dunbar20927f22009-08-07 08:26:05 +00001055}
1056
Daniel Dunbar3b6910d2010-02-12 01:46:54 +00001057static std::pair<unsigned, unsigned> *
1058GetTiedOperandAtIndex(SmallVectorImpl<std::pair<unsigned, unsigned> > &List,
1059 unsigned Index) {
1060 for (unsigned i = 0, e = List.size(); i != e; ++i)
1061 if (Index == List[i].first)
1062 return &List[i];
1063
1064 return 0;
1065}
1066
Daniel Dunbar606e8ad2009-08-09 04:00:06 +00001067static void EmitConvertToMCInst(CodeGenTarget &Target,
1068 std::vector<InstructionInfo*> &Infos,
1069 raw_ostream &OS) {
Daniel Dunbarb7479c02009-08-08 05:24:34 +00001070 // Write the convert function to a separate stream, so we can drop it after
1071 // the enum.
1072 std::string ConvertFnBody;
1073 raw_string_ostream CvtOS(ConvertFnBody);
1074
Daniel Dunbar20927f22009-08-07 08:26:05 +00001075 // Function we have already generated.
1076 std::set<std::string> GeneratedFns;
1077
Daniel Dunbarb7479c02009-08-08 05:24:34 +00001078 // Start the unified conversion function.
1079
Daniel Dunbar8cc9c0c2010-03-18 20:05:56 +00001080 CvtOS << "static void ConvertToMCInst(ConversionKind Kind, MCInst &Inst, "
Daniel Dunbarb7479c02009-08-08 05:24:34 +00001081 << "unsigned Opcode,\n"
Chris Lattner98986712010-01-14 22:21:20 +00001082 << " const SmallVectorImpl<MCParsedAsmOperand*"
1083 << "> &Operands) {\n";
Daniel Dunbarb7479c02009-08-08 05:24:34 +00001084 CvtOS << " Inst.setOpcode(Opcode);\n";
1085 CvtOS << " switch (Kind) {\n";
1086 CvtOS << " default:\n";
1087
1088 // Start the enum, which we will generate inline.
1089
1090 OS << "// Unified function for converting operants to MCInst instances.\n\n";
Daniel Dunbarb7479c02009-08-08 05:24:34 +00001091 OS << "enum ConversionKind {\n";
1092
Chris Lattner98986712010-01-14 22:21:20 +00001093 // TargetOperandClass - This is the target's operand class, like X86Operand.
1094 std::string TargetOperandClass = Target.getName() + "Operand";
1095
Daniel Dunbar20927f22009-08-07 08:26:05 +00001096 for (std::vector<InstructionInfo*>::const_iterator it = Infos.begin(),
1097 ie = Infos.end(); it != ie; ++it) {
1098 InstructionInfo &II = **it;
1099
1100 // Order the (class) operands by the order to convert them into an MCInst.
1101 SmallVector<std::pair<unsigned, unsigned>, 4> MIOperandList;
1102 for (unsigned i = 0, e = II.Operands.size(); i != e; ++i) {
1103 InstructionInfo::Operand &Op = II.Operands[i];
Benjamin Kramerfa1165a2009-08-08 10:06:30 +00001104 if (Op.OperandInfo)
1105 MIOperandList.push_back(std::make_pair(Op.OperandInfo->MIOperandNo, i));
Daniel Dunbar20927f22009-08-07 08:26:05 +00001106 }
Daniel Dunbaraf616812010-02-10 08:15:48 +00001107
1108 // Find any tied operands.
1109 SmallVector<std::pair<unsigned, unsigned>, 4> TiedOperands;
1110 for (unsigned i = 0, e = II.Instr->OperandList.size(); i != e; ++i) {
1111 const CodeGenInstruction::OperandInfo &OpInfo = II.Instr->OperandList[i];
1112 for (unsigned j = 0, e = OpInfo.Constraints.size(); j != e; ++j) {
1113 const CodeGenInstruction::ConstraintInfo &CI = OpInfo.Constraints[j];
1114 if (CI.isTied())
1115 TiedOperands.push_back(std::make_pair(OpInfo.MIOperandNo + j,
1116 CI.getTiedOperand()));
1117 }
1118 }
1119
Daniel Dunbar20927f22009-08-07 08:26:05 +00001120 std::sort(MIOperandList.begin(), MIOperandList.end());
1121
1122 // Compute the total number of operands.
1123 unsigned NumMIOperands = 0;
1124 for (unsigned i = 0, e = II.Instr->OperandList.size(); i != e; ++i) {
1125 const CodeGenInstruction::OperandInfo &OI = II.Instr->OperandList[i];
1126 NumMIOperands = std::max(NumMIOperands,
1127 OI.MIOperandNo + OI.MINumOperands);
1128 }
1129
1130 // Build the conversion function signature.
1131 std::string Signature = "Convert";
1132 unsigned CurIndex = 0;
1133 for (unsigned i = 0, e = MIOperandList.size(); i != e; ++i) {
1134 InstructionInfo::Operand &Op = II.Operands[MIOperandList[i].second];
Benjamin Kramerfa1165a2009-08-08 10:06:30 +00001135 assert(CurIndex <= Op.OperandInfo->MIOperandNo &&
Daniel Dunbar20927f22009-08-07 08:26:05 +00001136 "Duplicate match for instruction operand!");
Daniel Dunbar20927f22009-08-07 08:26:05 +00001137
1138 // Skip operands which weren't matched by anything, this occurs when the
1139 // .td file encodes "implicit" operands as explicit ones.
1140 //
1141 // FIXME: This should be removed from the MCInst structure.
Daniel Dunbaraf616812010-02-10 08:15:48 +00001142 for (; CurIndex != Op.OperandInfo->MIOperandNo; ++CurIndex) {
Daniel Dunbar3b6910d2010-02-12 01:46:54 +00001143 std::pair<unsigned, unsigned> *Tie = GetTiedOperandAtIndex(TiedOperands,
1144 CurIndex);
1145 if (!Tie)
Daniel Dunbaraf616812010-02-10 08:15:48 +00001146 Signature += "__Imp";
1147 else
Daniel Dunbar3b6910d2010-02-12 01:46:54 +00001148 Signature += "__Tie" + utostr(Tie->second);
Daniel Dunbaraf616812010-02-10 08:15:48 +00001149 }
1150
1151 Signature += "__";
Daniel Dunbar20927f22009-08-07 08:26:05 +00001152
Daniel Dunbarea6408f2009-08-11 02:59:53 +00001153 // Registers are always converted the same, don't duplicate the conversion
1154 // function based on them.
1155 //
1156 // FIXME: We could generalize this based on the render method, if it
1157 // mattered.
1158 if (Op.Class->isRegisterClass())
1159 Signature += "Reg";
1160 else
1161 Signature += Op.Class->ClassName;
Benjamin Kramerfa1165a2009-08-08 10:06:30 +00001162 Signature += utostr(Op.OperandInfo->MINumOperands);
Daniel Dunbarb7479c02009-08-08 05:24:34 +00001163 Signature += "_" + utostr(MIOperandList[i].second);
1164
Benjamin Kramerfa1165a2009-08-08 10:06:30 +00001165 CurIndex += Op.OperandInfo->MINumOperands;
Daniel Dunbar20927f22009-08-07 08:26:05 +00001166 }
1167
1168 // Add any trailing implicit operands.
Daniel Dunbar3b6910d2010-02-12 01:46:54 +00001169 for (; CurIndex != NumMIOperands; ++CurIndex) {
1170 std::pair<unsigned, unsigned> *Tie = GetTiedOperandAtIndex(TiedOperands,
1171 CurIndex);
1172 if (!Tie)
1173 Signature += "__Imp";
1174 else
1175 Signature += "__Tie" + utostr(Tie->second);
1176 }
Daniel Dunbar20927f22009-08-07 08:26:05 +00001177
Daniel Dunbarb7479c02009-08-08 05:24:34 +00001178 II.ConversionFnKind = Signature;
Daniel Dunbar20927f22009-08-07 08:26:05 +00001179
Daniel Dunbarb7479c02009-08-08 05:24:34 +00001180 // Check if we have already generated this signature.
Daniel Dunbar20927f22009-08-07 08:26:05 +00001181 if (!GeneratedFns.insert(Signature).second)
1182 continue;
1183
1184 // If not, emit it now.
Daniel Dunbarb7479c02009-08-08 05:24:34 +00001185
1186 // Add to the enum list.
1187 OS << " " << Signature << ",\n";
1188
1189 // And to the convert function.
1190 CvtOS << " case " << Signature << ":\n";
Daniel Dunbar20927f22009-08-07 08:26:05 +00001191 CurIndex = 0;
1192 for (unsigned i = 0, e = MIOperandList.size(); i != e; ++i) {
1193 InstructionInfo::Operand &Op = II.Operands[MIOperandList[i].second];
1194
1195 // Add the implicit operands.
Daniel Dunbaraf616812010-02-10 08:15:48 +00001196 for (; CurIndex != Op.OperandInfo->MIOperandNo; ++CurIndex) {
1197 // See if this is a tied operand.
Daniel Dunbar3b6910d2010-02-12 01:46:54 +00001198 std::pair<unsigned, unsigned> *Tie = GetTiedOperandAtIndex(TiedOperands,
1199 CurIndex);
Daniel Dunbaraf616812010-02-10 08:15:48 +00001200
Daniel Dunbar3b6910d2010-02-12 01:46:54 +00001201 if (!Tie) {
Daniel Dunbaraf616812010-02-10 08:15:48 +00001202 // If not, this is some implicit operand. Just assume it is a register
1203 // for now.
1204 CvtOS << " Inst.addOperand(MCOperand::CreateReg(0));\n";
1205 } else {
1206 // Copy the tied operand.
Daniel Dunbar3b6910d2010-02-12 01:46:54 +00001207 assert(Tie->first>Tie->second && "Tied operand preceeds its target!");
Daniel Dunbaraf616812010-02-10 08:15:48 +00001208 CvtOS << " Inst.addOperand(Inst.getOperand("
Daniel Dunbar3b6910d2010-02-12 01:46:54 +00001209 << Tie->second << "));\n";
Daniel Dunbaraf616812010-02-10 08:15:48 +00001210 }
1211 }
Daniel Dunbar20927f22009-08-07 08:26:05 +00001212
Chris Lattner98986712010-01-14 22:21:20 +00001213 CvtOS << " ((" << TargetOperandClass << "*)Operands["
1214 << MIOperandList[i].second
1215 << "])->" << Op.Class->RenderMethod
Benjamin Kramerfa1165a2009-08-08 10:06:30 +00001216 << "(Inst, " << Op.OperandInfo->MINumOperands << ");\n";
1217 CurIndex += Op.OperandInfo->MINumOperands;
Daniel Dunbar20927f22009-08-07 08:26:05 +00001218 }
1219
1220 // And add trailing implicit operands.
Daniel Dunbar3b6910d2010-02-12 01:46:54 +00001221 for (; CurIndex != NumMIOperands; ++CurIndex) {
1222 std::pair<unsigned, unsigned> *Tie = GetTiedOperandAtIndex(TiedOperands,
1223 CurIndex);
1224
1225 if (!Tie) {
1226 // If not, this is some implicit operand. Just assume it is a register
1227 // for now.
1228 CvtOS << " Inst.addOperand(MCOperand::CreateReg(0));\n";
1229 } else {
1230 // Copy the tied operand.
1231 assert(Tie->first>Tie->second && "Tied operand preceeds its target!");
1232 CvtOS << " Inst.addOperand(Inst.getOperand("
1233 << Tie->second << "));\n";
1234 }
1235 }
1236
Daniel Dunbar8cc9c0c2010-03-18 20:05:56 +00001237 CvtOS << " return;\n";
Daniel Dunbar20927f22009-08-07 08:26:05 +00001238 }
Daniel Dunbarb7479c02009-08-08 05:24:34 +00001239
1240 // Finish the convert function.
1241
1242 CvtOS << " }\n";
Daniel Dunbarb7479c02009-08-08 05:24:34 +00001243 CvtOS << "}\n\n";
1244
1245 // Finish the enum, and drop the convert function after it.
1246
1247 OS << " NumConversionVariants\n";
1248 OS << "};\n\n";
1249
Daniel Dunbarb7479c02009-08-08 05:24:34 +00001250 OS << CvtOS.str();
Daniel Dunbara027d222009-07-31 02:32:59 +00001251}
1252
Daniel Dunbara3741fa2009-08-08 07:50:56 +00001253/// EmitMatchClassEnumeration - Emit the enumeration for match class kinds.
1254static void EmitMatchClassEnumeration(CodeGenTarget &Target,
1255 std::vector<ClassInfo*> &Infos,
1256 raw_ostream &OS) {
1257 OS << "namespace {\n\n";
1258
1259 OS << "/// MatchClassKind - The kinds of classes which participate in\n"
1260 << "/// instruction matching.\n";
1261 OS << "enum MatchClassKind {\n";
1262 OS << " InvalidMatchClass = 0,\n";
1263 for (std::vector<ClassInfo*>::iterator it = Infos.begin(),
1264 ie = Infos.end(); it != ie; ++it) {
1265 ClassInfo &CI = **it;
1266 OS << " " << CI.Name << ", // ";
1267 if (CI.Kind == ClassInfo::Token) {
1268 OS << "'" << CI.ValueName << "'\n";
Daniel Dunbarea6408f2009-08-11 02:59:53 +00001269 } else if (CI.isRegisterClass()) {
Daniel Dunbara3741fa2009-08-08 07:50:56 +00001270 if (!CI.ValueName.empty())
1271 OS << "register class '" << CI.ValueName << "'\n";
1272 else
1273 OS << "derived register class\n";
1274 } else {
1275 OS << "user defined class '" << CI.ValueName << "'\n";
1276 }
1277 }
1278 OS << " NumMatchClassKinds\n";
1279 OS << "};\n\n";
1280
1281 OS << "}\n\n";
1282}
1283
Daniel Dunbara3741fa2009-08-08 07:50:56 +00001284/// EmitClassifyOperand - Emit the function to classify an operand.
1285static void EmitClassifyOperand(CodeGenTarget &Target,
Daniel Dunbarea6408f2009-08-11 02:59:53 +00001286 AsmMatcherInfo &Info,
Daniel Dunbara3741fa2009-08-08 07:50:56 +00001287 raw_ostream &OS) {
Chris Lattner98986712010-01-14 22:21:20 +00001288 OS << "static MatchClassKind ClassifyOperand(MCParsedAsmOperand *GOp) {\n"
1289 << " " << Target.getName() << "Operand &Operand = *("
1290 << Target.getName() << "Operand*)GOp;\n";
Daniel Dunbarea6408f2009-08-11 02:59:53 +00001291
1292 // Classify tokens.
Daniel Dunbara3741fa2009-08-08 07:50:56 +00001293 OS << " if (Operand.isToken())\n";
1294 OS << " return MatchTokenString(Operand.getToken());\n\n";
Daniel Dunbarea6408f2009-08-11 02:59:53 +00001295
1296 // Classify registers.
1297 //
1298 // FIXME: Don't hardcode isReg, getReg.
1299 OS << " if (Operand.isReg()) {\n";
1300 OS << " switch (Operand.getReg()) {\n";
1301 OS << " default: return InvalidMatchClass;\n";
1302 for (std::map<Record*, ClassInfo*>::iterator
1303 it = Info.RegisterClasses.begin(), ie = Info.RegisterClasses.end();
1304 it != ie; ++it)
1305 OS << " case " << Target.getName() << "::"
1306 << it->first->getName() << ": return " << it->second->Name << ";\n";
1307 OS << " }\n";
1308 OS << " }\n\n";
1309
1310 // Classify user defined operands.
1311 for (std::vector<ClassInfo*>::iterator it = Info.Classes.begin(),
1312 ie = Info.Classes.end(); it != ie; ++it) {
Daniel Dunbara3741fa2009-08-08 07:50:56 +00001313 ClassInfo &CI = **it;
1314
Daniel Dunbarea6408f2009-08-11 02:59:53 +00001315 if (!CI.isUserClass())
1316 continue;
1317
1318 OS << " // '" << CI.ClassName << "' class";
1319 if (!CI.SuperClasses.empty()) {
1320 OS << ", subclass of ";
1321 for (unsigned i = 0, e = CI.SuperClasses.size(); i != e; ++i) {
1322 if (i) OS << ", ";
1323 OS << "'" << CI.SuperClasses[i]->ClassName << "'";
1324 assert(CI < *CI.SuperClasses[i] && "Invalid class relation!");
Daniel Dunbar5fe63382009-08-09 07:20:21 +00001325 }
Daniel Dunbara3741fa2009-08-08 07:50:56 +00001326 }
Daniel Dunbarea6408f2009-08-11 02:59:53 +00001327 OS << "\n";
1328
1329 OS << " if (Operand." << CI.PredicateMethod << "()) {\n";
1330
1331 // Validate subclass relationships.
1332 if (!CI.SuperClasses.empty()) {
1333 for (unsigned i = 0, e = CI.SuperClasses.size(); i != e; ++i)
1334 OS << " assert(Operand." << CI.SuperClasses[i]->PredicateMethod
1335 << "() && \"Invalid class relationship!\");\n";
1336 }
1337
1338 OS << " return " << CI.Name << ";\n";
1339 OS << " }\n\n";
Daniel Dunbara3741fa2009-08-08 07:50:56 +00001340 }
1341 OS << " return InvalidMatchClass;\n";
1342 OS << "}\n\n";
1343}
1344
Daniel Dunbarfdb1f492009-08-10 16:05:47 +00001345/// EmitIsSubclass - Emit the subclass predicate function.
1346static void EmitIsSubclass(CodeGenTarget &Target,
1347 std::vector<ClassInfo*> &Infos,
1348 raw_ostream &OS) {
1349 OS << "/// IsSubclass - Compute whether \\arg A is a subclass of \\arg B.\n";
1350 OS << "static bool IsSubclass(MatchClassKind A, MatchClassKind B) {\n";
1351 OS << " if (A == B)\n";
1352 OS << " return true;\n\n";
1353
1354 OS << " switch (A) {\n";
1355 OS << " default:\n";
1356 OS << " return false;\n";
1357 for (std::vector<ClassInfo*>::iterator it = Infos.begin(),
1358 ie = Infos.end(); it != ie; ++it) {
1359 ClassInfo &A = **it;
1360
1361 if (A.Kind != ClassInfo::Token) {
1362 std::vector<StringRef> SuperClasses;
1363 for (std::vector<ClassInfo*>::iterator it = Infos.begin(),
1364 ie = Infos.end(); it != ie; ++it) {
1365 ClassInfo &B = **it;
1366
Daniel Dunbarea6408f2009-08-11 02:59:53 +00001367 if (&A != &B && A.isSubsetOf(B))
Daniel Dunbarfdb1f492009-08-10 16:05:47 +00001368 SuperClasses.push_back(B.Name);
1369 }
1370
1371 if (SuperClasses.empty())
1372 continue;
1373
1374 OS << "\n case " << A.Name << ":\n";
1375
1376 if (SuperClasses.size() == 1) {
Daniel Dunbarea6408f2009-08-11 02:59:53 +00001377 OS << " return B == " << SuperClasses.back() << ";\n";
Daniel Dunbarfdb1f492009-08-10 16:05:47 +00001378 continue;
1379 }
1380
Daniel Dunbarea6408f2009-08-11 02:59:53 +00001381 OS << " switch (B) {\n";
1382 OS << " default: return false;\n";
Daniel Dunbarfdb1f492009-08-10 16:05:47 +00001383 for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i)
Daniel Dunbarea6408f2009-08-11 02:59:53 +00001384 OS << " case " << SuperClasses[i] << ": return true;\n";
1385 OS << " }\n";
Daniel Dunbarfdb1f492009-08-10 16:05:47 +00001386 }
1387 }
1388 OS << " }\n";
1389 OS << "}\n\n";
1390}
1391
Chris Lattner70add882009-08-08 20:02:57 +00001392typedef std::pair<std::string, std::string> StringPair;
1393
1394/// FindFirstNonCommonLetter - Find the first character in the keys of the
1395/// string pairs that is not shared across the whole set of strings. All
1396/// strings are assumed to have the same length.
1397static unsigned
1398FindFirstNonCommonLetter(const std::vector<const StringPair*> &Matches) {
1399 assert(!Matches.empty());
1400 for (unsigned i = 0, e = Matches[0]->first.size(); i != e; ++i) {
1401 // Check to see if letter i is the same across the set.
1402 char Letter = Matches[0]->first[i];
1403
1404 for (unsigned str = 0, e = Matches.size(); str != e; ++str)
1405 if (Matches[str]->first[i] != Letter)
1406 return i;
1407 }
1408
1409 return Matches[0]->first.size();
1410}
1411
1412/// EmitStringMatcherForChar - Given a set of strings that are known to be the
1413/// same length and whose characters leading up to CharNo are the same, emit
1414/// code to verify that CharNo and later are the same.
Daniel Dunbar72ffae92009-08-08 22:57:25 +00001415///
1416/// \return - True if control can leave the emitted code fragment.
1417static bool EmitStringMatcherForChar(const std::string &StrVariableName,
Chris Lattner70add882009-08-08 20:02:57 +00001418 const std::vector<const StringPair*> &Matches,
1419 unsigned CharNo, unsigned IndentCount,
1420 raw_ostream &OS) {
1421 assert(!Matches.empty() && "Must have at least one string to match!");
1422 std::string Indent(IndentCount*2+4, ' ');
1423
1424 // If we have verified that the entire string matches, we're done: output the
1425 // matching code.
1426 if (CharNo == Matches[0]->first.size()) {
1427 assert(Matches.size() == 1 && "Had duplicate keys to match on");
1428
1429 // FIXME: If Matches[0].first has embeded \n, this will be bad.
1430 OS << Indent << Matches[0]->second << "\t // \"" << Matches[0]->first
1431 << "\"\n";
Daniel Dunbar72ffae92009-08-08 22:57:25 +00001432 return false;
Chris Lattner70add882009-08-08 20:02:57 +00001433 }
1434
1435 // Bucket the matches by the character we are comparing.
1436 std::map<char, std::vector<const StringPair*> > MatchesByLetter;
1437
1438 for (unsigned i = 0, e = Matches.size(); i != e; ++i)
1439 MatchesByLetter[Matches[i]->first[CharNo]].push_back(Matches[i]);
1440
1441
1442 // If we have exactly one bucket to match, see how many characters are common
1443 // across the whole set and match all of them at once.
Chris Lattner70add882009-08-08 20:02:57 +00001444 if (MatchesByLetter.size() == 1) {
1445 unsigned FirstNonCommonLetter = FindFirstNonCommonLetter(Matches);
1446 unsigned NumChars = FirstNonCommonLetter-CharNo;
1447
Daniel Dunbar72ffae92009-08-08 22:57:25 +00001448 // Emit code to break out if the prefix doesn't match.
Chris Lattner70add882009-08-08 20:02:57 +00001449 if (NumChars == 1) {
Daniel Dunbar72ffae92009-08-08 22:57:25 +00001450 // Do the comparison with if (Str[1] != 'f')
Chris Lattner70add882009-08-08 20:02:57 +00001451 // FIXME: Need to escape general characters.
Daniel Dunbar72ffae92009-08-08 22:57:25 +00001452 OS << Indent << "if (" << StrVariableName << "[" << CharNo << "] != '"
1453 << Matches[0]->first[CharNo] << "')\n";
1454 OS << Indent << " break;\n";
Chris Lattner70add882009-08-08 20:02:57 +00001455 } else {
Daniel Dunbar72ffae92009-08-08 22:57:25 +00001456 // Do the comparison with if (Str.substr(1,3) != "foo").
Chris Lattner70add882009-08-08 20:02:57 +00001457 // FIXME: Need to escape general strings.
Daniel Dunbar72ffae92009-08-08 22:57:25 +00001458 OS << Indent << "if (" << StrVariableName << ".substr(" << CharNo << ","
1459 << NumChars << ") != \"";
1460 OS << Matches[0]->first.substr(CharNo, NumChars) << "\")\n";
Daniel Dunbaraf3e9d42009-08-08 23:43:16 +00001461 OS << Indent << " break;\n";
Chris Lattner70add882009-08-08 20:02:57 +00001462 }
1463
Daniel Dunbar72ffae92009-08-08 22:57:25 +00001464 return EmitStringMatcherForChar(StrVariableName, Matches,
1465 FirstNonCommonLetter, IndentCount, OS);
Chris Lattner70add882009-08-08 20:02:57 +00001466 }
1467
1468 // Otherwise, we have multiple possible things, emit a switch on the
1469 // character.
1470 OS << Indent << "switch (" << StrVariableName << "[" << CharNo << "]) {\n";
1471 OS << Indent << "default: break;\n";
1472
1473 for (std::map<char, std::vector<const StringPair*> >::iterator LI =
1474 MatchesByLetter.begin(), E = MatchesByLetter.end(); LI != E; ++LI) {
1475 // TODO: escape hard stuff (like \n) if we ever care about it.
1476 OS << Indent << "case '" << LI->first << "':\t // "
1477 << LI->second.size() << " strings to match.\n";
Daniel Dunbar72ffae92009-08-08 22:57:25 +00001478 if (EmitStringMatcherForChar(StrVariableName, LI->second, CharNo+1,
1479 IndentCount+1, OS))
1480 OS << Indent << " break;\n";
Chris Lattner70add882009-08-08 20:02:57 +00001481 }
1482
1483 OS << Indent << "}\n";
Daniel Dunbar72ffae92009-08-08 22:57:25 +00001484 return true;
Chris Lattner70add882009-08-08 20:02:57 +00001485}
1486
1487
1488/// EmitStringMatcher - Given a list of strings and code to execute when they
Daniel Dunbar72ffae92009-08-08 22:57:25 +00001489/// match, output a simple switch tree to classify the input string.
1490///
1491/// If a match is found, the code in Vals[i].second is executed; control must
1492/// not exit this code fragment. If nothing matches, execution falls through.
1493///
1494/// \param StrVariableName - The name of the variable to test.
Chris Lattner70add882009-08-08 20:02:57 +00001495static void EmitStringMatcher(const std::string &StrVariableName,
1496 const std::vector<StringPair> &Matches,
1497 raw_ostream &OS) {
1498 // First level categorization: group strings by length.
1499 std::map<unsigned, std::vector<const StringPair*> > MatchesByLength;
1500
1501 for (unsigned i = 0, e = Matches.size(); i != e; ++i)
1502 MatchesByLength[Matches[i].first.size()].push_back(&Matches[i]);
1503
1504 // Output a switch statement on length and categorize the elements within each
1505 // bin.
1506 OS << " switch (" << StrVariableName << ".size()) {\n";
1507 OS << " default: break;\n";
1508
Chris Lattner70add882009-08-08 20:02:57 +00001509 for (std::map<unsigned, std::vector<const StringPair*> >::iterator LI =
1510 MatchesByLength.begin(), E = MatchesByLength.end(); LI != E; ++LI) {
1511 OS << " case " << LI->first << ":\t // " << LI->second.size()
1512 << " strings to match.\n";
Daniel Dunbar72ffae92009-08-08 22:57:25 +00001513 if (EmitStringMatcherForChar(StrVariableName, LI->second, 0, 0, OS))
1514 OS << " break;\n";
Chris Lattner70add882009-08-08 20:02:57 +00001515 }
1516
Chris Lattner70add882009-08-08 20:02:57 +00001517 OS << " }\n";
1518}
1519
1520
Daniel Dunbar245f0582009-08-08 21:22:41 +00001521/// EmitMatchTokenString - Emit the function to match a token string to the
1522/// appropriate match class value.
1523static void EmitMatchTokenString(CodeGenTarget &Target,
1524 std::vector<ClassInfo*> &Infos,
1525 raw_ostream &OS) {
1526 // Construct the match list.
1527 std::vector<StringPair> Matches;
1528 for (std::vector<ClassInfo*>::iterator it = Infos.begin(),
1529 ie = Infos.end(); it != ie; ++it) {
1530 ClassInfo &CI = **it;
1531
1532 if (CI.Kind == ClassInfo::Token)
1533 Matches.push_back(StringPair(CI.ValueName, "return " + CI.Name + ";"));
1534 }
1535
Chris Lattnerb8d6e982010-02-09 00:34:28 +00001536 OS << "static MatchClassKind MatchTokenString(StringRef Name) {\n";
Daniel Dunbar245f0582009-08-08 21:22:41 +00001537
1538 EmitStringMatcher("Name", Matches, OS);
1539
1540 OS << " return InvalidMatchClass;\n";
1541 OS << "}\n\n";
1542}
Chris Lattner70add882009-08-08 20:02:57 +00001543
Daniel Dunbar2234e5e2009-08-07 21:01:44 +00001544/// EmitMatchRegisterName - Emit the function to match a string to the target
1545/// specific register enum.
1546static void EmitMatchRegisterName(CodeGenTarget &Target, Record *AsmParser,
1547 raw_ostream &OS) {
Daniel Dunbar245f0582009-08-08 21:22:41 +00001548 // Construct the match list.
Chris Lattner70add882009-08-08 20:02:57 +00001549 std::vector<StringPair> Matches;
Daniel Dunbar245f0582009-08-08 21:22:41 +00001550 for (unsigned i = 0, e = Target.getRegisters().size(); i != e; ++i) {
1551 const CodeGenRegister &Reg = Target.getRegisters()[i];
Daniel Dunbar22be5222009-07-17 18:51:11 +00001552 if (Reg.TheDef->getValueAsString("AsmName").empty())
1553 continue;
1554
Chris Lattner70add882009-08-08 20:02:57 +00001555 Matches.push_back(StringPair(Reg.TheDef->getValueAsString("AsmName"),
Daniel Dunbar245f0582009-08-08 21:22:41 +00001556 "return " + utostr(i + 1) + ";"));
Daniel Dunbar22be5222009-07-17 18:51:11 +00001557 }
Chris Lattner70add882009-08-08 20:02:57 +00001558
Chris Lattnerb8d6e982010-02-09 00:34:28 +00001559 OS << "static unsigned MatchRegisterName(StringRef Name) {\n";
Daniel Dunbar245f0582009-08-08 21:22:41 +00001560
Chris Lattner70add882009-08-08 20:02:57 +00001561 EmitStringMatcher("Name", Matches, OS);
1562
Daniel Dunbar245f0582009-08-08 21:22:41 +00001563 OS << " return 0;\n";
Daniel Dunbar20927f22009-08-07 08:26:05 +00001564 OS << "}\n\n";
Daniel Dunbar2234e5e2009-08-07 21:01:44 +00001565}
Daniel Dunbara027d222009-07-31 02:32:59 +00001566
Daniel Dunbar54074b52010-07-19 05:44:09 +00001567/// EmitSubtargetFeatureFlagEnumeration - Emit the subtarget feature flag
1568/// definitions.
1569static void EmitSubtargetFeatureFlagEnumeration(CodeGenTarget &Target,
1570 AsmMatcherInfo &Info,
1571 raw_ostream &OS) {
1572 OS << "// Flags for subtarget features that participate in "
1573 << "instruction matching.\n";
1574 OS << "enum SubtargetFeatureFlag {\n";
1575 for (std::map<Record*, SubtargetFeatureInfo*>::const_iterator
1576 it = Info.SubtargetFeatures.begin(),
1577 ie = Info.SubtargetFeatures.end(); it != ie; ++it) {
1578 SubtargetFeatureInfo &SFI = *it->second;
1579 OS << " " << SFI.EnumName << " = (1 << " << SFI.Index << "),\n";
1580 }
1581 OS << " Feature_None = 0\n";
1582 OS << "};\n\n";
1583}
1584
1585/// EmitComputeAvailableFeatures - Emit the function to compute the list of
1586/// available features given a subtarget.
1587static void EmitComputeAvailableFeatures(CodeGenTarget &Target,
1588 AsmMatcherInfo &Info,
1589 raw_ostream &OS) {
1590 std::string ClassName =
1591 Info.AsmParser->getValueAsString("AsmParserClassName");
1592
1593 OS << "unsigned " << Target.getName() << ClassName << "::\n"
1594 << "ComputeAvailableFeatures(const " << Target.getName()
1595 << "Subtarget *Subtarget) const {\n";
1596 OS << " unsigned Features = 0;\n";
1597 for (std::map<Record*, SubtargetFeatureInfo*>::const_iterator
1598 it = Info.SubtargetFeatures.begin(),
1599 ie = Info.SubtargetFeatures.end(); it != ie; ++it) {
1600 SubtargetFeatureInfo &SFI = *it->second;
1601 OS << " if (" << SFI.TheDef->getValueAsString("CondString")
1602 << ")\n";
1603 OS << " Features |= " << SFI.EnumName << ";\n";
1604 }
1605 OS << " return Features;\n";
1606 OS << "}\n\n";
1607}
1608
Daniel Dunbar2234e5e2009-08-07 21:01:44 +00001609void AsmMatcherEmitter::run(raw_ostream &OS) {
1610 CodeGenTarget Target;
1611 Record *AsmParser = Target.getAsmParser();
1612 std::string ClassName = AsmParser->getValueAsString("AsmParserClassName");
1613
Daniel Dunbara3741fa2009-08-08 07:50:56 +00001614 // Compute the information on the instructions to match.
Daniel Dunbar59fc42d2009-08-11 20:59:47 +00001615 AsmMatcherInfo Info(AsmParser);
Daniel Dunbara3741fa2009-08-08 07:50:56 +00001616 Info.BuildInfo(Target);
Daniel Dunbara027d222009-07-31 02:32:59 +00001617
Daniel Dunbare1f6de32010-02-02 23:46:36 +00001618 // Sort the instruction table using the partial order on classes. We use
1619 // stable_sort to ensure that ambiguous instructions are still
1620 // deterministically ordered.
1621 std::stable_sort(Info.Instructions.begin(), Info.Instructions.end(),
1622 less_ptr<InstructionInfo>());
Daniel Dunbar606e8ad2009-08-09 04:00:06 +00001623
Daniel Dunbarb7479c02009-08-08 05:24:34 +00001624 DEBUG_WITH_TYPE("instruction_info", {
Daniel Dunbara3741fa2009-08-08 07:50:56 +00001625 for (std::vector<InstructionInfo*>::iterator
1626 it = Info.Instructions.begin(), ie = Info.Instructions.end();
1627 it != ie; ++it)
Daniel Dunbar20927f22009-08-07 08:26:05 +00001628 (*it)->dump();
1629 });
Daniel Dunbara027d222009-07-31 02:32:59 +00001630
Daniel Dunbar606e8ad2009-08-09 04:00:06 +00001631 // Check for ambiguous instructions.
1632 unsigned NumAmbiguous = 0;
Daniel Dunbar2b544812009-08-09 06:05:33 +00001633 for (unsigned i = 0, e = Info.Instructions.size(); i != e; ++i) {
1634 for (unsigned j = i + 1; j != e; ++j) {
1635 InstructionInfo &A = *Info.Instructions[i];
1636 InstructionInfo &B = *Info.Instructions[j];
Daniel Dunbar606e8ad2009-08-09 04:00:06 +00001637
Daniel Dunbar2b544812009-08-09 06:05:33 +00001638 if (A.CouldMatchAmiguouslyWith(B)) {
1639 DEBUG_WITH_TYPE("ambiguous_instrs", {
1640 errs() << "warning: ambiguous instruction match:\n";
1641 A.dump();
1642 errs() << "\nis incomparable with:\n";
1643 B.dump();
1644 errs() << "\n\n";
1645 });
1646 ++NumAmbiguous;
1647 }
Daniel Dunbar606e8ad2009-08-09 04:00:06 +00001648 }
1649 }
1650 if (NumAmbiguous)
1651 DEBUG_WITH_TYPE("ambiguous_instrs", {
1652 errs() << "warning: " << NumAmbiguous
1653 << " ambiguous instructions!\n";
1654 });
1655
Daniel Dunbar1095f2a2009-08-11 23:23:44 +00001656 // Write the output.
1657
1658 EmitSourceFileHeader("Assembly Matcher Source Fragment", OS);
1659
Daniel Dunbar54074b52010-07-19 05:44:09 +00001660 // Emit the subtarget feature enumeration.
1661 EmitSubtargetFeatureFlagEnumeration(Target, Info, OS);
1662
Daniel Dunbar1095f2a2009-08-11 23:23:44 +00001663 // Emit the function to match a register name to number.
1664 EmitMatchRegisterName(Target, AsmParser, OS);
Sean Callanane9b466d2010-01-23 00:40:33 +00001665
1666 OS << "#ifndef REGISTERS_ONLY\n\n";
Daniel Dunbar1095f2a2009-08-11 23:23:44 +00001667
Daniel Dunbar606e8ad2009-08-09 04:00:06 +00001668 // Generate the unified function to convert operands into an MCInst.
1669 EmitConvertToMCInst(Target, Info.Instructions, OS);
Daniel Dunbara027d222009-07-31 02:32:59 +00001670
Daniel Dunbara3741fa2009-08-08 07:50:56 +00001671 // Emit the enumeration for classes which participate in matching.
1672 EmitMatchClassEnumeration(Target, Info.Classes, OS);
Daniel Dunbara027d222009-07-31 02:32:59 +00001673
Daniel Dunbara3741fa2009-08-08 07:50:56 +00001674 // Emit the routine to match token strings to their match class.
1675 EmitMatchTokenString(Target, Info.Classes, OS);
1676
1677 // Emit the routine to classify an operand.
Daniel Dunbarea6408f2009-08-11 02:59:53 +00001678 EmitClassifyOperand(Target, Info, OS);
Daniel Dunbara3741fa2009-08-08 07:50:56 +00001679
Daniel Dunbarfdb1f492009-08-10 16:05:47 +00001680 // Emit the subclass predicate routine.
1681 EmitIsSubclass(Target, Info.Classes, OS);
1682
Daniel Dunbar54074b52010-07-19 05:44:09 +00001683 // Emit the available features compute function.
1684 EmitComputeAvailableFeatures(Target, Info, OS);
1685
Daniel Dunbara3741fa2009-08-08 07:50:56 +00001686 // Finally, build the match function.
1687
1688 size_t MaxNumOperands = 0;
1689 for (std::vector<InstructionInfo*>::const_iterator it =
1690 Info.Instructions.begin(), ie = Info.Instructions.end();
1691 it != ie; ++it)
1692 MaxNumOperands = std::max(MaxNumOperands, (*it)->Operands.size());
Daniel Dunbar4f83e732010-05-04 00:33:13 +00001693
1694 const std::string &MatchName =
1695 AsmParser->getValueAsString("MatchInstructionName");
1696 OS << "bool " << Target.getName() << ClassName << "::\n"
1697 << MatchName
1698 << "(const SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n";
1699 OS.indent(MatchName.size() + 1);
1700 OS << "MCInst &Inst) {\n";
Daniel Dunbar20927f22009-08-07 08:26:05 +00001701
Daniel Dunbara3741fa2009-08-08 07:50:56 +00001702 // Emit the static match table; unused classes get initalized to 0 which is
1703 // guaranteed to be InvalidMatchClass.
1704 //
1705 // FIXME: We can reduce the size of this table very easily. First, we change
1706 // it so that store the kinds in separate bit-fields for each index, which
1707 // only needs to be the max width used for classes at that index (we also need
1708 // to reject based on this during classification). If we then make sure to
1709 // order the match kinds appropriately (putting mnemonics last), then we
1710 // should only end up using a few bits for each class, especially the ones
1711 // following the mnemonic.
Chris Lattnerc6049532009-08-08 19:15:25 +00001712 OS << " static const struct MatchEntry {\n";
Daniel Dunbara3741fa2009-08-08 07:50:56 +00001713 OS << " unsigned Opcode;\n";
1714 OS << " ConversionKind ConvertFn;\n";
1715 OS << " MatchClassKind Classes[" << MaxNumOperands << "];\n";
Daniel Dunbar54074b52010-07-19 05:44:09 +00001716 OS << " unsigned RequiredFeatures;\n";
Daniel Dunbara3741fa2009-08-08 07:50:56 +00001717 OS << " } MatchTable[" << Info.Instructions.size() << "] = {\n";
1718
1719 for (std::vector<InstructionInfo*>::const_iterator it =
1720 Info.Instructions.begin(), ie = Info.Instructions.end();
1721 it != ie; ++it) {
Daniel Dunbar20927f22009-08-07 08:26:05 +00001722 InstructionInfo &II = **it;
1723
Daniel Dunbara3741fa2009-08-08 07:50:56 +00001724 OS << " { " << Target.getName() << "::" << II.InstrName
1725 << ", " << II.ConversionFnKind << ", { ";
Daniel Dunbar20927f22009-08-07 08:26:05 +00001726 for (unsigned i = 0, e = II.Operands.size(); i != e; ++i) {
1727 InstructionInfo::Operand &Op = II.Operands[i];
1728
Daniel Dunbara3741fa2009-08-08 07:50:56 +00001729 if (i) OS << ", ";
1730 OS << Op.Class->Name;
Daniel Dunbar20927f22009-08-07 08:26:05 +00001731 }
Daniel Dunbar54074b52010-07-19 05:44:09 +00001732 OS << " }, ";
1733
1734 // Write the required features mask.
1735 if (!II.RequiredFeatures.empty()) {
1736 for (unsigned i = 0, e = II.RequiredFeatures.size(); i != e; ++i) {
1737 if (i) OS << "|";
1738 OS << II.RequiredFeatures[i]->EnumName;
1739 }
1740 } else
1741 OS << "0";
1742
1743 OS << "},\n";
Daniel Dunbara027d222009-07-31 02:32:59 +00001744 }
1745
Daniel Dunbara3741fa2009-08-08 07:50:56 +00001746 OS << " };\n\n";
1747
Daniel Dunbar54074b52010-07-19 05:44:09 +00001748
1749 // Emit code to get the available features.
1750 OS << " // Get the current feature set.\n";
1751 OS << " unsigned AvailableFeatures = getAvailableFeatures();\n\n";
1752
Daniel Dunbara3741fa2009-08-08 07:50:56 +00001753 // Emit code to compute the class list for this operand vector.
1754 OS << " // Eliminate obvious mismatches.\n";
1755 OS << " if (Operands.size() > " << MaxNumOperands << ")\n";
1756 OS << " return true;\n\n";
1757
1758 OS << " // Compute the class list for this operand vector.\n";
1759 OS << " MatchClassKind Classes[" << MaxNumOperands << "];\n";
1760 OS << " for (unsigned i = 0, e = Operands.size(); i != e; ++i) {\n";
1761 OS << " Classes[i] = ClassifyOperand(Operands[i]);\n\n";
1762
1763 OS << " // Check for invalid operands before matching.\n";
1764 OS << " if (Classes[i] == InvalidMatchClass)\n";
1765 OS << " return true;\n";
1766 OS << " }\n\n";
1767
1768 OS << " // Mark unused classes.\n";
1769 OS << " for (unsigned i = Operands.size(), e = " << MaxNumOperands << "; "
1770 << "i != e; ++i)\n";
1771 OS << " Classes[i] = InvalidMatchClass;\n\n";
1772
1773 // Emit code to search the table.
1774 OS << " // Search the table.\n";
Chris Lattnerd39bd3a2009-08-08 19:16:05 +00001775 OS << " for (const MatchEntry *it = MatchTable, "
Daniel Dunbara3741fa2009-08-08 07:50:56 +00001776 << "*ie = MatchTable + " << Info.Instructions.size()
1777 << "; it != ie; ++it) {\n";
Daniel Dunbar54074b52010-07-19 05:44:09 +00001778
1779 // Emit check that the required features are available.
1780 OS << " if ((AvailableFeatures & it->RequiredFeatures) "
1781 << "!= it->RequiredFeatures)\n";
1782 OS << " continue;\n";
1783
1784 // Emit check that the subclasses match.
Daniel Dunbara3741fa2009-08-08 07:50:56 +00001785 for (unsigned i = 0; i != MaxNumOperands; ++i) {
Daniel Dunbarfdb1f492009-08-10 16:05:47 +00001786 OS << " if (!IsSubclass(Classes["
1787 << i << "], it->Classes[" << i << "]))\n";
Daniel Dunbara3741fa2009-08-08 07:50:56 +00001788 OS << " continue;\n";
1789 }
1790 OS << "\n";
Daniel Dunbar8cc9c0c2010-03-18 20:05:56 +00001791 OS << " ConvertToMCInst(it->ConvertFn, Inst, it->Opcode, Operands);\n";
1792
1793 // Call the post-processing function, if used.
1794 std::string InsnCleanupFn =
1795 AsmParser->getValueAsString("AsmParserInstCleanup");
1796 if (!InsnCleanupFn.empty())
1797 OS << " " << InsnCleanupFn << "(Inst);\n";
1798
1799 OS << " return false;\n";
Daniel Dunbara3741fa2009-08-08 07:50:56 +00001800 OS << " }\n\n";
1801
Daniel Dunbara027d222009-07-31 02:32:59 +00001802 OS << " return true;\n";
1803 OS << "}\n\n";
Sean Callanane9b466d2010-01-23 00:40:33 +00001804
1805 OS << "#endif // REGISTERS_ONLY\n";
Daniel Dunbard51ffcf2009-07-11 19:39:44 +00001806}