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