xref: /freebsd/contrib/llvm-project/clang/lib/Basic/Targets/Hexagon.cpp (revision 4b50c451720d8b427757a6da1dd2bb4c52cd9e35)
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 }
171