]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/lib/Basic/Targets/Hexagon.cpp
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / lib / Basic / Targets / Hexagon.cpp
1 //===--- Hexagon.cpp - Implement Hexagon target feature support -----------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements Hexagon TargetInfo objects.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "Hexagon.h"
15 #include "Targets.h"
16 #include "clang/Basic/MacroBuilder.h"
17 #include "clang/Basic/TargetBuiltins.h"
18 #include "llvm/ADT/StringSwitch.h"
19
20 using namespace clang;
21 using namespace clang::targets;
22
23 void HexagonTargetInfo::getTargetDefines(const LangOptions &Opts,
24                                          MacroBuilder &Builder) const {
25   Builder.defineMacro("__qdsp6__", "1");
26   Builder.defineMacro("__hexagon__", "1");
27
28   if (CPU == "hexagonv4") {
29     Builder.defineMacro("__HEXAGON_V4__");
30     Builder.defineMacro("__HEXAGON_ARCH__", "4");
31     if (Opts.HexagonQdsp6Compat) {
32       Builder.defineMacro("__QDSP6_V4__");
33       Builder.defineMacro("__QDSP6_ARCH__", "4");
34     }
35   } else if (CPU == "hexagonv5") {
36     Builder.defineMacro("__HEXAGON_V5__");
37     Builder.defineMacro("__HEXAGON_ARCH__", "5");
38     if (Opts.HexagonQdsp6Compat) {
39       Builder.defineMacro("__QDSP6_V5__");
40       Builder.defineMacro("__QDSP6_ARCH__", "5");
41     }
42   } else if (CPU == "hexagonv55") {
43     Builder.defineMacro("__HEXAGON_V55__");
44     Builder.defineMacro("__HEXAGON_ARCH__", "55");
45     Builder.defineMacro("__QDSP6_V55__");
46     Builder.defineMacro("__QDSP6_ARCH__", "55");
47   } else if (CPU == "hexagonv60") {
48     Builder.defineMacro("__HEXAGON_V60__");
49     Builder.defineMacro("__HEXAGON_ARCH__", "60");
50     Builder.defineMacro("__QDSP6_V60__");
51     Builder.defineMacro("__QDSP6_ARCH__", "60");
52   } else if (CPU == "hexagonv62") {
53     Builder.defineMacro("__HEXAGON_V62__");
54     Builder.defineMacro("__HEXAGON_ARCH__", "62");
55   } else if (CPU == "hexagonv65") {
56     Builder.defineMacro("__HEXAGON_V65__");
57     Builder.defineMacro("__HEXAGON_ARCH__", "65");
58   }
59
60   if (hasFeature("hvx-length64b")) {
61     Builder.defineMacro("__HVX__");
62     Builder.defineMacro("__HVX_ARCH__", HVXVersion);
63     Builder.defineMacro("__HVX_LENGTH__", "64");
64   }
65
66   if (hasFeature("hvx-length128b")) {
67     Builder.defineMacro("__HVX__");
68     Builder.defineMacro("__HVX_ARCH__", HVXVersion);
69     Builder.defineMacro("__HVX_LENGTH__", "128");
70     // FIXME: This macro is deprecated.
71     Builder.defineMacro("__HVXDBL__");
72   }
73 }
74
75 bool HexagonTargetInfo::initFeatureMap(
76     llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
77     const std::vector<std::string> &FeaturesVec) const {
78   Features["long-calls"] = false;
79
80   return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
81 }
82
83 bool HexagonTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
84                                              DiagnosticsEngine &Diags) {
85   for (auto &F : Features) {
86     if (F == "+hvx-length64b")
87       HasHVX = HasHVX64B = true;
88     else if (F == "+hvx-length128b")
89       HasHVX = HasHVX128B = true;
90     else if (F.find("+hvxv") != std::string::npos) {
91       HasHVX = true;
92       HVXVersion = F.substr(std::string("+hvxv").length());
93     } else if (F == "-hvx")
94       HasHVX = HasHVX64B = HasHVX128B = false;
95     else if (F == "+long-calls")
96       UseLongCalls = true;
97     else if (F == "-long-calls")
98       UseLongCalls = false;
99   }
100   return true;
101 }
102
103 const char *const HexagonTargetInfo::GCCRegNames[] = {
104     "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",  "r8",
105     "r9",  "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17",
106     "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26",
107     "r27", "r28", "r29", "r30", "r31", "p0",  "p1",  "p2",  "p3",
108     "sa0", "lc0", "sa1", "lc1", "m0",  "m1",  "usr", "ugp"
109 };
110
111 ArrayRef<const char *> HexagonTargetInfo::getGCCRegNames() const {
112   return llvm::makeArrayRef(GCCRegNames);
113 }
114
115 const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = {
116     {{"sp"}, "r29"},
117     {{"fp"}, "r30"},
118     {{"lr"}, "r31"},
119 };
120
121 ArrayRef<TargetInfo::GCCRegAlias> HexagonTargetInfo::getGCCRegAliases() const {
122   return llvm::makeArrayRef(GCCRegAliases);
123 }
124
125 const Builtin::Info HexagonTargetInfo::BuiltinInfo[] = {
126 #define BUILTIN(ID, TYPE, ATTRS)                                               \
127   {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
128 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)                                    \
129   {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
130 #include "clang/Basic/BuiltinsHexagon.def"
131 };
132
133 bool HexagonTargetInfo::hasFeature(StringRef Feature) const {
134   std::string VS = "hvxv" + HVXVersion;
135   if (Feature == VS)
136     return true;
137
138   return llvm::StringSwitch<bool>(Feature)
139       .Case("hexagon", true)
140       .Case("hvx", HasHVX)
141       .Case("hvx-length64b", HasHVX64B)
142       .Case("hvx-length128b", HasHVX128B)
143       .Case("long-calls", UseLongCalls)
144       .Default(false);
145 }
146
147 struct CPUSuffix {
148   llvm::StringLiteral Name;
149   llvm::StringLiteral Suffix;
150 };
151
152 static constexpr CPUSuffix Suffixes[] = {
153     {{"hexagonv4"}, {"4"}},   {{"hexagonv5"}, {"5"}},
154     {{"hexagonv55"}, {"55"}}, {{"hexagonv60"}, {"60"}},
155     {{"hexagonv62"}, {"62"}}, {{"hexagonv65"}, {"65"}},
156 };
157
158 const char *HexagonTargetInfo::getHexagonCPUSuffix(StringRef Name) {
159   const CPUSuffix *Item = llvm::find_if(
160       Suffixes, [Name](const CPUSuffix &S) { return S.Name == Name; });
161   if (Item == std::end(Suffixes))
162     return nullptr;
163   return Item->Suffix.data();
164 }
165
166 void HexagonTargetInfo::fillValidCPUList(
167     SmallVectorImpl<StringRef> &Values) const {
168   for (const CPUSuffix &Suffix : Suffixes)
169     Values.push_back(Suffix.Name);
170 }
171
172 ArrayRef<Builtin::Info> HexagonTargetInfo::getTargetBuiltins() const {
173   return llvm::makeArrayRef(BuiltinInfo, clang::Hexagon::LastTSBuiltin -
174                                              Builtin::FirstTSBuiltin);
175 }