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