blob: 0ef1f6db281eaa2fd6fbf683ae42ed71b710f725 [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["long-calls"] = false;
79
80 return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
81}
82
83bool HexagonTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
84 DiagnosticsEngine &Diags) {
85 for (auto &F : Features) {
Sumanth Gundapaneni57098f52017-10-18 18:10:13 +000086 if (F == "+hvx-length64b")
87 HasHVX = HasHVX64B = true;
88 else if (F == "+hvx-length128b")
89 HasHVX = HasHVX128B = true;
90 else if (F.find("+hvxv") != std::string::npos) {
Erich Keaneebba5922017-07-21 22:37:03 +000091 HasHVX = true;
Sumanth Gundapaneni57098f52017-10-18 18:10:13 +000092 HVXVersion = F.substr(std::string("+hvxv").length());
93 } else if (F == "-hvx")
94 HasHVX = HasHVX64B = HasHVX128B = false;
95 else if (F == "+long-calls")
Erich Keaneebba5922017-07-21 22:37:03 +000096 UseLongCalls = true;
97 else if (F == "-long-calls")
98 UseLongCalls = false;
99 }
100 return true;
101}
102
Erich Keaneebba5922017-07-21 22:37:03 +0000103const char *const HexagonTargetInfo::GCCRegNames[] = {
104 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8",
105 "r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17",
106 "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26",
107 "r27", "r28", "r29", "r30", "r31", "p0", "p1", "p2", "p3",
108 "sa0", "lc0", "sa1", "lc1", "m0", "m1", "usr", "ugp"
109};
110
111ArrayRef<const char *> HexagonTargetInfo::getGCCRegNames() const {
112 return llvm::makeArrayRef(GCCRegNames);
113}
114
115const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = {
116 {{"sp"}, "r29"},
117 {{"fp"}, "r30"},
118 {{"lr"}, "r31"},
119};
120
121ArrayRef<TargetInfo::GCCRegAlias> HexagonTargetInfo::getGCCRegAliases() const {
122 return llvm::makeArrayRef(GCCRegAliases);
123}
124
125const Builtin::Info HexagonTargetInfo::BuiltinInfo[] = {
126#define BUILTIN(ID, TYPE, ATTRS) \
127 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
128#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
129 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
130#include "clang/Basic/BuiltinsHexagon.def"
131};
132
133bool HexagonTargetInfo::hasFeature(StringRef Feature) const {
Krzysztof Parzyszek762dee52018-07-12 18:54:04 +0000134 std::string VS = "hvxv" + HVXVersion;
135 if (Feature == VS)
136 return true;
137
Erich Keaneebba5922017-07-21 22:37:03 +0000138 return llvm::StringSwitch<bool>(Feature)
139 .Case("hexagon", true)
140 .Case("hvx", HasHVX)
Sumanth Gundapaneni57098f52017-10-18 18:10:13 +0000141 .Case("hvx-length64b", HasHVX64B)
142 .Case("hvx-length128b", HasHVX128B)
Erich Keaneebba5922017-07-21 22:37:03 +0000143 .Case("long-calls", UseLongCalls)
144 .Default(false);
145}
146
Erich Keanee44bdb32018-02-08 23:16:55 +0000147struct CPUSuffix {
148 llvm::StringLiteral Name;
149 llvm::StringLiteral Suffix;
150};
151
152static constexpr CPUSuffix Suffixes[] = {
153 {{"hexagonv4"}, {"4"}}, {{"hexagonv5"}, {"5"}},
154 {{"hexagonv55"}, {"55"}}, {{"hexagonv60"}, {"60"}},
155 {{"hexagonv62"}, {"62"}}, {{"hexagonv65"}, {"65"}},
156};
157
Erich Keaneebba5922017-07-21 22:37:03 +0000158const char *HexagonTargetInfo::getHexagonCPUSuffix(StringRef Name) {
Erich Keanee44bdb32018-02-08 23:16:55 +0000159 const CPUSuffix *Item = llvm::find_if(
160 Suffixes, [Name](const CPUSuffix &S) { return S.Name == Name; });
161 if (Item == std::end(Suffixes))
162 return nullptr;
163 return Item->Suffix.data();
164}
165
166void HexagonTargetInfo::fillValidCPUList(
167 SmallVectorImpl<StringRef> &Values) const {
168 for (const CPUSuffix &Suffix : Suffixes)
169 Values.push_back(Suffix.Name);
Erich Keaneebba5922017-07-21 22:37:03 +0000170}
171
172ArrayRef<Builtin::Info> HexagonTargetInfo::getTargetBuiltins() const {
173 return llvm::makeArrayRef(BuiltinInfo, clang::Hexagon::LastTSBuiltin -
174 Builtin::FirstTSBuiltin);
175}