1009b1c42SEd Schouten //===- SubtargetFeature.cpp - CPU characteristics Implementation ----------===//
2009b1c42SEd Schouten //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6009b1c42SEd Schouten //
7009b1c42SEd Schouten //===----------------------------------------------------------------------===//
8009b1c42SEd Schouten //
971d5a254SDimitry Andric /// \file Implements the SubtargetFeature interface.
10009b1c42SEd Schouten //
11009b1c42SEd Schouten //===----------------------------------------------------------------------===//
12009b1c42SEd Schouten
137fa27ce4SDimitry Andric #include "llvm/TargetParser/SubtargetFeature.h"
1471d5a254SDimitry Andric #include "llvm/ADT/SmallVector.h"
1585d8b2bbSDimitry Andric #include "llvm/ADT/StringExtras.h"
1671d5a254SDimitry Andric #include "llvm/ADT/StringRef.h"
17eb11fae6SDimitry Andric #include "llvm/Config/llvm-config.h"
1871d5a254SDimitry Andric #include "llvm/Support/Compiler.h"
19829000e0SRoman Divacky #include "llvm/Support/Debug.h"
2059850d08SRoman Divacky #include "llvm/Support/raw_ostream.h"
217fa27ce4SDimitry Andric #include "llvm/TargetParser/Triple.h"
22009b1c42SEd Schouten #include <algorithm>
2371d5a254SDimitry Andric #include <string>
2471d5a254SDimitry Andric #include <vector>
2571d5a254SDimitry Andric
26009b1c42SEd Schouten using namespace llvm;
27009b1c42SEd Schouten
2871d5a254SDimitry Andric /// Splits a string of comma separated items in to a vector of strings.
Split(std::vector<std::string> & V,StringRef S)29e6d15924SDimitry Andric void SubtargetFeatures::Split(std::vector<std::string> &V, StringRef S) {
3067c32a98SDimitry Andric SmallVector<StringRef, 3> Tmp;
31dd58ef01SDimitry Andric S.split(Tmp, ',', -1, false /* KeepEmpty */);
32cfca06d7SDimitry Andric V.reserve(Tmp.size());
33cfca06d7SDimitry Andric for (StringRef T : Tmp)
34cfca06d7SDimitry Andric V.push_back(std::string(T));
35009b1c42SEd Schouten }
36009b1c42SEd Schouten
AddFeature(StringRef String,bool Enable)375a5ac124SDimitry Andric void SubtargetFeatures::AddFeature(StringRef String, bool Enable) {
385a5ac124SDimitry Andric // Don't add empty features.
395ca98fd9SDimitry Andric if (!String.empty())
405ca98fd9SDimitry Andric // Convert to lowercase, prepend flag if we don't already have a flag.
415a5ac124SDimitry Andric Features.push_back(hasFlag(String) ? String.lower()
425a5ac124SDimitry Andric : (Enable ? "+" : "-") + String.lower());
43009b1c42SEd Schouten }
44009b1c42SEd Schouten
addFeaturesVector(const ArrayRef<std::string> OtherFeatures)45e3b55780SDimitry Andric void SubtargetFeatures::addFeaturesVector(
46e3b55780SDimitry Andric const ArrayRef<std::string> OtherFeatures) {
47e3b55780SDimitry Andric Features.insert(Features.cend(), OtherFeatures.begin(), OtherFeatures.end());
48e3b55780SDimitry Andric }
49e3b55780SDimitry Andric
SubtargetFeatures(StringRef Initial)5067c32a98SDimitry Andric SubtargetFeatures::SubtargetFeatures(StringRef Initial) {
51009b1c42SEd Schouten // Break up string into separate features
52009b1c42SEd Schouten Split(Features, Initial);
53009b1c42SEd Schouten }
54009b1c42SEd Schouten
getString() const55009b1c42SEd Schouten std::string SubtargetFeatures::getString() const {
5685d8b2bbSDimitry Andric return join(Features.begin(), Features.end(), ",");
57009b1c42SEd Schouten }
58009b1c42SEd Schouten
print(raw_ostream & OS) const5959850d08SRoman Divacky void SubtargetFeatures::print(raw_ostream &OS) const {
60e3b55780SDimitry Andric for (const auto &F : Features)
615ca98fd9SDimitry Andric OS << F << " ";
62009b1c42SEd Schouten OS << "\n";
63009b1c42SEd Schouten }
64009b1c42SEd Schouten
6571d5a254SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const6601095a5dSDimitry Andric LLVM_DUMP_METHOD void SubtargetFeatures::dump() const {
67829000e0SRoman Divacky print(dbgs());
68009b1c42SEd Schouten }
6971d5a254SDimitry Andric #endif
707d453863SRoman Divacky
getDefaultSubtargetFeatures(const Triple & Triple)71411bd29eSDimitry Andric void SubtargetFeatures::getDefaultSubtargetFeatures(const Triple& Triple) {
7271d5a254SDimitry Andric // FIXME: This is an inelegant way of specifying the features of a
7371d5a254SDimitry Andric // subtarget. It would be better if we could encode this information
74b1c73532SDimitry Andric // into the IR.
75abdf259dSRoman Divacky if (Triple.getVendor() == Triple::Apple) {
76abdf259dSRoman Divacky if (Triple.getArch() == Triple::ppc) {
77abdf259dSRoman Divacky // powerpc-apple-*
78abdf259dSRoman Divacky AddFeature("altivec");
79abdf259dSRoman Divacky } else if (Triple.getArch() == Triple::ppc64) {
80abdf259dSRoman Divacky // powerpc64-apple-*
81abdf259dSRoman Divacky AddFeature("64bit");
82abdf259dSRoman Divacky AddFeature("altivec");
83abdf259dSRoman Divacky }
84abdf259dSRoman Divacky }
857d453863SRoman Divacky }
86