1 //===- MCSubtargetInfo.cpp - Subtarget Information ------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/MC/MCSubtargetInfo.h" 11 #include "llvm/ADT/ArrayRef.h" 12 #include "llvm/ADT/StringRef.h" 13 #include "llvm/MC/MCInstrItineraries.h" 14 #include "llvm/MC/MCSchedule.h" 15 #include "llvm/MC/SubtargetFeature.h" 16 #include "llvm/Support/raw_ostream.h" 17 #include <algorithm> 18 #include <cassert> 19 #include <cstring> 20 21 using namespace llvm; 22 23 static FeatureBitset getFeatures(StringRef CPU, StringRef FS, 24 ArrayRef<SubtargetFeatureKV> ProcDesc, 25 ArrayRef<SubtargetFeatureKV> ProcFeatures) { 26 SubtargetFeatures Features(FS); 27 return Features.getFeatureBits(CPU, ProcDesc, ProcFeatures); 28 } 29 30 void MCSubtargetInfo::InitMCProcessorInfo(StringRef CPU, StringRef FS) { 31 FeatureBits = getFeatures(CPU, FS, ProcDesc, ProcFeatures); 32 if (!CPU.empty()) 33 CPUSchedModel = &getSchedModelForCPU(CPU); 34 else 35 CPUSchedModel = &MCSchedModel::GetDefaultSchedModel(); 36 } 37 38 void MCSubtargetInfo::setDefaultFeatures(StringRef CPU, StringRef FS) { 39 FeatureBits = getFeatures(CPU, FS, ProcDesc, ProcFeatures); 40 } 41 42 MCSubtargetInfo::MCSubtargetInfo( 43 const Triple &TT, StringRef C, StringRef FS, 44 ArrayRef<SubtargetFeatureKV> PF, ArrayRef<SubtargetFeatureKV> PD, 45 const SubtargetInfoKV *ProcSched, const MCWriteProcResEntry *WPR, 46 const MCWriteLatencyEntry *WL, const MCReadAdvanceEntry *RA, 47 const InstrStage *IS, const unsigned *OC, const unsigned *FP) 48 : TargetTriple(TT), CPU(C), ProcFeatures(PF), ProcDesc(PD), 49 ProcSchedModels(ProcSched), WriteProcResTable(WPR), WriteLatencyTable(WL), 50 ReadAdvanceTable(RA), Stages(IS), OperandCycles(OC), ForwardingPaths(FP) { 51 InitMCProcessorInfo(CPU, FS); 52 } 53 54 FeatureBitset MCSubtargetInfo::ToggleFeature(uint64_t FB) { 55 FeatureBits.flip(FB); 56 return FeatureBits; 57 } 58 59 FeatureBitset MCSubtargetInfo::ToggleFeature(const FeatureBitset &FB) { 60 FeatureBits ^= FB; 61 return FeatureBits; 62 } 63 64 FeatureBitset MCSubtargetInfo::ToggleFeature(StringRef FS) { 65 SubtargetFeatures::ToggleFeature(FeatureBits, FS, ProcFeatures); 66 return FeatureBits; 67 } 68 69 FeatureBitset MCSubtargetInfo::ApplyFeatureFlag(StringRef FS) { 70 SubtargetFeatures::ApplyFeatureFlag(FeatureBits, FS, ProcFeatures); 71 return FeatureBits; 72 } 73 74 bool MCSubtargetInfo::checkFeatures(StringRef FS) const { 75 SubtargetFeatures T(FS); 76 FeatureBitset Set, All; 77 for (std::string F : T.getFeatures()) { 78 SubtargetFeatures::ApplyFeatureFlag(Set, F, ProcFeatures); 79 if (F[0] == '-') 80 F[0] = '+'; 81 SubtargetFeatures::ApplyFeatureFlag(All, F, ProcFeatures); 82 } 83 return (FeatureBits & All) == Set; 84 } 85 86 const MCSchedModel &MCSubtargetInfo::getSchedModelForCPU(StringRef CPU) const { 87 assert(ProcSchedModels && "Processor machine model not available!"); 88 89 ArrayRef<SubtargetInfoKV> SchedModels(ProcSchedModels, ProcDesc.size()); 90 91 assert(std::is_sorted(SchedModels.begin(), SchedModels.end(), 92 [](const SubtargetInfoKV &LHS, const SubtargetInfoKV &RHS) { 93 return strcmp(LHS.Key, RHS.Key) < 0; 94 }) && 95 "Processor machine model table is not sorted"); 96 97 // Find entry 98 auto Found = 99 std::lower_bound(SchedModels.begin(), SchedModels.end(), CPU); 100 if (Found == SchedModels.end() || StringRef(Found->Key) != CPU) { 101 if (CPU != "help") // Don't error if the user asked for help. 102 errs() << "'" << CPU 103 << "' is not a recognized processor for this target" 104 << " (ignoring processor)\n"; 105 return MCSchedModel::GetDefaultSchedModel(); 106 } 107 assert(Found->Value && "Missing processor SchedModel value"); 108 return *(const MCSchedModel *)Found->Value; 109 } 110 111 InstrItineraryData 112 MCSubtargetInfo::getInstrItineraryForCPU(StringRef CPU) const { 113 const MCSchedModel &SchedModel = getSchedModelForCPU(CPU); 114 return InstrItineraryData(SchedModel, Stages, OperandCycles, ForwardingPaths); 115 } 116 117 void MCSubtargetInfo::initInstrItins(InstrItineraryData &InstrItins) const { 118 InstrItins = InstrItineraryData(getSchedModel(), Stages, OperandCycles, 119 ForwardingPaths); 120 } 121