AsmMatcherEmitter.cpp revision a027d222e18ea9028e9e12ae2f5cd566889b599a
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//
13d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar//===----------------------------------------------------------------------===//
14d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar
15d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar#include "AsmMatcherEmitter.h"
16d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar#include "CodeGenTarget.h"
17d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar#include "Record.h"
18a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar#include "llvm/ADT/SmallVector.h"
19a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar#include "llvm/Support/Debug.h"
20a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar#include <set>
21a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar#include <list>
22d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbarusing namespace llvm;
23d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar
24a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar/// FlattenVariants - Flatten an .td file assembly string by selecting the
25a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar/// variant at index \arg N.
26a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbarstatic std::string FlattenVariants(const std::string &AsmString,
27a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar                                   unsigned N) {
28a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar  StringRef Cur = AsmString;
29a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar  std::string Res = "";
30a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
31a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar  for (;;) {
32a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    // Add the prefix until the next '{', and split out the contents in the
33a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    // braces.
34a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    std::pair<StringRef, StringRef> Inner, Split = Cur.split('{');
35a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
36a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    Res += Split.first;
37a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    if (Split.second.empty())
38a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      break;
39a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
40a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    Inner = Split.second.split('}');
41a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
42a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    // Select the Nth variant (or empty).
43a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    StringRef Selection = Inner.first;
44a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    for (unsigned i = 0; i != N; ++i)
45a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      Selection = Selection.split('|').second;
46a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    Res += Selection.split('|').first;
47a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
48a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    Cur = Inner.second;
49a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar  }
50a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
51a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar  return Res;
52a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar}
53a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
54a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar/// TokenizeAsmString - Tokenize a simplified assembly string.
55a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbarstatic void TokenizeAsmString(const std::string &AsmString,
56a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar                              SmallVectorImpl<StringRef> &Tokens) {
57a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar  unsigned Prev = 0;
58a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar  bool InTok = true;
59a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar  for (unsigned i = 0, e = AsmString.size(); i != e; ++i) {
60a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    switch (AsmString[i]) {
61a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    case '*':
62a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    case '!':
63a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    case ' ':
64a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    case '\t':
65a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    case ',':
66a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      if (InTok) {
67a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar        Tokens.push_back(StringRef(&AsmString[Prev], i - Prev));
68a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar        InTok = false;
69a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      }
70a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      if (AsmString[i] == '*' || AsmString[i] == '!')
71a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar        Tokens.push_back(StringRef(&AsmString[i], 1));
72a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      Prev = i + 1;
73a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      break;
74a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
75a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    default:
76a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      InTok = true;
77a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    }
78a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar  }
79a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar  if (InTok && Prev != AsmString.size())
80a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    Tokens.push_back(StringRef(&AsmString[Prev], AsmString.size() - Prev));
81a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar}
82a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
8322be5225ff88ffaab83c36fa133e70586b91166dDaniel Dunbarvoid AsmMatcherEmitter::run(raw_ostream &OS) {
84d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar  CodeGenTarget Target;
8522be5225ff88ffaab83c36fa133e70586b91166dDaniel Dunbar  const std::vector<CodeGenRegister> &Registers = Target.getRegisters();
860e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar  Record *AsmParser = Target.getAsmParser();
870e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar  std::string ClassName = AsmParser->getValueAsString("AsmParserClassName");
8822be5225ff88ffaab83c36fa133e70586b91166dDaniel Dunbar
8922be5225ff88ffaab83c36fa133e70586b91166dDaniel Dunbar  std::string Namespace = Registers[0].TheDef->getValueAsString("Namespace");
9022be5225ff88ffaab83c36fa133e70586b91166dDaniel Dunbar
9122be5225ff88ffaab83c36fa133e70586b91166dDaniel Dunbar  EmitSourceFileHeader("Assembly Matcher Source Fragment", OS);
9222be5225ff88ffaab83c36fa133e70586b91166dDaniel Dunbar
9322be5225ff88ffaab83c36fa133e70586b91166dDaniel Dunbar  // Emit the function to match a register name to number.
9422be5225ff88ffaab83c36fa133e70586b91166dDaniel Dunbar
950e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar  OS << "bool " << Target.getName() << ClassName
960e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar     << "::MatchRegisterName(const StringRef &Name, unsigned &RegNo) {\n";
9722be5225ff88ffaab83c36fa133e70586b91166dDaniel Dunbar
9822be5225ff88ffaab83c36fa133e70586b91166dDaniel Dunbar  // FIXME: TableGen should have a fast string matcher generator.
9922be5225ff88ffaab83c36fa133e70586b91166dDaniel Dunbar  for (unsigned i = 0, e = Registers.size(); i != e; ++i) {
10022be5225ff88ffaab83c36fa133e70586b91166dDaniel Dunbar    const CodeGenRegister &Reg = Registers[i];
10122be5225ff88ffaab83c36fa133e70586b91166dDaniel Dunbar    if (Reg.TheDef->getValueAsString("AsmName").empty())
10222be5225ff88ffaab83c36fa133e70586b91166dDaniel Dunbar      continue;
10322be5225ff88ffaab83c36fa133e70586b91166dDaniel Dunbar
10422be5225ff88ffaab83c36fa133e70586b91166dDaniel Dunbar    OS << "  if (Name == \""
10522be5225ff88ffaab83c36fa133e70586b91166dDaniel Dunbar       << Reg.TheDef->getValueAsString("AsmName") << "\")\n"
10622be5225ff88ffaab83c36fa133e70586b91166dDaniel Dunbar       << "    return RegNo=" << i + 1 << ", false;\n";
10722be5225ff88ffaab83c36fa133e70586b91166dDaniel Dunbar  }
10822be5225ff88ffaab83c36fa133e70586b91166dDaniel Dunbar  OS << "  return true;\n";
10922be5225ff88ffaab83c36fa133e70586b91166dDaniel Dunbar  OS << "}\n";
110a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
111a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar  // Emit the function to match instructions.
112a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar  std::vector<const CodeGenInstruction*> NumberedInstructions;
113a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar  Target.getInstructionsByEnumValue(NumberedInstructions);
114a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
115a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar  std::list<std::string> MatchFns;
116a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
117a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar  OS << "\n";
118a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar  const std::map<std::string, CodeGenInstruction> &Instructions =
119a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    Target.getInstructions();
120a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar  for (std::map<std::string, CodeGenInstruction>::const_iterator
121a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar         it = Instructions.begin(), ie = Instructions.end(); it != ie; ++it) {
122a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    const CodeGenInstruction &CGI = it->second;
123a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
124a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    // Ignore psuedo ops.
125a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    //
126a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    // FIXME: This is a hack.
127a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    if (const RecordVal *Form = CGI.TheDef->getValue("Form"))
128a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      if (Form->getValue()->getAsString() == "Pseudo")
129a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar        continue;
130a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
131a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    // Ignore instructions with no .s string.
132a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    //
133a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    // FIXME: What are these?
134a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    if (CGI.AsmString.empty())
135a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      continue;
136a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
137a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    // FIXME: Hack; ignore "lock".
138a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    if (StringRef(CGI.AsmString).startswith("lock"))
139a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      continue;
140a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
141a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    // FIXME: Hack.
142a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar#if 0
143a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    if (1 && it->first != "SUB8mr")
144a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      continue;
145a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar#endif
146a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
147a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    std::string Flattened = FlattenVariants(CGI.AsmString, 0);
148a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    SmallVector<StringRef, 8> Tokens;
149a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
150a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    TokenizeAsmString(Flattened, Tokens);
151a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
152a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    DEBUG({
153a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar        outs() << it->first << " -- flattened:\""
154a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar               << Flattened << "\", tokens:[";
155a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar        for (unsigned i = 0, e = Tokens.size(); i != e; ++i) {
156a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar          outs() << Tokens[i];
157a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar          if (i + 1 != e)
158a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar            outs() << ", ";
159a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar        }
160a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar        outs() << "]\n";
161a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
162a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar        for (unsigned i = 0, e = CGI.OperandList.size(); i != e; ++i) {
163a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar          const CodeGenInstruction::OperandInfo &OI = CGI.OperandList[i];
164a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar          outs() << "  op[" << i << "] = " << OI.Name
165a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar                 << " " << OI.Rec->getName()
166a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar                 << " (" << OI.MIOperandNo << ", " << OI.MINumOperands << ")\n";
167a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar        }
168a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      });
169a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
170a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    // FIXME: Ignore non-literal tokens.
171a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    if (std::find(Tokens[0].begin(), Tokens[0].end(), '$') != Tokens[0].end())
172a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      continue;
173a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
174a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    std::string FnName = "Match_" + Target.getName() + "_Inst_" + it->first;
175a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    MatchFns.push_back(FnName);
176a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
177a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    OS << "static bool " << FnName
178a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar       << "(const StringRef &Name,"
179a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar       << " SmallVectorImpl<X86Operand> &Operands,"
180a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar       << " MCInst &Inst) {\n\n";
181a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
182a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    OS << "  // Match name.\n";
183a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    OS << "  if (Name != \"" << Tokens[0] << "\")\n";
184a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    OS << "    return true;\n\n";
185a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
186a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    OS << "  // Match number of operands.\n";
187a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    OS << "  if (Operands.size() != " << Tokens.size() - 1 << ")\n";
188a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    OS << "    return true;\n\n";
189a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
190a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    // Compute the total number of MCOperands.
191a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    //
192a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    // FIXME: Isn't this somewhere else?
193a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    unsigned NumMIOperands = 0;
194a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    for (unsigned i = 0, e = CGI.OperandList.size(); i != e; ++i) {
195a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      const CodeGenInstruction::OperandInfo &OI = CGI.OperandList[i];
196a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      NumMIOperands = std::max(NumMIOperands,
197a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar                               OI.MIOperandNo + OI.MINumOperands);
198a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    }
199a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
200a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    std::set<unsigned> MatchedOperands;
201a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    // This the list of operands we need to fill in.
202a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    if (NumMIOperands)
203a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      OS << "  MCOperand Ops[" << NumMIOperands << "];\n\n";
204a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
205a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    unsigned ParsedOpIdx = 0;
206a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    for (unsigned i = 1, e = Tokens.size(); i < e; ++i) {
207a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      // FIXME: Can only match simple operands.
208a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      if (Tokens[i][0] != '$') {
209a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar        OS << "  // FIXME: unable to match token: '" << Tokens[i] << "'!\n";
210a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar        OS << "  return true;\n\n";
211a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar        continue;
212a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      }
213a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
214a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      // Map this token to an operand. FIXME: Move elsewhere.
215a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
216a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      unsigned Idx;
217a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      try {
218a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar        Idx = CGI.getOperandNamed(Tokens[i].substr(1));
219a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      } catch(...) {
220a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar        OS << "  // FIXME: unable to find operand: '" << Tokens[i] << "'!\n";
221a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar        OS << "  return true;\n\n";
222a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar        continue;
223a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      }
224a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
225a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      // FIXME: Each match routine should always end up filling the same number
226a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      // of operands, we should just check that the number matches what the
227a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      // match routine expects here instead of passing it. We can do this once
228a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      // we start generating the class match functions.
229a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      const CodeGenInstruction::OperandInfo &OI = CGI.OperandList[Idx];
230a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
231a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      // Track that we have matched these operands.
232a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      //
233a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      // FIXME: Verify that we don't parse something to the same operand twice.
234a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      for (unsigned j = 0; j != OI.MINumOperands; ++j)
235a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar        MatchedOperands.insert(OI.MIOperandNo + j);
236a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
237a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      OS << "  // Match '" << Tokens[i] << "' (parsed operand " << ParsedOpIdx
238a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar         << ") to machine operands [" << OI.MIOperandNo << ", "
239a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar         << OI.MIOperandNo + OI.MINumOperands << ").\n";
240a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      OS << "  if (Match_" << Target.getName()
241a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar         << "_Op_" << OI.Rec->getName()  << "("
242a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar         << "Operands[" << ParsedOpIdx << "], "
243a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar         << "&Ops[" << OI.MIOperandNo << "], "
244a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar         << OI.MINumOperands << "))\n";
245a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      OS << "    return true;\n\n";
246a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
247a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      ++ParsedOpIdx;
248a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    }
249a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
250a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    // Generate code to construct the MCInst.
251a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
252a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    OS << "  // Construct MCInst.\n";
253a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    OS << "  Inst.setOpcode(" << Target.getName() << "::"
254a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar       << it->first << ");\n";
255a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    for (unsigned i = 0, e = NumMIOperands; i != e; ++i) {
256a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      // FIXME: Oops! Ignore this for now, the instruction should print ok. If
257a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      // we need to evaluate the constraints.
258a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      if (!MatchedOperands.count(i)) {
259a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar        OS << "\n";
260a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar        OS << "  // FIXME: Nothing matched Ops[" << i << "]!\n";
261a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar        OS << "  Ops[" << i << "].MakeReg(0);\n";
262a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar        OS << "\n";
263a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      }
264a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
265a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar      OS << "  Inst.addOperand(Ops[" << i << "]);\n";
266a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    }
267a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    OS << "\n";
268a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    OS << "  return false;\n";
269a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    OS << "}\n\n";
270a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar  }
271a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
272a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar  // Generate the top level match function.
273a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
274a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar  OS << "bool " << Target.getName() << ClassName
275a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar     << "::MatchInstruction(const StringRef &Name, "
276a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar     << "SmallVectorImpl<" << Target.getName() << "Operand> &Operands, "
277a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar     << "MCInst &Inst) {\n";
278a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar  for (std::list<std::string>::iterator it = MatchFns.begin(),
279a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar         ie = MatchFns.end(); it != ie; ++it) {
280a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    OS << "  if (!" << *it << "(Name, Operands, Inst))\n";
281a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar    OS << "    return false;\n\n";
282a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar  }
283a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar
284a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar  OS << "  return true;\n";
285a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar  OS << "}\n\n";
286d51ffcf303070b0a5aea7f365b85f6f969c384cbDaniel Dunbar}
287