1*06c3fb27SDimitry Andric //===- SubtargetFeature.cpp - CPU characteristics Implementation ----------===// 2*06c3fb27SDimitry Andric // 3*06c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*06c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*06c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*06c3fb27SDimitry Andric // 7*06c3fb27SDimitry Andric //===----------------------------------------------------------------------===// 8*06c3fb27SDimitry Andric // 9*06c3fb27SDimitry Andric /// \file Implements the SubtargetFeature interface. 10*06c3fb27SDimitry Andric // 11*06c3fb27SDimitry Andric //===----------------------------------------------------------------------===// 12*06c3fb27SDimitry Andric 13*06c3fb27SDimitry Andric #include "llvm/TargetParser/SubtargetFeature.h" 14*06c3fb27SDimitry Andric #include "llvm/ADT/SmallVector.h" 15*06c3fb27SDimitry Andric #include "llvm/ADT/StringExtras.h" 16*06c3fb27SDimitry Andric #include "llvm/ADT/StringRef.h" 17*06c3fb27SDimitry Andric #include "llvm/Config/llvm-config.h" 18*06c3fb27SDimitry Andric #include "llvm/Support/Compiler.h" 19*06c3fb27SDimitry Andric #include "llvm/Support/Debug.h" 20*06c3fb27SDimitry Andric #include "llvm/Support/raw_ostream.h" 21*06c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h" 22*06c3fb27SDimitry Andric #include <algorithm> 23*06c3fb27SDimitry Andric #include <string> 24*06c3fb27SDimitry Andric #include <vector> 25*06c3fb27SDimitry Andric 26*06c3fb27SDimitry Andric using namespace llvm; 27*06c3fb27SDimitry Andric 28*06c3fb27SDimitry Andric /// Splits a string of comma separated items in to a vector of strings. 29*06c3fb27SDimitry Andric void SubtargetFeatures::Split(std::vector<std::string> &V, StringRef S) { 30*06c3fb27SDimitry Andric SmallVector<StringRef, 3> Tmp; 31*06c3fb27SDimitry Andric S.split(Tmp, ',', -1, false /* KeepEmpty */); 32*06c3fb27SDimitry Andric V.reserve(Tmp.size()); 33*06c3fb27SDimitry Andric for (StringRef T : Tmp) 34*06c3fb27SDimitry Andric V.push_back(std::string(T)); 35*06c3fb27SDimitry Andric } 36*06c3fb27SDimitry Andric 37*06c3fb27SDimitry Andric void SubtargetFeatures::AddFeature(StringRef String, bool Enable) { 38*06c3fb27SDimitry Andric // Don't add empty features. 39*06c3fb27SDimitry Andric if (!String.empty()) 40*06c3fb27SDimitry Andric // Convert to lowercase, prepend flag if we don't already have a flag. 41*06c3fb27SDimitry Andric Features.push_back(hasFlag(String) ? String.lower() 42*06c3fb27SDimitry Andric : (Enable ? "+" : "-") + String.lower()); 43*06c3fb27SDimitry Andric } 44*06c3fb27SDimitry Andric 45*06c3fb27SDimitry Andric void SubtargetFeatures::addFeaturesVector( 46*06c3fb27SDimitry Andric const ArrayRef<std::string> OtherFeatures) { 47*06c3fb27SDimitry Andric Features.insert(Features.cend(), OtherFeatures.begin(), OtherFeatures.end()); 48*06c3fb27SDimitry Andric } 49*06c3fb27SDimitry Andric 50*06c3fb27SDimitry Andric SubtargetFeatures::SubtargetFeatures(StringRef Initial) { 51*06c3fb27SDimitry Andric // Break up string into separate features 52*06c3fb27SDimitry Andric Split(Features, Initial); 53*06c3fb27SDimitry Andric } 54*06c3fb27SDimitry Andric 55*06c3fb27SDimitry Andric std::string SubtargetFeatures::getString() const { 56*06c3fb27SDimitry Andric return join(Features.begin(), Features.end(), ","); 57*06c3fb27SDimitry Andric } 58*06c3fb27SDimitry Andric 59*06c3fb27SDimitry Andric void SubtargetFeatures::print(raw_ostream &OS) const { 60*06c3fb27SDimitry Andric for (const auto &F : Features) 61*06c3fb27SDimitry Andric OS << F << " "; 62*06c3fb27SDimitry Andric OS << "\n"; 63*06c3fb27SDimitry Andric } 64*06c3fb27SDimitry Andric 65*06c3fb27SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 66*06c3fb27SDimitry Andric LLVM_DUMP_METHOD void SubtargetFeatures::dump() const { 67*06c3fb27SDimitry Andric print(dbgs()); 68*06c3fb27SDimitry Andric } 69*06c3fb27SDimitry Andric #endif 70*06c3fb27SDimitry Andric 71*06c3fb27SDimitry Andric void SubtargetFeatures::getDefaultSubtargetFeatures(const Triple& Triple) { 72*06c3fb27SDimitry Andric // FIXME: This is an inelegant way of specifying the features of a 73*06c3fb27SDimitry Andric // subtarget. It would be better if we could encode this information 74*06c3fb27SDimitry Andric // into the IR. See <rdar://5972456>. 75*06c3fb27SDimitry Andric if (Triple.getVendor() == Triple::Apple) { 76*06c3fb27SDimitry Andric if (Triple.getArch() == Triple::ppc) { 77*06c3fb27SDimitry Andric // powerpc-apple-* 78*06c3fb27SDimitry Andric AddFeature("altivec"); 79*06c3fb27SDimitry Andric } else if (Triple.getArch() == Triple::ppc64) { 80*06c3fb27SDimitry Andric // powerpc64-apple-* 81*06c3fb27SDimitry Andric AddFeature("64bit"); 82*06c3fb27SDimitry Andric AddFeature("altivec"); 83*06c3fb27SDimitry Andric } 84*06c3fb27SDimitry Andric } 85*06c3fb27SDimitry Andric } 86