blob: be23fd2536e0771504f766c2897f5e2a7a448d05 [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",
103 "sa0", "lc0", "sa1", "lc1", "m0", "m1", "usr", "ugp"
104};
105
106ArrayRef<const char *> HexagonTargetInfo::getGCCRegNames() const {
107 return llvm::makeArrayRef(GCCRegNames);
108}
109
110const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = {
111 {{"sp"}, "r29"},
112 {{"fp"}, "r30"},
113 {{"lr"}, "r31"},
114};
115
116ArrayRef<TargetInfo::GCCRegAlias> HexagonTargetInfo::getGCCRegAliases() const {
117 return llvm::makeArrayRef(GCCRegAliases);
118}
119
120const 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
128bool HexagonTargetInfo::hasFeature(StringRef Feature) const {
Krzysztof Parzyszek762dee52018-07-12 18:54:04 +0000129 std::string VS = "hvxv" + HVXVersion;
130 if (Feature == VS)
131 return true;
132
Erich Keaneebba5922017-07-21 22:37:03 +0000133 return llvm::StringSwitch<bool>(Feature)
134 .Case("hexagon", true)
135 .Case("hvx", HasHVX)
Sumanth Gundapaneni57098f52017-10-18 18:10:13 +0000136 .Case("hvx-length64b", HasHVX64B)
137 .Case("hvx-length128b", HasHVX128B)
Erich Keaneebba5922017-07-21 22:37:03 +0000138 .Case("long-calls", UseLongCalls)
139 .Default(false);
140}
141
Erich Keanee44bdb32018-02-08 23:16:55 +0000142struct CPUSuffix {
143 llvm::StringLiteral Name;
144 llvm::StringLiteral Suffix;
145};
146
147static constexpr CPUSuffix Suffixes[] = {
Krzysztof Parzyszek57e67062018-10-19 15:36:45 +0000148 {{"hexagonv5"}, {"5"}}, {{"hexagonv55"}, {"55"}},
149 {{"hexagonv60"}, {"60"}}, {{"hexagonv62"}, {"62"}},
Krzysztof Parzyszek85393b22018-12-05 21:38:35 +0000150 {{"hexagonv65"}, {"65"}}, {{"hexagonv66"}, {"66"}},
Erich Keanee44bdb32018-02-08 23:16:55 +0000151};
152
Erich Keaneebba5922017-07-21 22:37:03 +0000153const char *HexagonTargetInfo::getHexagonCPUSuffix(StringRef Name) {
Erich Keanee44bdb32018-02-08 23:16:55 +0000154 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
161void HexagonTargetInfo::fillValidCPUList(
162 SmallVectorImpl<StringRef> &Values) const {
163 for (const CPUSuffix &Suffix : Suffixes)
164 Values.push_back(Suffix.Name);
Erich Keaneebba5922017-07-21 22:37:03 +0000165}
166
167ArrayRef<Builtin::Info> HexagonTargetInfo::getTargetBuiltins() const {
168 return llvm::makeArrayRef(BuiltinInfo, clang::Hexagon::LastTSBuiltin -
169 Builtin::FirstTSBuiltin);
170}