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
17de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/ADT/ArrayRef.h"
1894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng#include "llvm/MC/MCInstrItineraries.h"
19255f89faee13dc491cb64fbeae3c763e7e2ea4e6Chandler Carruth#include "llvm/MC/SubtargetFeature.h"
2059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng#include <string>
2194214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
2294214703d97d8d9dfca88174ffc7e94820a85e62Evan Chengnamespace llvm {
2394214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
2494214703d97d8d9dfca88174ffc7e94820a85e62Evan Chengclass StringRef;
2594214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
2694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng//===----------------------------------------------------------------------===//
2794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng///
2894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng/// MCSubtargetInfo - Generic base class for all target subtargets.
2994214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng///
3094214703d97d8d9dfca88174ffc7e94820a85e62Evan Chengclass MCSubtargetInfo {
316948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  Triple TargetTriple;                        // Target triple
32ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  std::string CPU; // CPU being targeted.
33dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  ArrayRef<SubtargetFeatureKV> ProcFeatures;  // Processor feature list
34dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  ArrayRef<SubtargetFeatureKV> ProcDesc;  // Processor descriptions
3572d048b69705f01d48bdef7b235ec96b24290767Andrew Trick
3672d048b69705f01d48bdef7b235ec96b24290767Andrew Trick  // Scheduler machine model
3772d048b69705f01d48bdef7b235ec96b24290767Andrew Trick  const SubtargetInfoKV *ProcSchedModels;
3872d048b69705f01d48bdef7b235ec96b24290767Andrew Trick  const MCWriteProcResEntry *WriteProcResTable;
3972d048b69705f01d48bdef7b235ec96b24290767Andrew Trick  const MCWriteLatencyEntry *WriteLatencyTable;
4072d048b69705f01d48bdef7b235ec96b24290767Andrew Trick  const MCReadAdvanceEntry *ReadAdvanceTable;
41f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const MCSchedModel *CPUSchedModel;
4272d048b69705f01d48bdef7b235ec96b24290767Andrew Trick
432661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick  const InstrStage *Stages;            // Instruction itinerary stages
442661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick  const unsigned *OperandCycles;       // Itinerary operand cycles
45a11a6287a504d1d7503e744d14314df1e696f506Andrew Trick  const unsigned *ForwardingPaths;     // Forwarding paths
466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  FeatureBitset FeatureBits;           // Feature bits for current CPU + FS
470ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng
48f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  MCSubtargetInfo() = delete;
49f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  MCSubtargetInfo &operator=(MCSubtargetInfo &&) = delete;
50f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  MCSubtargetInfo &operator=(const MCSubtargetInfo &) = delete;
51f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
5294214703d97d8d9dfca88174ffc7e94820a85e62Evan Chengpublic:
53f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  MCSubtargetInfo(const MCSubtargetInfo &) = default;
54f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  MCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS,
55f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                  ArrayRef<SubtargetFeatureKV> PF,
56f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                  ArrayRef<SubtargetFeatureKV> PD,
57f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                  const SubtargetInfoKV *ProcSched,
58f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                  const MCWriteProcResEntry *WPR, const MCWriteLatencyEntry *WL,
59f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                  const MCReadAdvanceEntry *RA, const InstrStage *IS,
60f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                  const unsigned *OC, const unsigned *FP);
610ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng
6259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  /// getTargetTriple - Return the target triple string.
636948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  const Triple &getTargetTriple() const { return TargetTriple; }
6459ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng
65ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  /// getCPU - Return the CPU string.
66ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  StringRef getCPU() const {
67ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return CPU;
68ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
69ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
7059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  /// getFeatureBits - Return the feature bits.
710ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng  ///
726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  const FeatureBitset& getFeatureBits() const {
730ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng    return FeatureBits;
7494214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  }
7594214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
7637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  /// setFeatureBits - Set the feature bits.
7737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  ///
786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  void setFeatureBits(const FeatureBitset &FeatureBits_) {
796948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    FeatureBits = FeatureBits_;
806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  }
8137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
82f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarprotected:
83f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  /// Initialize the scheduling model and feature bits.
84f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  ///
85f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  /// FIXME: Find a way to stick this in the constructor, since it should only
86f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  /// be called during initialization.
8734aadd63346b5f9b98749a306b71fcb00ee6996fAndrew Trick  void InitMCProcessorInfo(StringRef CPU, StringRef FS);
880ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng
89f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarpublic:
90f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  /// Set the features to the default for the given CPU with an appended feature
91f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  /// string.
92f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  void setDefaultFeatures(StringRef CPU, StringRef FS);
93773c07606e61c5090d73ea1317a0d1b0c29ec023Craig Topper
94ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  /// ToggleFeature - Toggle a feature and returns the re-computed feature
95ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  /// bits. This version does not change the implied bits.
966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  FeatureBitset ToggleFeature(uint64_t FB);
97ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng
98ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  /// ToggleFeature - Toggle a feature and returns the re-computed feature
996948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  /// bits. This version does not change the implied bits.
1006948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  FeatureBitset ToggleFeature(const FeatureBitset& FB);
1016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
1026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  /// ToggleFeature - Toggle a set of features and returns the re-computed
1036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  /// feature bits. This version will also change all implied bits.
1046948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  FeatureBitset ToggleFeature(StringRef FS);
1056948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
1066948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  /// Apply a feature flag and return the re-computed feature bits, including
1076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  /// all feature bits implied by the flag.
1086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  FeatureBitset ApplyFeatureFlag(StringRef FS);
109ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng
1102661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick  /// getSchedModelForCPU - Get the machine model of a CPU.
1112661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick  ///
112f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const MCSchedModel &getSchedModelForCPU(StringRef CPU) const;
1132661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick
114f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  /// Get the machine model for this subtarget's CPU.
115f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const MCSchedModel &getSchedModel() const { return *CPUSchedModel; }
116e127dfd0b175b5a336e61fecaad7fc2aec65d95cAndrew Trick
11772d048b69705f01d48bdef7b235ec96b24290767Andrew Trick  /// Return an iterator at the first process resource consumed by the given
11872d048b69705f01d48bdef7b235ec96b24290767Andrew Trick  /// scheduling class.
11972d048b69705f01d48bdef7b235ec96b24290767Andrew Trick  const MCWriteProcResEntry *getWriteProcResBegin(
12072d048b69705f01d48bdef7b235ec96b24290767Andrew Trick    const MCSchedClassDesc *SC) const {
12172d048b69705f01d48bdef7b235ec96b24290767Andrew Trick    return &WriteProcResTable[SC->WriteProcResIdx];
12272d048b69705f01d48bdef7b235ec96b24290767Andrew Trick  }
12372d048b69705f01d48bdef7b235ec96b24290767Andrew Trick  const MCWriteProcResEntry *getWriteProcResEnd(
12472d048b69705f01d48bdef7b235ec96b24290767Andrew Trick    const MCSchedClassDesc *SC) const {
12572d048b69705f01d48bdef7b235ec96b24290767Andrew Trick    return getWriteProcResBegin(SC) + SC->NumWriteProcResEntries;
12672d048b69705f01d48bdef7b235ec96b24290767Andrew Trick  }
12772d048b69705f01d48bdef7b235ec96b24290767Andrew Trick
12872d048b69705f01d48bdef7b235ec96b24290767Andrew Trick  const MCWriteLatencyEntry *getWriteLatencyEntry(const MCSchedClassDesc *SC,
12972d048b69705f01d48bdef7b235ec96b24290767Andrew Trick                                                  unsigned DefIdx) const {
13072d048b69705f01d48bdef7b235ec96b24290767Andrew Trick    assert(DefIdx < SC->NumWriteLatencyEntries &&
13172d048b69705f01d48bdef7b235ec96b24290767Andrew Trick           "MachineModel does not specify a WriteResource for DefIdx");
13272d048b69705f01d48bdef7b235ec96b24290767Andrew Trick
13372d048b69705f01d48bdef7b235ec96b24290767Andrew Trick    return &WriteLatencyTable[SC->WriteLatencyIdx + DefIdx];
13472d048b69705f01d48bdef7b235ec96b24290767Andrew Trick  }
13572d048b69705f01d48bdef7b235ec96b24290767Andrew Trick
13672d048b69705f01d48bdef7b235ec96b24290767Andrew Trick  int getReadAdvanceCycles(const MCSchedClassDesc *SC, unsigned UseIdx,
13772d048b69705f01d48bdef7b235ec96b24290767Andrew Trick                           unsigned WriteResID) const {
13885c7b6108f8c8cea77d0bce30343f736f6c15981Andrew Trick    // TODO: The number of read advance entries in a class can be significant
13985c7b6108f8c8cea77d0bce30343f736f6c15981Andrew Trick    // (~50). Consider compressing the WriteID into a dense ID of those that are
14085c7b6108f8c8cea77d0bce30343f736f6c15981Andrew Trick    // used by ReadAdvance and representing them as a bitset.
14172d048b69705f01d48bdef7b235ec96b24290767Andrew Trick    for (const MCReadAdvanceEntry *I = &ReadAdvanceTable[SC->ReadAdvanceIdx],
14272d048b69705f01d48bdef7b235ec96b24290767Andrew Trick           *E = I + SC->NumReadAdvanceEntries; I != E; ++I) {
14372d048b69705f01d48bdef7b235ec96b24290767Andrew Trick      if (I->UseIdx < UseIdx)
14472d048b69705f01d48bdef7b235ec96b24290767Andrew Trick        continue;
14572d048b69705f01d48bdef7b235ec96b24290767Andrew Trick      if (I->UseIdx > UseIdx)
14672d048b69705f01d48bdef7b235ec96b24290767Andrew Trick        break;
14772d048b69705f01d48bdef7b235ec96b24290767Andrew Trick      // Find the first WriteResIdx match, which has the highest cycle count.
14872d048b69705f01d48bdef7b235ec96b24290767Andrew Trick      if (!I->WriteResourceID || I->WriteResourceID == WriteResID) {
14972d048b69705f01d48bdef7b235ec96b24290767Andrew Trick        return I->Cycles;
15072d048b69705f01d48bdef7b235ec96b24290767Andrew Trick      }
15172d048b69705f01d48bdef7b235ec96b24290767Andrew Trick    }
15272d048b69705f01d48bdef7b235ec96b24290767Andrew Trick    return 0;
15372d048b69705f01d48bdef7b235ec96b24290767Andrew Trick  }
15472d048b69705f01d48bdef7b235ec96b24290767Andrew Trick
15594214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  /// getInstrItineraryForCPU - Get scheduling itinerary of a CPU.
15694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  ///
15794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  InstrItineraryData getInstrItineraryForCPU(StringRef CPU) const;
15899ab6c6035aec3c0e9b0cc5b76a4666fc5fd7b7bAndrew Trick
15999ab6c6035aec3c0e9b0cc5b76a4666fc5fd7b7bAndrew Trick  /// Initialize an InstrItineraryData instance.
16099ab6c6035aec3c0e9b0cc5b76a4666fc5fd7b7bAndrew Trick  void initInstrItins(InstrItineraryData &InstrItins) const;
161ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
162ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  /// Check whether the CPU string is valid.
163f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool isCPUStringValid(StringRef CPU) const {
164f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    auto Found = std::lower_bound(ProcDesc.begin(), ProcDesc.end(), CPU);
165f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return Found != ProcDesc.end() && StringRef(Found->Key) == CPU;
166ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
16794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng};
16894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
16994214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng} // End llvm namespace
17094214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
17194214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng#endif
172