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