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/StringRef.h"
12 #include "llvm/ADT/Triple.h"
13 #include "llvm/MC/MCInstrItineraries.h"
14 #include "llvm/MC/SubtargetFeature.h"
15 #include "llvm/Support/raw_ostream.h"
16 #include <algorithm>
17 
18 using namespace llvm;
19 
20 /// InitMCProcessorInfo - Set or change the CPU (optionally supplemented
21 /// with feature string). Recompute feature bits and scheduling model.
22 void
InitMCProcessorInfo(StringRef CPU,StringRef FS)23 MCSubtargetInfo::InitMCProcessorInfo(StringRef CPU, StringRef FS) {
24   SubtargetFeatures Features(FS);
25   FeatureBits = Features.getFeatureBits(CPU, ProcDesc, ProcFeatures);
26   InitCPUSchedModel(CPU);
27 }
28 
29 void
InitCPUSchedModel(StringRef CPU)30 MCSubtargetInfo::InitCPUSchedModel(StringRef CPU) {
31   if (!CPU.empty())
32     CPUSchedModel = getSchedModelForCPU(CPU);
33   else
34     CPUSchedModel = MCSchedModel::GetDefaultSchedModel();
35 }
36 
37 void
InitMCSubtargetInfo(StringRef TT,StringRef C,StringRef FS,ArrayRef<SubtargetFeatureKV> PF,ArrayRef<SubtargetFeatureKV> PD,const SubtargetInfoKV * ProcSched,const MCWriteProcResEntry * WPR,const MCWriteLatencyEntry * WL,const MCReadAdvanceEntry * RA,const InstrStage * IS,const unsigned * OC,const unsigned * FP)38 MCSubtargetInfo::InitMCSubtargetInfo(StringRef TT, StringRef C, StringRef FS,
39                                      ArrayRef<SubtargetFeatureKV> PF,
40                                      ArrayRef<SubtargetFeatureKV> PD,
41                                      const SubtargetInfoKV *ProcSched,
42                                      const MCWriteProcResEntry *WPR,
43                                      const MCWriteLatencyEntry *WL,
44                                      const MCReadAdvanceEntry *RA,
45                                      const InstrStage *IS,
46                                      const unsigned *OC,
47                                      const unsigned *FP) {
48   TargetTriple = TT;
49   CPU = C;
50   ProcFeatures = PF;
51   ProcDesc = PD;
52   ProcSchedModels = ProcSched;
53   WriteProcResTable = WPR;
54   WriteLatencyTable = WL;
55   ReadAdvanceTable = RA;
56 
57   Stages = IS;
58   OperandCycles = OC;
59   ForwardingPaths = FP;
60 
61   InitMCProcessorInfo(CPU, FS);
62 }
63 
64 /// ToggleFeature - Toggle a feature and returns the re-computed feature
65 /// bits. This version does not change the implied bits.
ToggleFeature(uint64_t FB)66 uint64_t MCSubtargetInfo::ToggleFeature(uint64_t FB) {
67   FeatureBits ^= FB;
68   return FeatureBits;
69 }
70 
71 /// ToggleFeature - Toggle a feature and returns the re-computed feature
72 /// bits. This version will also change all implied bits.
ToggleFeature(StringRef FS)73 uint64_t MCSubtargetInfo::ToggleFeature(StringRef FS) {
74   SubtargetFeatures Features;
75   FeatureBits = Features.ToggleFeature(FeatureBits, FS, ProcFeatures);
76   return FeatureBits;
77 }
78 
79 
80 MCSchedModel
getSchedModelForCPU(StringRef CPU) const81 MCSubtargetInfo::getSchedModelForCPU(StringRef CPU) const {
82   assert(ProcSchedModels && "Processor machine model not available!");
83 
84   unsigned NumProcs = ProcDesc.size();
85 #ifndef NDEBUG
86   for (size_t i = 1; i < NumProcs; i++) {
87     assert(strcmp(ProcSchedModels[i - 1].Key, ProcSchedModels[i].Key) < 0 &&
88            "Processor machine model table is not sorted");
89   }
90 #endif
91 
92   // Find entry
93   const SubtargetInfoKV *Found =
94     std::lower_bound(ProcSchedModels, ProcSchedModels+NumProcs, CPU);
95   if (Found == ProcSchedModels+NumProcs || StringRef(Found->Key) != CPU) {
96     if (CPU != "help") // Don't error if the user asked for help.
97       errs() << "'" << CPU
98              << "' is not a recognized processor for this target"
99              << " (ignoring processor)\n";
100     return MCSchedModel::GetDefaultSchedModel();
101   }
102   assert(Found->Value && "Missing processor SchedModel value");
103   return *(const MCSchedModel *)Found->Value;
104 }
105 
106 InstrItineraryData
getInstrItineraryForCPU(StringRef CPU) const107 MCSubtargetInfo::getInstrItineraryForCPU(StringRef CPU) const {
108   const MCSchedModel SchedModel = getSchedModelForCPU(CPU);
109   return InstrItineraryData(SchedModel, Stages, OperandCycles, ForwardingPaths);
110 }
111 
112 /// Initialize an InstrItineraryData instance.
initInstrItins(InstrItineraryData & InstrItins) const113 void MCSubtargetInfo::initInstrItins(InstrItineraryData &InstrItins) const {
114   InstrItins =
115     InstrItineraryData(CPUSchedModel, Stages, OperandCycles, ForwardingPaths);
116 }
117