194214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng//==-- llvm/MC/MCSubtargetInfo.h - Subtarget Information ---------*- C++ -*-==//
294214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng//
394214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng//                     The LLVM Compiler Infrastructure
494214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng//
594214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng// This file is distributed under the University of Illinois Open Source
694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng// License. See LICENSE.TXT for details.
794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng//
894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng//===----------------------------------------------------------------------===//
994214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng//
1094214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng// This file describes the subtarget options of a Target machine.
1194214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng//
1294214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng//===----------------------------------------------------------------------===//
1394214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
1437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#ifndef LLVM_MC_MCSUBTARGETINFO_H
1537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#define LLVM_MC_MCSUBTARGETINFO_H
1694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
1794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng#include "llvm/MC/MCInstrItineraries.h"
18255f89faee13dc491cb64fbeae3c763e7e2ea4e6Chandler Carruth#include "llvm/MC/SubtargetFeature.h"
1959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng#include <string>
2094214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
2194214703d97d8d9dfca88174ffc7e94820a85e62Evan Chengnamespace llvm {
2294214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
2394214703d97d8d9dfca88174ffc7e94820a85e62Evan Chengclass StringRef;
2494214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
2594214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng//===----------------------------------------------------------------------===//
2694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng///
2794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng/// MCSubtargetInfo - Generic base class for all target subtargets.
2894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng///
2994214703d97d8d9dfca88174ffc7e94820a85e62Evan Chengclass MCSubtargetInfo {
3059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  std::string TargetTriple;            // Target triple
31ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  std::string CPU; // CPU being targeted.
32dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  ArrayRef<SubtargetFeatureKV> ProcFeatures;  // Processor feature list
33dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  ArrayRef<SubtargetFeatureKV> ProcDesc;  // Processor descriptions
3472d048b69705f01d48bdef7b235ec96b24290767Andrew Trick
3572d048b69705f01d48bdef7b235ec96b24290767Andrew Trick  // Scheduler machine model
3672d048b69705f01d48bdef7b235ec96b24290767Andrew Trick  const SubtargetInfoKV *ProcSchedModels;
3772d048b69705f01d48bdef7b235ec96b24290767Andrew Trick  const MCWriteProcResEntry *WriteProcResTable;
3872d048b69705f01d48bdef7b235ec96b24290767Andrew Trick  const MCWriteLatencyEntry *WriteLatencyTable;
3972d048b69705f01d48bdef7b235ec96b24290767Andrew Trick  const MCReadAdvanceEntry *ReadAdvanceTable;
4037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCSchedModel CPUSchedModel;
4172d048b69705f01d48bdef7b235ec96b24290767Andrew Trick
422661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick  const InstrStage *Stages;            // Instruction itinerary stages
432661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick  const unsigned *OperandCycles;       // Itinerary operand cycles
44a11a6287a504d1d7503e744d14314df1e696f506Andrew Trick  const unsigned *ForwardingPaths;     // Forwarding paths
45ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  uint64_t FeatureBits;                // Feature bits for current CPU + FS
460ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng
4794214703d97d8d9dfca88174ffc7e94820a85e62Evan Chengpublic:
4859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  void InitMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS,
49dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                           ArrayRef<SubtargetFeatureKV> PF,
50dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                           ArrayRef<SubtargetFeatureKV> PD,
512661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick                           const SubtargetInfoKV *ProcSched,
52e127dfd0b175b5a336e61fecaad7fc2aec65d95cAndrew Trick                           const MCWriteProcResEntry *WPR,
53e127dfd0b175b5a336e61fecaad7fc2aec65d95cAndrew Trick                           const MCWriteLatencyEntry *WL,
54e127dfd0b175b5a336e61fecaad7fc2aec65d95cAndrew Trick                           const MCReadAdvanceEntry *RA,
552661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick                           const InstrStage *IS,
56dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                           const unsigned *OC, const unsigned *FP);
570ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng
5859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  /// getTargetTriple - Return the target triple string.
5959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  StringRef getTargetTriple() const {
6059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng    return TargetTriple;
6159ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  }
6259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng
63ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  /// getCPU - Return the CPU string.
64ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  StringRef getCPU() const {
65ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return CPU;
66ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
67ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
6859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  /// getFeatureBits - Return the feature bits.
690ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng  ///
700ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng  uint64_t getFeatureBits() const {
710ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng    return FeatureBits;
7294214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  }
7394214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
7437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  /// setFeatureBits - Set the feature bits.
7537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  ///
7637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  void setFeatureBits(uint64_t FeatureBits_) { FeatureBits = FeatureBits_; }
7737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
7834aadd63346b5f9b98749a306b71fcb00ee6996fAndrew Trick  /// InitMCProcessorInfo - Set or change the CPU (optionally supplemented with
7934aadd63346b5f9b98749a306b71fcb00ee6996fAndrew Trick  /// feature string). Recompute feature bits and scheduling model.
8034aadd63346b5f9b98749a306b71fcb00ee6996fAndrew Trick  void InitMCProcessorInfo(StringRef CPU, StringRef FS);
810ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng
82773c07606e61c5090d73ea1317a0d1b0c29ec023Craig Topper  /// InitCPUSchedModel - Recompute scheduling model based on CPU.
83773c07606e61c5090d73ea1317a0d1b0c29ec023Craig Topper  void InitCPUSchedModel(StringRef CPU);
84773c07606e61c5090d73ea1317a0d1b0c29ec023Craig Topper
85ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  /// ToggleFeature - Toggle a feature and returns the re-computed feature
86ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  /// bits. This version does not change the implied bits.
87ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  uint64_t ToggleFeature(uint64_t FB);
88ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng
89ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  /// ToggleFeature - Toggle a feature and returns the re-computed feature
90ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  /// bits. This version will also change all implied bits.
91ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  uint64_t ToggleFeature(StringRef FS);
92ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng
932661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick  /// getSchedModelForCPU - Get the machine model of a CPU.
942661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick  ///
9537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCSchedModel getSchedModelForCPU(StringRef CPU) const;
962661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick
97e127dfd0b175b5a336e61fecaad7fc2aec65d95cAndrew Trick  /// getSchedModel - Get the machine model for this subtarget's CPU.
98e127dfd0b175b5a336e61fecaad7fc2aec65d95cAndrew Trick  ///
9937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const MCSchedModel &getSchedModel() const { return CPUSchedModel; }
100e127dfd0b175b5a336e61fecaad7fc2aec65d95cAndrew Trick
10172d048b69705f01d48bdef7b235ec96b24290767Andrew Trick  /// Return an iterator at the first process resource consumed by the given
10272d048b69705f01d48bdef7b235ec96b24290767Andrew Trick  /// scheduling class.
10372d048b69705f01d48bdef7b235ec96b24290767Andrew Trick  const MCWriteProcResEntry *getWriteProcResBegin(
10472d048b69705f01d48bdef7b235ec96b24290767Andrew Trick    const MCSchedClassDesc *SC) const {
10572d048b69705f01d48bdef7b235ec96b24290767Andrew Trick    return &WriteProcResTable[SC->WriteProcResIdx];
10672d048b69705f01d48bdef7b235ec96b24290767Andrew Trick  }
10772d048b69705f01d48bdef7b235ec96b24290767Andrew Trick  const MCWriteProcResEntry *getWriteProcResEnd(
10872d048b69705f01d48bdef7b235ec96b24290767Andrew Trick    const MCSchedClassDesc *SC) const {
10972d048b69705f01d48bdef7b235ec96b24290767Andrew Trick    return getWriteProcResBegin(SC) + SC->NumWriteProcResEntries;
11072d048b69705f01d48bdef7b235ec96b24290767Andrew Trick  }
11172d048b69705f01d48bdef7b235ec96b24290767Andrew Trick
11272d048b69705f01d48bdef7b235ec96b24290767Andrew Trick  const MCWriteLatencyEntry *getWriteLatencyEntry(const MCSchedClassDesc *SC,
11372d048b69705f01d48bdef7b235ec96b24290767Andrew Trick                                                  unsigned DefIdx) const {
11472d048b69705f01d48bdef7b235ec96b24290767Andrew Trick    assert(DefIdx < SC->NumWriteLatencyEntries &&
11572d048b69705f01d48bdef7b235ec96b24290767Andrew Trick           "MachineModel does not specify a WriteResource for DefIdx");
11672d048b69705f01d48bdef7b235ec96b24290767Andrew Trick
11772d048b69705f01d48bdef7b235ec96b24290767Andrew Trick    return &WriteLatencyTable[SC->WriteLatencyIdx + DefIdx];
11872d048b69705f01d48bdef7b235ec96b24290767Andrew Trick  }
11972d048b69705f01d48bdef7b235ec96b24290767Andrew Trick
12072d048b69705f01d48bdef7b235ec96b24290767Andrew Trick  int getReadAdvanceCycles(const MCSchedClassDesc *SC, unsigned UseIdx,
12172d048b69705f01d48bdef7b235ec96b24290767Andrew Trick                           unsigned WriteResID) const {
12285c7b6108f8c8cea77d0bce30343f736f6c15981Andrew Trick    // TODO: The number of read advance entries in a class can be significant
12385c7b6108f8c8cea77d0bce30343f736f6c15981Andrew Trick    // (~50). Consider compressing the WriteID into a dense ID of those that are
12485c7b6108f8c8cea77d0bce30343f736f6c15981Andrew Trick    // used by ReadAdvance and representing them as a bitset.
12572d048b69705f01d48bdef7b235ec96b24290767Andrew Trick    for (const MCReadAdvanceEntry *I = &ReadAdvanceTable[SC->ReadAdvanceIdx],
12672d048b69705f01d48bdef7b235ec96b24290767Andrew Trick           *E = I + SC->NumReadAdvanceEntries; I != E; ++I) {
12772d048b69705f01d48bdef7b235ec96b24290767Andrew Trick      if (I->UseIdx < UseIdx)
12872d048b69705f01d48bdef7b235ec96b24290767Andrew Trick        continue;
12972d048b69705f01d48bdef7b235ec96b24290767Andrew Trick      if (I->UseIdx > UseIdx)
13072d048b69705f01d48bdef7b235ec96b24290767Andrew Trick        break;
13172d048b69705f01d48bdef7b235ec96b24290767Andrew Trick      // Find the first WriteResIdx match, which has the highest cycle count.
13272d048b69705f01d48bdef7b235ec96b24290767Andrew Trick      if (!I->WriteResourceID || I->WriteResourceID == WriteResID) {
13372d048b69705f01d48bdef7b235ec96b24290767Andrew Trick        return I->Cycles;
13472d048b69705f01d48bdef7b235ec96b24290767Andrew Trick      }
13572d048b69705f01d48bdef7b235ec96b24290767Andrew Trick    }
13672d048b69705f01d48bdef7b235ec96b24290767Andrew Trick    return 0;
13772d048b69705f01d48bdef7b235ec96b24290767Andrew Trick  }
13872d048b69705f01d48bdef7b235ec96b24290767Andrew Trick
13994214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  /// getInstrItineraryForCPU - Get scheduling itinerary of a CPU.
14094214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  ///
14194214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  InstrItineraryData getInstrItineraryForCPU(StringRef CPU) const;
14299ab6c6035aec3c0e9b0cc5b76a4666fc5fd7b7bAndrew Trick
14399ab6c6035aec3c0e9b0cc5b76a4666fc5fd7b7bAndrew Trick  /// Initialize an InstrItineraryData instance.
14499ab6c6035aec3c0e9b0cc5b76a4666fc5fd7b7bAndrew Trick  void initInstrItins(InstrItineraryData &InstrItins) const;
145ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
146ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  /// Check whether the CPU string is valid.
147ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  bool isCPUStringValid(StringRef CPU) {
148ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    auto Found = std::find_if(ProcDesc.begin(), ProcDesc.end(),
149ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                              [=](const SubtargetFeatureKV &KV) {
150ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                return CPU == KV.Key;
151ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                              });
152ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return Found != ProcDesc.end();
153ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
15494214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng};
15594214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
15694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng} // End llvm namespace
15794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
15894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng#endif
159