blob: fcb94b93d69df53389ed69c19d184d5cc8b1d09a [file] [log] [blame]
Erich Keaneebba5922017-07-21 22:37:03 +00001//===--- Hexagon.cpp - Implement Hexagon target feature support -----------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Erich Keaneebba5922017-07-21 22:37:03 +00006//
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
19using namespace clang;
20using namespace clang::targets;
21
22void HexagonTargetInfo::getTargetDefines(const LangOptions &Opts,
23 MacroBuilder &Builder) const {
24 Builder.defineMacro("__qdsp6__", "1");
25 Builder.defineMacro("__hexagon__", "1");
26
Krzysztof Parzyszek57e67062018-10-19 15:36:45 +000027 if (CPU == "hexagonv5") {
Erich Keaneebba5922017-07-21 22:37:03 +000028 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");
Krzysztof Parzyszekcc5cd2c2017-12-13 13:48:07 +000047 } else if (CPU == "hexagonv65") {
48 Builder.defineMacro("__HEXAGON_V65__");
49 Builder.defineMacro("__HEXAGON_ARCH__", "65");
Krzysztof Parzyszek85393b22018-12-05 21:38:35 +000050 } else if (CPU == "hexagonv66") {
51 Builder.defineMacro("__HEXAGON_V66__");
52 Builder.defineMacro("__HEXAGON_ARCH__", "66");
Erich Keaneebba5922017-07-21 22:37:03 +000053 }
54
Sumanth Gundapaneni57098f52017-10-18 18:10:13 +000055 if (hasFeature("hvx-length64b")) {
Erich Keaneebba5922017-07-21 22:37:03 +000056 Builder.defineMacro("__HVX__");
Sumanth Gundapaneni57098f52017-10-18 18:10:13 +000057 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__");
Erich Keaneebba5922017-07-21 22:37:03 +000067 }
68}
69
70bool HexagonTargetInfo::initFeatureMap(
71 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
72 const std::vector<std::string> &FeaturesVec) const {
Erich Keaneebba5922017-07-21 22:37:03 +000073 Features["long-calls"] = false;
74
75 return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
76}
77
78bool HexagonTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
79 DiagnosticsEngine &Diags) {
80 for (auto &F : Features) {
Sumanth Gundapaneni57098f52017-10-18 18:10:13 +000081 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) {
Erich Keaneebba5922017-07-21 22:37:03 +000086 HasHVX = true;
Sumanth Gundapaneni57098f52017-10-18 18:10:13 +000087 HVXVersion = F.substr(std::string("+hvxv").length());
88 } else if (F == "-hvx")
89 HasHVX = HasHVX64B = HasHVX128B = false;
90 else if (F == "+long-calls")
Erich Keaneebba5922017-07-21 22:37:03 +000091 UseLongCalls = true;
92 else if (F == "-long-calls")
93 UseLongCalls = false;
94 }
95 return true;
96}
97
Erich Keaneebba5922017-07-21 22:37:03 +000098const 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",
Krzysztof Parzyszek99f51962019-10-28 15:12:43 -0500103 "sa0", "lc0", "sa1", "lc1", "m0", "m1", "usr", "ugp",
104 "r1:0", "r3:2", "r5:4", "r7:6", "r9:8", "r11:10", "r13:12", "r15:14",
105 "r17:16", "r19:18", "r21:20", "r23:22", "r25:24", "r27:26", "r29:28",
106 "r31:30"
Erich Keaneebba5922017-07-21 22:37:03 +0000107};
108
109ArrayRef<const char *> HexagonTargetInfo::getGCCRegNames() const {
110 return llvm::makeArrayRef(GCCRegNames);
111}
112
113const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = {
114 {{"sp"}, "r29"},
115 {{"fp"}, "r30"},
116 {{"lr"}, "r31"},
117};
118
119ArrayRef<TargetInfo::GCCRegAlias> HexagonTargetInfo::getGCCRegAliases() const {
120 return llvm::makeArrayRef(GCCRegAliases);
121}
122
123const Builtin::Info HexagonTargetInfo::BuiltinInfo[] = {
124#define BUILTIN(ID, TYPE, ATTRS) \
125 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
126#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
127 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
128#include "clang/Basic/BuiltinsHexagon.def"
129};
130
131bool HexagonTargetInfo::hasFeature(StringRef Feature) const {
Krzysztof Parzyszek762dee52018-07-12 18:54:04 +0000132 std::string VS = "hvxv" + HVXVersion;
133 if (Feature == VS)
134 return true;
135
Erich Keaneebba5922017-07-21 22:37:03 +0000136 return llvm::StringSwitch<bool>(Feature)
137 .Case("hexagon", true)
138 .Case("hvx", HasHVX)
Sumanth Gundapaneni57098f52017-10-18 18:10:13 +0000139 .Case("hvx-length64b", HasHVX64B)
140 .Case("hvx-length128b", HasHVX128B)
Erich Keaneebba5922017-07-21 22:37:03 +0000141 .Case("long-calls", UseLongCalls)
142 .Default(false);
143}
144
Erich Keanee44bdb32018-02-08 23:16:55 +0000145struct CPUSuffix {
146 llvm::StringLiteral Name;
147 llvm::StringLiteral Suffix;
148};
149
150static constexpr CPUSuffix Suffixes[] = {
Krzysztof Parzyszek57e67062018-10-19 15:36:45 +0000151 {{"hexagonv5"}, {"5"}}, {{"hexagonv55"}, {"55"}},
152 {{"hexagonv60"}, {"60"}}, {{"hexagonv62"}, {"62"}},
Krzysztof Parzyszek85393b22018-12-05 21:38:35 +0000153 {{"hexagonv65"}, {"65"}}, {{"hexagonv66"}, {"66"}},
Erich Keanee44bdb32018-02-08 23:16:55 +0000154};
155
Erich Keaneebba5922017-07-21 22:37:03 +0000156const char *HexagonTargetInfo::getHexagonCPUSuffix(StringRef Name) {
Erich Keanee44bdb32018-02-08 23:16:55 +0000157 const CPUSuffix *Item = llvm::find_if(
158 Suffixes, [Name](const CPUSuffix &S) { return S.Name == Name; });
159 if (Item == std::end(Suffixes))
160 return nullptr;
161 return Item->Suffix.data();
162}
163
164void HexagonTargetInfo::fillValidCPUList(
165 SmallVectorImpl<StringRef> &Values) const {
166 for (const CPUSuffix &Suffix : Suffixes)
167 Values.push_back(Suffix.Name);
Erich Keaneebba5922017-07-21 22:37:03 +0000168}
169
170ArrayRef<Builtin::Info> HexagonTargetInfo::getTargetBuiltins() const {
171 return llvm::makeArrayRef(BuiltinInfo, clang::Hexagon::LastTSBuiltin -
172 Builtin::FirstTSBuiltin);
173}