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. 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 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 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 5006c3fb27SDimitry Andric SubtargetFeatures::SubtargetFeatures(StringRef Initial) { 5106c3fb27SDimitry Andric // Break up string into separate features 5206c3fb27SDimitry Andric Split(Features, Initial); 5306c3fb27SDimitry Andric } 5406c3fb27SDimitry Andric 5506c3fb27SDimitry Andric std::string SubtargetFeatures::getString() const { 5606c3fb27SDimitry Andric return join(Features.begin(), Features.end(), ","); 5706c3fb27SDimitry Andric } 5806c3fb27SDimitry Andric 5906c3fb27SDimitry 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) 6606c3fb27SDimitry Andric LLVM_DUMP_METHOD void SubtargetFeatures::dump() const { 6706c3fb27SDimitry Andric print(dbgs()); 6806c3fb27SDimitry Andric } 6906c3fb27SDimitry Andric #endif 7006c3fb27SDimitry Andric 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