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/MC/MCInstrItineraries.h"
1294214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng#include "llvm/MC/SubtargetFeature.h"
1394214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng#include "llvm/ADT/StringRef.h"
1459ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng#include "llvm/ADT/Triple.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
2259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Chengvoid
2359ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan ChengMCSubtargetInfo::InitMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS,
2459ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng                                     const SubtargetFeatureKV *PF,
2559ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng                                     const SubtargetFeatureKV *PD,
262661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick                                     const SubtargetInfoKV *ProcSched,
2759ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng                                     const InstrStage *IS,
2859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng                                     const unsigned *OC,
2959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng                                     const unsigned *FP,
3059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng                                     unsigned NF, unsigned NP) {
3159ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  TargetTriple = TT;
320ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng  ProcFeatures = PF;
330ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng  ProcDesc = PD;
342661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick  ProcSchedModel = ProcSched;
350ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng  Stages = IS;
360ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng  OperandCycles = OC;
37a11a6287a504d1d7503e744d14314df1e696f506Andrew Trick  ForwardingPaths = FP;
380ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng  NumFeatures = NF;
390ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng  NumProcs = NP;
400ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng
410ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng  SubtargetFeatures Features(FS);
420ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng  FeatureBits = Features.getFeatureBits(CPU, ProcDesc, NumProcs,
430ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng                                        ProcFeatures, NumFeatures);
440ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng}
450ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng
460ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng
470ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng/// ReInitMCSubtargetInfo - Change CPU (and optionally supplemented with
480ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng/// feature string) and recompute feature bits.
490ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Chenguint64_t MCSubtargetInfo::ReInitMCSubtargetInfo(StringRef CPU, StringRef FS) {
500ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng  SubtargetFeatures Features(FS);
510ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng  FeatureBits = Features.getFeatureBits(CPU, ProcDesc, NumProcs,
520ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng                                        ProcFeatures, NumFeatures);
530ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng  return FeatureBits;
540ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng}
550ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng
56ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng/// ToggleFeature - Toggle a feature and returns the re-computed feature
57ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng/// bits. This version does not change the implied bits.
58ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Chenguint64_t MCSubtargetInfo::ToggleFeature(uint64_t FB) {
59ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  FeatureBits ^= FB;
60ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  return FeatureBits;
61ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng}
62ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng
63ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng/// ToggleFeature - Toggle a feature and returns the re-computed feature
64ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng/// bits. This version will also change all implied bits.
65ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Chenguint64_t MCSubtargetInfo::ToggleFeature(StringRef FS) {
66ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  SubtargetFeatures Features;
67ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  FeatureBits = Features.ToggleFeature(FeatureBits, FS,
68ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng                                       ProcFeatures, NumFeatures);
69ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  return FeatureBits;
70ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng}
71ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng
72ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng
7398eb98b0f2e6573f5aee67ce3e75624392d637b7Roman Divackyconst MCSchedModel *
742661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew TrickMCSubtargetInfo::getSchedModelForCPU(StringRef CPU) const {
752661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick  assert(ProcSchedModel && "Processor machine model not available!");
7694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
7794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng#ifndef NDEBUG
7894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  for (size_t i = 1; i < NumProcs; i++) {
792661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick    assert(strcmp(ProcSchedModel[i - 1].Key, ProcSchedModel[i].Key) < 0 &&
802661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick           "Processor machine model table is not sorted");
8194214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  }
8294214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng#endif
8394214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
8494214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  // Find entry
8594214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  SubtargetInfoKV KV;
8694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  KV.Key = CPU.data();
8794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  const SubtargetInfoKV *Found =
882661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick    std::lower_bound(ProcSchedModel, ProcSchedModel+NumProcs, KV);
892661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick  if (Found == ProcSchedModel+NumProcs || StringRef(Found->Key) != CPU) {
9094214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng    errs() << "'" << CPU
9194214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng           << "' is not a recognized processor for this target"
9294214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng           << " (ignoring processor)\n";
932661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick    return &MCSchedModel::DefaultSchedModel;
9494214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  }
952661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick  assert(Found->Value && "Missing processor SchedModel value");
9698eb98b0f2e6573f5aee67ce3e75624392d637b7Roman Divacky  return (const MCSchedModel *)Found->Value;
972661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick}
9894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
992661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew TrickInstrItineraryData
1002661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew TrickMCSubtargetInfo::getInstrItineraryForCPU(StringRef CPU) const {
10198eb98b0f2e6573f5aee67ce3e75624392d637b7Roman Divacky  const MCSchedModel *SchedModel = getSchedModelForCPU(CPU);
1022661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick  return InstrItineraryData(SchedModel, Stages, OperandCycles, ForwardingPaths);
10394214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng}
104