void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, Record *InstrInfo, std::map<std::vector<Record*>, unsigned> &EmittedLists, std::map<Record*, unsigned> &BarriersMap, const OperandInfoMapTy &OpInfo, raw_ostream &OS) { int MinOperands = 0; if (!Inst.OperandList.empty()) // Each logical operand can be multiple MI operands. MinOperands = Inst.OperandList.back().MIOperandNo + Inst.OperandList.back().MINumOperands; OS << " { "; OS << Num << ",\t" << MinOperands << ",\t" << Inst.NumDefs << ",\t" << getItinClassNumber(Inst.TheDef) << ",\t\"" << Inst.TheDef->getName() << "\", 0"; // Emit all of the target indepedent flags... if (Inst.isReturn) OS << "|(1<<TID::Return)"; if (Inst.isBranch) OS << "|(1<<TID::Branch)"; if (Inst.isIndirectBranch) OS << "|(1<<TID::IndirectBranch)"; if (Inst.isBarrier) OS << "|(1<<TID::Barrier)"; if (Inst.hasDelaySlot) OS << "|(1<<TID::DelaySlot)"; if (Inst.isCall) OS << "|(1<<TID::Call)"; if (Inst.canFoldAsLoad) OS << "|(1<<TID::FoldableAsLoad)"; if (Inst.mayLoad) OS << "|(1<<TID::MayLoad)"; if (Inst.mayStore) OS << "|(1<<TID::MayStore)"; if (Inst.isPredicable) OS << "|(1<<TID::Predicable)"; if (Inst.isConvertibleToThreeAddress) OS << "|(1<<TID::ConvertibleTo3Addr)"; if (Inst.isCommutable) OS << "|(1<<TID::Commutable)"; if (Inst.isTerminator) OS << "|(1<<TID::Terminator)"; if (Inst.isReMaterializable) OS << "|(1<<TID::Rematerializable)"; if (Inst.isNotDuplicable) OS << "|(1<<TID::NotDuplicable)"; if (Inst.hasOptionalDef) OS << "|(1<<TID::HasOptionalDef)"; if (Inst.usesCustomDAGSchedInserter) OS << "|(1<<TID::UsesCustomDAGSchedInserter)"; if (Inst.isVariadic) OS << "|(1<<TID::Variadic)"; if (Inst.hasSideEffects) OS << "|(1<<TID::UnmodeledSideEffects)"; if (Inst.isAsCheapAsAMove) OS << "|(1<<TID::CheapAsAMove)"; OS << ", 0"; // Emit all of the target-specific flags... ListInit *LI = InstrInfo->getValueAsListInit("TSFlagsFields"); ListInit *Shift = InstrInfo->getValueAsListInit("TSFlagsShifts"); if (LI->getSize() != Shift->getSize()) throw "Lengths of " + InstrInfo->getName() + ":(TargetInfoFields, TargetInfoPositions) must be equal!"; for (unsigned i = 0, e = LI->getSize(); i != e; ++i) emitShiftedValue(Inst.TheDef, dynamic_cast<StringInit*>(LI->getElement(i)), dynamic_cast<IntInit*>(Shift->getElement(i)), OS); OS << ", "; // Emit the implicit uses and defs lists... std::vector<Record*> UseList = Inst.TheDef->getValueAsListOfDefs("Uses"); if (UseList.empty()) OS << "NULL, "; else OS << "ImplicitList" << EmittedLists[UseList] << ", "; std::vector<Record*> DefList = Inst.TheDef->getValueAsListOfDefs("Defs"); if (DefList.empty()) OS << "NULL, "; else OS << "ImplicitList" << EmittedLists[DefList] << ", "; std::map<Record*, unsigned>::iterator BI = BarriersMap.find(Inst.TheDef); if (BI == BarriersMap.end()) OS << "NULL, "; else OS << "Barriers" << BI->second << ", "; // Emit the operand info. std::vector<std::string> OperandInfo = GetOperandInfo(Inst); if (OperandInfo.empty()) OS << "0"; else OS << "OperandInfo" << OpInfo.find(OperandInfo)->second; OS << " }, // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n"; }
void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, Record *InstrInfo, std::map<std::vector<Record*>, unsigned> &EmittedLists, const OperandInfoMapTy &OpInfo, raw_ostream &OS) { int MinOperands = 0; if (!Inst.Operands.empty()) // Each logical operand can be multiple MI operands. MinOperands = Inst.Operands.back().MIOperandNo + Inst.Operands.back().MINumOperands; OS << " { "; OS << Num << ",\t" << MinOperands << ",\t" << Inst.Operands.NumDefs << ",\t" << Inst.TheDef->getValueAsInt("Size") << ",\t" << SchedModels.getSchedClassIdx(Inst) << ",\t0"; // Emit all of the target independent flags... if (Inst.isPseudo) OS << "|(1ULL<<MCID::Pseudo)"; if (Inst.isReturn) OS << "|(1ULL<<MCID::Return)"; if (Inst.isBranch) OS << "|(1ULL<<MCID::Branch)"; if (Inst.isIndirectBranch) OS << "|(1ULL<<MCID::IndirectBranch)"; if (Inst.isCompare) OS << "|(1ULL<<MCID::Compare)"; if (Inst.isMoveImm) OS << "|(1ULL<<MCID::MoveImm)"; if (Inst.isBitcast) OS << "|(1ULL<<MCID::Bitcast)"; if (Inst.isSelect) OS << "|(1ULL<<MCID::Select)"; if (Inst.isBarrier) OS << "|(1ULL<<MCID::Barrier)"; if (Inst.hasDelaySlot) OS << "|(1ULL<<MCID::DelaySlot)"; if (Inst.isCall) OS << "|(1ULL<<MCID::Call)"; if (Inst.canFoldAsLoad) OS << "|(1ULL<<MCID::FoldableAsLoad)"; if (Inst.mayLoad) OS << "|(1ULL<<MCID::MayLoad)"; if (Inst.mayStore) OS << "|(1ULL<<MCID::MayStore)"; if (Inst.isPredicable) OS << "|(1ULL<<MCID::Predicable)"; if (Inst.isConvertibleToThreeAddress) OS << "|(1ULL<<MCID::ConvertibleTo3Addr)"; if (Inst.isCommutable) OS << "|(1ULL<<MCID::Commutable)"; if (Inst.isTerminator) OS << "|(1ULL<<MCID::Terminator)"; if (Inst.isReMaterializable) OS << "|(1ULL<<MCID::Rematerializable)"; if (Inst.isNotDuplicable) OS << "|(1ULL<<MCID::NotDuplicable)"; if (Inst.Operands.hasOptionalDef) OS << "|(1ULL<<MCID::HasOptionalDef)"; if (Inst.usesCustomInserter) OS << "|(1ULL<<MCID::UsesCustomInserter)"; if (Inst.hasPostISelHook) OS << "|(1ULL<<MCID::HasPostISelHook)"; if (Inst.Operands.isVariadic)OS << "|(1ULL<<MCID::Variadic)"; if (Inst.hasSideEffects) OS << "|(1ULL<<MCID::UnmodeledSideEffects)"; if (Inst.isAsCheapAsAMove) OS << "|(1ULL<<MCID::CheapAsAMove)"; if (Inst.hasExtraSrcRegAllocReq) OS << "|(1ULL<<MCID::ExtraSrcRegAllocReq)"; if (Inst.hasExtraDefRegAllocReq) OS << "|(1ULL<<MCID::ExtraDefRegAllocReq)"; if (Inst.isRegSequence) OS << "|(1ULL<<MCID::RegSequence)"; if (Inst.isExtractSubreg) OS << "|(1ULL<<MCID::ExtractSubreg)"; if (Inst.isInsertSubreg) OS << "|(1ULL<<MCID::InsertSubreg)"; if (Inst.isConvergent) OS << "|(1ULL<<MCID::Convergent)"; // Emit all of the target-specific flags... BitsInit *TSF = Inst.TheDef->getValueAsBitsInit("TSFlags"); if (!TSF) PrintFatalError("no TSFlags?"); uint64_t Value = 0; for (unsigned i = 0, e = TSF->getNumBits(); i != e; ++i) { if (BitInit *Bit = dyn_cast<BitInit>(TSF->getBit(i))) Value |= uint64_t(Bit->getValue()) << i; else PrintFatalError("Invalid TSFlags bit in " + Inst.TheDef->getName()); } OS << ", 0x"; OS.write_hex(Value); OS << "ULL, "; // Emit the implicit uses and defs lists... std::vector<Record*> UseList = Inst.TheDef->getValueAsListOfDefs("Uses"); if (UseList.empty()) OS << "nullptr, "; else OS << "ImplicitList" << EmittedLists[UseList] << ", "; std::vector<Record*> DefList = Inst.TheDef->getValueAsListOfDefs("Defs"); if (DefList.empty()) OS << "nullptr, "; else OS << "ImplicitList" << EmittedLists[DefList] << ", "; // Emit the operand info. std::vector<std::string> OperandInfo = GetOperandInfo(Inst); if (OperandInfo.empty()) OS << "nullptr"; else OS << "OperandInfo" << OpInfo.find(OperandInfo)->second; CodeGenTarget &Target = CDP.getTargetInfo(); if (Inst.HasComplexDeprecationPredicate) // Emit a function pointer to the complex predicate method. OS << ", -1 " << ",&get" << Inst.DeprecatedReason << "DeprecationInfo"; else if (!Inst.DeprecatedReason.empty()) // Emit the Subtarget feature. OS << ", " << Target.getInstNamespace() << "::" << Inst.DeprecatedReason << " ,nullptr"; else // Instruction isn't deprecated. OS << ", -1 ,nullptr"; OS << " }, // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n"; }
void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, Record *InstrInfo, std::map<std::vector<Record*>, unsigned> &EmittedLists, const OperandInfoMapTy &OpInfo, raw_ostream &OS) { int MinOperands = 0; if (!Inst.Operands.size() == 0) // Each logical operand can be multiple MI operands. MinOperands = Inst.Operands.back().MIOperandNo + Inst.Operands.back().MINumOperands; OS << " { "; OS << Num << ",\t" << MinOperands << ",\t" << Inst.Operands.NumDefs << ",\t" << getItinClassNumber(Inst.TheDef) << ",\t" << Inst.TheDef->getValueAsInt("Size") << ",\t0"; // Emit all of the target indepedent flags... if (Inst.isPseudo) OS << "|(1<<MCID::Pseudo)"; if (Inst.isReturn) OS << "|(1<<MCID::Return)"; if (Inst.isBranch) OS << "|(1<<MCID::Branch)"; if (Inst.isIndirectBranch) OS << "|(1<<MCID::IndirectBranch)"; if (Inst.isCompare) OS << "|(1<<MCID::Compare)"; if (Inst.isMoveImm) OS << "|(1<<MCID::MoveImm)"; if (Inst.isBitcast) OS << "|(1<<MCID::Bitcast)"; if (Inst.isBarrier) OS << "|(1<<MCID::Barrier)"; if (Inst.hasDelaySlot) OS << "|(1<<MCID::DelaySlot)"; if (Inst.isCall) OS << "|(1<<MCID::Call)"; if (Inst.canFoldAsLoad) OS << "|(1<<MCID::FoldableAsLoad)"; if (Inst.mayLoad) OS << "|(1<<MCID::MayLoad)"; if (Inst.mayStore) OS << "|(1<<MCID::MayStore)"; if (Inst.isPredicable) OS << "|(1<<MCID::Predicable)"; if (Inst.isConvertibleToThreeAddress) OS << "|(1<<MCID::ConvertibleTo3Addr)"; if (Inst.isCommutable) OS << "|(1<<MCID::Commutable)"; if (Inst.isTerminator) OS << "|(1<<MCID::Terminator)"; if (Inst.isReMaterializable) OS << "|(1<<MCID::Rematerializable)"; if (Inst.isNotDuplicable) OS << "|(1<<MCID::NotDuplicable)"; if (Inst.Operands.hasOptionalDef) OS << "|(1<<MCID::HasOptionalDef)"; if (Inst.usesCustomInserter) OS << "|(1<<MCID::UsesCustomInserter)"; if (Inst.hasPostISelHook) OS << "|(1<<MCID::HasPostISelHook)"; if (Inst.Operands.isVariadic)OS << "|(1<<MCID::Variadic)"; if (Inst.hasSideEffects) OS << "|(1<<MCID::UnmodeledSideEffects)"; if (Inst.isAsCheapAsAMove) OS << "|(1<<MCID::CheapAsAMove)"; if (Inst.hasExtraSrcRegAllocReq) OS << "|(1<<MCID::ExtraSrcRegAllocReq)"; if (Inst.hasExtraDefRegAllocReq) OS << "|(1<<MCID::ExtraDefRegAllocReq)"; // Emit all of the target-specific flags... BitsInit *TSF = Inst.TheDef->getValueAsBitsInit("TSFlags"); if (!TSF) throw "no TSFlags?"; uint64_t Value = 0; for (unsigned i = 0, e = TSF->getNumBits(); i != e; ++i) { if (BitInit *Bit = dynamic_cast<BitInit*>(TSF->getBit(i))) Value |= uint64_t(Bit->getValue()) << i; else throw "Invalid TSFlags bit in " + Inst.TheDef->getName(); } OS << ", 0x"; OS.write_hex(Value); OS << "ULL, "; // Emit the implicit uses and defs lists... std::vector<Record*> UseList = Inst.TheDef->getValueAsListOfDefs("Uses"); if (UseList.empty()) OS << "NULL, "; else OS << "ImplicitList" << EmittedLists[UseList] << ", "; std::vector<Record*> DefList = Inst.TheDef->getValueAsListOfDefs("Defs"); if (DefList.empty()) OS << "NULL, "; else OS << "ImplicitList" << EmittedLists[DefList] << ", "; // Emit the operand info. std::vector<std::string> OperandInfo = GetOperandInfo(Inst); if (OperandInfo.empty()) OS << "0"; else OS << "OperandInfo" << OpInfo.find(OperandInfo)->second; OS << " }, // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n"; }