xref: /freebsd/contrib/llvm-project/llvm/utils/TableGen/FastISelEmitter.cpp (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric ///===- FastISelEmitter.cpp - Generate an instruction selector -------------===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric //
9*0b57cec5SDimitry Andric // This tablegen backend emits code for use by the "fast" instruction
10*0b57cec5SDimitry Andric // selection algorithm. See the comments at the top of
11*0b57cec5SDimitry Andric // lib/CodeGen/SelectionDAG/FastISel.cpp for background.
12*0b57cec5SDimitry Andric //
13*0b57cec5SDimitry Andric // This file scans through the target's tablegen instruction-info files
14*0b57cec5SDimitry Andric // and extracts instructions with obvious-looking patterns, and it emits
15*0b57cec5SDimitry Andric // code to look up these instructions by type and operator.
16*0b57cec5SDimitry Andric //
17*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
18*0b57cec5SDimitry Andric 
19*0b57cec5SDimitry Andric #include "CodeGenDAGPatterns.h"
20*0b57cec5SDimitry Andric #include "llvm/ADT/StringSwitch.h"
21*0b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
22*0b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
23*0b57cec5SDimitry Andric #include "llvm/TableGen/Error.h"
24*0b57cec5SDimitry Andric #include "llvm/TableGen/Record.h"
25*0b57cec5SDimitry Andric #include "llvm/TableGen/TableGenBackend.h"
26*0b57cec5SDimitry Andric #include <utility>
27*0b57cec5SDimitry Andric using namespace llvm;
28*0b57cec5SDimitry Andric 
29*0b57cec5SDimitry Andric 
30*0b57cec5SDimitry Andric /// InstructionMemo - This class holds additional information about an
31*0b57cec5SDimitry Andric /// instruction needed to emit code for it.
32*0b57cec5SDimitry Andric ///
33*0b57cec5SDimitry Andric namespace {
34*0b57cec5SDimitry Andric struct InstructionMemo {
35*0b57cec5SDimitry Andric   std::string Name;
36*0b57cec5SDimitry Andric   const CodeGenRegisterClass *RC;
37*0b57cec5SDimitry Andric   std::string SubRegNo;
38*0b57cec5SDimitry Andric   std::vector<std::string> PhysRegs;
39*0b57cec5SDimitry Andric   std::string PredicateCheck;
40*0b57cec5SDimitry Andric 
41*0b57cec5SDimitry Andric   InstructionMemo(StringRef Name, const CodeGenRegisterClass *RC,
42*0b57cec5SDimitry Andric                   std::string SubRegNo, std::vector<std::string> PhysRegs,
43*0b57cec5SDimitry Andric                   std::string PredicateCheck)
44*0b57cec5SDimitry Andric       : Name(Name), RC(RC), SubRegNo(std::move(SubRegNo)),
45*0b57cec5SDimitry Andric         PhysRegs(std::move(PhysRegs)),
46*0b57cec5SDimitry Andric         PredicateCheck(std::move(PredicateCheck)) {}
47*0b57cec5SDimitry Andric 
48*0b57cec5SDimitry Andric   // Make sure we do not copy InstructionMemo.
49*0b57cec5SDimitry Andric   InstructionMemo(const InstructionMemo &Other) = delete;
50*0b57cec5SDimitry Andric   InstructionMemo(InstructionMemo &&Other) = default;
51*0b57cec5SDimitry Andric };
52*0b57cec5SDimitry Andric } // End anonymous namespace
53*0b57cec5SDimitry Andric 
54*0b57cec5SDimitry Andric /// ImmPredicateSet - This uniques predicates (represented as a string) and
55*0b57cec5SDimitry Andric /// gives them unique (small) integer ID's that start at 0.
56*0b57cec5SDimitry Andric namespace {
57*0b57cec5SDimitry Andric class ImmPredicateSet {
58*0b57cec5SDimitry Andric   DenseMap<TreePattern *, unsigned> ImmIDs;
59*0b57cec5SDimitry Andric   std::vector<TreePredicateFn> PredsByName;
60*0b57cec5SDimitry Andric public:
61*0b57cec5SDimitry Andric 
62*0b57cec5SDimitry Andric   unsigned getIDFor(TreePredicateFn Pred) {
63*0b57cec5SDimitry Andric     unsigned &Entry = ImmIDs[Pred.getOrigPatFragRecord()];
64*0b57cec5SDimitry Andric     if (Entry == 0) {
65*0b57cec5SDimitry Andric       PredsByName.push_back(Pred);
66*0b57cec5SDimitry Andric       Entry = PredsByName.size();
67*0b57cec5SDimitry Andric     }
68*0b57cec5SDimitry Andric     return Entry-1;
69*0b57cec5SDimitry Andric   }
70*0b57cec5SDimitry Andric 
71*0b57cec5SDimitry Andric   const TreePredicateFn &getPredicate(unsigned i) {
72*0b57cec5SDimitry Andric     assert(i < PredsByName.size());
73*0b57cec5SDimitry Andric     return PredsByName[i];
74*0b57cec5SDimitry Andric   }
75*0b57cec5SDimitry Andric 
76*0b57cec5SDimitry Andric   typedef std::vector<TreePredicateFn>::const_iterator iterator;
77*0b57cec5SDimitry Andric   iterator begin() const { return PredsByName.begin(); }
78*0b57cec5SDimitry Andric   iterator end() const { return PredsByName.end(); }
79*0b57cec5SDimitry Andric 
80*0b57cec5SDimitry Andric };
81*0b57cec5SDimitry Andric } // End anonymous namespace
82*0b57cec5SDimitry Andric 
83*0b57cec5SDimitry Andric /// OperandsSignature - This class holds a description of a list of operand
84*0b57cec5SDimitry Andric /// types. It has utility methods for emitting text based on the operands.
85*0b57cec5SDimitry Andric ///
86*0b57cec5SDimitry Andric namespace {
87*0b57cec5SDimitry Andric struct OperandsSignature {
88*0b57cec5SDimitry Andric   class OpKind {
89*0b57cec5SDimitry Andric     enum { OK_Reg, OK_FP, OK_Imm, OK_Invalid = -1 };
90*0b57cec5SDimitry Andric     char Repr;
91*0b57cec5SDimitry Andric   public:
92*0b57cec5SDimitry Andric 
93*0b57cec5SDimitry Andric     OpKind() : Repr(OK_Invalid) {}
94*0b57cec5SDimitry Andric 
95*0b57cec5SDimitry Andric     bool operator<(OpKind RHS) const { return Repr < RHS.Repr; }
96*0b57cec5SDimitry Andric     bool operator==(OpKind RHS) const { return Repr == RHS.Repr; }
97*0b57cec5SDimitry Andric 
98*0b57cec5SDimitry Andric     static OpKind getReg() { OpKind K; K.Repr = OK_Reg; return K; }
99*0b57cec5SDimitry Andric     static OpKind getFP()  { OpKind K; K.Repr = OK_FP; return K; }
100*0b57cec5SDimitry Andric     static OpKind getImm(unsigned V) {
101*0b57cec5SDimitry Andric       assert((unsigned)OK_Imm+V < 128 &&
102*0b57cec5SDimitry Andric              "Too many integer predicates for the 'Repr' char");
103*0b57cec5SDimitry Andric       OpKind K; K.Repr = OK_Imm+V; return K;
104*0b57cec5SDimitry Andric     }
105*0b57cec5SDimitry Andric 
106*0b57cec5SDimitry Andric     bool isReg() const { return Repr == OK_Reg; }
107*0b57cec5SDimitry Andric     bool isFP() const  { return Repr == OK_FP; }
108*0b57cec5SDimitry Andric     bool isImm() const { return Repr >= OK_Imm; }
109*0b57cec5SDimitry Andric 
110*0b57cec5SDimitry Andric     unsigned getImmCode() const { assert(isImm()); return Repr-OK_Imm; }
111*0b57cec5SDimitry Andric 
112*0b57cec5SDimitry Andric     void printManglingSuffix(raw_ostream &OS, ImmPredicateSet &ImmPredicates,
113*0b57cec5SDimitry Andric                              bool StripImmCodes) const {
114*0b57cec5SDimitry Andric       if (isReg())
115*0b57cec5SDimitry Andric         OS << 'r';
116*0b57cec5SDimitry Andric       else if (isFP())
117*0b57cec5SDimitry Andric         OS << 'f';
118*0b57cec5SDimitry Andric       else {
119*0b57cec5SDimitry Andric         OS << 'i';
120*0b57cec5SDimitry Andric         if (!StripImmCodes)
121*0b57cec5SDimitry Andric           if (unsigned Code = getImmCode())
122*0b57cec5SDimitry Andric             OS << "_" << ImmPredicates.getPredicate(Code-1).getFnName();
123*0b57cec5SDimitry Andric       }
124*0b57cec5SDimitry Andric     }
125*0b57cec5SDimitry Andric   };
126*0b57cec5SDimitry Andric 
127*0b57cec5SDimitry Andric 
128*0b57cec5SDimitry Andric   SmallVector<OpKind, 3> Operands;
129*0b57cec5SDimitry Andric 
130*0b57cec5SDimitry Andric   bool operator<(const OperandsSignature &O) const {
131*0b57cec5SDimitry Andric     return Operands < O.Operands;
132*0b57cec5SDimitry Andric   }
133*0b57cec5SDimitry Andric   bool operator==(const OperandsSignature &O) const {
134*0b57cec5SDimitry Andric     return Operands == O.Operands;
135*0b57cec5SDimitry Andric   }
136*0b57cec5SDimitry Andric 
137*0b57cec5SDimitry Andric   bool empty() const { return Operands.empty(); }
138*0b57cec5SDimitry Andric 
139*0b57cec5SDimitry Andric   bool hasAnyImmediateCodes() const {
140*0b57cec5SDimitry Andric     for (unsigned i = 0, e = Operands.size(); i != e; ++i)
141*0b57cec5SDimitry Andric       if (Operands[i].isImm() && Operands[i].getImmCode() != 0)
142*0b57cec5SDimitry Andric         return true;
143*0b57cec5SDimitry Andric     return false;
144*0b57cec5SDimitry Andric   }
145*0b57cec5SDimitry Andric 
146*0b57cec5SDimitry Andric   /// getWithoutImmCodes - Return a copy of this with any immediate codes forced
147*0b57cec5SDimitry Andric   /// to zero.
148*0b57cec5SDimitry Andric   OperandsSignature getWithoutImmCodes() const {
149*0b57cec5SDimitry Andric     OperandsSignature Result;
150*0b57cec5SDimitry Andric     for (unsigned i = 0, e = Operands.size(); i != e; ++i)
151*0b57cec5SDimitry Andric       if (!Operands[i].isImm())
152*0b57cec5SDimitry Andric         Result.Operands.push_back(Operands[i]);
153*0b57cec5SDimitry Andric       else
154*0b57cec5SDimitry Andric         Result.Operands.push_back(OpKind::getImm(0));
155*0b57cec5SDimitry Andric     return Result;
156*0b57cec5SDimitry Andric   }
157*0b57cec5SDimitry Andric 
158*0b57cec5SDimitry Andric   void emitImmediatePredicate(raw_ostream &OS, ImmPredicateSet &ImmPredicates) {
159*0b57cec5SDimitry Andric     bool EmittedAnything = false;
160*0b57cec5SDimitry Andric     for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
161*0b57cec5SDimitry Andric       if (!Operands[i].isImm()) continue;
162*0b57cec5SDimitry Andric 
163*0b57cec5SDimitry Andric       unsigned Code = Operands[i].getImmCode();
164*0b57cec5SDimitry Andric       if (Code == 0) continue;
165*0b57cec5SDimitry Andric 
166*0b57cec5SDimitry Andric       if (EmittedAnything)
167*0b57cec5SDimitry Andric         OS << " &&\n        ";
168*0b57cec5SDimitry Andric 
169*0b57cec5SDimitry Andric       TreePredicateFn PredFn = ImmPredicates.getPredicate(Code-1);
170*0b57cec5SDimitry Andric 
171*0b57cec5SDimitry Andric       // Emit the type check.
172*0b57cec5SDimitry Andric       TreePattern *TP = PredFn.getOrigPatFragRecord();
173*0b57cec5SDimitry Andric       ValueTypeByHwMode VVT = TP->getTree(0)->getType(0);
174*0b57cec5SDimitry Andric       assert(VVT.isSimple() &&
175*0b57cec5SDimitry Andric              "Cannot use variable value types with fast isel");
176*0b57cec5SDimitry Andric       OS << "VT == " << getEnumName(VVT.getSimple().SimpleTy) << " && ";
177*0b57cec5SDimitry Andric 
178*0b57cec5SDimitry Andric       OS << PredFn.getFnName() << "(imm" << i <<')';
179*0b57cec5SDimitry Andric       EmittedAnything = true;
180*0b57cec5SDimitry Andric     }
181*0b57cec5SDimitry Andric   }
182*0b57cec5SDimitry Andric 
183*0b57cec5SDimitry Andric   /// initialize - Examine the given pattern and initialize the contents
184*0b57cec5SDimitry Andric   /// of the Operands array accordingly. Return true if all the operands
185*0b57cec5SDimitry Andric   /// are supported, false otherwise.
186*0b57cec5SDimitry Andric   ///
187*0b57cec5SDimitry Andric   bool initialize(TreePatternNode *InstPatNode, const CodeGenTarget &Target,
188*0b57cec5SDimitry Andric                   MVT::SimpleValueType VT,
189*0b57cec5SDimitry Andric                   ImmPredicateSet &ImmediatePredicates,
190*0b57cec5SDimitry Andric                   const CodeGenRegisterClass *OrigDstRC) {
191*0b57cec5SDimitry Andric     if (InstPatNode->isLeaf())
192*0b57cec5SDimitry Andric       return false;
193*0b57cec5SDimitry Andric 
194*0b57cec5SDimitry Andric     if (InstPatNode->getOperator()->getName() == "imm") {
195*0b57cec5SDimitry Andric       Operands.push_back(OpKind::getImm(0));
196*0b57cec5SDimitry Andric       return true;
197*0b57cec5SDimitry Andric     }
198*0b57cec5SDimitry Andric 
199*0b57cec5SDimitry Andric     if (InstPatNode->getOperator()->getName() == "fpimm") {
200*0b57cec5SDimitry Andric       Operands.push_back(OpKind::getFP());
201*0b57cec5SDimitry Andric       return true;
202*0b57cec5SDimitry Andric     }
203*0b57cec5SDimitry Andric 
204*0b57cec5SDimitry Andric     const CodeGenRegisterClass *DstRC = nullptr;
205*0b57cec5SDimitry Andric 
206*0b57cec5SDimitry Andric     for (unsigned i = 0, e = InstPatNode->getNumChildren(); i != e; ++i) {
207*0b57cec5SDimitry Andric       TreePatternNode *Op = InstPatNode->getChild(i);
208*0b57cec5SDimitry Andric 
209*0b57cec5SDimitry Andric       // Handle imm operands specially.
210*0b57cec5SDimitry Andric       if (!Op->isLeaf() && Op->getOperator()->getName() == "imm") {
211*0b57cec5SDimitry Andric         unsigned PredNo = 0;
212*0b57cec5SDimitry Andric         if (!Op->getPredicateCalls().empty()) {
213*0b57cec5SDimitry Andric           TreePredicateFn PredFn = Op->getPredicateCalls()[0].Fn;
214*0b57cec5SDimitry Andric           // If there is more than one predicate weighing in on this operand
215*0b57cec5SDimitry Andric           // then we don't handle it.  This doesn't typically happen for
216*0b57cec5SDimitry Andric           // immediates anyway.
217*0b57cec5SDimitry Andric           if (Op->getPredicateCalls().size() > 1 ||
218*0b57cec5SDimitry Andric               !PredFn.isImmediatePattern() || PredFn.usesOperands())
219*0b57cec5SDimitry Andric             return false;
220*0b57cec5SDimitry Andric           // Ignore any instruction with 'FastIselShouldIgnore', these are
221*0b57cec5SDimitry Andric           // not needed and just bloat the fast instruction selector.  For
222*0b57cec5SDimitry Andric           // example, X86 doesn't need to generate code to match ADD16ri8 since
223*0b57cec5SDimitry Andric           // ADD16ri will do just fine.
224*0b57cec5SDimitry Andric           Record *Rec = PredFn.getOrigPatFragRecord()->getRecord();
225*0b57cec5SDimitry Andric           if (Rec->getValueAsBit("FastIselShouldIgnore"))
226*0b57cec5SDimitry Andric             return false;
227*0b57cec5SDimitry Andric 
228*0b57cec5SDimitry Andric           PredNo = ImmediatePredicates.getIDFor(PredFn)+1;
229*0b57cec5SDimitry Andric         }
230*0b57cec5SDimitry Andric 
231*0b57cec5SDimitry Andric         Operands.push_back(OpKind::getImm(PredNo));
232*0b57cec5SDimitry Andric         continue;
233*0b57cec5SDimitry Andric       }
234*0b57cec5SDimitry Andric 
235*0b57cec5SDimitry Andric 
236*0b57cec5SDimitry Andric       // For now, filter out any operand with a predicate.
237*0b57cec5SDimitry Andric       // For now, filter out any operand with multiple values.
238*0b57cec5SDimitry Andric       if (!Op->getPredicateCalls().empty() || Op->getNumTypes() != 1)
239*0b57cec5SDimitry Andric         return false;
240*0b57cec5SDimitry Andric 
241*0b57cec5SDimitry Andric       if (!Op->isLeaf()) {
242*0b57cec5SDimitry Andric          if (Op->getOperator()->getName() == "fpimm") {
243*0b57cec5SDimitry Andric           Operands.push_back(OpKind::getFP());
244*0b57cec5SDimitry Andric           continue;
245*0b57cec5SDimitry Andric         }
246*0b57cec5SDimitry Andric         // For now, ignore other non-leaf nodes.
247*0b57cec5SDimitry Andric         return false;
248*0b57cec5SDimitry Andric       }
249*0b57cec5SDimitry Andric 
250*0b57cec5SDimitry Andric       assert(Op->hasConcreteType(0) && "Type infererence not done?");
251*0b57cec5SDimitry Andric 
252*0b57cec5SDimitry Andric       // For now, all the operands must have the same type (if they aren't
253*0b57cec5SDimitry Andric       // immediates).  Note that this causes us to reject variable sized shifts
254*0b57cec5SDimitry Andric       // on X86.
255*0b57cec5SDimitry Andric       if (Op->getSimpleType(0) != VT)
256*0b57cec5SDimitry Andric         return false;
257*0b57cec5SDimitry Andric 
258*0b57cec5SDimitry Andric       DefInit *OpDI = dyn_cast<DefInit>(Op->getLeafValue());
259*0b57cec5SDimitry Andric       if (!OpDI)
260*0b57cec5SDimitry Andric         return false;
261*0b57cec5SDimitry Andric       Record *OpLeafRec = OpDI->getDef();
262*0b57cec5SDimitry Andric 
263*0b57cec5SDimitry Andric       // For now, the only other thing we accept is register operands.
264*0b57cec5SDimitry Andric       const CodeGenRegisterClass *RC = nullptr;
265*0b57cec5SDimitry Andric       if (OpLeafRec->isSubClassOf("RegisterOperand"))
266*0b57cec5SDimitry Andric         OpLeafRec = OpLeafRec->getValueAsDef("RegClass");
267*0b57cec5SDimitry Andric       if (OpLeafRec->isSubClassOf("RegisterClass"))
268*0b57cec5SDimitry Andric         RC = &Target.getRegisterClass(OpLeafRec);
269*0b57cec5SDimitry Andric       else if (OpLeafRec->isSubClassOf("Register"))
270*0b57cec5SDimitry Andric         RC = Target.getRegBank().getRegClassForRegister(OpLeafRec);
271*0b57cec5SDimitry Andric       else if (OpLeafRec->isSubClassOf("ValueType")) {
272*0b57cec5SDimitry Andric         RC = OrigDstRC;
273*0b57cec5SDimitry Andric       } else
274*0b57cec5SDimitry Andric         return false;
275*0b57cec5SDimitry Andric 
276*0b57cec5SDimitry Andric       // For now, this needs to be a register class of some sort.
277*0b57cec5SDimitry Andric       if (!RC)
278*0b57cec5SDimitry Andric         return false;
279*0b57cec5SDimitry Andric 
280*0b57cec5SDimitry Andric       // For now, all the operands must have the same register class or be
281*0b57cec5SDimitry Andric       // a strict subclass of the destination.
282*0b57cec5SDimitry Andric       if (DstRC) {
283*0b57cec5SDimitry Andric         if (DstRC != RC && !DstRC->hasSubClass(RC))
284*0b57cec5SDimitry Andric           return false;
285*0b57cec5SDimitry Andric       } else
286*0b57cec5SDimitry Andric         DstRC = RC;
287*0b57cec5SDimitry Andric       Operands.push_back(OpKind::getReg());
288*0b57cec5SDimitry Andric     }
289*0b57cec5SDimitry Andric     return true;
290*0b57cec5SDimitry Andric   }
291*0b57cec5SDimitry Andric 
292*0b57cec5SDimitry Andric   void PrintParameters(raw_ostream &OS) const {
293*0b57cec5SDimitry Andric     for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
294*0b57cec5SDimitry Andric       if (Operands[i].isReg()) {
295*0b57cec5SDimitry Andric         OS << "unsigned Op" << i << ", bool Op" << i << "IsKill";
296*0b57cec5SDimitry Andric       } else if (Operands[i].isImm()) {
297*0b57cec5SDimitry Andric         OS << "uint64_t imm" << i;
298*0b57cec5SDimitry Andric       } else if (Operands[i].isFP()) {
299*0b57cec5SDimitry Andric         OS << "const ConstantFP *f" << i;
300*0b57cec5SDimitry Andric       } else {
301*0b57cec5SDimitry Andric         llvm_unreachable("Unknown operand kind!");
302*0b57cec5SDimitry Andric       }
303*0b57cec5SDimitry Andric       if (i + 1 != e)
304*0b57cec5SDimitry Andric         OS << ", ";
305*0b57cec5SDimitry Andric     }
306*0b57cec5SDimitry Andric   }
307*0b57cec5SDimitry Andric 
308*0b57cec5SDimitry Andric   void PrintArguments(raw_ostream &OS,
309*0b57cec5SDimitry Andric                       const std::vector<std::string> &PR) const {
310*0b57cec5SDimitry Andric     assert(PR.size() == Operands.size());
311*0b57cec5SDimitry Andric     bool PrintedArg = false;
312*0b57cec5SDimitry Andric     for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
313*0b57cec5SDimitry Andric       if (PR[i] != "")
314*0b57cec5SDimitry Andric         // Implicit physical register operand.
315*0b57cec5SDimitry Andric         continue;
316*0b57cec5SDimitry Andric 
317*0b57cec5SDimitry Andric       if (PrintedArg)
318*0b57cec5SDimitry Andric         OS << ", ";
319*0b57cec5SDimitry Andric       if (Operands[i].isReg()) {
320*0b57cec5SDimitry Andric         OS << "Op" << i << ", Op" << i << "IsKill";
321*0b57cec5SDimitry Andric         PrintedArg = true;
322*0b57cec5SDimitry Andric       } else if (Operands[i].isImm()) {
323*0b57cec5SDimitry Andric         OS << "imm" << i;
324*0b57cec5SDimitry Andric         PrintedArg = true;
325*0b57cec5SDimitry Andric       } else if (Operands[i].isFP()) {
326*0b57cec5SDimitry Andric         OS << "f" << i;
327*0b57cec5SDimitry Andric         PrintedArg = true;
328*0b57cec5SDimitry Andric       } else {
329*0b57cec5SDimitry Andric         llvm_unreachable("Unknown operand kind!");
330*0b57cec5SDimitry Andric       }
331*0b57cec5SDimitry Andric     }
332*0b57cec5SDimitry Andric   }
333*0b57cec5SDimitry Andric 
334*0b57cec5SDimitry Andric   void PrintArguments(raw_ostream &OS) const {
335*0b57cec5SDimitry Andric     for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
336*0b57cec5SDimitry Andric       if (Operands[i].isReg()) {
337*0b57cec5SDimitry Andric         OS << "Op" << i << ", Op" << i << "IsKill";
338*0b57cec5SDimitry Andric       } else if (Operands[i].isImm()) {
339*0b57cec5SDimitry Andric         OS << "imm" << i;
340*0b57cec5SDimitry Andric       } else if (Operands[i].isFP()) {
341*0b57cec5SDimitry Andric         OS << "f" << i;
342*0b57cec5SDimitry Andric       } else {
343*0b57cec5SDimitry Andric         llvm_unreachable("Unknown operand kind!");
344*0b57cec5SDimitry Andric       }
345*0b57cec5SDimitry Andric       if (i + 1 != e)
346*0b57cec5SDimitry Andric         OS << ", ";
347*0b57cec5SDimitry Andric     }
348*0b57cec5SDimitry Andric   }
349*0b57cec5SDimitry Andric 
350*0b57cec5SDimitry Andric 
351*0b57cec5SDimitry Andric   void PrintManglingSuffix(raw_ostream &OS, const std::vector<std::string> &PR,
352*0b57cec5SDimitry Andric                            ImmPredicateSet &ImmPredicates,
353*0b57cec5SDimitry Andric                            bool StripImmCodes = false) const {
354*0b57cec5SDimitry Andric     for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
355*0b57cec5SDimitry Andric       if (PR[i] != "")
356*0b57cec5SDimitry Andric         // Implicit physical register operand. e.g. Instruction::Mul expect to
357*0b57cec5SDimitry Andric         // select to a binary op. On x86, mul may take a single operand with
358*0b57cec5SDimitry Andric         // the other operand being implicit. We must emit something that looks
359*0b57cec5SDimitry Andric         // like a binary instruction except for the very inner fastEmitInst_*
360*0b57cec5SDimitry Andric         // call.
361*0b57cec5SDimitry Andric         continue;
362*0b57cec5SDimitry Andric       Operands[i].printManglingSuffix(OS, ImmPredicates, StripImmCodes);
363*0b57cec5SDimitry Andric     }
364*0b57cec5SDimitry Andric   }
365*0b57cec5SDimitry Andric 
366*0b57cec5SDimitry Andric   void PrintManglingSuffix(raw_ostream &OS, ImmPredicateSet &ImmPredicates,
367*0b57cec5SDimitry Andric                            bool StripImmCodes = false) const {
368*0b57cec5SDimitry Andric     for (unsigned i = 0, e = Operands.size(); i != e; ++i)
369*0b57cec5SDimitry Andric       Operands[i].printManglingSuffix(OS, ImmPredicates, StripImmCodes);
370*0b57cec5SDimitry Andric   }
371*0b57cec5SDimitry Andric };
372*0b57cec5SDimitry Andric } // End anonymous namespace
373*0b57cec5SDimitry Andric 
374*0b57cec5SDimitry Andric namespace {
375*0b57cec5SDimitry Andric class FastISelMap {
376*0b57cec5SDimitry Andric   // A multimap is needed instead of a "plain" map because the key is
377*0b57cec5SDimitry Andric   // the instruction's complexity (an int) and they are not unique.
378*0b57cec5SDimitry Andric   typedef std::multimap<int, InstructionMemo> PredMap;
379*0b57cec5SDimitry Andric   typedef std::map<MVT::SimpleValueType, PredMap> RetPredMap;
380*0b57cec5SDimitry Andric   typedef std::map<MVT::SimpleValueType, RetPredMap> TypeRetPredMap;
381*0b57cec5SDimitry Andric   typedef std::map<std::string, TypeRetPredMap> OpcodeTypeRetPredMap;
382*0b57cec5SDimitry Andric   typedef std::map<OperandsSignature, OpcodeTypeRetPredMap>
383*0b57cec5SDimitry Andric             OperandsOpcodeTypeRetPredMap;
384*0b57cec5SDimitry Andric 
385*0b57cec5SDimitry Andric   OperandsOpcodeTypeRetPredMap SimplePatterns;
386*0b57cec5SDimitry Andric 
387*0b57cec5SDimitry Andric   // This is used to check that there are no duplicate predicates
388*0b57cec5SDimitry Andric   typedef std::multimap<std::string, bool> PredCheckMap;
389*0b57cec5SDimitry Andric   typedef std::map<MVT::SimpleValueType, PredCheckMap> RetPredCheckMap;
390*0b57cec5SDimitry Andric   typedef std::map<MVT::SimpleValueType, RetPredCheckMap> TypeRetPredCheckMap;
391*0b57cec5SDimitry Andric   typedef std::map<std::string, TypeRetPredCheckMap> OpcodeTypeRetPredCheckMap;
392*0b57cec5SDimitry Andric   typedef std::map<OperandsSignature, OpcodeTypeRetPredCheckMap>
393*0b57cec5SDimitry Andric             OperandsOpcodeTypeRetPredCheckMap;
394*0b57cec5SDimitry Andric 
395*0b57cec5SDimitry Andric   OperandsOpcodeTypeRetPredCheckMap SimplePatternsCheck;
396*0b57cec5SDimitry Andric 
397*0b57cec5SDimitry Andric   std::map<OperandsSignature, std::vector<OperandsSignature> >
398*0b57cec5SDimitry Andric     SignaturesWithConstantForms;
399*0b57cec5SDimitry Andric 
400*0b57cec5SDimitry Andric   StringRef InstNS;
401*0b57cec5SDimitry Andric   ImmPredicateSet ImmediatePredicates;
402*0b57cec5SDimitry Andric public:
403*0b57cec5SDimitry Andric   explicit FastISelMap(StringRef InstNS);
404*0b57cec5SDimitry Andric 
405*0b57cec5SDimitry Andric   void collectPatterns(CodeGenDAGPatterns &CGP);
406*0b57cec5SDimitry Andric   void printImmediatePredicates(raw_ostream &OS);
407*0b57cec5SDimitry Andric   void printFunctionDefinitions(raw_ostream &OS);
408*0b57cec5SDimitry Andric private:
409*0b57cec5SDimitry Andric   void emitInstructionCode(raw_ostream &OS,
410*0b57cec5SDimitry Andric                            const OperandsSignature &Operands,
411*0b57cec5SDimitry Andric                            const PredMap &PM,
412*0b57cec5SDimitry Andric                            const std::string &RetVTName);
413*0b57cec5SDimitry Andric };
414*0b57cec5SDimitry Andric } // End anonymous namespace
415*0b57cec5SDimitry Andric 
416*0b57cec5SDimitry Andric static std::string getOpcodeName(Record *Op, CodeGenDAGPatterns &CGP) {
417*0b57cec5SDimitry Andric   return CGP.getSDNodeInfo(Op).getEnumName();
418*0b57cec5SDimitry Andric }
419*0b57cec5SDimitry Andric 
420*0b57cec5SDimitry Andric static std::string getLegalCName(std::string OpName) {
421*0b57cec5SDimitry Andric   std::string::size_type pos = OpName.find("::");
422*0b57cec5SDimitry Andric   if (pos != std::string::npos)
423*0b57cec5SDimitry Andric     OpName.replace(pos, 2, "_");
424*0b57cec5SDimitry Andric   return OpName;
425*0b57cec5SDimitry Andric }
426*0b57cec5SDimitry Andric 
427*0b57cec5SDimitry Andric FastISelMap::FastISelMap(StringRef instns) : InstNS(instns) {}
428*0b57cec5SDimitry Andric 
429*0b57cec5SDimitry Andric static std::string PhyRegForNode(TreePatternNode *Op,
430*0b57cec5SDimitry Andric                                  const CodeGenTarget &Target) {
431*0b57cec5SDimitry Andric   std::string PhysReg;
432*0b57cec5SDimitry Andric 
433*0b57cec5SDimitry Andric   if (!Op->isLeaf())
434*0b57cec5SDimitry Andric     return PhysReg;
435*0b57cec5SDimitry Andric 
436*0b57cec5SDimitry Andric   Record *OpLeafRec = cast<DefInit>(Op->getLeafValue())->getDef();
437*0b57cec5SDimitry Andric   if (!OpLeafRec->isSubClassOf("Register"))
438*0b57cec5SDimitry Andric     return PhysReg;
439*0b57cec5SDimitry Andric 
440*0b57cec5SDimitry Andric   PhysReg += cast<StringInit>(OpLeafRec->getValue("Namespace")->getValue())
441*0b57cec5SDimitry Andric                ->getValue();
442*0b57cec5SDimitry Andric   PhysReg += "::";
443*0b57cec5SDimitry Andric   PhysReg += Target.getRegBank().getReg(OpLeafRec)->getName();
444*0b57cec5SDimitry Andric   return PhysReg;
445*0b57cec5SDimitry Andric }
446*0b57cec5SDimitry Andric 
447*0b57cec5SDimitry Andric void FastISelMap::collectPatterns(CodeGenDAGPatterns &CGP) {
448*0b57cec5SDimitry Andric   const CodeGenTarget &Target = CGP.getTargetInfo();
449*0b57cec5SDimitry Andric 
450*0b57cec5SDimitry Andric   // Scan through all the patterns and record the simple ones.
451*0b57cec5SDimitry Andric   for (CodeGenDAGPatterns::ptm_iterator I = CGP.ptm_begin(),
452*0b57cec5SDimitry Andric        E = CGP.ptm_end(); I != E; ++I) {
453*0b57cec5SDimitry Andric     const PatternToMatch &Pattern = *I;
454*0b57cec5SDimitry Andric 
455*0b57cec5SDimitry Andric     // For now, just look at Instructions, so that we don't have to worry
456*0b57cec5SDimitry Andric     // about emitting multiple instructions for a pattern.
457*0b57cec5SDimitry Andric     TreePatternNode *Dst = Pattern.getDstPattern();
458*0b57cec5SDimitry Andric     if (Dst->isLeaf()) continue;
459*0b57cec5SDimitry Andric     Record *Op = Dst->getOperator();
460*0b57cec5SDimitry Andric     if (!Op->isSubClassOf("Instruction"))
461*0b57cec5SDimitry Andric       continue;
462*0b57cec5SDimitry Andric     CodeGenInstruction &II = CGP.getTargetInfo().getInstruction(Op);
463*0b57cec5SDimitry Andric     if (II.Operands.empty())
464*0b57cec5SDimitry Andric       continue;
465*0b57cec5SDimitry Andric 
466*0b57cec5SDimitry Andric     // Allow instructions to be marked as unavailable for FastISel for
467*0b57cec5SDimitry Andric     // certain cases, i.e. an ISA has two 'and' instruction which differ
468*0b57cec5SDimitry Andric     // by what registers they can use but are otherwise identical for
469*0b57cec5SDimitry Andric     // codegen purposes.
470*0b57cec5SDimitry Andric     if (II.FastISelShouldIgnore)
471*0b57cec5SDimitry Andric       continue;
472*0b57cec5SDimitry Andric 
473*0b57cec5SDimitry Andric     // For now, ignore multi-instruction patterns.
474*0b57cec5SDimitry Andric     bool MultiInsts = false;
475*0b57cec5SDimitry Andric     for (unsigned i = 0, e = Dst->getNumChildren(); i != e; ++i) {
476*0b57cec5SDimitry Andric       TreePatternNode *ChildOp = Dst->getChild(i);
477*0b57cec5SDimitry Andric       if (ChildOp->isLeaf())
478*0b57cec5SDimitry Andric         continue;
479*0b57cec5SDimitry Andric       if (ChildOp->getOperator()->isSubClassOf("Instruction")) {
480*0b57cec5SDimitry Andric         MultiInsts = true;
481*0b57cec5SDimitry Andric         break;
482*0b57cec5SDimitry Andric       }
483*0b57cec5SDimitry Andric     }
484*0b57cec5SDimitry Andric     if (MultiInsts)
485*0b57cec5SDimitry Andric       continue;
486*0b57cec5SDimitry Andric 
487*0b57cec5SDimitry Andric     // For now, ignore instructions where the first operand is not an
488*0b57cec5SDimitry Andric     // output register.
489*0b57cec5SDimitry Andric     const CodeGenRegisterClass *DstRC = nullptr;
490*0b57cec5SDimitry Andric     std::string SubRegNo;
491*0b57cec5SDimitry Andric     if (Op->getName() != "EXTRACT_SUBREG") {
492*0b57cec5SDimitry Andric       Record *Op0Rec = II.Operands[0].Rec;
493*0b57cec5SDimitry Andric       if (Op0Rec->isSubClassOf("RegisterOperand"))
494*0b57cec5SDimitry Andric         Op0Rec = Op0Rec->getValueAsDef("RegClass");
495*0b57cec5SDimitry Andric       if (!Op0Rec->isSubClassOf("RegisterClass"))
496*0b57cec5SDimitry Andric         continue;
497*0b57cec5SDimitry Andric       DstRC = &Target.getRegisterClass(Op0Rec);
498*0b57cec5SDimitry Andric       if (!DstRC)
499*0b57cec5SDimitry Andric         continue;
500*0b57cec5SDimitry Andric     } else {
501*0b57cec5SDimitry Andric       // If this isn't a leaf, then continue since the register classes are
502*0b57cec5SDimitry Andric       // a bit too complicated for now.
503*0b57cec5SDimitry Andric       if (!Dst->getChild(1)->isLeaf()) continue;
504*0b57cec5SDimitry Andric 
505*0b57cec5SDimitry Andric       DefInit *SR = dyn_cast<DefInit>(Dst->getChild(1)->getLeafValue());
506*0b57cec5SDimitry Andric       if (SR)
507*0b57cec5SDimitry Andric         SubRegNo = getQualifiedName(SR->getDef());
508*0b57cec5SDimitry Andric       else
509*0b57cec5SDimitry Andric         SubRegNo = Dst->getChild(1)->getLeafValue()->getAsString();
510*0b57cec5SDimitry Andric     }
511*0b57cec5SDimitry Andric 
512*0b57cec5SDimitry Andric     // Inspect the pattern.
513*0b57cec5SDimitry Andric     TreePatternNode *InstPatNode = Pattern.getSrcPattern();
514*0b57cec5SDimitry Andric     if (!InstPatNode) continue;
515*0b57cec5SDimitry Andric     if (InstPatNode->isLeaf()) continue;
516*0b57cec5SDimitry Andric 
517*0b57cec5SDimitry Andric     // Ignore multiple result nodes for now.
518*0b57cec5SDimitry Andric     if (InstPatNode->getNumTypes() > 1) continue;
519*0b57cec5SDimitry Andric 
520*0b57cec5SDimitry Andric     Record *InstPatOp = InstPatNode->getOperator();
521*0b57cec5SDimitry Andric     std::string OpcodeName = getOpcodeName(InstPatOp, CGP);
522*0b57cec5SDimitry Andric     MVT::SimpleValueType RetVT = MVT::isVoid;
523*0b57cec5SDimitry Andric     if (InstPatNode->getNumTypes()) RetVT = InstPatNode->getSimpleType(0);
524*0b57cec5SDimitry Andric     MVT::SimpleValueType VT = RetVT;
525*0b57cec5SDimitry Andric     if (InstPatNode->getNumChildren()) {
526*0b57cec5SDimitry Andric       assert(InstPatNode->getChild(0)->getNumTypes() == 1);
527*0b57cec5SDimitry Andric       VT = InstPatNode->getChild(0)->getSimpleType(0);
528*0b57cec5SDimitry Andric     }
529*0b57cec5SDimitry Andric 
530*0b57cec5SDimitry Andric     // For now, filter out any instructions with predicates.
531*0b57cec5SDimitry Andric     if (!InstPatNode->getPredicateCalls().empty())
532*0b57cec5SDimitry Andric       continue;
533*0b57cec5SDimitry Andric 
534*0b57cec5SDimitry Andric     // Check all the operands.
535*0b57cec5SDimitry Andric     OperandsSignature Operands;
536*0b57cec5SDimitry Andric     if (!Operands.initialize(InstPatNode, Target, VT, ImmediatePredicates,
537*0b57cec5SDimitry Andric                              DstRC))
538*0b57cec5SDimitry Andric       continue;
539*0b57cec5SDimitry Andric 
540*0b57cec5SDimitry Andric     std::vector<std::string> PhysRegInputs;
541*0b57cec5SDimitry Andric     if (InstPatNode->getOperator()->getName() == "imm" ||
542*0b57cec5SDimitry Andric         InstPatNode->getOperator()->getName() == "fpimm")
543*0b57cec5SDimitry Andric       PhysRegInputs.push_back("");
544*0b57cec5SDimitry Andric     else {
545*0b57cec5SDimitry Andric       // Compute the PhysRegs used by the given pattern, and check that
546*0b57cec5SDimitry Andric       // the mapping from the src to dst patterns is simple.
547*0b57cec5SDimitry Andric       bool FoundNonSimplePattern = false;
548*0b57cec5SDimitry Andric       unsigned DstIndex = 0;
549*0b57cec5SDimitry Andric       for (unsigned i = 0, e = InstPatNode->getNumChildren(); i != e; ++i) {
550*0b57cec5SDimitry Andric         std::string PhysReg = PhyRegForNode(InstPatNode->getChild(i), Target);
551*0b57cec5SDimitry Andric         if (PhysReg.empty()) {
552*0b57cec5SDimitry Andric           if (DstIndex >= Dst->getNumChildren() ||
553*0b57cec5SDimitry Andric               Dst->getChild(DstIndex)->getName() !=
554*0b57cec5SDimitry Andric               InstPatNode->getChild(i)->getName()) {
555*0b57cec5SDimitry Andric             FoundNonSimplePattern = true;
556*0b57cec5SDimitry Andric             break;
557*0b57cec5SDimitry Andric           }
558*0b57cec5SDimitry Andric           ++DstIndex;
559*0b57cec5SDimitry Andric         }
560*0b57cec5SDimitry Andric 
561*0b57cec5SDimitry Andric         PhysRegInputs.push_back(PhysReg);
562*0b57cec5SDimitry Andric       }
563*0b57cec5SDimitry Andric 
564*0b57cec5SDimitry Andric       if (Op->getName() != "EXTRACT_SUBREG" && DstIndex < Dst->getNumChildren())
565*0b57cec5SDimitry Andric         FoundNonSimplePattern = true;
566*0b57cec5SDimitry Andric 
567*0b57cec5SDimitry Andric       if (FoundNonSimplePattern)
568*0b57cec5SDimitry Andric         continue;
569*0b57cec5SDimitry Andric     }
570*0b57cec5SDimitry Andric 
571*0b57cec5SDimitry Andric     // Check if the operands match one of the patterns handled by FastISel.
572*0b57cec5SDimitry Andric     std::string ManglingSuffix;
573*0b57cec5SDimitry Andric     raw_string_ostream SuffixOS(ManglingSuffix);
574*0b57cec5SDimitry Andric     Operands.PrintManglingSuffix(SuffixOS, ImmediatePredicates, true);
575*0b57cec5SDimitry Andric     SuffixOS.flush();
576*0b57cec5SDimitry Andric     if (!StringSwitch<bool>(ManglingSuffix)
577*0b57cec5SDimitry Andric         .Cases("", "r", "rr", "ri", "i", "f", true)
578*0b57cec5SDimitry Andric         .Default(false))
579*0b57cec5SDimitry Andric       continue;
580*0b57cec5SDimitry Andric 
581*0b57cec5SDimitry Andric     // Get the predicate that guards this pattern.
582*0b57cec5SDimitry Andric     std::string PredicateCheck = Pattern.getPredicateCheck();
583*0b57cec5SDimitry Andric 
584*0b57cec5SDimitry Andric     // Ok, we found a pattern that we can handle. Remember it.
585*0b57cec5SDimitry Andric     InstructionMemo Memo(
586*0b57cec5SDimitry Andric       Pattern.getDstPattern()->getOperator()->getName(),
587*0b57cec5SDimitry Andric       DstRC,
588*0b57cec5SDimitry Andric       SubRegNo,
589*0b57cec5SDimitry Andric       PhysRegInputs,
590*0b57cec5SDimitry Andric       PredicateCheck
591*0b57cec5SDimitry Andric     );
592*0b57cec5SDimitry Andric 
593*0b57cec5SDimitry Andric     int complexity = Pattern.getPatternComplexity(CGP);
594*0b57cec5SDimitry Andric 
595*0b57cec5SDimitry Andric     if (SimplePatternsCheck[Operands][OpcodeName][VT]
596*0b57cec5SDimitry Andric          [RetVT].count(PredicateCheck)) {
597*0b57cec5SDimitry Andric       PrintFatalError(Pattern.getSrcRecord()->getLoc(),
598*0b57cec5SDimitry Andric                     "Duplicate predicate in FastISel table!");
599*0b57cec5SDimitry Andric     }
600*0b57cec5SDimitry Andric     SimplePatternsCheck[Operands][OpcodeName][VT][RetVT].insert(
601*0b57cec5SDimitry Andric             std::make_pair(PredicateCheck, true));
602*0b57cec5SDimitry Andric 
603*0b57cec5SDimitry Andric        // Note: Instructions with the same complexity will appear in the order
604*0b57cec5SDimitry Andric           // that they are encountered.
605*0b57cec5SDimitry Andric     SimplePatterns[Operands][OpcodeName][VT][RetVT].emplace(complexity,
606*0b57cec5SDimitry Andric                                                             std::move(Memo));
607*0b57cec5SDimitry Andric 
608*0b57cec5SDimitry Andric     // If any of the operands were immediates with predicates on them, strip
609*0b57cec5SDimitry Andric     // them down to a signature that doesn't have predicates so that we can
610*0b57cec5SDimitry Andric     // associate them with the stripped predicate version.
611*0b57cec5SDimitry Andric     if (Operands.hasAnyImmediateCodes()) {
612*0b57cec5SDimitry Andric       SignaturesWithConstantForms[Operands.getWithoutImmCodes()]
613*0b57cec5SDimitry Andric         .push_back(Operands);
614*0b57cec5SDimitry Andric     }
615*0b57cec5SDimitry Andric   }
616*0b57cec5SDimitry Andric }
617*0b57cec5SDimitry Andric 
618*0b57cec5SDimitry Andric void FastISelMap::printImmediatePredicates(raw_ostream &OS) {
619*0b57cec5SDimitry Andric   if (ImmediatePredicates.begin() == ImmediatePredicates.end())
620*0b57cec5SDimitry Andric     return;
621*0b57cec5SDimitry Andric 
622*0b57cec5SDimitry Andric   OS << "\n// FastEmit Immediate Predicate functions.\n";
623*0b57cec5SDimitry Andric   for (ImmPredicateSet::iterator I = ImmediatePredicates.begin(),
624*0b57cec5SDimitry Andric        E = ImmediatePredicates.end(); I != E; ++I) {
625*0b57cec5SDimitry Andric     OS << "static bool " << I->getFnName() << "(int64_t Imm) {\n";
626*0b57cec5SDimitry Andric     OS << I->getImmediatePredicateCode() << "\n}\n";
627*0b57cec5SDimitry Andric   }
628*0b57cec5SDimitry Andric 
629*0b57cec5SDimitry Andric   OS << "\n\n";
630*0b57cec5SDimitry Andric }
631*0b57cec5SDimitry Andric 
632*0b57cec5SDimitry Andric void FastISelMap::emitInstructionCode(raw_ostream &OS,
633*0b57cec5SDimitry Andric                                       const OperandsSignature &Operands,
634*0b57cec5SDimitry Andric                                       const PredMap &PM,
635*0b57cec5SDimitry Andric                                       const std::string &RetVTName) {
636*0b57cec5SDimitry Andric   // Emit code for each possible instruction. There may be
637*0b57cec5SDimitry Andric   // multiple if there are subtarget concerns.  A reverse iterator
638*0b57cec5SDimitry Andric   // is used to produce the ones with highest complexity first.
639*0b57cec5SDimitry Andric 
640*0b57cec5SDimitry Andric   bool OneHadNoPredicate = false;
641*0b57cec5SDimitry Andric   for (PredMap::const_reverse_iterator PI = PM.rbegin(), PE = PM.rend();
642*0b57cec5SDimitry Andric        PI != PE; ++PI) {
643*0b57cec5SDimitry Andric     const InstructionMemo &Memo = PI->second;
644*0b57cec5SDimitry Andric     std::string PredicateCheck = Memo.PredicateCheck;
645*0b57cec5SDimitry Andric 
646*0b57cec5SDimitry Andric     if (PredicateCheck.empty()) {
647*0b57cec5SDimitry Andric       assert(!OneHadNoPredicate &&
648*0b57cec5SDimitry Andric              "Multiple instructions match and more than one had "
649*0b57cec5SDimitry Andric              "no predicate!");
650*0b57cec5SDimitry Andric       OneHadNoPredicate = true;
651*0b57cec5SDimitry Andric     } else {
652*0b57cec5SDimitry Andric       if (OneHadNoPredicate) {
653*0b57cec5SDimitry Andric         PrintFatalError("Multiple instructions match and one with no "
654*0b57cec5SDimitry Andric                         "predicate came before one with a predicate!  "
655*0b57cec5SDimitry Andric                         "name:" + Memo.Name + "  predicate: " + PredicateCheck);
656*0b57cec5SDimitry Andric       }
657*0b57cec5SDimitry Andric       OS << "  if (" + PredicateCheck + ") {\n";
658*0b57cec5SDimitry Andric       OS << "  ";
659*0b57cec5SDimitry Andric     }
660*0b57cec5SDimitry Andric 
661*0b57cec5SDimitry Andric     for (unsigned i = 0; i < Memo.PhysRegs.size(); ++i) {
662*0b57cec5SDimitry Andric       if (Memo.PhysRegs[i] != "")
663*0b57cec5SDimitry Andric         OS << "  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, "
664*0b57cec5SDimitry Andric            << "TII.get(TargetOpcode::COPY), " << Memo.PhysRegs[i]
665*0b57cec5SDimitry Andric            << ").addReg(Op" << i << ");\n";
666*0b57cec5SDimitry Andric     }
667*0b57cec5SDimitry Andric 
668*0b57cec5SDimitry Andric     OS << "  return fastEmitInst_";
669*0b57cec5SDimitry Andric     if (Memo.SubRegNo.empty()) {
670*0b57cec5SDimitry Andric       Operands.PrintManglingSuffix(OS, Memo.PhysRegs, ImmediatePredicates,
671*0b57cec5SDimitry Andric                                    true);
672*0b57cec5SDimitry Andric       OS << "(" << InstNS << "::" << Memo.Name << ", ";
673*0b57cec5SDimitry Andric       OS << "&" << InstNS << "::" << Memo.RC->getName() << "RegClass";
674*0b57cec5SDimitry Andric       if (!Operands.empty())
675*0b57cec5SDimitry Andric         OS << ", ";
676*0b57cec5SDimitry Andric       Operands.PrintArguments(OS, Memo.PhysRegs);
677*0b57cec5SDimitry Andric       OS << ");\n";
678*0b57cec5SDimitry Andric     } else {
679*0b57cec5SDimitry Andric       OS << "extractsubreg(" << RetVTName
680*0b57cec5SDimitry Andric          << ", Op0, Op0IsKill, " << Memo.SubRegNo << ");\n";
681*0b57cec5SDimitry Andric     }
682*0b57cec5SDimitry Andric 
683*0b57cec5SDimitry Andric     if (!PredicateCheck.empty()) {
684*0b57cec5SDimitry Andric       OS << "  }\n";
685*0b57cec5SDimitry Andric     }
686*0b57cec5SDimitry Andric   }
687*0b57cec5SDimitry Andric   // Return 0 if all of the possibilities had predicates but none
688*0b57cec5SDimitry Andric   // were satisfied.
689*0b57cec5SDimitry Andric   if (!OneHadNoPredicate)
690*0b57cec5SDimitry Andric     OS << "  return 0;\n";
691*0b57cec5SDimitry Andric   OS << "}\n";
692*0b57cec5SDimitry Andric   OS << "\n";
693*0b57cec5SDimitry Andric }
694*0b57cec5SDimitry Andric 
695*0b57cec5SDimitry Andric 
696*0b57cec5SDimitry Andric void FastISelMap::printFunctionDefinitions(raw_ostream &OS) {
697*0b57cec5SDimitry Andric   // Now emit code for all the patterns that we collected.
698*0b57cec5SDimitry Andric   for (OperandsOpcodeTypeRetPredMap::const_iterator OI = SimplePatterns.begin(),
699*0b57cec5SDimitry Andric        OE = SimplePatterns.end(); OI != OE; ++OI) {
700*0b57cec5SDimitry Andric     const OperandsSignature &Operands = OI->first;
701*0b57cec5SDimitry Andric     const OpcodeTypeRetPredMap &OTM = OI->second;
702*0b57cec5SDimitry Andric 
703*0b57cec5SDimitry Andric     for (OpcodeTypeRetPredMap::const_iterator I = OTM.begin(), E = OTM.end();
704*0b57cec5SDimitry Andric          I != E; ++I) {
705*0b57cec5SDimitry Andric       const std::string &Opcode = I->first;
706*0b57cec5SDimitry Andric       const TypeRetPredMap &TM = I->second;
707*0b57cec5SDimitry Andric 
708*0b57cec5SDimitry Andric       OS << "// FastEmit functions for " << Opcode << ".\n";
709*0b57cec5SDimitry Andric       OS << "\n";
710*0b57cec5SDimitry Andric 
711*0b57cec5SDimitry Andric       // Emit one function for each opcode,type pair.
712*0b57cec5SDimitry Andric       for (TypeRetPredMap::const_iterator TI = TM.begin(), TE = TM.end();
713*0b57cec5SDimitry Andric            TI != TE; ++TI) {
714*0b57cec5SDimitry Andric         MVT::SimpleValueType VT = TI->first;
715*0b57cec5SDimitry Andric         const RetPredMap &RM = TI->second;
716*0b57cec5SDimitry Andric         if (RM.size() != 1) {
717*0b57cec5SDimitry Andric           for (RetPredMap::const_iterator RI = RM.begin(), RE = RM.end();
718*0b57cec5SDimitry Andric                RI != RE; ++RI) {
719*0b57cec5SDimitry Andric             MVT::SimpleValueType RetVT = RI->first;
720*0b57cec5SDimitry Andric             const PredMap &PM = RI->second;
721*0b57cec5SDimitry Andric 
722*0b57cec5SDimitry Andric             OS << "unsigned fastEmit_"
723*0b57cec5SDimitry Andric                << getLegalCName(Opcode)
724*0b57cec5SDimitry Andric                << "_" << getLegalCName(getName(VT))
725*0b57cec5SDimitry Andric                << "_" << getLegalCName(getName(RetVT)) << "_";
726*0b57cec5SDimitry Andric             Operands.PrintManglingSuffix(OS, ImmediatePredicates);
727*0b57cec5SDimitry Andric             OS << "(";
728*0b57cec5SDimitry Andric             Operands.PrintParameters(OS);
729*0b57cec5SDimitry Andric             OS << ") {\n";
730*0b57cec5SDimitry Andric 
731*0b57cec5SDimitry Andric             emitInstructionCode(OS, Operands, PM, getName(RetVT));
732*0b57cec5SDimitry Andric           }
733*0b57cec5SDimitry Andric 
734*0b57cec5SDimitry Andric           // Emit one function for the type that demultiplexes on return type.
735*0b57cec5SDimitry Andric           OS << "unsigned fastEmit_"
736*0b57cec5SDimitry Andric              << getLegalCName(Opcode) << "_"
737*0b57cec5SDimitry Andric              << getLegalCName(getName(VT)) << "_";
738*0b57cec5SDimitry Andric           Operands.PrintManglingSuffix(OS, ImmediatePredicates);
739*0b57cec5SDimitry Andric           OS << "(MVT RetVT";
740*0b57cec5SDimitry Andric           if (!Operands.empty())
741*0b57cec5SDimitry Andric             OS << ", ";
742*0b57cec5SDimitry Andric           Operands.PrintParameters(OS);
743*0b57cec5SDimitry Andric           OS << ") {\nswitch (RetVT.SimpleTy) {\n";
744*0b57cec5SDimitry Andric           for (RetPredMap::const_iterator RI = RM.begin(), RE = RM.end();
745*0b57cec5SDimitry Andric                RI != RE; ++RI) {
746*0b57cec5SDimitry Andric             MVT::SimpleValueType RetVT = RI->first;
747*0b57cec5SDimitry Andric             OS << "  case " << getName(RetVT) << ": return fastEmit_"
748*0b57cec5SDimitry Andric                << getLegalCName(Opcode) << "_" << getLegalCName(getName(VT))
749*0b57cec5SDimitry Andric                << "_" << getLegalCName(getName(RetVT)) << "_";
750*0b57cec5SDimitry Andric             Operands.PrintManglingSuffix(OS, ImmediatePredicates);
751*0b57cec5SDimitry Andric             OS << "(";
752*0b57cec5SDimitry Andric             Operands.PrintArguments(OS);
753*0b57cec5SDimitry Andric             OS << ");\n";
754*0b57cec5SDimitry Andric           }
755*0b57cec5SDimitry Andric           OS << "  default: return 0;\n}\n}\n\n";
756*0b57cec5SDimitry Andric 
757*0b57cec5SDimitry Andric         } else {
758*0b57cec5SDimitry Andric           // Non-variadic return type.
759*0b57cec5SDimitry Andric           OS << "unsigned fastEmit_"
760*0b57cec5SDimitry Andric              << getLegalCName(Opcode) << "_"
761*0b57cec5SDimitry Andric              << getLegalCName(getName(VT)) << "_";
762*0b57cec5SDimitry Andric           Operands.PrintManglingSuffix(OS, ImmediatePredicates);
763*0b57cec5SDimitry Andric           OS << "(MVT RetVT";
764*0b57cec5SDimitry Andric           if (!Operands.empty())
765*0b57cec5SDimitry Andric             OS << ", ";
766*0b57cec5SDimitry Andric           Operands.PrintParameters(OS);
767*0b57cec5SDimitry Andric           OS << ") {\n";
768*0b57cec5SDimitry Andric 
769*0b57cec5SDimitry Andric           OS << "  if (RetVT.SimpleTy != " << getName(RM.begin()->first)
770*0b57cec5SDimitry Andric              << ")\n    return 0;\n";
771*0b57cec5SDimitry Andric 
772*0b57cec5SDimitry Andric           const PredMap &PM = RM.begin()->second;
773*0b57cec5SDimitry Andric 
774*0b57cec5SDimitry Andric           emitInstructionCode(OS, Operands, PM, "RetVT");
775*0b57cec5SDimitry Andric         }
776*0b57cec5SDimitry Andric       }
777*0b57cec5SDimitry Andric 
778*0b57cec5SDimitry Andric       // Emit one function for the opcode that demultiplexes based on the type.
779*0b57cec5SDimitry Andric       OS << "unsigned fastEmit_"
780*0b57cec5SDimitry Andric          << getLegalCName(Opcode) << "_";
781*0b57cec5SDimitry Andric       Operands.PrintManglingSuffix(OS, ImmediatePredicates);
782*0b57cec5SDimitry Andric       OS << "(MVT VT, MVT RetVT";
783*0b57cec5SDimitry Andric       if (!Operands.empty())
784*0b57cec5SDimitry Andric         OS << ", ";
785*0b57cec5SDimitry Andric       Operands.PrintParameters(OS);
786*0b57cec5SDimitry Andric       OS << ") {\n";
787*0b57cec5SDimitry Andric       OS << "  switch (VT.SimpleTy) {\n";
788*0b57cec5SDimitry Andric       for (TypeRetPredMap::const_iterator TI = TM.begin(), TE = TM.end();
789*0b57cec5SDimitry Andric            TI != TE; ++TI) {
790*0b57cec5SDimitry Andric         MVT::SimpleValueType VT = TI->first;
791*0b57cec5SDimitry Andric         std::string TypeName = getName(VT);
792*0b57cec5SDimitry Andric         OS << "  case " << TypeName << ": return fastEmit_"
793*0b57cec5SDimitry Andric            << getLegalCName(Opcode) << "_" << getLegalCName(TypeName) << "_";
794*0b57cec5SDimitry Andric         Operands.PrintManglingSuffix(OS, ImmediatePredicates);
795*0b57cec5SDimitry Andric         OS << "(RetVT";
796*0b57cec5SDimitry Andric         if (!Operands.empty())
797*0b57cec5SDimitry Andric           OS << ", ";
798*0b57cec5SDimitry Andric         Operands.PrintArguments(OS);
799*0b57cec5SDimitry Andric         OS << ");\n";
800*0b57cec5SDimitry Andric       }
801*0b57cec5SDimitry Andric       OS << "  default: return 0;\n";
802*0b57cec5SDimitry Andric       OS << "  }\n";
803*0b57cec5SDimitry Andric       OS << "}\n";
804*0b57cec5SDimitry Andric       OS << "\n";
805*0b57cec5SDimitry Andric     }
806*0b57cec5SDimitry Andric 
807*0b57cec5SDimitry Andric     OS << "// Top-level FastEmit function.\n";
808*0b57cec5SDimitry Andric     OS << "\n";
809*0b57cec5SDimitry Andric 
810*0b57cec5SDimitry Andric     // Emit one function for the operand signature that demultiplexes based
811*0b57cec5SDimitry Andric     // on opcode and type.
812*0b57cec5SDimitry Andric     OS << "unsigned fastEmit_";
813*0b57cec5SDimitry Andric     Operands.PrintManglingSuffix(OS, ImmediatePredicates);
814*0b57cec5SDimitry Andric     OS << "(MVT VT, MVT RetVT, unsigned Opcode";
815*0b57cec5SDimitry Andric     if (!Operands.empty())
816*0b57cec5SDimitry Andric       OS << ", ";
817*0b57cec5SDimitry Andric     Operands.PrintParameters(OS);
818*0b57cec5SDimitry Andric     OS << ") ";
819*0b57cec5SDimitry Andric     if (!Operands.hasAnyImmediateCodes())
820*0b57cec5SDimitry Andric       OS << "override ";
821*0b57cec5SDimitry Andric     OS << "{\n";
822*0b57cec5SDimitry Andric 
823*0b57cec5SDimitry Andric     // If there are any forms of this signature available that operate on
824*0b57cec5SDimitry Andric     // constrained forms of the immediate (e.g., 32-bit sext immediate in a
825*0b57cec5SDimitry Andric     // 64-bit operand), check them first.
826*0b57cec5SDimitry Andric 
827*0b57cec5SDimitry Andric     std::map<OperandsSignature, std::vector<OperandsSignature> >::iterator MI
828*0b57cec5SDimitry Andric       = SignaturesWithConstantForms.find(Operands);
829*0b57cec5SDimitry Andric     if (MI != SignaturesWithConstantForms.end()) {
830*0b57cec5SDimitry Andric       // Unique any duplicates out of the list.
831*0b57cec5SDimitry Andric       llvm::sort(MI->second);
832*0b57cec5SDimitry Andric       MI->second.erase(std::unique(MI->second.begin(), MI->second.end()),
833*0b57cec5SDimitry Andric                        MI->second.end());
834*0b57cec5SDimitry Andric 
835*0b57cec5SDimitry Andric       // Check each in order it was seen.  It would be nice to have a good
836*0b57cec5SDimitry Andric       // relative ordering between them, but we're not going for optimality
837*0b57cec5SDimitry Andric       // here.
838*0b57cec5SDimitry Andric       for (unsigned i = 0, e = MI->second.size(); i != e; ++i) {
839*0b57cec5SDimitry Andric         OS << "  if (";
840*0b57cec5SDimitry Andric         MI->second[i].emitImmediatePredicate(OS, ImmediatePredicates);
841*0b57cec5SDimitry Andric         OS << ")\n    if (unsigned Reg = fastEmit_";
842*0b57cec5SDimitry Andric         MI->second[i].PrintManglingSuffix(OS, ImmediatePredicates);
843*0b57cec5SDimitry Andric         OS << "(VT, RetVT, Opcode";
844*0b57cec5SDimitry Andric         if (!MI->second[i].empty())
845*0b57cec5SDimitry Andric           OS << ", ";
846*0b57cec5SDimitry Andric         MI->second[i].PrintArguments(OS);
847*0b57cec5SDimitry Andric         OS << "))\n      return Reg;\n\n";
848*0b57cec5SDimitry Andric       }
849*0b57cec5SDimitry Andric 
850*0b57cec5SDimitry Andric       // Done with this, remove it.
851*0b57cec5SDimitry Andric       SignaturesWithConstantForms.erase(MI);
852*0b57cec5SDimitry Andric     }
853*0b57cec5SDimitry Andric 
854*0b57cec5SDimitry Andric     OS << "  switch (Opcode) {\n";
855*0b57cec5SDimitry Andric     for (OpcodeTypeRetPredMap::const_iterator I = OTM.begin(), E = OTM.end();
856*0b57cec5SDimitry Andric          I != E; ++I) {
857*0b57cec5SDimitry Andric       const std::string &Opcode = I->first;
858*0b57cec5SDimitry Andric 
859*0b57cec5SDimitry Andric       OS << "  case " << Opcode << ": return fastEmit_"
860*0b57cec5SDimitry Andric          << getLegalCName(Opcode) << "_";
861*0b57cec5SDimitry Andric       Operands.PrintManglingSuffix(OS, ImmediatePredicates);
862*0b57cec5SDimitry Andric       OS << "(VT, RetVT";
863*0b57cec5SDimitry Andric       if (!Operands.empty())
864*0b57cec5SDimitry Andric         OS << ", ";
865*0b57cec5SDimitry Andric       Operands.PrintArguments(OS);
866*0b57cec5SDimitry Andric       OS << ");\n";
867*0b57cec5SDimitry Andric     }
868*0b57cec5SDimitry Andric     OS << "  default: return 0;\n";
869*0b57cec5SDimitry Andric     OS << "  }\n";
870*0b57cec5SDimitry Andric     OS << "}\n";
871*0b57cec5SDimitry Andric     OS << "\n";
872*0b57cec5SDimitry Andric   }
873*0b57cec5SDimitry Andric 
874*0b57cec5SDimitry Andric   // TODO: SignaturesWithConstantForms should be empty here.
875*0b57cec5SDimitry Andric }
876*0b57cec5SDimitry Andric 
877*0b57cec5SDimitry Andric namespace llvm {
878*0b57cec5SDimitry Andric 
879*0b57cec5SDimitry Andric void EmitFastISel(RecordKeeper &RK, raw_ostream &OS) {
880*0b57cec5SDimitry Andric   CodeGenDAGPatterns CGP(RK);
881*0b57cec5SDimitry Andric   const CodeGenTarget &Target = CGP.getTargetInfo();
882*0b57cec5SDimitry Andric   emitSourceFileHeader("\"Fast\" Instruction Selector for the " +
883*0b57cec5SDimitry Andric                        Target.getName().str() + " target", OS);
884*0b57cec5SDimitry Andric 
885*0b57cec5SDimitry Andric   // Determine the target's namespace name.
886*0b57cec5SDimitry Andric   StringRef InstNS = Target.getInstNamespace();
887*0b57cec5SDimitry Andric   assert(!InstNS.empty() && "Can't determine target-specific namespace!");
888*0b57cec5SDimitry Andric 
889*0b57cec5SDimitry Andric   FastISelMap F(InstNS);
890*0b57cec5SDimitry Andric   F.collectPatterns(CGP);
891*0b57cec5SDimitry Andric   F.printImmediatePredicates(OS);
892*0b57cec5SDimitry Andric   F.printFunctionDefinitions(OS);
893*0b57cec5SDimitry Andric }
894*0b57cec5SDimitry Andric 
895*0b57cec5SDimitry Andric } // End llvm namespace
896