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