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