xref: /freebsd-src/contrib/llvm-project/llvm/lib/TargetParser/SubtargetFeature.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
106c3fb27SDimitry Andric //===- SubtargetFeature.cpp - CPU characteristics Implementation ----------===//
206c3fb27SDimitry Andric //
306c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
506c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606c3fb27SDimitry Andric //
706c3fb27SDimitry Andric //===----------------------------------------------------------------------===//
806c3fb27SDimitry Andric //
906c3fb27SDimitry Andric /// \file Implements the SubtargetFeature interface.
1006c3fb27SDimitry Andric //
1106c3fb27SDimitry Andric //===----------------------------------------------------------------------===//
1206c3fb27SDimitry Andric 
1306c3fb27SDimitry Andric #include "llvm/TargetParser/SubtargetFeature.h"
1406c3fb27SDimitry Andric #include "llvm/ADT/SmallVector.h"
1506c3fb27SDimitry Andric #include "llvm/ADT/StringExtras.h"
1606c3fb27SDimitry Andric #include "llvm/ADT/StringRef.h"
1706c3fb27SDimitry Andric #include "llvm/Config/llvm-config.h"
1806c3fb27SDimitry Andric #include "llvm/Support/Compiler.h"
1906c3fb27SDimitry Andric #include "llvm/Support/Debug.h"
2006c3fb27SDimitry Andric #include "llvm/Support/raw_ostream.h"
2106c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h"
2206c3fb27SDimitry Andric #include <algorithm>
2306c3fb27SDimitry Andric #include <string>
2406c3fb27SDimitry Andric #include <vector>
2506c3fb27SDimitry Andric 
2606c3fb27SDimitry Andric using namespace llvm;
2706c3fb27SDimitry Andric 
2806c3fb27SDimitry Andric /// Splits a string of comma separated items in to a vector of strings.
Split(std::vector<std::string> & V,StringRef S)2906c3fb27SDimitry Andric void SubtargetFeatures::Split(std::vector<std::string> &V, StringRef S) {
3006c3fb27SDimitry Andric   SmallVector<StringRef, 3> Tmp;
3106c3fb27SDimitry Andric   S.split(Tmp, ',', -1, false /* KeepEmpty */);
3206c3fb27SDimitry Andric   V.reserve(Tmp.size());
3306c3fb27SDimitry Andric   for (StringRef T : Tmp)
3406c3fb27SDimitry Andric     V.push_back(std::string(T));
3506c3fb27SDimitry Andric }
3606c3fb27SDimitry Andric 
AddFeature(StringRef String,bool Enable)3706c3fb27SDimitry Andric void SubtargetFeatures::AddFeature(StringRef String, bool Enable) {
3806c3fb27SDimitry Andric   // Don't add empty features.
3906c3fb27SDimitry Andric   if (!String.empty())
4006c3fb27SDimitry Andric     // Convert to lowercase, prepend flag if we don't already have a flag.
4106c3fb27SDimitry Andric     Features.push_back(hasFlag(String) ? String.lower()
4206c3fb27SDimitry Andric                                        : (Enable ? "+" : "-") + String.lower());
4306c3fb27SDimitry Andric }
4406c3fb27SDimitry Andric 
addFeaturesVector(const ArrayRef<std::string> OtherFeatures)4506c3fb27SDimitry Andric void SubtargetFeatures::addFeaturesVector(
4606c3fb27SDimitry Andric     const ArrayRef<std::string> OtherFeatures) {
4706c3fb27SDimitry Andric   Features.insert(Features.cend(), OtherFeatures.begin(), OtherFeatures.end());
4806c3fb27SDimitry Andric }
4906c3fb27SDimitry Andric 
SubtargetFeatures(StringRef Initial)5006c3fb27SDimitry Andric SubtargetFeatures::SubtargetFeatures(StringRef Initial) {
5106c3fb27SDimitry Andric   // Break up string into separate features
5206c3fb27SDimitry Andric   Split(Features, Initial);
5306c3fb27SDimitry Andric }
5406c3fb27SDimitry Andric 
getString() const5506c3fb27SDimitry Andric std::string SubtargetFeatures::getString() const {
5606c3fb27SDimitry Andric   return join(Features.begin(), Features.end(), ",");
5706c3fb27SDimitry Andric }
5806c3fb27SDimitry Andric 
print(raw_ostream & OS) const5906c3fb27SDimitry Andric void SubtargetFeatures::print(raw_ostream &OS) const {
6006c3fb27SDimitry Andric   for (const auto &F : Features)
6106c3fb27SDimitry Andric     OS << F << " ";
6206c3fb27SDimitry Andric   OS << "\n";
6306c3fb27SDimitry Andric }
6406c3fb27SDimitry Andric 
6506c3fb27SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const6606c3fb27SDimitry Andric LLVM_DUMP_METHOD void SubtargetFeatures::dump() const {
6706c3fb27SDimitry Andric   print(dbgs());
6806c3fb27SDimitry Andric }
6906c3fb27SDimitry Andric #endif
7006c3fb27SDimitry Andric 
getDefaultSubtargetFeatures(const Triple & Triple)7106c3fb27SDimitry Andric void SubtargetFeatures::getDefaultSubtargetFeatures(const Triple& Triple) {
7206c3fb27SDimitry Andric   // FIXME: This is an inelegant way of specifying the features of a
7306c3fb27SDimitry Andric   // subtarget. It would be better if we could encode this information
74*5f757f3fSDimitry Andric   // into the IR.
7506c3fb27SDimitry Andric   if (Triple.getVendor() == Triple::Apple) {
7606c3fb27SDimitry Andric     if (Triple.getArch() == Triple::ppc) {
7706c3fb27SDimitry Andric       // powerpc-apple-*
7806c3fb27SDimitry Andric       AddFeature("altivec");
7906c3fb27SDimitry Andric     } else if (Triple.getArch() == Triple::ppc64) {
8006c3fb27SDimitry Andric       // powerpc64-apple-*
8106c3fb27SDimitry Andric       AddFeature("64bit");
8206c3fb27SDimitry Andric       AddFeature("altivec");
8306c3fb27SDimitry Andric     }
8406c3fb27SDimitry Andric   }
8506c3fb27SDimitry Andric }
86