]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/Basic/Targets/Hexagon.cpp
Vendor import of clang trunk r351319 (just before the release_80 branch
[FreeBSD/FreeBSD.git] / 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 == "hexagonv5") {
29     Builder.defineMacro("__HEXAGON_V5__");
30     Builder.defineMacro("__HEXAGON_ARCH__", "5");
31     if (Opts.HexagonQdsp6Compat) {
32       Builder.defineMacro("__QDSP6_V5__");
33       Builder.defineMacro("__QDSP6_ARCH__", "5");
34     }
35   } else if (CPU == "hexagonv55") {
36     Builder.defineMacro("__HEXAGON_V55__");
37     Builder.defineMacro("__HEXAGON_ARCH__", "55");
38     Builder.defineMacro("__QDSP6_V55__");
39     Builder.defineMacro("__QDSP6_ARCH__", "55");
40   } else if (CPU == "hexagonv60") {
41     Builder.defineMacro("__HEXAGON_V60__");
42     Builder.defineMacro("__HEXAGON_ARCH__", "60");
43     Builder.defineMacro("__QDSP6_V60__");
44     Builder.defineMacro("__QDSP6_ARCH__", "60");
45   } else if (CPU == "hexagonv62") {
46     Builder.defineMacro("__HEXAGON_V62__");
47     Builder.defineMacro("__HEXAGON_ARCH__", "62");
48   } else if (CPU == "hexagonv65") {
49     Builder.defineMacro("__HEXAGON_V65__");
50     Builder.defineMacro("__HEXAGON_ARCH__", "65");
51   } else if (CPU == "hexagonv66") {
52     Builder.defineMacro("__HEXAGON_V66__");
53     Builder.defineMacro("__HEXAGON_ARCH__", "66");
54   }
55
56   if (hasFeature("hvx-length64b")) {
57     Builder.defineMacro("__HVX__");
58     Builder.defineMacro("__HVX_ARCH__", HVXVersion);
59     Builder.defineMacro("__HVX_LENGTH__", "64");
60   }
61
62   if (hasFeature("hvx-length128b")) {
63     Builder.defineMacro("__HVX__");
64     Builder.defineMacro("__HVX_ARCH__", HVXVersion);
65     Builder.defineMacro("__HVX_LENGTH__", "128");
66     // FIXME: This macro is deprecated.
67     Builder.defineMacro("__HVXDBL__");
68   }
69 }
70
71 bool HexagonTargetInfo::initFeatureMap(
72     llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
73     const std::vector<std::string> &FeaturesVec) const {
74   Features["long-calls"] = false;
75
76   return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
77 }
78
79 bool HexagonTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
80                                              DiagnosticsEngine &Diags) {
81   for (auto &F : Features) {
82     if (F == "+hvx-length64b")
83       HasHVX = HasHVX64B = true;
84     else if (F == "+hvx-length128b")
85       HasHVX = HasHVX128B = true;
86     else if (F.find("+hvxv") != std::string::npos) {
87       HasHVX = true;
88       HVXVersion = F.substr(std::string("+hvxv").length());
89     } else if (F == "-hvx")
90       HasHVX = HasHVX64B = HasHVX128B = false;
91     else if (F == "+long-calls")
92       UseLongCalls = true;
93     else if (F == "-long-calls")
94       UseLongCalls = false;
95   }
96   return true;
97 }
98
99 const char *const HexagonTargetInfo::GCCRegNames[] = {
100     "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",  "r8",
101     "r9",  "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17",
102     "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26",
103     "r27", "r28", "r29", "r30", "r31", "p0",  "p1",  "p2",  "p3",
104     "sa0", "lc0", "sa1", "lc1", "m0",  "m1",  "usr", "ugp"
105 };
106
107 ArrayRef<const char *> HexagonTargetInfo::getGCCRegNames() const {
108   return llvm::makeArrayRef(GCCRegNames);
109 }
110
111 const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = {
112     {{"sp"}, "r29"},
113     {{"fp"}, "r30"},
114     {{"lr"}, "r31"},
115 };
116
117 ArrayRef<TargetInfo::GCCRegAlias> HexagonTargetInfo::getGCCRegAliases() const {
118   return llvm::makeArrayRef(GCCRegAliases);
119 }
120
121 const Builtin::Info HexagonTargetInfo::BuiltinInfo[] = {
122 #define BUILTIN(ID, TYPE, ATTRS)                                               \
123   {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
124 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)                                    \
125   {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
126 #include "clang/Basic/BuiltinsHexagon.def"
127 };
128
129 bool HexagonTargetInfo::hasFeature(StringRef Feature) const {
130   std::string VS = "hvxv" + HVXVersion;
131   if (Feature == VS)
132     return true;
133
134   return llvm::StringSwitch<bool>(Feature)
135       .Case("hexagon", true)
136       .Case("hvx", HasHVX)
137       .Case("hvx-length64b", HasHVX64B)
138       .Case("hvx-length128b", HasHVX128B)
139       .Case("long-calls", UseLongCalls)
140       .Default(false);
141 }
142
143 struct CPUSuffix {
144   llvm::StringLiteral Name;
145   llvm::StringLiteral Suffix;
146 };
147
148 static constexpr CPUSuffix Suffixes[] = {
149     {{"hexagonv5"},  {"5"}},  {{"hexagonv55"}, {"55"}},
150     {{"hexagonv60"}, {"60"}}, {{"hexagonv62"}, {"62"}},
151     {{"hexagonv65"}, {"65"}}, {{"hexagonv66"}, {"66"}},
152 };
153
154 const char *HexagonTargetInfo::getHexagonCPUSuffix(StringRef Name) {
155   const CPUSuffix *Item = llvm::find_if(
156       Suffixes, [Name](const CPUSuffix &S) { return S.Name == Name; });
157   if (Item == std::end(Suffixes))
158     return nullptr;
159   return Item->Suffix.data();
160 }
161
162 void HexagonTargetInfo::fillValidCPUList(
163     SmallVectorImpl<StringRef> &Values) const {
164   for (const CPUSuffix &Suffix : Suffixes)
165     Values.push_back(Suffix.Name);
166 }
167
168 ArrayRef<Builtin::Info> HexagonTargetInfo::getTargetBuiltins() const {
169   return llvm::makeArrayRef(BuiltinInfo, clang::Hexagon::LastTSBuiltin -
170                                              Builtin::FirstTSBuiltin);
171 }