Clang Project

clang_source_code/lib/Basic/Targets/Hexagon.cpp
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
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
27  if (CPU == "hexagonv5") {
28    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");
47  } else if (CPU == "hexagonv65") {
48    Builder.defineMacro("__HEXAGON_V65__");
49    Builder.defineMacro("__HEXAGON_ARCH__""65");
50  } else if (CPU == "hexagonv66") {
51    Builder.defineMacro("__HEXAGON_V66__");
52    Builder.defineMacro("__HEXAGON_ARCH__""66");
53  }
54
55  if (hasFeature("hvx-length64b")) {
56    Builder.defineMacro("__HVX__");
57    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__");
67  }
68}
69
70bool HexagonTargetInfo::initFeatureMap(
71    llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
72    const std::vector<std::string> &FeaturesVec) const {
73  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) {
81    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) {
86      HasHVX = true;
87      HVXVersion = F.substr(std::string("+hvxv").length());
88    } else if (F == "-hvx")
89      HasHVX = HasHVX64B = HasHVX128B = false;
90    else if (F == "+long-calls")
91      UseLongCalls = true;
92    else if (F == "-long-calls")
93      UseLongCalls = false;
94  }
95  return true;
96}
97
98const 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 {
129  std::string VS = "hvxv" + HVXVersion;
130  if (Feature == VS)
131    return true;
132
133  return llvm::StringSwitch<bool>(Feature)
134      .Case("hexagon"true)
135      .Case("hvx", HasHVX)
136      .Case("hvx-length64b", HasHVX64B)
137      .Case("hvx-length128b", HasHVX128B)
138      .Case("long-calls", UseLongCalls)
139      .Default(false);
140}
141
142struct CPUSuffix {
143  llvm::StringLiteral Name;
144  llvm::StringLiteral Suffix;
145};
146
147static constexpr CPUSuffix Suffixes[] = {
148    {{"hexagonv5"},  {"5"}},  {{"hexagonv55"}, {"55"}},
149    {{"hexagonv60"}, {"60"}}, {{"hexagonv62"}, {"62"}},
150    {{"hexagonv65"}, {"65"}}, {{"hexagonv66"}, {"66"}},
151};
152
153const char *HexagonTargetInfo::getHexagonCPUSuffix(StringRef Name) {
154  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);
165}
166
167ArrayRef<Builtin::Info> HexagonTargetInfo::getTargetBuiltins() const {
168  return llvm::makeArrayRef(BuiltinInfo, clang::Hexagon::LastTSBuiltin -
169                                             Builtin::FirstTSBuiltin);
170}
171