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