blob: 20d0c5c213e2367501abc6abfafba650b3e41dc3 [file] [log] [blame]
Erich Keaneebba5922017-07-21 22:37:03 +00001//===--- 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
20using namespace clang;
21using namespace clang::targets;
22
23void 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");
Krzysztof Parzyszekcc5cd2c2017-12-13 13:48:07 +000055 } else if (CPU == "hexagonv65") {
56 Builder.defineMacro("__HEXAGON_V65__");
57 Builder.defineMacro("__HEXAGON_ARCH__", "65");
Erich Keaneebba5922017-07-21 22:37:03 +000058 }
59
Sumanth Gundapaneni57098f52017-10-18 18:10:13 +000060 if (hasFeature("hvx-length64b")) {
Erich Keaneebba5922017-07-21 22:37:03 +000061 Builder.defineMacro("__HVX__");
Sumanth Gundapaneni57098f52017-10-18 18:10:13 +000062 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__");
Erich Keaneebba5922017-07-21 22:37:03 +000072 }
73}
74
75bool HexagonTargetInfo::initFeatureMap(
76 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
77 const std::vector<std::string> &FeaturesVec) const {
Erich Keaneebba5922017-07-21 22:37:03 +000078 Features["hvx-double"] = false;
79 Features["long-calls"] = false;
80
81 return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
82}
83
84bool HexagonTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
85 DiagnosticsEngine &Diags) {
86 for (auto &F : Features) {
Sumanth Gundapaneni57098f52017-10-18 18:10:13 +000087 if (F == "+hvx-length64b")
88 HasHVX = HasHVX64B = true;
89 else if (F == "+hvx-length128b")
90 HasHVX = HasHVX128B = true;
91 else if (F.find("+hvxv") != std::string::npos) {
Erich Keaneebba5922017-07-21 22:37:03 +000092 HasHVX = true;
Sumanth Gundapaneni57098f52017-10-18 18:10:13 +000093 HVXVersion = F.substr(std::string("+hvxv").length());
94 } else if (F == "-hvx")
95 HasHVX = HasHVX64B = HasHVX128B = false;
96 else if (F == "+long-calls")
Erich Keaneebba5922017-07-21 22:37:03 +000097 UseLongCalls = true;
98 else if (F == "-long-calls")
99 UseLongCalls = false;
100 }
101 return true;
102}
103
Erich Keaneebba5922017-07-21 22:37:03 +0000104const char *const HexagonTargetInfo::GCCRegNames[] = {
105 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8",
106 "r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17",
107 "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26",
108 "r27", "r28", "r29", "r30", "r31", "p0", "p1", "p2", "p3",
109 "sa0", "lc0", "sa1", "lc1", "m0", "m1", "usr", "ugp"
110};
111
112ArrayRef<const char *> HexagonTargetInfo::getGCCRegNames() const {
113 return llvm::makeArrayRef(GCCRegNames);
114}
115
116const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = {
117 {{"sp"}, "r29"},
118 {{"fp"}, "r30"},
119 {{"lr"}, "r31"},
120};
121
122ArrayRef<TargetInfo::GCCRegAlias> HexagonTargetInfo::getGCCRegAliases() const {
123 return llvm::makeArrayRef(GCCRegAliases);
124}
125
126const Builtin::Info HexagonTargetInfo::BuiltinInfo[] = {
127#define BUILTIN(ID, TYPE, ATTRS) \
128 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
129#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
130 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
131#include "clang/Basic/BuiltinsHexagon.def"
132};
133
134bool HexagonTargetInfo::hasFeature(StringRef Feature) const {
135 return llvm::StringSwitch<bool>(Feature)
136 .Case("hexagon", true)
137 .Case("hvx", HasHVX)
Sumanth Gundapaneni57098f52017-10-18 18:10:13 +0000138 .Case("hvx-length64b", HasHVX64B)
139 .Case("hvx-length128b", HasHVX128B)
Erich Keaneebba5922017-07-21 22:37:03 +0000140 .Case("long-calls", UseLongCalls)
141 .Default(false);
142}
143
Erich Keanee44bdb32018-02-08 23:16:55 +0000144struct CPUSuffix {
145 llvm::StringLiteral Name;
146 llvm::StringLiteral Suffix;
147};
148
149static constexpr CPUSuffix Suffixes[] = {
150 {{"hexagonv4"}, {"4"}}, {{"hexagonv5"}, {"5"}},
151 {{"hexagonv55"}, {"55"}}, {{"hexagonv60"}, {"60"}},
152 {{"hexagonv62"}, {"62"}}, {{"hexagonv65"}, {"65"}},
153};
154
Erich Keaneebba5922017-07-21 22:37:03 +0000155const char *HexagonTargetInfo::getHexagonCPUSuffix(StringRef Name) {
Erich Keanee44bdb32018-02-08 23:16:55 +0000156 const CPUSuffix *Item = llvm::find_if(
157 Suffixes, [Name](const CPUSuffix &S) { return S.Name == Name; });
158 if (Item == std::end(Suffixes))
159 return nullptr;
160 return Item->Suffix.data();
161}
162
163void HexagonTargetInfo::fillValidCPUList(
164 SmallVectorImpl<StringRef> &Values) const {
165 for (const CPUSuffix &Suffix : Suffixes)
166 Values.push_back(Suffix.Name);
Erich Keaneebba5922017-07-21 22:37:03 +0000167}
168
169ArrayRef<Builtin::Info> HexagonTargetInfo::getTargetBuiltins() const {
170 return llvm::makeArrayRef(BuiltinInfo, clang::Hexagon::LastTSBuiltin -
171 Builtin::FirstTSBuiltin);
172}