| Eugene Zelenko | 3d8b0eb | 2017-02-08 22:23:19 +0000 | [diff] [blame] | 1 | //===- MCSubtargetInfo.cpp - Subtarget Information ------------------------===// |
| Evan Cheng | 54b68e3 | 2011-07-01 20:45:01 +0000 | [diff] [blame] | 2 | // |
| Chandler Carruth | 2946cd7 | 2019-01-19 08:50:56 +0000 | [diff] [blame] | 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| Evan Cheng | 54b68e3 | 2011-07-01 20:45:01 +0000 | [diff] [blame] | 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | |
| Chandler Carruth | 6bda14b | 2017-06-06 11:49:48 +0000 | [diff] [blame] | 9 | #include "llvm/MC/MCSubtargetInfo.h" |
| Eugene Zelenko | 3d8b0eb | 2017-02-08 22:23:19 +0000 | [diff] [blame] | 10 | #include "llvm/ADT/ArrayRef.h" |
| Evan Cheng | 54b68e3 | 2011-07-01 20:45:01 +0000 | [diff] [blame] | 11 | #include "llvm/ADT/StringRef.h" |
| Chandler Carruth | ed0881b | 2012-12-03 16:50:05 +0000 | [diff] [blame] | 12 | #include "llvm/MC/MCInstrItineraries.h" |
| Eugene Zelenko | 3d8b0eb | 2017-02-08 22:23:19 +0000 | [diff] [blame] | 13 | #include "llvm/MC/MCSchedule.h" |
| Chandler Carruth | ed0881b | 2012-12-03 16:50:05 +0000 | [diff] [blame] | 14 | #include "llvm/MC/SubtargetFeature.h" |
| Evan Cheng | 54b68e3 | 2011-07-01 20:45:01 +0000 | [diff] [blame] | 15 | #include "llvm/Support/raw_ostream.h" |
| 16 | #include <algorithm> |
| Eugene Zelenko | 3d8b0eb | 2017-02-08 22:23:19 +0000 | [diff] [blame] | 17 | #include <cassert> |
| 18 | #include <cstring> |
| Evan Cheng | 54b68e3 | 2011-07-01 20:45:01 +0000 | [diff] [blame] | 19 | |
| 20 | using namespace llvm; |
| 21 | |
| Duncan P. N. Exon Smith | e463e47 | 2015-07-10 22:52:15 +0000 | [diff] [blame] | 22 | static FeatureBitset getFeatures(StringRef CPU, StringRef FS, |
| 23 | ArrayRef<SubtargetFeatureKV> ProcDesc, |
| 24 | ArrayRef<SubtargetFeatureKV> ProcFeatures) { |
| Andrew Trick | ba7b921 | 2012-09-18 05:33:15 +0000 | [diff] [blame] | 25 | SubtargetFeatures Features(FS); |
| Duncan P. N. Exon Smith | e463e47 | 2015-07-10 22:52:15 +0000 | [diff] [blame] | 26 | return Features.getFeatureBits(CPU, ProcDesc, ProcFeatures); |
| 27 | } |
| 28 | |
| 29 | void MCSubtargetInfo::InitMCProcessorInfo(StringRef CPU, StringRef FS) { |
| 30 | FeatureBits = getFeatures(CPU, FS, ProcDesc, ProcFeatures); |
| Andrew Trick | ba7b921 | 2012-09-18 05:33:15 +0000 | [diff] [blame] | 31 | if (!CPU.empty()) |
| Duncan P. N. Exon Smith | f862f87 | 2015-07-10 22:13:43 +0000 | [diff] [blame] | 32 | CPUSchedModel = &getSchedModelForCPU(CPU); |
| Andrew Trick | ba7b921 | 2012-09-18 05:33:15 +0000 | [diff] [blame] | 33 | else |
| Duncan P. N. Exon Smith | f862f87 | 2015-07-10 22:13:43 +0000 | [diff] [blame] | 34 | CPUSchedModel = &MCSchedModel::GetDefaultSchedModel(); |
| Andrew Trick | ba7b921 | 2012-09-18 05:33:15 +0000 | [diff] [blame] | 35 | } |
| 36 | |
| Bradley Smith | 323fee1 | 2015-11-16 11:10:19 +0000 | [diff] [blame] | 37 | void MCSubtargetInfo::setDefaultFeatures(StringRef CPU, StringRef FS) { |
| 38 | FeatureBits = getFeatures(CPU, FS, ProcDesc, ProcFeatures); |
| Duncan P. N. Exon Smith | e463e47 | 2015-07-10 22:52:15 +0000 | [diff] [blame] | 39 | } |
| 40 | |
| Duncan P. N. Exon Smith | 754e21f | 2015-07-10 22:43:42 +0000 | [diff] [blame] | 41 | MCSubtargetInfo::MCSubtargetInfo( |
| Daniel Sanders | 50f1723 | 2015-09-15 16:17:27 +0000 | [diff] [blame] | 42 | const Triple &TT, StringRef C, StringRef FS, |
| Daniel Sanders | a73f1fd | 2015-06-10 12:11:26 +0000 | [diff] [blame] | 43 | ArrayRef<SubtargetFeatureKV> PF, ArrayRef<SubtargetFeatureKV> PD, |
| 44 | const SubtargetInfoKV *ProcSched, const MCWriteProcResEntry *WPR, |
| 45 | const MCWriteLatencyEntry *WL, const MCReadAdvanceEntry *RA, |
| Duncan P. N. Exon Smith | 754e21f | 2015-07-10 22:43:42 +0000 | [diff] [blame] | 46 | const InstrStage *IS, const unsigned *OC, const unsigned *FP) |
| Daniel Sanders | 50f1723 | 2015-09-15 16:17:27 +0000 | [diff] [blame] | 47 | : TargetTriple(TT), CPU(C), ProcFeatures(PF), ProcDesc(PD), |
| Duncan P. N. Exon Smith | 754e21f | 2015-07-10 22:43:42 +0000 | [diff] [blame] | 48 | ProcSchedModels(ProcSched), WriteProcResTable(WPR), WriteLatencyTable(WL), |
| 49 | ReadAdvanceTable(RA), Stages(IS), OperandCycles(OC), ForwardingPaths(FP) { |
| Andrew Trick | ba7b921 | 2012-09-18 05:33:15 +0000 | [diff] [blame] | 50 | InitMCProcessorInfo(CPU, FS); |
| Evan Cheng | 1a72add6 | 2011-07-07 07:07:08 +0000 | [diff] [blame] | 51 | } |
| 52 | |
| Michael Kuperstein | db0712f | 2015-05-26 10:47:10 +0000 | [diff] [blame] | 53 | FeatureBitset MCSubtargetInfo::ToggleFeature(uint64_t FB) { |
| 54 | FeatureBits.flip(FB); |
| 55 | return FeatureBits; |
| 56 | } |
| 57 | |
| 58 | FeatureBitset MCSubtargetInfo::ToggleFeature(const FeatureBitset &FB) { |
| Evan Cheng | 91111d2 | 2011-07-09 05:47:46 +0000 | [diff] [blame] | 59 | FeatureBits ^= FB; |
| 60 | return FeatureBits; |
| 61 | } |
| 62 | |
| Michael Kuperstein | db0712f | 2015-05-26 10:47:10 +0000 | [diff] [blame] | 63 | FeatureBitset MCSubtargetInfo::ToggleFeature(StringRef FS) { |
| Artyom Skrobov | 8c69923 | 2016-01-05 10:25:56 +0000 | [diff] [blame] | 64 | SubtargetFeatures::ToggleFeature(FeatureBits, FS, ProcFeatures); |
| Evan Cheng | 91111d2 | 2011-07-09 05:47:46 +0000 | [diff] [blame] | 65 | return FeatureBits; |
| 66 | } |
| 67 | |
| John Brawn | d03d229 | 2015-06-05 13:29:24 +0000 | [diff] [blame] | 68 | FeatureBitset MCSubtargetInfo::ApplyFeatureFlag(StringRef FS) { |
| Artyom Skrobov | 8c69923 | 2016-01-05 10:25:56 +0000 | [diff] [blame] | 69 | SubtargetFeatures::ApplyFeatureFlag(FeatureBits, FS, ProcFeatures); |
| John Brawn | d03d229 | 2015-06-05 13:29:24 +0000 | [diff] [blame] | 70 | return FeatureBits; |
| 71 | } |
| Evan Cheng | 91111d2 | 2011-07-09 05:47:46 +0000 | [diff] [blame] | 72 | |
| Krzysztof Parzyszek | 788e768 | 2017-09-14 20:44:20 +0000 | [diff] [blame] | 73 | bool MCSubtargetInfo::checkFeatures(StringRef FS) const { |
| 74 | SubtargetFeatures T(FS); |
| 75 | FeatureBitset Set, All; |
| 76 | for (std::string F : T.getFeatures()) { |
| 77 | SubtargetFeatures::ApplyFeatureFlag(Set, F, ProcFeatures); |
| 78 | if (F[0] == '-') |
| 79 | F[0] = '+'; |
| 80 | SubtargetFeatures::ApplyFeatureFlag(All, F, ProcFeatures); |
| 81 | } |
| 82 | return (FeatureBits & All) == Set; |
| 83 | } |
| 84 | |
| Duncan P. N. Exon Smith | f862f87 | 2015-07-10 22:13:43 +0000 | [diff] [blame] | 85 | const MCSchedModel &MCSubtargetInfo::getSchedModelForCPU(StringRef CPU) const { |
| Andrew Trick | ac36af4 | 2012-09-14 20:26:41 +0000 | [diff] [blame] | 86 | assert(ProcSchedModels && "Processor machine model not available!"); |
| Evan Cheng | 54b68e3 | 2011-07-01 20:45:01 +0000 | [diff] [blame] | 87 | |
| Craig Topper | 90b18c4 | 2016-01-03 08:45:36 +0000 | [diff] [blame] | 88 | ArrayRef<SubtargetInfoKV> SchedModels(ProcSchedModels, ProcDesc.size()); |
| 89 | |
| 90 | assert(std::is_sorted(SchedModels.begin(), SchedModels.end(), |
| Craig Topper | c177d9e | 2015-10-17 16:37:11 +0000 | [diff] [blame] | 91 | [](const SubtargetInfoKV &LHS, const SubtargetInfoKV &RHS) { |
| 92 | return strcmp(LHS.Key, RHS.Key) < 0; |
| 93 | }) && |
| 94 | "Processor machine model table is not sorted"); |
| Evan Cheng | 54b68e3 | 2011-07-01 20:45:01 +0000 | [diff] [blame] | 95 | |
| 96 | // Find entry |
| Craig Topper | 90b18c4 | 2016-01-03 08:45:36 +0000 | [diff] [blame] | 97 | auto Found = |
| 98 | std::lower_bound(SchedModels.begin(), SchedModels.end(), CPU); |
| 99 | if (Found == SchedModels.end() || StringRef(Found->Key) != CPU) { |
| Craig Topper | 768ccc4 | 2015-04-02 04:27:50 +0000 | [diff] [blame] | 100 | if (CPU != "help") // Don't error if the user asked for help. |
| 101 | errs() << "'" << CPU |
| 102 | << "' is not a recognized processor for this target" |
| 103 | << " (ignoring processor)\n"; |
| Pete Cooper | 1175945 | 2014-09-02 17:43:54 +0000 | [diff] [blame] | 104 | return MCSchedModel::GetDefaultSchedModel(); |
| Artyom Skrobov | eab7515 | 2014-01-25 16:56:18 +0000 | [diff] [blame] | 105 | } |
| Andrew Trick | 87255e3 | 2012-07-07 04:00:00 +0000 | [diff] [blame] | 106 | assert(Found->Value && "Missing processor SchedModel value"); |
| Pete Cooper | 1175945 | 2014-09-02 17:43:54 +0000 | [diff] [blame] | 107 | return *(const MCSchedModel *)Found->Value; |
| Andrew Trick | 87255e3 | 2012-07-07 04:00:00 +0000 | [diff] [blame] | 108 | } |
| Evan Cheng | 54b68e3 | 2011-07-01 20:45:01 +0000 | [diff] [blame] | 109 | |
| Andrew Trick | 87255e3 | 2012-07-07 04:00:00 +0000 | [diff] [blame] | 110 | InstrItineraryData |
| 111 | MCSubtargetInfo::getInstrItineraryForCPU(StringRef CPU) const { |
| Krzysztof Parzyszek | d0b6ceb | 2017-09-27 12:48:48 +0000 | [diff] [blame] | 112 | const MCSchedModel &SchedModel = getSchedModelForCPU(CPU); |
| Andrew Trick | 87255e3 | 2012-07-07 04:00:00 +0000 | [diff] [blame] | 113 | return InstrItineraryData(SchedModel, Stages, OperandCycles, ForwardingPaths); |
| Evan Cheng | 54b68e3 | 2011-07-01 20:45:01 +0000 | [diff] [blame] | 114 | } |
| Andrew Trick | d2a19da | 2012-09-14 20:26:46 +0000 | [diff] [blame] | 115 | |
| Andrew Trick | d2a19da | 2012-09-14 20:26:46 +0000 | [diff] [blame] | 116 | void MCSubtargetInfo::initInstrItins(InstrItineraryData &InstrItins) const { |
| Duncan P. N. Exon Smith | f862f87 | 2015-07-10 22:13:43 +0000 | [diff] [blame] | 117 | InstrItins = InstrItineraryData(getSchedModel(), Stages, OperandCycles, |
| 118 | ForwardingPaths); |
| Andrew Trick | d2a19da | 2012-09-14 20:26:46 +0000 | [diff] [blame] | 119 | } |