xref: /freebsd/contrib/llvm-project/llvm/lib/TargetParser/SubtargetFeature.cpp (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
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