/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Basic/Targets/Hexagon.cpp
Line | Count | Source (jump to first uncovered line) |
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 | 59 | MacroBuilder &Builder) const { |
24 | 59 | Builder.defineMacro("__qdsp6__", "1"); |
25 | 59 | Builder.defineMacro("__hexagon__", "1"); |
26 | | |
27 | 59 | Builder.defineMacro("__ELF__"); |
28 | | |
29 | | // The macro __HVXDBL__ is deprecated. |
30 | 59 | bool DefineHvxDbl = false; |
31 | | |
32 | 59 | if (CPU == "hexagonv5") { |
33 | 1 | Builder.defineMacro("__HEXAGON_V5__"); |
34 | 1 | Builder.defineMacro("__HEXAGON_ARCH__", "5"); |
35 | 1 | if (Opts.HexagonQdsp6Compat) { |
36 | 0 | Builder.defineMacro("__QDSP6_V5__"); |
37 | 0 | Builder.defineMacro("__QDSP6_ARCH__", "5"); |
38 | 0 | } |
39 | 58 | } else if (CPU == "hexagonv55") { |
40 | 4 | Builder.defineMacro("__HEXAGON_V55__"); |
41 | 4 | Builder.defineMacro("__HEXAGON_ARCH__", "55"); |
42 | 4 | Builder.defineMacro("__QDSP6_V55__"); |
43 | 4 | Builder.defineMacro("__QDSP6_ARCH__", "55"); |
44 | 54 | } else if (CPU == "hexagonv60") { |
45 | 15 | DefineHvxDbl = true; |
46 | 15 | Builder.defineMacro("__HEXAGON_V60__"); |
47 | 15 | Builder.defineMacro("__HEXAGON_ARCH__", "60"); |
48 | 15 | Builder.defineMacro("__QDSP6_V60__"); |
49 | 15 | Builder.defineMacro("__QDSP6_ARCH__", "60"); |
50 | 39 | } else if (CPU == "hexagonv62") { |
51 | 7 | DefineHvxDbl = true; |
52 | 7 | Builder.defineMacro("__HEXAGON_V62__"); |
53 | 7 | Builder.defineMacro("__HEXAGON_ARCH__", "62"); |
54 | 32 | } else if (CPU == "hexagonv65") { |
55 | 6 | DefineHvxDbl = true; |
56 | 6 | Builder.defineMacro("__HEXAGON_V65__"); |
57 | 6 | Builder.defineMacro("__HEXAGON_ARCH__", "65"); |
58 | 26 | } else if (CPU == "hexagonv66") { |
59 | 7 | DefineHvxDbl = true; |
60 | 7 | Builder.defineMacro("__HEXAGON_V66__"); |
61 | 7 | Builder.defineMacro("__HEXAGON_ARCH__", "66"); |
62 | 19 | } else if (CPU == "hexagonv67") { |
63 | 6 | Builder.defineMacro("__HEXAGON_V67__"); |
64 | 6 | Builder.defineMacro("__HEXAGON_ARCH__", "67"); |
65 | 13 | } else if (CPU == "hexagonv67t") { |
66 | 1 | Builder.defineMacro("__HEXAGON_V67T__"); |
67 | 1 | Builder.defineMacro("__HEXAGON_ARCH__", "67"); |
68 | 1 | } |
69 | | |
70 | 59 | if (hasFeature("hvx-length64b")) { |
71 | 6 | Builder.defineMacro("__HVX__"); |
72 | 6 | Builder.defineMacro("__HVX_ARCH__", HVXVersion); |
73 | 6 | Builder.defineMacro("__HVX_LENGTH__", "64"); |
74 | 6 | } |
75 | | |
76 | 59 | if (hasFeature("hvx-length128b")) { |
77 | 16 | Builder.defineMacro("__HVX__"); |
78 | 16 | Builder.defineMacro("__HVX_ARCH__", HVXVersion); |
79 | 16 | Builder.defineMacro("__HVX_LENGTH__", "128"); |
80 | 16 | if (DefineHvxDbl) |
81 | 12 | Builder.defineMacro("__HVXDBL__"); |
82 | 16 | } |
83 | | |
84 | 59 | if (hasFeature("audio")) { |
85 | 2 | Builder.defineMacro("__HEXAGON_AUDIO__"); |
86 | 2 | } |
87 | | |
88 | 58 | std::string NumPhySlots = isTinyCore() ? "3"1 : "4"; |
89 | 59 | Builder.defineMacro("__HEXAGON_PHYSICAL_SLOTS__", NumPhySlots); |
90 | 59 | } |
91 | | |
92 | | bool HexagonTargetInfo::initFeatureMap( |
93 | | llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU, |
94 | 59 | const std::vector<std::string> &FeaturesVec) const { |
95 | 59 | if (isTinyCore()) |
96 | 1 | Features["audio"] = true; |
97 | | |
98 | 59 | StringRef CPUFeature = CPU; |
99 | 59 | CPUFeature.consume_front("hexagon"); |
100 | 59 | CPUFeature.consume_back("t"); |
101 | 59 | if (!CPUFeature.empty()) |
102 | 47 | Features[CPUFeature] = true; |
103 | | |
104 | 59 | Features["long-calls"] = false; |
105 | | |
106 | 59 | return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); |
107 | 59 | } |
108 | | |
109 | | bool HexagonTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, |
110 | 59 | DiagnosticsEngine &Diags) { |
111 | 153 | for (auto &F : Features) { |
112 | 153 | if (F == "+hvx-length64b") |
113 | 6 | HasHVX = HasHVX64B = true; |
114 | 147 | else if (F == "+hvx-length128b") |
115 | 16 | HasHVX = HasHVX128B = true; |
116 | 131 | else if (F.find("+hvxv") != std::string::npos) { |
117 | 22 | HasHVX = true; |
118 | 22 | HVXVersion = F.substr(std::string("+hvxv").length()); |
119 | 109 | } else if (F == "-hvx") |
120 | 0 | HasHVX = HasHVX64B = HasHVX128B = false; |
121 | 109 | else if (F == "+long-calls") |
122 | 0 | UseLongCalls = true; |
123 | 109 | else if (F == "-long-calls") |
124 | 59 | UseLongCalls = false; |
125 | 50 | else if (F == "+audio") |
126 | 2 | HasAudio = true; |
127 | 153 | } |
128 | 59 | return true; |
129 | 59 | } |
130 | | |
131 | | const char *const HexagonTargetInfo::GCCRegNames[] = { |
132 | | "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", |
133 | | "r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", |
134 | | "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", |
135 | | "r27", "r28", "r29", "r30", "r31", "p0", "p1", "p2", "p3", |
136 | | "sa0", "lc0", "sa1", "lc1", "m0", "m1", "usr", "ugp", |
137 | | "r1:0", "r3:2", "r5:4", "r7:6", "r9:8", "r11:10", "r13:12", "r15:14", |
138 | | "r17:16", "r19:18", "r21:20", "r23:22", "r25:24", "r27:26", "r29:28", |
139 | | "r31:30" |
140 | | }; |
141 | | |
142 | 1 | ArrayRef<const char *> HexagonTargetInfo::getGCCRegNames() const { |
143 | 1 | return llvm::makeArrayRef(GCCRegNames); |
144 | 1 | } |
145 | | |
146 | | const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = { |
147 | | {{"sp"}, "r29"}, |
148 | | {{"fp"}, "r30"}, |
149 | | {{"lr"}, "r31"}, |
150 | | }; |
151 | | |
152 | 1 | ArrayRef<TargetInfo::GCCRegAlias> HexagonTargetInfo::getGCCRegAliases() const { |
153 | 1 | return llvm::makeArrayRef(GCCRegAliases); |
154 | 1 | } |
155 | | |
156 | | const Builtin::Info HexagonTargetInfo::BuiltinInfo[] = { |
157 | | #define BUILTIN(ID, TYPE, ATTRS) \ |
158 | | {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, |
159 | | #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ |
160 | | {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr}, |
161 | | #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ |
162 | | {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE}, |
163 | | #include "clang/Basic/BuiltinsHexagon.def" |
164 | | }; |
165 | | |
166 | 232 | bool HexagonTargetInfo::hasFeature(StringRef Feature) const { |
167 | 232 | std::string VS = "hvxv" + HVXVersion; |
168 | 232 | if (Feature == VS) |
169 | 0 | return true; |
170 | | |
171 | 232 | return llvm::StringSwitch<bool>(Feature) |
172 | 232 | .Case("hexagon", true) |
173 | 232 | .Case("hvx", HasHVX) |
174 | 232 | .Case("hvx-length64b", HasHVX64B) |
175 | 232 | .Case("hvx-length128b", HasHVX128B) |
176 | 232 | .Case("long-calls", UseLongCalls) |
177 | 232 | .Case("audio", HasAudio) |
178 | 232 | .Default(false); |
179 | 232 | } |
180 | | |
181 | | struct CPUSuffix { |
182 | | llvm::StringLiteral Name; |
183 | | llvm::StringLiteral Suffix; |
184 | | }; |
185 | | |
186 | | static constexpr CPUSuffix Suffixes[] = { |
187 | | {{"hexagonv5"}, {"5"}}, {{"hexagonv55"}, {"55"}}, |
188 | | {{"hexagonv60"}, {"60"}}, {{"hexagonv62"}, {"62"}}, |
189 | | {{"hexagonv65"}, {"65"}}, {{"hexagonv66"}, {"66"}}, |
190 | | {{"hexagonv67"}, {"67"}}, {{"hexagonv67t"}, {"67t"}}, |
191 | | }; |
192 | | |
193 | 48 | const char *HexagonTargetInfo::getHexagonCPUSuffix(StringRef Name) { |
194 | 48 | const CPUSuffix *Item = llvm::find_if( |
195 | 212 | Suffixes, [Name](const CPUSuffix &S) { return S.Name == Name; }); |
196 | 48 | if (Item == std::end(Suffixes)) |
197 | 1 | return nullptr; |
198 | 47 | return Item->Suffix.data(); |
199 | 47 | } |
200 | | |
201 | | void HexagonTargetInfo::fillValidCPUList( |
202 | 1 | SmallVectorImpl<StringRef> &Values) const { |
203 | 1 | for (const CPUSuffix &Suffix : Suffixes) |
204 | 8 | Values.push_back(Suffix.Name); |
205 | 1 | } |
206 | | |
207 | 59 | ArrayRef<Builtin::Info> HexagonTargetInfo::getTargetBuiltins() const { |
208 | 59 | return llvm::makeArrayRef(BuiltinInfo, clang::Hexagon::LastTSBuiltin - |
209 | 59 | Builtin::FirstTSBuiltin); |
210 | 59 | } |