1224133Sdim//==-- llvm/MC/MCSubtargetInfo.h - Subtarget Information ---------*- C++ -*-==//
2224133Sdim//
3224133Sdim//                     The LLVM Compiler Infrastructure
4224133Sdim//
5224133Sdim// This file is distributed under the University of Illinois Open Source
6224133Sdim// License. See LICENSE.TXT for details.
7224133Sdim//
8224133Sdim//===----------------------------------------------------------------------===//
9224133Sdim//
10224133Sdim// This file describes the subtarget options of a Target machine.
11224133Sdim//
12224133Sdim//===----------------------------------------------------------------------===//
13224133Sdim
14224133Sdim#ifndef LLVM_MC_MCSUBTARGET_H
15224133Sdim#define LLVM_MC_MCSUBTARGET_H
16224133Sdim
17249423Sdim#include "llvm/MC/MCInstrItineraries.h"
18224133Sdim#include "llvm/MC/SubtargetFeature.h"
19224133Sdim#include <string>
20224133Sdim
21224133Sdimnamespace llvm {
22224133Sdim
23224133Sdimclass StringRef;
24224133Sdim
25224133Sdim//===----------------------------------------------------------------------===//
26224133Sdim///
27224133Sdim/// MCSubtargetInfo - Generic base class for all target subtargets.
28224133Sdim///
29224133Sdimclass MCSubtargetInfo {
30224133Sdim  std::string TargetTriple;            // Target triple
31224133Sdim  const SubtargetFeatureKV *ProcFeatures;  // Processor feature list
32224133Sdim  const SubtargetFeatureKV *ProcDesc;  // Processor descriptions
33243830Sdim
34243830Sdim  // Scheduler machine model
35243830Sdim  const SubtargetInfoKV *ProcSchedModels;
36243830Sdim  const MCWriteProcResEntry *WriteProcResTable;
37243830Sdim  const MCWriteLatencyEntry *WriteLatencyTable;
38243830Sdim  const MCReadAdvanceEntry *ReadAdvanceTable;
39243830Sdim  const MCSchedModel *CPUSchedModel;
40243830Sdim
41239462Sdim  const InstrStage *Stages;            // Instruction itinerary stages
42239462Sdim  const unsigned *OperandCycles;       // Itinerary operand cycles
43239462Sdim  const unsigned *ForwardingPaths;     // Forwarding paths
44224133Sdim  unsigned NumFeatures;                // Number of processor features
45224133Sdim  unsigned NumProcs;                   // Number of processors
46224133Sdim  uint64_t FeatureBits;                // Feature bits for current CPU + FS
47224133Sdim
48224133Sdimpublic:
49224133Sdim  void InitMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS,
50224133Sdim                           const SubtargetFeatureKV *PF,
51224133Sdim                           const SubtargetFeatureKV *PD,
52239462Sdim                           const SubtargetInfoKV *ProcSched,
53243830Sdim                           const MCWriteProcResEntry *WPR,
54243830Sdim                           const MCWriteLatencyEntry *WL,
55243830Sdim                           const MCReadAdvanceEntry *RA,
56239462Sdim                           const InstrStage *IS,
57224133Sdim                           const unsigned *OC, const unsigned *FP,
58224133Sdim                           unsigned NF, unsigned NP);
59224133Sdim
60224133Sdim  /// getTargetTriple - Return the target triple string.
61224133Sdim  StringRef getTargetTriple() const {
62224133Sdim    return TargetTriple;
63224133Sdim  }
64224133Sdim
65224133Sdim  /// getFeatureBits - Return the feature bits.
66224133Sdim  ///
67224133Sdim  uint64_t getFeatureBits() const {
68224133Sdim    return FeatureBits;
69224133Sdim  }
70224133Sdim
71243830Sdim  /// InitMCProcessorInfo - Set or change the CPU (optionally supplemented with
72243830Sdim  /// feature string). Recompute feature bits and scheduling model.
73243830Sdim  void InitMCProcessorInfo(StringRef CPU, StringRef FS);
74224133Sdim
75263508Sdim  /// InitCPUSchedModel - Recompute scheduling model based on CPU.
76263508Sdim  void InitCPUSchedModel(StringRef CPU);
77263508Sdim
78224133Sdim  /// ToggleFeature - Toggle a feature and returns the re-computed feature
79224133Sdim  /// bits. This version does not change the implied bits.
80224133Sdim  uint64_t ToggleFeature(uint64_t FB);
81224133Sdim
82224133Sdim  /// ToggleFeature - Toggle a feature and returns the re-computed feature
83224133Sdim  /// bits. This version will also change all implied bits.
84224133Sdim  uint64_t ToggleFeature(StringRef FS);
85224133Sdim
86239462Sdim  /// getSchedModelForCPU - Get the machine model of a CPU.
87239462Sdim  ///
88243830Sdim  const MCSchedModel *getSchedModelForCPU(StringRef CPU) const;
89239462Sdim
90243830Sdim  /// getSchedModel - Get the machine model for this subtarget's CPU.
91243830Sdim  ///
92243830Sdim  const MCSchedModel *getSchedModel() const { return CPUSchedModel; }
93243830Sdim
94243830Sdim  /// Return an iterator at the first process resource consumed by the given
95243830Sdim  /// scheduling class.
96243830Sdim  const MCWriteProcResEntry *getWriteProcResBegin(
97243830Sdim    const MCSchedClassDesc *SC) const {
98243830Sdim    return &WriteProcResTable[SC->WriteProcResIdx];
99243830Sdim  }
100243830Sdim  const MCWriteProcResEntry *getWriteProcResEnd(
101243830Sdim    const MCSchedClassDesc *SC) const {
102243830Sdim    return getWriteProcResBegin(SC) + SC->NumWriteProcResEntries;
103243830Sdim  }
104243830Sdim
105243830Sdim  const MCWriteLatencyEntry *getWriteLatencyEntry(const MCSchedClassDesc *SC,
106243830Sdim                                                  unsigned DefIdx) const {
107243830Sdim    assert(DefIdx < SC->NumWriteLatencyEntries &&
108243830Sdim           "MachineModel does not specify a WriteResource for DefIdx");
109243830Sdim
110243830Sdim    return &WriteLatencyTable[SC->WriteLatencyIdx + DefIdx];
111243830Sdim  }
112243830Sdim
113243830Sdim  int getReadAdvanceCycles(const MCSchedClassDesc *SC, unsigned UseIdx,
114243830Sdim                           unsigned WriteResID) const {
115243830Sdim    // TODO: The number of read advance entries in a class can be significant
116243830Sdim    // (~50). Consider compressing the WriteID into a dense ID of those that are
117243830Sdim    // used by ReadAdvance and representing them as a bitset.
118243830Sdim    for (const MCReadAdvanceEntry *I = &ReadAdvanceTable[SC->ReadAdvanceIdx],
119243830Sdim           *E = I + SC->NumReadAdvanceEntries; I != E; ++I) {
120243830Sdim      if (I->UseIdx < UseIdx)
121243830Sdim        continue;
122243830Sdim      if (I->UseIdx > UseIdx)
123243830Sdim        break;
124243830Sdim      // Find the first WriteResIdx match, which has the highest cycle count.
125243830Sdim      if (!I->WriteResourceID || I->WriteResourceID == WriteResID) {
126243830Sdim        return I->Cycles;
127243830Sdim      }
128243830Sdim    }
129243830Sdim    return 0;
130243830Sdim  }
131243830Sdim
132224133Sdim  /// getInstrItineraryForCPU - Get scheduling itinerary of a CPU.
133224133Sdim  ///
134224133Sdim  InstrItineraryData getInstrItineraryForCPU(StringRef CPU) const;
135243830Sdim
136243830Sdim  /// Initialize an InstrItineraryData instance.
137243830Sdim  void initInstrItins(InstrItineraryData &InstrItins) const;
138224133Sdim};
139224133Sdim
140224133Sdim} // End llvm namespace
141224133Sdim
142224133Sdim#endif
143