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