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 24805bce0beee87512e52428d4b80f5a8e79a949576David Greene DefInit *OpDI = dynamic_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 40905bce0beee87512e52428d4b80f5a8e79a949576David Greene DefInit *OpDI = dynamic_cast<DefInit*>(Op->getLeafValue()); 410206a10cf286572cd22140559b328e0a14cef7984Eli Friedman Record *OpLeafRec = OpDI->getDef(); 411206a10cf286572cd22140559b328e0a14cef7984Eli Friedman if (!OpLeafRec->isSubClassOf("Register")) 412206a10cf286572cd22140559b328e0a14cef7984Eli Friedman return PhysReg; 413206a10cf286572cd22140559b328e0a14cef7984Eli Friedman 41405bce0beee87512e52428d4b80f5a8e79a949576David Greene PhysReg += static_cast<StringInit*>(OpLeafRec->getValue( \ 415206a10cf286572cd22140559b328e0a14cef7984Eli Friedman "Namespace")->getValue())->getValue(); 416206a10cf286572cd22140559b328e0a14cef7984Eli Friedman PhysReg += "::"; 417abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen PhysReg += Target.getRegBank().getReg(OpLeafRec)->getName(); 418206a10cf286572cd22140559b328e0a14cef7984Eli Friedman return PhysReg; 419206a10cf286572cd22140559b328e0a14cef7984Eli Friedman} 420206a10cf286572cd22140559b328e0a14cef7984Eli Friedman 4211518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattnervoid FastISelMap::collectPatterns(CodeGenDAGPatterns &CGP) { 42272d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman const CodeGenTarget &Target = CGP.getTargetInfo(); 42372d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman 42472d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman // Determine the target's namespace name. 42572d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman InstNS = Target.getInstNamespace() + "::"; 42672d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman assert(InstNS.size() > 2 && "Can't determine target-specific namespace!"); 427b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 4280bfb75277f6d6e160dd29d99e6870da927500b50Dan Gohman // Scan through all the patterns and record the simple ones. 429b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman for (CodeGenDAGPatterns::ptm_iterator I = CGP.ptm_begin(), 430b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman E = CGP.ptm_end(); I != E; ++I) { 431b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman const PatternToMatch &Pattern = *I; 432b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 433b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman // For now, just look at Instructions, so that we don't have to worry 434b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman // about emitting multiple instructions for a pattern. 435b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman TreePatternNode *Dst = Pattern.getDstPattern(); 436b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman if (Dst->isLeaf()) continue; 437b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman Record *Op = Dst->getOperator(); 438b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman if (!Op->isSubClassOf("Instruction")) 439b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman continue; 440f30187a36324fb75042d9ffd20c3fb70aff7763dChris Lattner CodeGenInstruction &II = CGP.getTargetInfo().getInstruction(Op); 441a90dbc133f7bc7bf0e042fb03222bfdfafce3965Chris Lattner if (II.Operands.empty()) 442b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman continue; 44345258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 44434fc6ceb73ed9e6acaa40c86b0b68684b95cca23Evan Cheng // For now, ignore multi-instruction patterns. 44534fc6ceb73ed9e6acaa40c86b0b68684b95cca23Evan Cheng bool MultiInsts = false; 44634fc6ceb73ed9e6acaa40c86b0b68684b95cca23Evan Cheng for (unsigned i = 0, e = Dst->getNumChildren(); i != e; ++i) { 44734fc6ceb73ed9e6acaa40c86b0b68684b95cca23Evan Cheng TreePatternNode *ChildOp = Dst->getChild(i); 44834fc6ceb73ed9e6acaa40c86b0b68684b95cca23Evan Cheng if (ChildOp->isLeaf()) 44934fc6ceb73ed9e6acaa40c86b0b68684b95cca23Evan Cheng continue; 45034fc6ceb73ed9e6acaa40c86b0b68684b95cca23Evan Cheng if (ChildOp->getOperator()->isSubClassOf("Instruction")) { 45134fc6ceb73ed9e6acaa40c86b0b68684b95cca23Evan Cheng MultiInsts = true; 45234fc6ceb73ed9e6acaa40c86b0b68684b95cca23Evan Cheng break; 45334fc6ceb73ed9e6acaa40c86b0b68684b95cca23Evan Cheng } 45434fc6ceb73ed9e6acaa40c86b0b68684b95cca23Evan Cheng } 45534fc6ceb73ed9e6acaa40c86b0b68684b95cca23Evan Cheng if (MultiInsts) 45634fc6ceb73ed9e6acaa40c86b0b68684b95cca23Evan Cheng continue; 45734fc6ceb73ed9e6acaa40c86b0b68684b95cca23Evan Cheng 458379cad44ecc91be24b2b147081d2089024cbacebDan Gohman // For now, ignore instructions where the first operand is not an 459379cad44ecc91be24b2b147081d2089024cbacebDan Gohman // output register. 460b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson const CodeGenRegisterClass *DstRC = 0; 46173ea7bf4509663267317ec3911aac00ca35a2f2cJakob Stoklund Olesen std::string SubRegNo; 462b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson if (Op->getName() != "EXTRACT_SUBREG") { 463c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner Record *Op0Rec = II.Operands[0].Rec; 464bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson if (Op0Rec->isSubClassOf("RegisterOperand")) 465bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson Op0Rec = Op0Rec->getValueAsDef("RegClass"); 466b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson if (!Op0Rec->isSubClassOf("RegisterClass")) 467b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson continue; 468b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson DstRC = &Target.getRegisterClass(Op0Rec); 469b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson if (!DstRC) 470b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson continue; 471b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson } else { 47207fdd897e2c4304b6f70345c488e97fd97374576Eric Christopher // If this isn't a leaf, then continue since the register classes are 47307fdd897e2c4304b6f70345c488e97fd97374576Eric Christopher // a bit too complicated for now. 47407fdd897e2c4304b6f70345c488e97fd97374576Eric Christopher if (!Dst->getChild(1)->isLeaf()) continue; 47545258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 47605bce0beee87512e52428d4b80f5a8e79a949576David Greene DefInit *SR = dynamic_cast<DefInit*>(Dst->getChild(1)->getLeafValue()); 47773ea7bf4509663267317ec3911aac00ca35a2f2cJakob Stoklund Olesen if (SR) 47873ea7bf4509663267317ec3911aac00ca35a2f2cJakob Stoklund Olesen SubRegNo = getQualifiedName(SR->getDef()); 47973ea7bf4509663267317ec3911aac00ca35a2f2cJakob Stoklund Olesen else 48073ea7bf4509663267317ec3911aac00ca35a2f2cJakob Stoklund Olesen SubRegNo = Dst->getChild(1)->getLeafValue()->getAsString(); 481b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson } 482b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 483b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman // Inspect the pattern. 484b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman TreePatternNode *InstPatNode = Pattern.getSrcPattern(); 485b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman if (!InstPatNode) continue; 486b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman if (InstPatNode->isLeaf()) continue; 487b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 488084df627c82fdf4e1829723edf0a833b5bc31f89Chris Lattner // Ignore multiple result nodes for now. 489084df627c82fdf4e1829723edf0a833b5bc31f89Chris Lattner if (InstPatNode->getNumTypes() > 1) continue; 49045258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 491b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman Record *InstPatOp = InstPatNode->getOperator(); 492b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman std::string OpcodeName = getOpcodeName(InstPatOp, CGP); 493d7349194650386d97a1d779369cb46f20ba9f252Chris Lattner MVT::SimpleValueType RetVT = MVT::isVoid; 494d7349194650386d97a1d779369cb46f20ba9f252Chris Lattner if (InstPatNode->getNumTypes()) RetVT = InstPatNode->getType(0); 495825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson MVT::SimpleValueType VT = RetVT; 496d7349194650386d97a1d779369cb46f20ba9f252Chris Lattner if (InstPatNode->getNumChildren()) { 497d7349194650386d97a1d779369cb46f20ba9f252Chris Lattner assert(InstPatNode->getChild(0)->getNumTypes() == 1); 498d7349194650386d97a1d779369cb46f20ba9f252Chris Lattner VT = InstPatNode->getChild(0)->getType(0); 499d7349194650386d97a1d779369cb46f20ba9f252Chris Lattner } 500f4137b5f409525b41ec4d4bff56c54fd2a9db274Dan Gohman 501f4137b5f409525b41ec4d4bff56c54fd2a9db274Dan Gohman // For now, filter out any instructions with predicates. 5020540e17788f0d09d784fb9bd9b354e02f1c5e4a4Dan Gohman if (!InstPatNode->getPredicateFns().empty()) 503f4137b5f409525b41ec4d4bff56c54fd2a9db274Dan Gohman continue; 504b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 505379cad44ecc91be24b2b147081d2089024cbacebDan Gohman // Check all the operands. 506b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OperandsSignature Operands; 5071518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner if (!Operands.initialize(InstPatNode, Target, VT, ImmediatePredicates)) 508d1d2ee8ccbcf0d8c54a07413d4ae599ebfdda14bDan Gohman continue; 50945258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 510667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson std::vector<std::string>* PhysRegInputs = new std::vector<std::string>(); 511206a10cf286572cd22140559b328e0a14cef7984Eli Friedman if (InstPatNode->getOperator()->getName() == "imm" || 512691a4882ed086912edfe60da225bdc3f3e2f9a82Eric Christopher InstPatNode->getOperator()->getName() == "fpimm") 513667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson PhysRegInputs->push_back(""); 514206a10cf286572cd22140559b328e0a14cef7984Eli Friedman else { 515206a10cf286572cd22140559b328e0a14cef7984Eli Friedman // Compute the PhysRegs used by the given pattern, and check that 516206a10cf286572cd22140559b328e0a14cef7984Eli Friedman // the mapping from the src to dst patterns is simple. 517206a10cf286572cd22140559b328e0a14cef7984Eli Friedman bool FoundNonSimplePattern = false; 518206a10cf286572cd22140559b328e0a14cef7984Eli Friedman unsigned DstIndex = 0; 519667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson for (unsigned i = 0, e = InstPatNode->getNumChildren(); i != e; ++i) { 520206a10cf286572cd22140559b328e0a14cef7984Eli Friedman std::string PhysReg = PhyRegForNode(InstPatNode->getChild(i), Target); 521206a10cf286572cd22140559b328e0a14cef7984Eli Friedman if (PhysReg.empty()) { 522206a10cf286572cd22140559b328e0a14cef7984Eli Friedman if (DstIndex >= Dst->getNumChildren() || 523206a10cf286572cd22140559b328e0a14cef7984Eli Friedman Dst->getChild(DstIndex)->getName() != 524206a10cf286572cd22140559b328e0a14cef7984Eli Friedman InstPatNode->getChild(i)->getName()) { 525206a10cf286572cd22140559b328e0a14cef7984Eli Friedman FoundNonSimplePattern = true; 526206a10cf286572cd22140559b328e0a14cef7984Eli Friedman break; 527667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson } 528206a10cf286572cd22140559b328e0a14cef7984Eli Friedman ++DstIndex; 529667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson } 53045258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 531667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson PhysRegInputs->push_back(PhysReg); 532667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson } 533206a10cf286572cd22140559b328e0a14cef7984Eli Friedman 534206a10cf286572cd22140559b328e0a14cef7984Eli Friedman if (Op->getName() != "EXTRACT_SUBREG" && DstIndex < Dst->getNumChildren()) 535206a10cf286572cd22140559b328e0a14cef7984Eli Friedman FoundNonSimplePattern = true; 536206a10cf286572cd22140559b328e0a14cef7984Eli Friedman 537206a10cf286572cd22140559b328e0a14cef7984Eli Friedman if (FoundNonSimplePattern) 538206a10cf286572cd22140559b328e0a14cef7984Eli Friedman continue; 539206a10cf286572cd22140559b328e0a14cef7984Eli Friedman } 540b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 54122bb31103de3337f0bb74c7bee16d1817d4dca14Dan Gohman // Get the predicate that guards this pattern. 54222bb31103de3337f0bb74c7bee16d1817d4dca14Dan Gohman std::string PredicateCheck = Pattern.getPredicateCheck(); 54322bb31103de3337f0bb74c7bee16d1817d4dca14Dan Gohman 544b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman // Ok, we found a pattern that we can handle. Remember it. 545520b50c00d237ef4309fca364202d111f9faa82fDan Gohman InstructionMemo Memo = { 546520b50c00d237ef4309fca364202d111f9faa82fDan Gohman Pattern.getDstPattern()->getOperator()->getName(), 547b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson DstRC, 548667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson SubRegNo, 549667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson PhysRegInputs 550520b50c00d237ef4309fca364202d111f9faa82fDan Gohman }; 5511518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 5521518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner if (SimplePatterns[Operands][OpcodeName][VT][RetVT].count(PredicateCheck)) 5531518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner throw TGError(Pattern.getSrcRecord()->getLoc(), 5541518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner "Duplicate record in FastISel table!"); 555997759ac22dc1de6f324b1c09c0a2a558236c489Jim Grosbach 556abb1f1688172cf6f3c5bc539841da76053f23533Owen Anderson SimplePatterns[Operands][OpcodeName][VT][RetVT][PredicateCheck] = Memo; 5571518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 5581518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner // If any of the operands were immediates with predicates on them, strip 5591518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner // them down to a signature that doesn't have predicates so that we can 5601518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner // associate them with the stripped predicate version. 5611518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner if (Operands.hasAnyImmediateCodes()) { 5621518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner SignaturesWithConstantForms[Operands.getWithoutImmCodes()] 5631518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner .push_back(Operands); 5641518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner } 565b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman } 56672d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman} 567b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 5681518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattnervoid FastISelMap::printImmediatePredicates(raw_ostream &OS) { 5691518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner if (ImmediatePredicates.begin() == ImmediatePredicates.end()) 5701518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner return; 5711518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 5721518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner OS << "\n// FastEmit Immediate Predicate functions.\n"; 5731518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner for (ImmPredicateSet::iterator I = ImmediatePredicates.begin(), 5741518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner E = ImmediatePredicates.end(); I != E; ++I) { 5751518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner OS << "static bool " << I->getFnName() << "(int64_t Imm) {\n"; 5761518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner OS << I->getImmediatePredicateCode() << "\n}\n"; 5771518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner } 5781518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 5791518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner OS << "\n\n"; 5801518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner} 5811518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 5821518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 5831518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattnervoid FastISelMap::printFunctionDefinitions(raw_ostream &OS) { 584b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman // Now emit code for all the patterns that we collected. 5857b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson for (OperandsOpcodeTypeRetPredMap::const_iterator OI = SimplePatterns.begin(), 586b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OE = SimplePatterns.end(); OI != OE; ++OI) { 587b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman const OperandsSignature &Operands = OI->first; 5887b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson const OpcodeTypeRetPredMap &OTM = OI->second; 589b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 5907b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson for (OpcodeTypeRetPredMap::const_iterator I = OTM.begin(), E = OTM.end(); 591b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman I != E; ++I) { 592b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman const std::string &Opcode = I->first; 5937b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson const TypeRetPredMap &TM = I->second; 594b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 595b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << "// FastEmit functions for " << Opcode << ".\n"; 596b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << "\n"; 597b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 598b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman // Emit one function for each opcode,type pair. 5997b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson for (TypeRetPredMap::const_iterator TI = TM.begin(), TE = TM.end(); 600b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman TI != TE; ++TI) { 601825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson MVT::SimpleValueType VT = TI->first; 6027b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson const RetPredMap &RM = TI->second; 60371669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson if (RM.size() != 1) { 60471669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson for (RetPredMap::const_iterator RI = RM.begin(), RE = RM.end(); 60571669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson RI != RE; ++RI) { 606825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson MVT::SimpleValueType RetVT = RI->first; 60771669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson const PredMap &PM = RI->second; 60871669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson bool HasPred = false; 60971669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson 610c3f44b0d636ff9a6d706ea9ac17ae77c8fa8aeffEvan Cheng OS << "unsigned FastEmit_" 61171669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson << getLegalCName(Opcode) 61271669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson << "_" << getLegalCName(getName(VT)) 61371669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson << "_" << getLegalCName(getName(RetVT)) << "_"; 6141518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner Operands.PrintManglingSuffix(OS, ImmediatePredicates); 61571669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson OS << "("; 61671669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson Operands.PrintParameters(OS); 61771669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson OS << ") {\n"; 61871669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson 61971669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson // Emit code for each possible instruction. There may be 62071669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson // multiple if there are subtarget concerns. 62171669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson for (PredMap::const_iterator PI = PM.begin(), PE = PM.end(); 62271669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson PI != PE; ++PI) { 62371669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson std::string PredicateCheck = PI->first; 62471669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson const InstructionMemo &Memo = PI->second; 62545258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 62671669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson if (PredicateCheck.empty()) { 62771669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson assert(!HasPred && 62871669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson "Multiple instructions match, at least one has " 62971669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson "a predicate and at least one doesn't!"); 63071669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson } else { 631667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson OS << " if (" + PredicateCheck + ") {\n"; 63271669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson OS << " "; 63371669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson HasPred = true; 63471669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson } 63545258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 636667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson for (unsigned i = 0; i < Memo.PhysRegs->size(); ++i) { 637667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson if ((*Memo.PhysRegs)[i] != "") 6384f8e771ae89bcf934f931d64ef3ad9a188ce4921Jakob Stoklund Olesen OS << " BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, " 6394f8e771ae89bcf934f931d64ef3ad9a188ce4921Jakob Stoklund Olesen << "TII.get(TargetOpcode::COPY), " 6404f8e771ae89bcf934f931d64ef3ad9a188ce4921Jakob Stoklund Olesen << (*Memo.PhysRegs)[i] << ").addReg(Op" << i << ");\n"; 641667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson } 64245258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 64371669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson OS << " return FastEmitInst_"; 64473ea7bf4509663267317ec3911aac00ca35a2f2cJakob Stoklund Olesen if (Memo.SubRegNo.empty()) { 6451518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner Operands.PrintManglingSuffix(OS, *Memo.PhysRegs, 6461518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner ImmediatePredicates, true); 647b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson OS << "(" << InstNS << Memo.Name << ", "; 6489b58f29ad0f5f3eb53d5303aec5ca81456c76209Craig Topper OS << "&" << InstNS << Memo.RC->getName() << "RegClass"; 649b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson if (!Operands.empty()) 650b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson OS << ", "; 651667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson Operands.PrintArguments(OS, *Memo.PhysRegs); 652b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson OS << ");\n"; 653b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson } else { 654536ab130ec95cbb7bf30530251dafa7dfecc8471Evan Cheng OS << "extractsubreg(" << getName(RetVT); 6551518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner OS << ", Op0, Op0IsKill, " << Memo.SubRegNo << ");\n"; 656b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson } 65745258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 658667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson if (HasPred) 659d07b46e9080c0c2b965e5a618c13fa2a25131c86Evan Cheng OS << " }\n"; 66045258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 66171669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson } 66271669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson // Return 0 if none of the predicates were satisfied. 66371669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson if (HasPred) 66471669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson OS << " return 0;\n"; 66571669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson OS << "}\n"; 66671669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson OS << "\n"; 66771669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson } 66845258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 66971669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson // Emit one function for the type that demultiplexes on return type. 670c3f44b0d636ff9a6d706ea9ac17ae77c8fa8aeffEvan Cheng OS << "unsigned FastEmit_" 67171669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson << getLegalCName(Opcode) << "_" 672abb1f1688172cf6f3c5bc539841da76053f23533Owen Anderson << getLegalCName(getName(VT)) << "_"; 6731518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner Operands.PrintManglingSuffix(OS, ImmediatePredicates); 674825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson OS << "(MVT RetVT"; 67571669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson if (!Operands.empty()) 67671669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson OS << ", "; 67771669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson Operands.PrintParameters(OS); 678825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson OS << ") {\nswitch (RetVT.SimpleTy) {\n"; 67971669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson for (RetPredMap::const_iterator RI = RM.begin(), RE = RM.end(); 68071669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson RI != RE; ++RI) { 681825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson MVT::SimpleValueType RetVT = RI->first; 68271669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson OS << " case " << getName(RetVT) << ": return FastEmit_" 68371669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson << getLegalCName(Opcode) << "_" << getLegalCName(getName(VT)) 68471669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson << "_" << getLegalCName(getName(RetVT)) << "_"; 6851518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner Operands.PrintManglingSuffix(OS, ImmediatePredicates); 68671669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson OS << "("; 68771669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson Operands.PrintArguments(OS); 68871669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson OS << ");\n"; 68971669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson } 69071669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson OS << " default: return 0;\n}\n}\n\n"; 69145258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 69271669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson } else { 69371669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson // Non-variadic return type. 694c3f44b0d636ff9a6d706ea9ac17ae77c8fa8aeffEvan Cheng OS << "unsigned FastEmit_" 69571669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson << getLegalCName(Opcode) << "_" 69671669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson << getLegalCName(getName(VT)) << "_"; 6971518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner Operands.PrintManglingSuffix(OS, ImmediatePredicates); 698825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson OS << "(MVT RetVT"; 6990f84e4e31009eecf2dfcbe6113b65d0919f30254Owen Anderson if (!Operands.empty()) 7000f84e4e31009eecf2dfcbe6113b65d0919f30254Owen Anderson OS << ", "; 7017b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson Operands.PrintParameters(OS); 7027b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson OS << ") {\n"; 70345258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 704825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson OS << " if (RetVT.SimpleTy != " << getName(RM.begin()->first) 70570647e81e320245f02f003f6403d0222f5951c52Owen Anderson << ")\n return 0;\n"; 70645258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 70771669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson const PredMap &PM = RM.begin()->second; 70871669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson bool HasPred = false; 70945258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 7107b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson // Emit code for each possible instruction. There may be 7117b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson // multiple if there are subtarget concerns. 71298d2d07d416b3431a298eec5a2bfe8b39652c3aaEvan Cheng for (PredMap::const_iterator PI = PM.begin(), PE = PM.end(); PI != PE; 71398d2d07d416b3431a298eec5a2bfe8b39652c3aaEvan Cheng ++PI) { 7147b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson std::string PredicateCheck = PI->first; 7157b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson const InstructionMemo &Memo = PI->second; 71671669e51e5bd2b34365b2b1401310a0bbdb86de4Owen Anderson 7177b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson if (PredicateCheck.empty()) { 7187b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson assert(!HasPred && 7197b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson "Multiple instructions match, at least one has " 7207b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson "a predicate and at least one doesn't!"); 7217b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson } else { 722667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson OS << " if (" + PredicateCheck + ") {\n"; 7237b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson OS << " "; 7247b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson HasPred = true; 7257b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson } 72645258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 7274f8e771ae89bcf934f931d64ef3ad9a188ce4921Jakob Stoklund Olesen for (unsigned i = 0; i < Memo.PhysRegs->size(); ++i) { 7284f8e771ae89bcf934f931d64ef3ad9a188ce4921Jakob Stoklund Olesen if ((*Memo.PhysRegs)[i] != "") 7294f8e771ae89bcf934f931d64ef3ad9a188ce4921Jakob Stoklund Olesen OS << " BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, " 7304f8e771ae89bcf934f931d64ef3ad9a188ce4921Jakob Stoklund Olesen << "TII.get(TargetOpcode::COPY), " 7314f8e771ae89bcf934f931d64ef3ad9a188ce4921Jakob Stoklund Olesen << (*Memo.PhysRegs)[i] << ").addReg(Op" << i << ");\n"; 7324f8e771ae89bcf934f931d64ef3ad9a188ce4921Jakob Stoklund Olesen } 73345258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 7347b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson OS << " return FastEmitInst_"; 73545258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 73673ea7bf4509663267317ec3911aac00ca35a2f2cJakob Stoklund Olesen if (Memo.SubRegNo.empty()) { 7371518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner Operands.PrintManglingSuffix(OS, *Memo.PhysRegs, 7381518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner ImmediatePredicates, true); 739b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson OS << "(" << InstNS << Memo.Name << ", "; 7409b58f29ad0f5f3eb53d5303aec5ca81456c76209Craig Topper OS << "&" << InstNS << Memo.RC->getName() << "RegClass"; 741b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson if (!Operands.empty()) 742b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson OS << ", "; 743667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson Operands.PrintArguments(OS, *Memo.PhysRegs); 744b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson OS << ");\n"; 745b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson } else { 746a6cb641f48df20f6f79018569b519e5a32e897a2Dan Gohman OS << "extractsubreg(RetVT, Op0, Op0IsKill, "; 74773ea7bf4509663267317ec3911aac00ca35a2f2cJakob Stoklund Olesen OS << Memo.SubRegNo; 748b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson OS << ");\n"; 749b5dbcb538b2ecfde2c94a1981301ac9beea3ea3cOwen Anderson } 75045258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 751667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson if (HasPred) 752667d8f7607f021c66c854ff3ea35a9df107eabfeOwen Anderson OS << " }\n"; 75322bb31103de3337f0bb74c7bee16d1817d4dca14Dan Gohman } 75445258f570826bb4369042efa915a10248b4d7a42Jim Grosbach 7557b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson // Return 0 if none of the predicates were satisfied. 7567b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson if (HasPred) 7577b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson OS << " return 0;\n"; 7587b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson OS << "}\n"; 7597b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson OS << "\n"; 76022bb31103de3337f0bb74c7bee16d1817d4dca14Dan Gohman } 761b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman } 762b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 763b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman // Emit one function for the opcode that demultiplexes based on the type. 764c3f44b0d636ff9a6d706ea9ac17ae77c8fa8aeffEvan Cheng OS << "unsigned FastEmit_" 765d5fe57d2f980c6bd1a61450f99c254a76d0f1683Dan Gohman << getLegalCName(Opcode) << "_"; 7661518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner Operands.PrintManglingSuffix(OS, ImmediatePredicates); 767825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson OS << "(MVT VT, MVT RetVT"; 768b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman if (!Operands.empty()) 769b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << ", "; 770b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman Operands.PrintParameters(OS); 771b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << ") {\n"; 772825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson OS << " switch (VT.SimpleTy) {\n"; 7737b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson for (TypeRetPredMap::const_iterator TI = TM.begin(), TE = TM.end(); 774b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman TI != TE; ++TI) { 775825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson MVT::SimpleValueType VT = TI->first; 776b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman std::string TypeName = getName(VT); 777b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << " case " << TypeName << ": return FastEmit_" 778d5fe57d2f980c6bd1a61450f99c254a76d0f1683Dan Gohman << getLegalCName(Opcode) << "_" << getLegalCName(TypeName) << "_"; 7791518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner Operands.PrintManglingSuffix(OS, ImmediatePredicates); 7800f84e4e31009eecf2dfcbe6113b65d0919f30254Owen Anderson OS << "(RetVT"; 7810f84e4e31009eecf2dfcbe6113b65d0919f30254Owen Anderson if (!Operands.empty()) 7820f84e4e31009eecf2dfcbe6113b65d0919f30254Owen Anderson OS << ", "; 783b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman Operands.PrintArguments(OS); 784b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << ");\n"; 785b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman } 786b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << " default: return 0;\n"; 787b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << " }\n"; 788b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << "}\n"; 789b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << "\n"; 790b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman } 791b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 7920bfb75277f6d6e160dd29d99e6870da927500b50Dan Gohman OS << "// Top-level FastEmit function.\n"; 7930bfb75277f6d6e160dd29d99e6870da927500b50Dan Gohman OS << "\n"; 7940bfb75277f6d6e160dd29d99e6870da927500b50Dan Gohman 795b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman // Emit one function for the operand signature that demultiplexes based 796b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman // on opcode and type. 797c3f44b0d636ff9a6d706ea9ac17ae77c8fa8aeffEvan Cheng OS << "unsigned FastEmit_"; 7981518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner Operands.PrintManglingSuffix(OS, ImmediatePredicates); 7997c3ecb6838ef7a2ca306c0f3cd68022f0855ae71Dan Gohman OS << "(MVT VT, MVT RetVT, unsigned Opcode"; 800b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman if (!Operands.empty()) 801b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << ", "; 802b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman Operands.PrintParameters(OS); 803b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << ") {\n"; 8041518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 8051518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner // If there are any forms of this signature available that operand on 8061518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner // constrained forms of the immediate (e.g. 32-bit sext immediate in a 8071518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner // 64-bit operand), check them first. 8081518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 8091518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner std::map<OperandsSignature, std::vector<OperandsSignature> >::iterator MI 8101518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner = SignaturesWithConstantForms.find(Operands); 8111518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner if (MI != SignaturesWithConstantForms.end()) { 8121518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner // Unique any duplicates out of the list. 8131518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner std::sort(MI->second.begin(), MI->second.end()); 8141518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner MI->second.erase(std::unique(MI->second.begin(), MI->second.end()), 8151518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner MI->second.end()); 8161518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 8171518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner // Check each in order it was seen. It would be nice to have a good 8181518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner // relative ordering between them, but we're not going for optimality 8191518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner // here. 8201518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner for (unsigned i = 0, e = MI->second.size(); i != e; ++i) { 8211518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner OS << " if ("; 8221518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner MI->second[i].emitImmediatePredicate(OS, ImmediatePredicates); 8231518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner OS << ")\n if (unsigned Reg = FastEmit_"; 8241518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner MI->second[i].PrintManglingSuffix(OS, ImmediatePredicates); 8251518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner OS << "(VT, RetVT, Opcode"; 8261518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner if (!MI->second[i].empty()) 8271518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner OS << ", "; 8281518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner MI->second[i].PrintArguments(OS); 8291518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner OS << "))\n return Reg;\n\n"; 8301518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner } 8311518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 8321518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner // Done with this, remove it. 8331518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner SignaturesWithConstantForms.erase(MI); 8341518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner } 8351518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 836b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << " switch (Opcode) {\n"; 8377b2e579546d1ebf49c2e187efab2c76be9e32050Owen Anderson for (OpcodeTypeRetPredMap::const_iterator I = OTM.begin(), E = OTM.end(); 838b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman I != E; ++I) { 839b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman const std::string &Opcode = I->first; 840b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman 841b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << " case " << Opcode << ": return FastEmit_" 842d5fe57d2f980c6bd1a61450f99c254a76d0f1683Dan Gohman << getLegalCName(Opcode) << "_"; 8431518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner Operands.PrintManglingSuffix(OS, ImmediatePredicates); 8440f84e4e31009eecf2dfcbe6113b65d0919f30254Owen Anderson OS << "(VT, RetVT"; 845b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman if (!Operands.empty()) 846b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << ", "; 847b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman Operands.PrintArguments(OS); 848b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << ");\n"; 849b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman } 850b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << " default: return 0;\n"; 851b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << " }\n"; 852b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << "}\n"; 853b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman OS << "\n"; 854b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman } 8551518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner 8561518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner // TODO: SignaturesWithConstantForms should be empty here. 85772d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman} 85872d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman 8596f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesennamespace llvm { 8606f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 8616f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenvoid EmitFastISel(RecordKeeper &RK, raw_ostream &OS) { 8626f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen CodeGenDAGPatterns CGP(RK); 86372d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman const CodeGenTarget &Target = CGP.getTargetInfo(); 8646f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen emitSourceFileHeader("\"Fast\" Instruction Selector for the " + 8656f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen Target.getName() + " target", OS); 86672d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman 86772d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman // Determine the target's namespace name. 86872d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman std::string InstNS = Target.getInstNamespace() + "::"; 86972d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman assert(InstNS.size() > 2 && "Can't determine target-specific namespace!"); 87072d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman 87172d63af3f76250f198910f0f69cb4ccffd4c14a6Dan Gohman FastISelMap F(InstNS); 8721518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner F.collectPatterns(CGP); 8731518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner F.printImmediatePredicates(OS); 8741518afddea6c0a4275a9ac64a9ffe2b6b4c0600aChris Lattner F.printFunctionDefinitions(OS); 875c7f72de3b4ef21828ea4780f0693bf0acd04e1c5Dan Gohman} 876c7f72de3b4ef21828ea4780f0693bf0acd04e1c5Dan Gohman 8776f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End llvm namespace 878