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