194214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng//===-- MCSubtargetInfo.cpp - Subtarget Information -----------------------===//
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#include "llvm/MC/MCSubtargetInfo.h"
1194214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng#include "llvm/ADT/StringRef.h"
1259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng#include "llvm/ADT/Triple.h"
13d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCInstrItineraries.h"
14d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/SubtargetFeature.h"
1594214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng#include "llvm/Support/raw_ostream.h"
1694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng#include <algorithm>
1794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
1894214703d97d8d9dfca88174ffc7e94820a85e62Evan Chengusing namespace llvm;
1994214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
202661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew TrickMCSchedModel MCSchedModel::DefaultSchedModel; // For unknown processors.
212661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick
228e8f8724e17182b8faddd6b009e7f037e0b908e7Craig Topper/// InitMCProcessorInfo - Set or change the CPU (optionally supplemented
2334aadd63346b5f9b98749a306b71fcb00ee6996fAndrew Trick/// with feature string). Recompute feature bits and scheduling model.
2434aadd63346b5f9b98749a306b71fcb00ee6996fAndrew Trickvoid
2534aadd63346b5f9b98749a306b71fcb00ee6996fAndrew TrickMCSubtargetInfo::InitMCProcessorInfo(StringRef CPU, StringRef FS) {
2634aadd63346b5f9b98749a306b71fcb00ee6996fAndrew Trick  SubtargetFeatures Features(FS);
27dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  FeatureBits = Features.getFeatureBits(CPU, ProcDesc, ProcFeatures);
28773c07606e61c5090d73ea1317a0d1b0c29ec023Craig Topper  InitCPUSchedModel(CPU);
29773c07606e61c5090d73ea1317a0d1b0c29ec023Craig Topper}
30773c07606e61c5090d73ea1317a0d1b0c29ec023Craig Topper
31773c07606e61c5090d73ea1317a0d1b0c29ec023Craig Toppervoid
32773c07606e61c5090d73ea1317a0d1b0c29ec023Craig TopperMCSubtargetInfo::InitCPUSchedModel(StringRef CPU) {
3334aadd63346b5f9b98749a306b71fcb00ee6996fAndrew Trick  if (!CPU.empty())
3434aadd63346b5f9b98749a306b71fcb00ee6996fAndrew Trick    CPUSchedModel = getSchedModelForCPU(CPU);
3534aadd63346b5f9b98749a306b71fcb00ee6996fAndrew Trick  else
3634aadd63346b5f9b98749a306b71fcb00ee6996fAndrew Trick    CPUSchedModel = &MCSchedModel::DefaultSchedModel;
3734aadd63346b5f9b98749a306b71fcb00ee6996fAndrew Trick}
3834aadd63346b5f9b98749a306b71fcb00ee6996fAndrew Trick
3959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Chengvoid
4059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan ChengMCSubtargetInfo::InitMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS,
41dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                     ArrayRef<SubtargetFeatureKV> PF,
42dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                     ArrayRef<SubtargetFeatureKV> PD,
432661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick                                     const SubtargetInfoKV *ProcSched,
44e127dfd0b175b5a336e61fecaad7fc2aec65d95cAndrew Trick                                     const MCWriteProcResEntry *WPR,
45e127dfd0b175b5a336e61fecaad7fc2aec65d95cAndrew Trick                                     const MCWriteLatencyEntry *WL,
46e127dfd0b175b5a336e61fecaad7fc2aec65d95cAndrew Trick                                     const MCReadAdvanceEntry *RA,
4759ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng                                     const InstrStage *IS,
4859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng                                     const unsigned *OC,
49dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                     const unsigned *FP) {
5059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  TargetTriple = TT;
510ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng  ProcFeatures = PF;
520ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng  ProcDesc = PD;
5372d048b69705f01d48bdef7b235ec96b24290767Andrew Trick  ProcSchedModels = ProcSched;
54e127dfd0b175b5a336e61fecaad7fc2aec65d95cAndrew Trick  WriteProcResTable = WPR;
55e127dfd0b175b5a336e61fecaad7fc2aec65d95cAndrew Trick  WriteLatencyTable = WL;
56e127dfd0b175b5a336e61fecaad7fc2aec65d95cAndrew Trick  ReadAdvanceTable = RA;
57e127dfd0b175b5a336e61fecaad7fc2aec65d95cAndrew Trick
580ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng  Stages = IS;
590ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng  OperandCycles = OC;
60a11a6287a504d1d7503e744d14314df1e696f506Andrew Trick  ForwardingPaths = FP;
610ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng
6234aadd63346b5f9b98749a306b71fcb00ee6996fAndrew Trick  InitMCProcessorInfo(CPU, FS);
630ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng}
640ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng
65ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng/// ToggleFeature - Toggle a feature and returns the re-computed feature
66ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng/// bits. This version does not change the implied bits.
67ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Chenguint64_t MCSubtargetInfo::ToggleFeature(uint64_t FB) {
68ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  FeatureBits ^= FB;
69ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  return FeatureBits;
70ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng}
71ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng
72ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng/// ToggleFeature - Toggle a feature and returns the re-computed feature
73ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng/// bits. This version will also change all implied bits.
74ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Chenguint64_t MCSubtargetInfo::ToggleFeature(StringRef FS) {
75ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  SubtargetFeatures Features;
76dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  FeatureBits = Features.ToggleFeature(FeatureBits, FS, ProcFeatures);
77ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  return FeatureBits;
78ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng}
79ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng
80ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng
8198eb98b0f2e6573f5aee67ce3e75624392d637b7Roman Divackyconst MCSchedModel *
822661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew TrickMCSubtargetInfo::getSchedModelForCPU(StringRef CPU) const {
8372d048b69705f01d48bdef7b235ec96b24290767Andrew Trick  assert(ProcSchedModels && "Processor machine model not available!");
8494214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
85dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned NumProcs = ProcDesc.size();
8694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng#ifndef NDEBUG
8794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  for (size_t i = 1; i < NumProcs; i++) {
8872d048b69705f01d48bdef7b235ec96b24290767Andrew Trick    assert(strcmp(ProcSchedModels[i - 1].Key, ProcSchedModels[i].Key) < 0 &&
892661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick           "Processor machine model table is not sorted");
9094214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  }
9194214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng#endif
9294214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
9394214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  // Find entry
9494214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  const SubtargetInfoKV *Found =
954df7c5baa1dfe2d9de7eef2600c9ac325e9fdcd6Will Dietz    std::lower_bound(ProcSchedModels, ProcSchedModels+NumProcs, CPU);
9672d048b69705f01d48bdef7b235ec96b24290767Andrew Trick  if (Found == ProcSchedModels+NumProcs || StringRef(Found->Key) != CPU) {
9794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng    errs() << "'" << CPU
9894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng           << "' is not a recognized processor for this target"
9994214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng           << " (ignoring processor)\n";
1002661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick    return &MCSchedModel::DefaultSchedModel;
10194214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  }
1022661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick  assert(Found->Value && "Missing processor SchedModel value");
10398eb98b0f2e6573f5aee67ce3e75624392d637b7Roman Divacky  return (const MCSchedModel *)Found->Value;
1042661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick}
10594214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
1062661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew TrickInstrItineraryData
1072661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew TrickMCSubtargetInfo::getInstrItineraryForCPU(StringRef CPU) const {
10898eb98b0f2e6573f5aee67ce3e75624392d637b7Roman Divacky  const MCSchedModel *SchedModel = getSchedModelForCPU(CPU);
1092661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick  return InstrItineraryData(SchedModel, Stages, OperandCycles, ForwardingPaths);
11094214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng}
11199ab6c6035aec3c0e9b0cc5b76a4666fc5fd7b7bAndrew Trick
11299ab6c6035aec3c0e9b0cc5b76a4666fc5fd7b7bAndrew Trick/// Initialize an InstrItineraryData instance.
11399ab6c6035aec3c0e9b0cc5b76a4666fc5fd7b7bAndrew Trickvoid MCSubtargetInfo::initInstrItins(InstrItineraryData &InstrItins) const {
11499ab6c6035aec3c0e9b0cc5b76a4666fc5fd7b7bAndrew Trick  InstrItins =
11534301ceca8913f3126339f332d3dc6f2d7ac0d78Andrew Trick    InstrItineraryData(CPUSchedModel, Stages, OperandCycles, ForwardingPaths);
11699ab6c6035aec3c0e9b0cc5b76a4666fc5fd7b7bAndrew Trick}
117