1b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman//===- FastISelEmitter.cpp - Generate an instruction selector -------------===// 2b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman// 3b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman// The LLVM Compiler Infrastructure 4b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman// 5b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman// This file is distributed under the University of Illinois Open Source 6b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman// License. See LICENSE.TXT for details. 7b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman// 8b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman//===----------------------------------------------------------------------===// 9b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman// 105ec9efd61bc4214c787287409498e8b78f28c922Dan Gohman// This tablegen backend emits code for use by the "fast" instruction 115ec9efd61bc4214c787287409498e8b78f28c922Dan Gohman// selection algorithm. See the comments at the top of 125ec9efd61bc4214c787287409498e8b78f28c922Dan Gohman// lib/CodeGen/SelectionDAG/FastISel.cpp for background. 13b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman// 145ec9efd61bc4214c787287409498e8b78f28c922Dan Gohman// This file scans through the target's tablegen instruction-info files 155ec9efd61bc4214c787287409498e8b78f28c922Dan Gohman// and extracts instructions with obvious-looking patterns, and it emits 165ec9efd61bc4214c787287409498e8b78f28c922Dan Gohman// code to look up these instructions by type and operator. 17b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman// 18b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman//===----------------------------------------------------------------------===// 19b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 206f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include "CodeGenDAGPatterns.h" 2176612b549f176fd6db13c675003232d702c4b2baJim Grosbach#include "llvm/ADT/SmallString.h" 2236a300ac0263f37d6ce0deefd696cb625a1432fdChad Rosier#include "llvm/Support/Debug.h" 2336a300ac0263f37d6ce0deefd696cb625a1432fdChad Rosier#include "llvm/Support/ErrorHandling.h" 246f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include "llvm/TableGen/Error.h" 256f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include "llvm/TableGen/Record.h" 266f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include "llvm/TableGen/TableGenBackend.h" 27b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohmanusing namespace llvm; 28b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 29b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 30667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson/// InstructionMemo - This class holds additional information about an 31667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson/// instruction needed to emit code for it. 32667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson/// 336f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesennamespace { 34667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Andersonstruct InstructionMemo { 35667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson std::string Name; 36667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson const CodeGenRegisterClass *RC; 3773ea7bf4509663267317ec3911aac00ca35a2f2cJakob Stoklund Olesen std::string SubRegNo; 38667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson std::vector<std::string>* PhysRegs; 39667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson}; 406f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End anonymous namespace 416f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 421518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner/// ImmPredicateSet - This uniques predicates (represented as a string) and 431518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner/// gives them unique (small) integer ID's that start at 0. 446f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesennamespace { 451518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattnerclass ImmPredicateSet { 461518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner DenseMap<TreePattern *, unsigned> ImmIDs; 471518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner std::vector<TreePredicateFn> PredsByName; 481518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattnerpublic: 491518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 501518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner unsigned getIDFor(TreePredicateFn Pred) { 511518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner unsigned &Entry = ImmIDs[Pred.getOrigPatFragRecord()]; 521518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner if (Entry == 0) { 531518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner PredsByName.push_back(Pred); 541518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner Entry = PredsByName.size(); 551518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner } 561518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner return Entry-1; 571518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner } 581518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 591518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner const TreePredicateFn &getPredicate(unsigned i) { 601518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner assert(i < PredsByName.size()); 611518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner return PredsByName[i]; 621518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner } 631518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 641518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner typedef std::vector<TreePredicateFn>::const_iterator iterator; 651518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner iterator begin() const { return PredsByName.begin(); } 661518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner iterator end() const { return PredsByName.end(); } 671518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 681518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner}; 696f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End anonymous namespace 70667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson 7104b7dfb233de210cd1c7d846f9fbde85f6824d5eDan Gohman/// OperandsSignature - This class holds a description of a list of operand 7204b7dfb233de210cd1c7d846f9fbde85f6824d5eDan Gohman/// types. It has utility methods for emitting text based on the operands. 7304b7dfb233de210cd1c7d846f9fbde85f6824d5eDan Gohman/// 746f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesennamespace { 75b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohmanstruct OperandsSignature { 769bfd5f3b22157ac2d14ddcaea93b98a6f1140f2fChris Lattner class OpKind { 779bfd5f3b22157ac2d14ddcaea93b98a6f1140f2fChris Lattner enum { OK_Reg, OK_FP, OK_Imm, OK_Invalid = -1 }; 789bfd5f3b22157ac2d14ddcaea93b98a6f1140f2fChris Lattner char Repr; 799bfd5f3b22157ac2d14ddcaea93b98a6f1140f2fChris Lattner public: 809bfd5f3b22157ac2d14ddcaea93b98a6f1140f2fChris Lattner 819bfd5f3b22157ac2d14ddcaea93b98a6f1140f2fChris Lattner OpKind() : Repr(OK_Invalid) {} 829bfd5f3b22157ac2d14ddcaea93b98a6f1140f2fChris Lattner 839bfd5f3b22157ac2d14ddcaea93b98a6f1140f2fChris Lattner bool operator<(OpKind RHS) const { return Repr < RHS.Repr; } 841518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner bool operator==(OpKind RHS) const { return Repr == RHS.Repr; } 859bfd5f3b22157ac2d14ddcaea93b98a6f1140f2fChris Lattner 869bfd5f3b22157ac2d14ddcaea93b98a6f1140f2fChris Lattner static OpKind getReg() { OpKind K; K.Repr = OK_Reg; return K; } 879bfd5f3b22157ac2d14ddcaea93b98a6f1140f2fChris Lattner static OpKind getFP() { OpKind K; K.Repr = OK_FP; return K; } 881518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner static OpKind getImm(unsigned V) { 891518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner assert((unsigned)OK_Imm+V < 128 && 901518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner "Too many integer predicates for the 'Repr' char"); 911518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner OpKind K; K.Repr = OK_Imm+V; return K; 921518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner } 939bfd5f3b22157ac2d14ddcaea93b98a6f1140f2fChris Lattner 949bfd5f3b22157ac2d14ddcaea93b98a6f1140f2fChris Lattner bool isReg() const { return Repr == OK_Reg; } 959bfd5f3b22157ac2d14ddcaea93b98a6f1140f2fChris Lattner bool isFP() const { return Repr == OK_FP; } 961518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner bool isImm() const { return Repr >= OK_Imm; } 971518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 981518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner unsigned getImmCode() const { assert(isImm()); return Repr-OK_Imm; } 999bfd5f3b22157ac2d14ddcaea93b98a6f1140f2fChris Lattner 1001518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner void printManglingSuffix(raw_ostream &OS, ImmPredicateSet &ImmPredicates, 1011518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner bool StripImmCodes) const { 1029bfd5f3b22157ac2d14ddcaea93b98a6f1140f2fChris Lattner if (isReg()) 1039bfd5f3b22157ac2d14ddcaea93b98a6f1140f2fChris Lattner OS << 'r'; 1049bfd5f3b22157ac2d14ddcaea93b98a6f1140f2fChris Lattner else if (isFP()) 1059bfd5f3b22157ac2d14ddcaea93b98a6f1140f2fChris Lattner OS << 'f'; 1061518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner else { 1079bfd5f3b22157ac2d14ddcaea93b98a6f1140f2fChris Lattner OS << 'i'; 1081518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner if (!StripImmCodes) 1091518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner if (unsigned Code = getImmCode()) 1101518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner OS << "_" << ImmPredicates.getPredicate(Code-1).getFnName(); 1111518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner } 1129bfd5f3b22157ac2d14ddcaea93b98a6f1140f2fChris Lattner } 1139bfd5f3b22157ac2d14ddcaea93b98a6f1140f2fChris Lattner }; 1149bfd5f3b22157ac2d14ddcaea93b98a6f1140f2fChris Lattner 1151518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 1169bfd5f3b22157ac2d14ddcaea93b98a6f1140f2fChris Lattner SmallVector<OpKind, 3> Operands; 117b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 118b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman bool operator<(const OperandsSignature &O) const { 119b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman return Operands < O.Operands; 120b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman } 1211518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner bool operator==(const OperandsSignature &O) const { 1221518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner return Operands == O.Operands; 1231518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner } 124b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 125b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman bool empty() const { return Operands.empty(); } 126b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 1271518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner bool hasAnyImmediateCodes() const { 1281518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner for (unsigned i = 0, e = Operands.size(); i != e; ++i) 1291518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner if (Operands[i].isImm() && Operands[i].getImmCode() != 0) 1301518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner return true; 1311518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner return false; 1321518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner } 1331518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 1341518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner /// getWithoutImmCodes - Return a copy of this with any immediate codes forced 1351518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner /// to zero. 1361518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner OperandsSignature getWithoutImmCodes() const { 1371518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner OperandsSignature Result; 1381518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner for (unsigned i = 0, e = Operands.size(); i != e; ++i) 1391518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner if (!Operands[i].isImm()) 1401518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner Result.Operands.push_back(Operands[i]); 1411518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner else 1421518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner Result.Operands.push_back(OpKind::getImm(0)); 1431518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner return Result; 1441518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner } 1451518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 1461518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner void emitImmediatePredicate(raw_ostream &OS, ImmPredicateSet &ImmPredicates) { 1471518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner bool EmittedAnything = false; 1481518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner for (unsigned i = 0, e = Operands.size(); i != e; ++i) { 1491518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner if (!Operands[i].isImm()) continue; 1501518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 1511518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner unsigned Code = Operands[i].getImmCode(); 1521518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner if (Code == 0) continue; 1531518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 1541518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner if (EmittedAnything) 1551518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner OS << " &&\n "; 1561518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 1571518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner TreePredicateFn PredFn = ImmPredicates.getPredicate(Code-1); 1581518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 1591518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner // Emit the type check. 1601518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner OS << "VT == " 1611518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner << getEnumName(PredFn.getOrigPatFragRecord()->getTree(0)->getType(0)) 1621518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner << " && "; 1631518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 1641518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 1651518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner OS << PredFn.getFnName() << "(imm" << i <<')'; 1661518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner EmittedAnything = true; 1671518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner } 1681518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner } 1691518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 170d1d2ee8ccbcf0d8c54a07413d4ae599ebfdda14bDan Gohman /// initialize - Examine the given pattern and initialize the contents 171d1d2ee8ccbcf0d8c54a07413d4ae599ebfdda14bDan Gohman /// of the Operands array accordingly. Return true if all the operands 172d1d2ee8ccbcf0d8c54a07413d4ae599ebfdda14bDan Gohman /// are supported, false otherwise. 173d1d2ee8ccbcf0d8c54a07413d4ae599ebfdda14bDan Gohman /// 174602fc0681726155942907debee1fe0b8b44ffc1bChris Lattner bool initialize(TreePatternNode *InstPatNode, const CodeGenTarget &Target, 1751518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner MVT::SimpleValueType VT, 1761518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner ImmPredicateSet &ImmediatePredicates) { 1771518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner if (InstPatNode->isLeaf()) 1781518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner return false; 1791518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 1801518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner if (InstPatNode->getOperator()->getName() == "imm") { 1811518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner Operands.push_back(OpKind::getImm(0)); 1821518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner return true; 1831518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner } 1841518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 1851518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner if (InstPatNode->getOperator()->getName() == "fpimm") { 1861518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner Operands.push_back(OpKind::getFP()); 1871518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner return true; 18810df0fa73e396bbc93a8940e8b53827390c54d10Dan Gohman } 18945258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 190abb1f1688172cf6f3c5bc539841da76053f23533Owen Anderson const CodeGenRegisterClass *DstRC = 0; 19145258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 192d1d2ee8ccbcf0d8c54a07413d4ae599ebfdda14bDan Gohman for (unsigned i = 0, e = InstPatNode->getNumChildren(); i != e; ++i) { 193d1d2ee8ccbcf0d8c54a07413d4ae599ebfdda14bDan Gohman TreePatternNode *Op = InstPatNode->getChild(i); 19445258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 1951518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner // Handle imm operands specially. 1961518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner if (!Op->isLeaf() && Op->getOperator()->getName() == "imm") { 1971518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner unsigned PredNo = 0; 1981518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner if (!Op->getPredicateFns().empty()) { 199202a7a1e3fa661bf78b98d77de7e2d575facd9eeChris Lattner TreePredicateFn PredFn = Op->getPredicateFns()[0]; 2001518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner // If there is more than one predicate weighing in on this operand 2011518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner // then we don't handle it. This doesn't typically happen for 2021518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner // immediates anyway. 2031518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner if (Op->getPredicateFns().size() > 1 || 204202a7a1e3fa661bf78b98d77de7e2d575facd9eeChris Lattner !PredFn.isImmediatePattern()) 205202a7a1e3fa661bf78b98d77de7e2d575facd9eeChris Lattner return false; 206202a7a1e3fa661bf78b98d77de7e2d575facd9eeChris Lattner // Ignore any instruction with 'FastIselShouldIgnore', these are 207202a7a1e3fa661bf78b98d77de7e2d575facd9eeChris Lattner // not needed and just bloat the fast instruction selector. For 208202a7a1e3fa661bf78b98d77de7e2d575facd9eeChris Lattner // example, X86 doesn't need to generate code to match ADD16ri8 since 209202a7a1e3fa661bf78b98d77de7e2d575facd9eeChris Lattner // ADD16ri will do just fine. 210202a7a1e3fa661bf78b98d77de7e2d575facd9eeChris Lattner Record *Rec = PredFn.getOrigPatFragRecord()->getRecord(); 211202a7a1e3fa661bf78b98d77de7e2d575facd9eeChris Lattner if (Rec->getValueAsBit("FastIselShouldIgnore")) 2121518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner return false; 2131518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 214202a7a1e3fa661bf78b98d77de7e2d575facd9eeChris Lattner PredNo = ImmediatePredicates.getIDFor(PredFn)+1; 2151518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner } 2161518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 2171518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner // Handle unmatched immediate sizes here. 2181518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner //if (Op->getType(0) != VT) 2191518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner // return false; 2201518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 2211518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner Operands.push_back(OpKind::getImm(PredNo)); 2221518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner continue; 2231518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner } 2241518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 2251518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 226d1d2ee8ccbcf0d8c54a07413d4ae599ebfdda14bDan Gohman // For now, filter out any operand with a predicate. 227d5fe57d2f980c6bd1a61450f99c254a76d0f1683Dan Gohman // For now, filter out any operand with multiple values. 228602fc0681726155942907debee1fe0b8b44ffc1bChris Lattner if (!Op->getPredicateFns().empty() || Op->getNumTypes() != 1) 229d5fe57d2f980c6bd1a61450f99c254a76d0f1683Dan Gohman return false; 23045258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 231d5fe57d2f980c6bd1a61450f99c254a76d0f1683Dan Gohman if (!Op->isLeaf()) { 2321518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner if (Op->getOperator()->getName() == "fpimm") { 2339bfd5f3b22157ac2d14ddcaea93b98a6f1140f2fChris Lattner Operands.push_back(OpKind::getFP()); 234edc8774a7375dc74f226ee37d0ba321502ddf691Dale Johannesen continue; 23510df0fa73e396bbc93a8940e8b53827390c54d10Dan Gohman } 236833ddf84302aa08d9157b28d37c40ae134a74da6Dan Gohman // For now, ignore other non-leaf nodes. 237d5fe57d2f980c6bd1a61450f99c254a76d0f1683Dan Gohman return false; 238d5fe57d2f980c6bd1a61450f99c254a76d0f1683Dan Gohman } 239602fc0681726155942907debee1fe0b8b44ffc1bChris Lattner 240602fc0681726155942907debee1fe0b8b44ffc1bChris Lattner assert(Op->hasTypeSet(0) && "Type infererence not done?"); 241602fc0681726155942907debee1fe0b8b44ffc1bChris Lattner 242602fc0681726155942907debee1fe0b8b44ffc1bChris Lattner // For now, all the operands must have the same type (if they aren't 243602fc0681726155942907debee1fe0b8b44ffc1bChris Lattner // immediates). Note that this causes us to reject variable sized shifts 244602fc0681726155942907debee1fe0b8b44ffc1bChris Lattner // on X86. 245602fc0681726155942907debee1fe0b8b44ffc1bChris Lattner if (Op->getType(0) != VT) 246602fc0681726155942907debee1fe0b8b44ffc1bChris Lattner return false; 247602fc0681726155942907debee1fe0b8b44ffc1bChris Lattner 2486cfc806a6b82b60a3e923b6b89f2b4da62cdb50bSean Silva DefInit *OpDI = dyn_cast<DefInit>(Op->getLeafValue()); 249d1d2ee8ccbcf0d8c54a07413d4ae599ebfdda14bDan Gohman if (!OpDI) 250d1d2ee8ccbcf0d8c54a07413d4ae599ebfdda14bDan Gohman return false; 251d1d2ee8ccbcf0d8c54a07413d4ae599ebfdda14bDan Gohman Record *OpLeafRec = OpDI->getDef(); 2529bfd5f3b22157ac2d14ddcaea93b98a6f1140f2fChris Lattner 253d5fe57d2f980c6bd1a61450f99c254a76d0f1683Dan Gohman // For now, the only other thing we accept is register operands. 254667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson const CodeGenRegisterClass *RC = 0; 255bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson if (OpLeafRec->isSubClassOf("RegisterOperand")) 256bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson OpLeafRec = OpLeafRec->getValueAsDef("RegClass"); 257667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson if (OpLeafRec->isSubClassOf("RegisterClass")) 258667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson RC = &Target.getRegisterClass(OpLeafRec); 259667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson else if (OpLeafRec->isSubClassOf("Register")) 2607b9cafde5e3faec22bbfbbc90cca0876968abad9Jakob Stoklund Olesen RC = Target.getRegBank().getRegClassForRegister(OpLeafRec); 261667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson else 262d1d2ee8ccbcf0d8c54a07413d4ae599ebfdda14bDan Gohman return false; 26345258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 2642cfcad97b766068a20f3715ed3b4beb9143f329fEric Christopher // For now, this needs to be a register class of some sort. 265d1d2ee8ccbcf0d8c54a07413d4ae599ebfdda14bDan Gohman if (!RC) 266d1d2ee8ccbcf0d8c54a07413d4ae599ebfdda14bDan Gohman return false; 2672cfcad97b766068a20f3715ed3b4beb9143f329fEric Christopher 26853452606ca04929257b3bcbfa5e0d59a44925882Eric Christopher // For now, all the operands must have the same register class or be 26953452606ca04929257b3bcbfa5e0d59a44925882Eric Christopher // a strict subclass of the destination. 270abb1f1688172cf6f3c5bc539841da76053f23533Owen Anderson if (DstRC) { 27153452606ca04929257b3bcbfa5e0d59a44925882Eric Christopher if (DstRC != RC && !DstRC->hasSubClass(RC)) 272abb1f1688172cf6f3c5bc539841da76053f23533Owen Anderson return false; 273abb1f1688172cf6f3c5bc539841da76053f23533Owen Anderson } else 274abb1f1688172cf6f3c5bc539841da76053f23533Owen Anderson DstRC = RC; 2759bfd5f3b22157ac2d14ddcaea93b98a6f1140f2fChris Lattner Operands.push_back(OpKind::getReg()); 276d1d2ee8ccbcf0d8c54a07413d4ae599ebfdda14bDan Gohman } 277d1d2ee8ccbcf0d8c54a07413d4ae599ebfdda14bDan Gohman return true; 278d1d2ee8ccbcf0d8c54a07413d4ae599ebfdda14bDan Gohman } 279d1d2ee8ccbcf0d8c54a07413d4ae599ebfdda14bDan Gohman 2801a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar void PrintParameters(raw_ostream &OS) const { 281b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman for (unsigned i = 0, e = Operands.size(); i != e; ++i) { 2829bfd5f3b22157ac2d14ddcaea93b98a6f1140f2fChris Lattner if (Operands[i].isReg()) { 283a6cb641f48df20f6f79018569b519e5a32e897a2Dan Gohman OS << "unsigned Op" << i << ", bool Op" << i << "IsKill"; 2849bfd5f3b22157ac2d14ddcaea93b98a6f1140f2fChris Lattner } else if (Operands[i].isImm()) { 285d5fe57d2f980c6bd1a61450f99c254a76d0f1683Dan Gohman OS << "uint64_t imm" << i; 2869bfd5f3b22157ac2d14ddcaea93b98a6f1140f2fChris Lattner } else if (Operands[i].isFP()) { 28782f000266a93c6e18e7db23c6736a73dd31f46c1Cameron Zwarich OS << "const ConstantFP *f" << i; 288b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman } else { 28936a300ac0263f37d6ce0deefd696cb625a1432fdChad Rosier llvm_unreachable("Unknown operand kind!"); 290b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman } 291b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman if (i + 1 != e) 292b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << ", "; 293b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman } 294b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman } 295b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 2961a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar void PrintArguments(raw_ostream &OS, 2979bfd5f3b22157ac2d14ddcaea93b98a6f1140f2fChris Lattner const std::vector<std::string> &PR) const { 298667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson assert(PR.size() == Operands.size()); 29998d2d07d416b3431a298eec5a2bfe8b39652c3aaEvan Cheng bool PrintedArg = false; 300667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson for (unsigned i = 0, e = Operands.size(); i != e; ++i) { 30198d2d07d416b3431a298eec5a2bfe8b39652c3aaEvan Cheng if (PR[i] != "") 30298d2d07d416b3431a298eec5a2bfe8b39652c3aaEvan Cheng // Implicit physical register operand. 30398d2d07d416b3431a298eec5a2bfe8b39652c3aaEvan Cheng continue; 30498d2d07d416b3431a298eec5a2bfe8b39652c3aaEvan Cheng 30598d2d07d416b3431a298eec5a2bfe8b39652c3aaEvan Cheng if (PrintedArg) 30698d2d07d416b3431a298eec5a2bfe8b39652c3aaEvan Cheng OS << ", "; 3079bfd5f3b22157ac2d14ddcaea93b98a6f1140f2fChris Lattner if (Operands[i].isReg()) { 308a6cb641f48df20f6f79018569b519e5a32e897a2Dan Gohman OS << "Op" << i << ", Op" << i << "IsKill"; 30998d2d07d416b3431a298eec5a2bfe8b39652c3aaEvan Cheng PrintedArg = true; 3109bfd5f3b22157ac2d14ddcaea93b98a6f1140f2fChris Lattner } else if (Operands[i].isImm()) { 311667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson OS << "imm" << i; 31298d2d07d416b3431a298eec5a2bfe8b39652c3aaEvan Cheng PrintedArg = true; 3139bfd5f3b22157ac2d14ddcaea93b98a6f1140f2fChris Lattner } else if (Operands[i].isFP()) { 314667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson OS << "f" << i; 31598d2d07d416b3431a298eec5a2bfe8b39652c3aaEvan Cheng PrintedArg = true; 316667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson } else { 31736a300ac0263f37d6ce0deefd696cb625a1432fdChad Rosier llvm_unreachable("Unknown operand kind!"); 318667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson } 319667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson } 320667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson } 321667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson 3221a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar void PrintArguments(raw_ostream &OS) const { 323b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman for (unsigned i = 0, e = Operands.size(); i != e; ++i) { 3249bfd5f3b22157ac2d14ddcaea93b98a6f1140f2fChris Lattner if (Operands[i].isReg()) { 325a6cb641f48df20f6f79018569b519e5a32e897a2Dan Gohman OS << "Op" << i << ", Op" << i << "IsKill"; 3269bfd5f3b22157ac2d14ddcaea93b98a6f1140f2fChris Lattner } else if (Operands[i].isImm()) { 327d5fe57d2f980c6bd1a61450f99c254a76d0f1683Dan Gohman OS << "imm" << i; 3289bfd5f3b22157ac2d14ddcaea93b98a6f1140f2fChris Lattner } else if (Operands[i].isFP()) { 32910df0fa73e396bbc93a8940e8b53827390c54d10Dan Gohman OS << "f" << i; 330b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman } else { 33136a300ac0263f37d6ce0deefd696cb625a1432fdChad Rosier llvm_unreachable("Unknown operand kind!"); 332b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman } 333b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman if (i + 1 != e) 334b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << ", "; 335b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman } 336b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman } 337b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 338667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson 3391518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner void PrintManglingSuffix(raw_ostream &OS, const std::vector<std::string> &PR, 3401518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner ImmPredicateSet &ImmPredicates, 3411518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner bool StripImmCodes = false) const { 34298d2d07d416b3431a298eec5a2bfe8b39652c3aaEvan Cheng for (unsigned i = 0, e = Operands.size(); i != e; ++i) { 34398d2d07d416b3431a298eec5a2bfe8b39652c3aaEvan Cheng if (PR[i] != "") 34498d2d07d416b3431a298eec5a2bfe8b39652c3aaEvan Cheng // Implicit physical register operand. e.g. Instruction::Mul expect to 34598d2d07d416b3431a298eec5a2bfe8b39652c3aaEvan Cheng // select to a binary op. On x86, mul may take a single operand with 34698d2d07d416b3431a298eec5a2bfe8b39652c3aaEvan Cheng // the other operand being implicit. We must emit something that looks 34798d2d07d416b3431a298eec5a2bfe8b39652c3aaEvan Cheng // like a binary instruction except for the very inner FastEmitInst_* 34898d2d07d416b3431a298eec5a2bfe8b39652c3aaEvan Cheng // call. 34998d2d07d416b3431a298eec5a2bfe8b39652c3aaEvan Cheng continue; 3501518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner Operands[i].printManglingSuffix(OS, ImmPredicates, StripImmCodes); 35198d2d07d416b3431a298eec5a2bfe8b39652c3aaEvan Cheng } 35298d2d07d416b3431a298eec5a2bfe8b39652c3aaEvan Cheng } 35398d2d07d416b3431a298eec5a2bfe8b39652c3aaEvan Cheng 3541518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner void PrintManglingSuffix(raw_ostream &OS, ImmPredicateSet &ImmPredicates, 3551518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner bool StripImmCodes = false) const { 3569bfd5f3b22157ac2d14ddcaea93b98a6f1140f2fChris Lattner for (unsigned i = 0, e = Operands.size(); i != e; ++i) 3571518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner Operands[i].printManglingSuffix(OS, ImmPredicates, StripImmCodes); 358b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman } 359b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman}; 3606f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End anonymous namespace 361b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 3626f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesennamespace { 36372d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohmanclass FastISelMap { 36472d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman typedef std::map<std::string, InstructionMemo> PredMap; 365825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson typedef std::map<MVT::SimpleValueType, PredMap> RetPredMap; 366825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson typedef std::map<MVT::SimpleValueType, RetPredMap> TypeRetPredMap; 36772d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman typedef std::map<std::string, TypeRetPredMap> OpcodeTypeRetPredMap; 36845258f570826bb4369042efa915a10248b4d7a42Jim Grosbach typedef std::map<OperandsSignature, OpcodeTypeRetPredMap> 369ecfa079206912a1ae4069881cf63edf6be7fa117Eric Christopher OperandsOpcodeTypeRetPredMap; 37072d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman 37172d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman OperandsOpcodeTypeRetPredMap SimplePatterns; 37272d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman 3731518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner std::map<OperandsSignature, std::vector<OperandsSignature> > 3741518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner SignaturesWithConstantForms; 3751518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 37672d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman std::string InstNS; 3771518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner ImmPredicateSet ImmediatePredicates; 37872d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohmanpublic: 37972d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman explicit FastISelMap(std::string InstNS); 38072d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman 3811518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner void collectPatterns(CodeGenDAGPatterns &CGP); 3821518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner void printImmediatePredicates(raw_ostream &OS); 3831518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner void printFunctionDefinitions(raw_ostream &OS); 38472d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman}; 3856f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End anonymous namespace 386b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 387b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohmanstatic std::string getOpcodeName(Record *Op, CodeGenDAGPatterns &CGP) { 388b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman return CGP.getSDNodeInfo(Op).getEnumName(); 389b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman} 390b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 391b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohmanstatic std::string getLegalCName(std::string OpName) { 392b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman std::string::size_type pos = OpName.find("::"); 393b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman if (pos != std::string::npos) 394b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OpName.replace(pos, 2, "_"); 395b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman return OpName; 396b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman} 397b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 39872d63af3f76250f198910f0f69cb4ccffd4c14a6Dan GohmanFastISelMap::FastISelMap(std::string instns) 39972d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman : InstNS(instns) { 40072d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman} 401b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 402206a10cf286572cd22140559b328e0a14cef7984Eli Friedmanstatic std::string PhyRegForNode(TreePatternNode *Op, 403206a10cf286572cd22140559b328e0a14cef7984Eli Friedman const CodeGenTarget &Target) { 404206a10cf286572cd22140559b328e0a14cef7984Eli Friedman std::string PhysReg; 405206a10cf286572cd22140559b328e0a14cef7984Eli Friedman 406206a10cf286572cd22140559b328e0a14cef7984Eli Friedman if (!Op->isLeaf()) 407206a10cf286572cd22140559b328e0a14cef7984Eli Friedman return PhysReg; 408206a10cf286572cd22140559b328e0a14cef7984Eli Friedman 4093f7b7f8ce0b050fc6a0100839d9c5a84198b2aedSean Silva Record *OpLeafRec = cast<DefInit>(Op->getLeafValue())->getDef(); 410206a10cf286572cd22140559b328e0a14cef7984Eli Friedman if (!OpLeafRec->isSubClassOf("Register")) 411206a10cf286572cd22140559b328e0a14cef7984Eli Friedman return PhysReg; 412206a10cf286572cd22140559b328e0a14cef7984Eli Friedman 4133f7b7f8ce0b050fc6a0100839d9c5a84198b2aedSean Silva PhysReg += cast<StringInit>(OpLeafRec->getValue("Namespace")->getValue()) 4143f7b7f8ce0b050fc6a0100839d9c5a84198b2aedSean Silva ->getValue(); 415206a10cf286572cd22140559b328e0a14cef7984Eli Friedman PhysReg += "::"; 416abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen PhysReg += Target.getRegBank().getReg(OpLeafRec)->getName(); 417206a10cf286572cd22140559b328e0a14cef7984Eli Friedman return PhysReg; 418206a10cf286572cd22140559b328e0a14cef7984Eli Friedman} 419206a10cf286572cd22140559b328e0a14cef7984Eli Friedman 4201518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattnervoid FastISelMap::collectPatterns(CodeGenDAGPatterns &CGP) { 42172d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman const CodeGenTarget &Target = CGP.getTargetInfo(); 42272d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman 42372d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman // Determine the target's namespace name. 42472d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman InstNS = Target.getInstNamespace() + "::"; 42572d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman assert(InstNS.size() > 2 && "Can't determine target-specific namespace!"); 426b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 4270bfb75277f6d6e160dd29d99e6870da927500b50Dan Gohman // Scan through all the patterns and record the simple ones. 428b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman for (CodeGenDAGPatterns::ptm_iterator I = CGP.ptm_begin(), 429b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman E = CGP.ptm_end(); I != E; ++I) { 430b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman const PatternToMatch &Pattern = *I; 431b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 432b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman // For now, just look at Instructions, so that we don't have to worry 433b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman // about emitting multiple instructions for a pattern. 434b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman TreePatternNode *Dst = Pattern.getDstPattern(); 435b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman if (Dst->isLeaf()) continue; 436b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman Record *Op = Dst->getOperator(); 437b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman if (!Op->isSubClassOf("Instruction")) 438b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman continue; 439f30187a36324fb75042d9ffd20c3fb70aff7763dChris Lattner CodeGenInstruction &II = CGP.getTargetInfo().getInstruction(Op); 440a90dbc133f7bc7bf0e042fb03222bfdfafce3965Chris Lattner if (II.Operands.empty()) 441b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman continue; 44245258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 44334fc6ceb73ed9e6acaa40c86b0b68684b95cca23Evan Cheng // For now, ignore multi-instruction patterns. 44434fc6ceb73ed9e6acaa40c86b0b68684b95cca23Evan Cheng bool MultiInsts = false; 44534fc6ceb73ed9e6acaa40c86b0b68684b95cca23Evan Cheng for (unsigned i = 0, e = Dst->getNumChildren(); i != e; ++i) { 44634fc6ceb73ed9e6acaa40c86b0b68684b95cca23Evan Cheng TreePatternNode *ChildOp = Dst->getChild(i); 44734fc6ceb73ed9e6acaa40c86b0b68684b95cca23Evan Cheng if (ChildOp->isLeaf()) 44834fc6ceb73ed9e6acaa40c86b0b68684b95cca23Evan Cheng continue; 44934fc6ceb73ed9e6acaa40c86b0b68684b95cca23Evan Cheng if (ChildOp->getOperator()->isSubClassOf("Instruction")) { 45034fc6ceb73ed9e6acaa40c86b0b68684b95cca23Evan Cheng MultiInsts = true; 45134fc6ceb73ed9e6acaa40c86b0b68684b95cca23Evan Cheng break; 45234fc6ceb73ed9e6acaa40c86b0b68684b95cca23Evan Cheng } 45334fc6ceb73ed9e6acaa40c86b0b68684b95cca23Evan Cheng } 45434fc6ceb73ed9e6acaa40c86b0b68684b95cca23Evan Cheng if (MultiInsts) 45534fc6ceb73ed9e6acaa40c86b0b68684b95cca23Evan Cheng continue; 45634fc6ceb73ed9e6acaa40c86b0b68684b95cca23Evan Cheng 457379cad44ecc91be24b2b147081d2089024cbacebDan Gohman // For now, ignore instructions where the first operand is not an 458379cad44ecc91be24b2b147081d2089024cbacebDan Gohman // output register. 459b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson const CodeGenRegisterClass *DstRC = 0; 46073ea7bf4509663267317ec3911aac00ca35a2f2cJakob Stoklund Olesen std::string SubRegNo; 461b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson if (Op->getName() != "EXTRACT_SUBREG") { 462c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner Record *Op0Rec = II.Operands[0].Rec; 463bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson if (Op0Rec->isSubClassOf("RegisterOperand")) 464bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson Op0Rec = Op0Rec->getValueAsDef("RegClass"); 465b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson if (!Op0Rec->isSubClassOf("RegisterClass")) 466b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson continue; 467b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson DstRC = &Target.getRegisterClass(Op0Rec); 468b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson if (!DstRC) 469b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson continue; 470b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson } else { 47107fdd897e2c4304b6f70345c488e97fd97374576Eric Christopher // If this isn't a leaf, then continue since the register classes are 47207fdd897e2c4304b6f70345c488e97fd97374576Eric Christopher // a bit too complicated for now. 47307fdd897e2c4304b6f70345c488e97fd97374576Eric Christopher if (!Dst->getChild(1)->isLeaf()) continue; 47445258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 4756cfc806a6b82b60a3e923b6b89f2b4da62cdb50bSean Silva DefInit *SR = dyn_cast<DefInit>(Dst->getChild(1)->getLeafValue()); 47673ea7bf4509663267317ec3911aac00ca35a2f2cJakob Stoklund Olesen if (SR) 47773ea7bf4509663267317ec3911aac00ca35a2f2cJakob Stoklund Olesen SubRegNo = getQualifiedName(SR->getDef()); 47873ea7bf4509663267317ec3911aac00ca35a2f2cJakob Stoklund Olesen else 47973ea7bf4509663267317ec3911aac00ca35a2f2cJakob Stoklund Olesen SubRegNo = Dst->getChild(1)->getLeafValue()->getAsString(); 480b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson } 481b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 482b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman // Inspect the pattern. 483b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman TreePatternNode *InstPatNode = Pattern.getSrcPattern(); 484b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman if (!InstPatNode) continue; 485b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman if (InstPatNode->isLeaf()) continue; 486b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 487084df627c82fdf4e1829723edf0a833b5bc31f89Chris Lattner // Ignore multiple result nodes for now. 488084df627c82fdf4e1829723edf0a833b5bc31f89Chris Lattner if (InstPatNode->getNumTypes() > 1) continue; 48945258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 490b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman Record *InstPatOp = InstPatNode->getOperator(); 491b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman std::string OpcodeName = getOpcodeName(InstPatOp, CGP); 492d7349194650386d97a1d779369cb46f20ba9f252Chris Lattner MVT::SimpleValueType RetVT = MVT::isVoid; 493d7349194650386d97a1d779369cb46f20ba9f252Chris Lattner if (InstPatNode->getNumTypes()) RetVT = InstPatNode->getType(0); 494825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson MVT::SimpleValueType VT = RetVT; 495d7349194650386d97a1d779369cb46f20ba9f252Chris Lattner if (InstPatNode->getNumChildren()) { 496d7349194650386d97a1d779369cb46f20ba9f252Chris Lattner assert(InstPatNode->getChild(0)->getNumTypes() == 1); 497d7349194650386d97a1d779369cb46f20ba9f252Chris Lattner VT = InstPatNode->getChild(0)->getType(0); 498d7349194650386d97a1d779369cb46f20ba9f252Chris Lattner } 499f4137b5f409525b41ec4d4bff56c54fd2a9db274Dan Gohman 500f4137b5f409525b41ec4d4bff56c54fd2a9db274Dan Gohman // For now, filter out any instructions with predicates. 5010540e17788f0d09d784fb9bd9b354e02f1c5e4a4Dan Gohman if (!InstPatNode->getPredicateFns().empty()) 502f4137b5f409525b41ec4d4bff56c54fd2a9db274Dan Gohman continue; 503b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 504379cad44ecc91be24b2b147081d2089024cbacebDan Gohman // Check all the operands. 505b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OperandsSignature Operands; 5061518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner if (!Operands.initialize(InstPatNode, Target, VT, ImmediatePredicates)) 507d1d2ee8ccbcf0d8c54a07413d4ae599ebfdda14bDan Gohman continue; 50845258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 509667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson std::vector<std::string>* PhysRegInputs = new std::vector<std::string>(); 510206a10cf286572cd22140559b328e0a14cef7984Eli Friedman if (InstPatNode->getOperator()->getName() == "imm" || 511691a4882ed086912edfe60da225bdc3f3e2f9a82Eric Christopher InstPatNode->getOperator()->getName() == "fpimm") 512667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson PhysRegInputs->push_back(""); 513206a10cf286572cd22140559b328e0a14cef7984Eli Friedman else { 514206a10cf286572cd22140559b328e0a14cef7984Eli Friedman // Compute the PhysRegs used by the given pattern, and check that 515206a10cf286572cd22140559b328e0a14cef7984Eli Friedman // the mapping from the src to dst patterns is simple. 516206a10cf286572cd22140559b328e0a14cef7984Eli Friedman bool FoundNonSimplePattern = false; 517206a10cf286572cd22140559b328e0a14cef7984Eli Friedman unsigned DstIndex = 0; 518667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson for (unsigned i = 0, e = InstPatNode->getNumChildren(); i != e; ++i) { 519206a10cf286572cd22140559b328e0a14cef7984Eli Friedman std::string PhysReg = PhyRegForNode(InstPatNode->getChild(i), Target); 520206a10cf286572cd22140559b328e0a14cef7984Eli Friedman if (PhysReg.empty()) { 521206a10cf286572cd22140559b328e0a14cef7984Eli Friedman if (DstIndex >= Dst->getNumChildren() || 522206a10cf286572cd22140559b328e0a14cef7984Eli Friedman Dst->getChild(DstIndex)->getName() != 523206a10cf286572cd22140559b328e0a14cef7984Eli Friedman InstPatNode->getChild(i)->getName()) { 524206a10cf286572cd22140559b328e0a14cef7984Eli Friedman FoundNonSimplePattern = true; 525206a10cf286572cd22140559b328e0a14cef7984Eli Friedman break; 526667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson } 527206a10cf286572cd22140559b328e0a14cef7984Eli Friedman ++DstIndex; 528667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson } 52945258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 530667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson PhysRegInputs->push_back(PhysReg); 531667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson } 532206a10cf286572cd22140559b328e0a14cef7984Eli Friedman 533206a10cf286572cd22140559b328e0a14cef7984Eli Friedman if (Op->getName() != "EXTRACT_SUBREG" && DstIndex < Dst->getNumChildren()) 534206a10cf286572cd22140559b328e0a14cef7984Eli Friedman FoundNonSimplePattern = true; 535206a10cf286572cd22140559b328e0a14cef7984Eli Friedman 536206a10cf286572cd22140559b328e0a14cef7984Eli Friedman if (FoundNonSimplePattern) 537206a10cf286572cd22140559b328e0a14cef7984Eli Friedman continue; 538206a10cf286572cd22140559b328e0a14cef7984Eli Friedman } 539b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 54022bb31103de3337f0bb74c7bee16d1817d4dca14Dan Gohman // Get the predicate that guards this pattern. 54122bb31103de3337f0bb74c7bee16d1817d4dca14Dan Gohman std::string PredicateCheck = Pattern.getPredicateCheck(); 54222bb31103de3337f0bb74c7bee16d1817d4dca14Dan Gohman 543b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman // Ok, we found a pattern that we can handle. Remember it. 544520b50c00d237ef4309fca364202d111f9faa82fDan Gohman InstructionMemo Memo = { 545520b50c00d237ef4309fca364202d111f9faa82fDan Gohman Pattern.getDstPattern()->getOperator()->getName(), 546b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson DstRC, 547667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson SubRegNo, 548667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson PhysRegInputs 549520b50c00d237ef4309fca364202d111f9faa82fDan Gohman }; 5501518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 5511518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner if (SimplePatterns[Operands][OpcodeName][VT][RetVT].count(PredicateCheck)) 55261131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger PrintFatalError(Pattern.getSrcRecord()->getLoc(), 5531518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner "Duplicate record in FastISel table!"); 554997759ac22dc1de6f324b1c09c0a2a558236c489Jim Grosbach 555abb1f1688172cf6f3c5bc539841da76053f23533Owen Anderson SimplePatterns[Operands][OpcodeName][VT][RetVT][PredicateCheck] = Memo; 5561518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 5571518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner // If any of the operands were immediates with predicates on them, strip 5581518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner // them down to a signature that doesn't have predicates so that we can 5591518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner // associate them with the stripped predicate version. 5601518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner if (Operands.hasAnyImmediateCodes()) { 5611518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner SignaturesWithConstantForms[Operands.getWithoutImmCodes()] 5621518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner .push_back(Operands); 5631518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner } 564b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman } 56572d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman} 566b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 5671518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattnervoid FastISelMap::printImmediatePredicates(raw_ostream &OS) { 5681518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner if (ImmediatePredicates.begin() == ImmediatePredicates.end()) 5691518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner return; 5701518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 5711518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner OS << "\n// FastEmit Immediate Predicate functions.\n"; 5721518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner for (ImmPredicateSet::iterator I = ImmediatePredicates.begin(), 5731518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner E = ImmediatePredicates.end(); I != E; ++I) { 5741518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner OS << "static bool " << I->getFnName() << "(int64_t Imm) {\n"; 5751518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner OS << I->getImmediatePredicateCode() << "\n}\n"; 5761518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner } 5771518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 5781518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner OS << "\n\n"; 5791518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner} 5801518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 5811518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 5821518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattnervoid FastISelMap::printFunctionDefinitions(raw_ostream &OS) { 583b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman // Now emit code for all the patterns that we collected. 5847b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson for (OperandsOpcodeTypeRetPredMap::const_iterator OI = SimplePatterns.begin(), 585b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OE = SimplePatterns.end(); OI != OE; ++OI) { 586b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman const OperandsSignature &Operands = OI->first; 5877b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson const OpcodeTypeRetPredMap &OTM = OI->second; 588b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 5897b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson for (OpcodeTypeRetPredMap::const_iterator I = OTM.begin(), E = OTM.end(); 590b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman I != E; ++I) { 591b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman const std::string &Opcode = I->first; 5927b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson const TypeRetPredMap &TM = I->second; 593b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 594b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << "// FastEmit functions for " << Opcode << ".\n"; 595b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << "\n"; 596b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 597b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman // Emit one function for each opcode,type pair. 5987b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson for (TypeRetPredMap::const_iterator TI = TM.begin(), TE = TM.end(); 599b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman TI != TE; ++TI) { 600825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson MVT::SimpleValueType VT = TI->first; 6017b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson const RetPredMap &RM = TI->second; 60271669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson if (RM.size() != 1) { 60371669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson for (RetPredMap::const_iterator RI = RM.begin(), RE = RM.end(); 60471669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson RI != RE; ++RI) { 605825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson MVT::SimpleValueType RetVT = RI->first; 60671669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson const PredMap &PM = RI->second; 60771669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson bool HasPred = false; 60871669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson 609c3f44b0d636ff9a6d706ea9ac17ae77c8fa8aeffEvan Cheng OS << "unsigned FastEmit_" 61071669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson << getLegalCName(Opcode) 61171669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson << "_" << getLegalCName(getName(VT)) 61271669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson << "_" << getLegalCName(getName(RetVT)) << "_"; 6131518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner Operands.PrintManglingSuffix(OS, ImmediatePredicates); 61471669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson OS << "("; 61571669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson Operands.PrintParameters(OS); 61671669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson OS << ") {\n"; 61771669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson 61871669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson // Emit code for each possible instruction. There may be 61971669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson // multiple if there are subtarget concerns. 62071669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson for (PredMap::const_iterator PI = PM.begin(), PE = PM.end(); 62171669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson PI != PE; ++PI) { 62271669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson std::string PredicateCheck = PI->first; 62371669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson const InstructionMemo &Memo = PI->second; 62445258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 62571669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson if (PredicateCheck.empty()) { 62671669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson assert(!HasPred && 62771669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson "Multiple instructions match, at least one has " 62871669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson "a predicate and at least one doesn't!"); 62971669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson } else { 630667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson OS << " if (" + PredicateCheck + ") {\n"; 63171669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson OS << " "; 63271669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson HasPred = true; 63371669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson } 63445258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 635667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson for (unsigned i = 0; i < Memo.PhysRegs->size(); ++i) { 636667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson if ((*Memo.PhysRegs)[i] != "") 6374f8e771ae89bcf934f931d64ef3ad9a188ce4921Jakob Stoklund Olesen OS << " BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, " 6384f8e771ae89bcf934f931d64ef3ad9a188ce4921Jakob Stoklund Olesen << "TII.get(TargetOpcode::COPY), " 6394f8e771ae89bcf934f931d64ef3ad9a188ce4921Jakob Stoklund Olesen << (*Memo.PhysRegs)[i] << ").addReg(Op" << i << ");\n"; 640667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson } 64145258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 64271669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson OS << " return FastEmitInst_"; 64373ea7bf4509663267317ec3911aac00ca35a2f2cJakob Stoklund Olesen if (Memo.SubRegNo.empty()) { 6441518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner Operands.PrintManglingSuffix(OS, *Memo.PhysRegs, 6451518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner ImmediatePredicates, true); 646b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson OS << "(" << InstNS << Memo.Name << ", "; 6479b58f29ad0f5f3eb53d5303aec5ca81456c76209Craig Topper OS << "&" << InstNS << Memo.RC->getName() << "RegClass"; 648b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson if (!Operands.empty()) 649b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson OS << ", "; 650667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson Operands.PrintArguments(OS, *Memo.PhysRegs); 651b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson OS << ");\n"; 652b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson } else { 653536ab130ec95cbb7bf30530251dafa7dfecc8471Evan Cheng OS << "extractsubreg(" << getName(RetVT); 6541518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner OS << ", Op0, Op0IsKill, " << Memo.SubRegNo << ");\n"; 655b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson } 65645258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 657667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson if (HasPred) 658d07b46e9080c0c2b965e5a618c13fa2a25131c86Evan Cheng OS << " }\n"; 65945258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 66071669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson } 66171669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson // Return 0 if none of the predicates were satisfied. 66271669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson if (HasPred) 66371669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson OS << " return 0;\n"; 66471669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson OS << "}\n"; 66571669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson OS << "\n"; 66671669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson } 66745258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 66871669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson // Emit one function for the type that demultiplexes on return type. 669c3f44b0d636ff9a6d706ea9ac17ae77c8fa8aeffEvan Cheng OS << "unsigned FastEmit_" 67071669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson << getLegalCName(Opcode) << "_" 671abb1f1688172cf6f3c5bc539841da76053f23533Owen Anderson << getLegalCName(getName(VT)) << "_"; 6721518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner Operands.PrintManglingSuffix(OS, ImmediatePredicates); 673825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson OS << "(MVT RetVT"; 67471669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson if (!Operands.empty()) 67571669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson OS << ", "; 67671669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson Operands.PrintParameters(OS); 677825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson OS << ") {\nswitch (RetVT.SimpleTy) {\n"; 67871669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson for (RetPredMap::const_iterator RI = RM.begin(), RE = RM.end(); 67971669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson RI != RE; ++RI) { 680825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson MVT::SimpleValueType RetVT = RI->first; 68171669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson OS << " case " << getName(RetVT) << ": return FastEmit_" 68271669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson << getLegalCName(Opcode) << "_" << getLegalCName(getName(VT)) 68371669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson << "_" << getLegalCName(getName(RetVT)) << "_"; 6841518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner Operands.PrintManglingSuffix(OS, ImmediatePredicates); 68571669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson OS << "("; 68671669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson Operands.PrintArguments(OS); 68771669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson OS << ");\n"; 68871669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson } 68971669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson OS << " default: return 0;\n}\n}\n\n"; 69045258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 69171669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson } else { 69271669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson // Non-variadic return type. 693c3f44b0d636ff9a6d706ea9ac17ae77c8fa8aeffEvan Cheng OS << "unsigned FastEmit_" 69471669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson << getLegalCName(Opcode) << "_" 69571669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson << getLegalCName(getName(VT)) << "_"; 6961518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner Operands.PrintManglingSuffix(OS, ImmediatePredicates); 697825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson OS << "(MVT RetVT"; 6980f84e4e31009eecf2dfcbe6113b65d0919f30254Owen Anderson if (!Operands.empty()) 6990f84e4e31009eecf2dfcbe6113b65d0919f30254Owen Anderson OS << ", "; 7007b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson Operands.PrintParameters(OS); 7017b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson OS << ") {\n"; 70245258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 703825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson OS << " if (RetVT.SimpleTy != " << getName(RM.begin()->first) 70470647e81e320245f02f003f6403d0222f5951c52Owen Anderson << ")\n return 0;\n"; 70545258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 70671669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson const PredMap &PM = RM.begin()->second; 70771669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson bool HasPred = false; 70845258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 7097b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson // Emit code for each possible instruction. There may be 7107b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson // multiple if there are subtarget concerns. 71198d2d07d416b3431a298eec5a2bfe8b39652c3aaEvan Cheng for (PredMap::const_iterator PI = PM.begin(), PE = PM.end(); PI != PE; 71298d2d07d416b3431a298eec5a2bfe8b39652c3aaEvan Cheng ++PI) { 7137b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson std::string PredicateCheck = PI->first; 7147b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson const InstructionMemo &Memo = PI->second; 71571669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson 7167b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson if (PredicateCheck.empty()) { 7177b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson assert(!HasPred && 7187b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson "Multiple instructions match, at least one has " 7197b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson "a predicate and at least one doesn't!"); 7207b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson } else { 721667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson OS << " if (" + PredicateCheck + ") {\n"; 7227b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson OS << " "; 7237b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson HasPred = true; 7247b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson } 72545258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 7264f8e771ae89bcf934f931d64ef3ad9a188ce4921Jakob Stoklund Olesen for (unsigned i = 0; i < Memo.PhysRegs->size(); ++i) { 7274f8e771ae89bcf934f931d64ef3ad9a188ce4921Jakob Stoklund Olesen if ((*Memo.PhysRegs)[i] != "") 7284f8e771ae89bcf934f931d64ef3ad9a188ce4921Jakob Stoklund Olesen OS << " BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, " 7294f8e771ae89bcf934f931d64ef3ad9a188ce4921Jakob Stoklund Olesen << "TII.get(TargetOpcode::COPY), " 7304f8e771ae89bcf934f931d64ef3ad9a188ce4921Jakob Stoklund Olesen << (*Memo.PhysRegs)[i] << ").addReg(Op" << i << ");\n"; 7314f8e771ae89bcf934f931d64ef3ad9a188ce4921Jakob Stoklund Olesen } 73245258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 7337b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson OS << " return FastEmitInst_"; 73445258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 73573ea7bf4509663267317ec3911aac00ca35a2f2cJakob Stoklund Olesen if (Memo.SubRegNo.empty()) { 7361518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner Operands.PrintManglingSuffix(OS, *Memo.PhysRegs, 7371518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner ImmediatePredicates, true); 738b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson OS << "(" << InstNS << Memo.Name << ", "; 7399b58f29ad0f5f3eb53d5303aec5ca81456c76209Craig Topper OS << "&" << InstNS << Memo.RC->getName() << "RegClass"; 740b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson if (!Operands.empty()) 741b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson OS << ", "; 742667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson Operands.PrintArguments(OS, *Memo.PhysRegs); 743b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson OS << ");\n"; 744b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson } else { 745a6cb641f48df20f6f79018569b519e5a32e897a2Dan Gohman OS << "extractsubreg(RetVT, Op0, Op0IsKill, "; 74673ea7bf4509663267317ec3911aac00ca35a2f2cJakob Stoklund Olesen OS << Memo.SubRegNo; 747b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson OS << ");\n"; 748b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson } 74945258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 750667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson if (HasPred) 751667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson OS << " }\n"; 75222bb31103de3337f0bb74c7bee16d1817d4dca14Dan Gohman } 75345258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 7547b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson // Return 0 if none of the predicates were satisfied. 7557b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson if (HasPred) 7567b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson OS << " return 0;\n"; 7577b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson OS << "}\n"; 7587b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson OS << "\n"; 75922bb31103de3337f0bb74c7bee16d1817d4dca14Dan Gohman } 760b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman } 761b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 762b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman // Emit one function for the opcode that demultiplexes based on the type. 763c3f44b0d636ff9a6d706ea9ac17ae77c8fa8aeffEvan Cheng OS << "unsigned FastEmit_" 764d5fe57d2f980c6bd1a61450f99c254a76d0f1683Dan Gohman << getLegalCName(Opcode) << "_"; 7651518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner Operands.PrintManglingSuffix(OS, ImmediatePredicates); 766825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson OS << "(MVT VT, MVT RetVT"; 767b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman if (!Operands.empty()) 768b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << ", "; 769b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman Operands.PrintParameters(OS); 770b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << ") {\n"; 771825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson OS << " switch (VT.SimpleTy) {\n"; 7727b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson for (TypeRetPredMap::const_iterator TI = TM.begin(), TE = TM.end(); 773b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman TI != TE; ++TI) { 774825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson MVT::SimpleValueType VT = TI->first; 775b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman std::string TypeName = getName(VT); 776b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << " case " << TypeName << ": return FastEmit_" 777d5fe57d2f980c6bd1a61450f99c254a76d0f1683Dan Gohman << getLegalCName(Opcode) << "_" << getLegalCName(TypeName) << "_"; 7781518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner Operands.PrintManglingSuffix(OS, ImmediatePredicates); 7790f84e4e31009eecf2dfcbe6113b65d0919f30254Owen Anderson OS << "(RetVT"; 7800f84e4e31009eecf2dfcbe6113b65d0919f30254Owen Anderson if (!Operands.empty()) 7810f84e4e31009eecf2dfcbe6113b65d0919f30254Owen Anderson OS << ", "; 782b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman Operands.PrintArguments(OS); 783b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << ");\n"; 784b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman } 785b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << " default: return 0;\n"; 786b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << " }\n"; 787b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << "}\n"; 788b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << "\n"; 789b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman } 790b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 7910bfb75277f6d6e160dd29d99e6870da927500b50Dan Gohman OS << "// Top-level FastEmit function.\n"; 7920bfb75277f6d6e160dd29d99e6870da927500b50Dan Gohman OS << "\n"; 7930bfb75277f6d6e160dd29d99e6870da927500b50Dan Gohman 794b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman // Emit one function for the operand signature that demultiplexes based 795b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman // on opcode and type. 796c3f44b0d636ff9a6d706ea9ac17ae77c8fa8aeffEvan Cheng OS << "unsigned FastEmit_"; 7971518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner Operands.PrintManglingSuffix(OS, ImmediatePredicates); 7987c3ecb6838ef7a2ca306c0f3cd68022f0855ae71Dan Gohman OS << "(MVT VT, MVT RetVT, unsigned Opcode"; 799b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman if (!Operands.empty()) 800b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << ", "; 801b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman Operands.PrintParameters(OS); 802b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << ") {\n"; 8031518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 8041518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner // If there are any forms of this signature available that operand on 8051518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner // constrained forms of the immediate (e.g. 32-bit sext immediate in a 8061518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner // 64-bit operand), check them first. 8071518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 8081518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner std::map<OperandsSignature, std::vector<OperandsSignature> >::iterator MI 8091518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner = SignaturesWithConstantForms.find(Operands); 8101518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner if (MI != SignaturesWithConstantForms.end()) { 8111518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner // Unique any duplicates out of the list. 8121518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner std::sort(MI->second.begin(), MI->second.end()); 8131518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner MI->second.erase(std::unique(MI->second.begin(), MI->second.end()), 8141518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner MI->second.end()); 8151518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 8161518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner // Check each in order it was seen. It would be nice to have a good 8171518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner // relative ordering between them, but we're not going for optimality 8181518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner // here. 8191518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner for (unsigned i = 0, e = MI->second.size(); i != e; ++i) { 8201518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner OS << " if ("; 8211518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner MI->second[i].emitImmediatePredicate(OS, ImmediatePredicates); 8221518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner OS << ")\n if (unsigned Reg = FastEmit_"; 8231518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner MI->second[i].PrintManglingSuffix(OS, ImmediatePredicates); 8241518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner OS << "(VT, RetVT, Opcode"; 8251518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner if (!MI->second[i].empty()) 8261518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner OS << ", "; 8271518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner MI->second[i].PrintArguments(OS); 8281518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner OS << "))\n return Reg;\n\n"; 8291518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner } 8301518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 8311518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner // Done with this, remove it. 8321518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner SignaturesWithConstantForms.erase(MI); 8331518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner } 8341518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 835b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << " switch (Opcode) {\n"; 8367b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson for (OpcodeTypeRetPredMap::const_iterator I = OTM.begin(), E = OTM.end(); 837b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman I != E; ++I) { 838b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman const std::string &Opcode = I->first; 839b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 840b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << " case " << Opcode << ": return FastEmit_" 841d5fe57d2f980c6bd1a61450f99c254a76d0f1683Dan Gohman << getLegalCName(Opcode) << "_"; 8421518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner Operands.PrintManglingSuffix(OS, ImmediatePredicates); 8430f84e4e31009eecf2dfcbe6113b65d0919f30254Owen Anderson OS << "(VT, RetVT"; 844b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman if (!Operands.empty()) 845b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << ", "; 846b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman Operands.PrintArguments(OS); 847b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << ");\n"; 848b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman } 849b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << " default: return 0;\n"; 850b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << " }\n"; 851b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << "}\n"; 852b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << "\n"; 853b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman } 8541518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 8551518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner // TODO: SignaturesWithConstantForms should be empty here. 85672d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman} 85772d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman 8586f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesennamespace llvm { 8596f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 8606f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenvoid EmitFastISel(RecordKeeper &RK, raw_ostream &OS) { 8616f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen CodeGenDAGPatterns CGP(RK); 86272d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman const CodeGenTarget &Target = CGP.getTargetInfo(); 8636f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen emitSourceFileHeader("\"Fast\" Instruction Selector for the " + 8646f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen Target.getName() + " target", OS); 86572d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman 86672d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman // Determine the target's namespace name. 86772d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman std::string InstNS = Target.getInstNamespace() + "::"; 86872d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman assert(InstNS.size() > 2 && "Can't determine target-specific namespace!"); 86972d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman 87072d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman FastISelMap F(InstNS); 8711518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner F.collectPatterns(CGP); 8721518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner F.printImmediatePredicates(OS); 8731518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner F.printFunctionDefinitions(OS); 874c7f72de3b4ef21828ea4780f0693bf0acd04e1c5Dan Gohman} 875c7f72de3b4ef21828ea4780f0693bf0acd04e1c5Dan Gohman 8766f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End llvm namespace 877