Hexagon.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  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. #include "Hexagon.h"
  13. #include "Targets.h"
  14. #include "clang/Basic/MacroBuilder.h"
  15. #include "clang/Basic/TargetBuiltins.h"
  16. #include "llvm/ADT/StringSwitch.h"
  17. using namespace clang;
  18. using namespace clang::targets;
  19. void HexagonTargetInfo::getTargetDefines(const LangOptions &Opts,
  20. MacroBuilder &Builder) const {
  21. Builder.defineMacro("__qdsp6__", "1");
  22. Builder.defineMacro("__hexagon__", "1");
  23. if (CPU == "hexagonv5") {
  24. Builder.defineMacro("__HEXAGON_V5__");
  25. Builder.defineMacro("__HEXAGON_ARCH__", "5");
  26. if (Opts.HexagonQdsp6Compat) {
  27. Builder.defineMacro("__QDSP6_V5__");
  28. Builder.defineMacro("__QDSP6_ARCH__", "5");
  29. }
  30. } else if (CPU == "hexagonv55") {
  31. Builder.defineMacro("__HEXAGON_V55__");
  32. Builder.defineMacro("__HEXAGON_ARCH__", "55");
  33. Builder.defineMacro("__QDSP6_V55__");
  34. Builder.defineMacro("__QDSP6_ARCH__", "55");
  35. } else if (CPU == "hexagonv60") {
  36. Builder.defineMacro("__HEXAGON_V60__");
  37. Builder.defineMacro("__HEXAGON_ARCH__", "60");
  38. Builder.defineMacro("__QDSP6_V60__");
  39. Builder.defineMacro("__QDSP6_ARCH__", "60");
  40. } else if (CPU == "hexagonv62") {
  41. Builder.defineMacro("__HEXAGON_V62__");
  42. Builder.defineMacro("__HEXAGON_ARCH__", "62");
  43. } else if (CPU == "hexagonv65") {
  44. Builder.defineMacro("__HEXAGON_V65__");
  45. Builder.defineMacro("__HEXAGON_ARCH__", "65");
  46. } else if (CPU == "hexagonv66") {
  47. Builder.defineMacro("__HEXAGON_V66__");
  48. Builder.defineMacro("__HEXAGON_ARCH__", "66");
  49. }
  50. if (hasFeature("hvx-length64b")) {
  51. Builder.defineMacro("__HVX__");
  52. Builder.defineMacro("__HVX_ARCH__", HVXVersion);
  53. Builder.defineMacro("__HVX_LENGTH__", "64");
  54. }
  55. if (hasFeature("hvx-length128b")) {
  56. Builder.defineMacro("__HVX__");
  57. Builder.defineMacro("__HVX_ARCH__", HVXVersion);
  58. Builder.defineMacro("__HVX_LENGTH__", "128");
  59. // FIXME: This macro is deprecated.
  60. Builder.defineMacro("__HVXDBL__");
  61. }
  62. }
  63. bool HexagonTargetInfo::initFeatureMap(
  64. llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
  65. const std::vector<std::string> &FeaturesVec) const {
  66. Features["long-calls"] = false;
  67. return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
  68. }
  69. bool HexagonTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
  70. DiagnosticsEngine &Diags) {
  71. for (auto &F : Features) {
  72. if (F == "+hvx-length64b")
  73. HasHVX = HasHVX64B = true;
  74. else if (F == "+hvx-length128b")
  75. HasHVX = HasHVX128B = true;
  76. else if (F.find("+hvxv") != std::string::npos) {
  77. HasHVX = true;
  78. HVXVersion = F.substr(std::string("+hvxv").length());
  79. } else if (F == "-hvx")
  80. HasHVX = HasHVX64B = HasHVX128B = false;
  81. else if (F == "+long-calls")
  82. UseLongCalls = true;
  83. else if (F == "-long-calls")
  84. UseLongCalls = false;
  85. }
  86. return true;
  87. }
  88. const char *const HexagonTargetInfo::GCCRegNames[] = {
  89. "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8",
  90. "r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17",
  91. "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26",
  92. "r27", "r28", "r29", "r30", "r31", "p0", "p1", "p2", "p3",
  93. "sa0", "lc0", "sa1", "lc1", "m0", "m1", "usr", "ugp"
  94. };
  95. ArrayRef<const char *> HexagonTargetInfo::getGCCRegNames() const {
  96. return llvm::makeArrayRef(GCCRegNames);
  97. }
  98. const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = {
  99. {{"sp"}, "r29"},
  100. {{"fp"}, "r30"},
  101. {{"lr"}, "r31"},
  102. };
  103. ArrayRef<TargetInfo::GCCRegAlias> HexagonTargetInfo::getGCCRegAliases() const {
  104. return llvm::makeArrayRef(GCCRegAliases);
  105. }
  106. const Builtin::Info HexagonTargetInfo::BuiltinInfo[] = {
  107. #define BUILTIN(ID, TYPE, ATTRS) \
  108. {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
  109. #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
  110. {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
  111. #include "clang/Basic/BuiltinsHexagon.def"
  112. };
  113. bool HexagonTargetInfo::hasFeature(StringRef Feature) const {
  114. std::string VS = "hvxv" + HVXVersion;
  115. if (Feature == VS)
  116. return true;
  117. return llvm::StringSwitch<bool>(Feature)
  118. .Case("hexagon", true)
  119. .Case("hvx", HasHVX)
  120. .Case("hvx-length64b", HasHVX64B)
  121. .Case("hvx-length128b", HasHVX128B)
  122. .Case("long-calls", UseLongCalls)
  123. .Default(false);
  124. }
  125. struct CPUSuffix {
  126. llvm::StringLiteral Name;
  127. llvm::StringLiteral Suffix;
  128. };
  129. static constexpr CPUSuffix Suffixes[] = {
  130. {{"hexagonv5"}, {"5"}}, {{"hexagonv55"}, {"55"}},
  131. {{"hexagonv60"}, {"60"}}, {{"hexagonv62"}, {"62"}},
  132. {{"hexagonv65"}, {"65"}}, {{"hexagonv66"}, {"66"}},
  133. };
  134. const char *HexagonTargetInfo::getHexagonCPUSuffix(StringRef Name) {
  135. const CPUSuffix *Item = llvm::find_if(
  136. Suffixes, [Name](const CPUSuffix &S) { return S.Name == Name; });
  137. if (Item == std::end(Suffixes))
  138. return nullptr;
  139. return Item->Suffix.data();
  140. }
  141. void HexagonTargetInfo::fillValidCPUList(
  142. SmallVectorImpl<StringRef> &Values) const {
  143. for (const CPUSuffix &Suffix : Suffixes)
  144. Values.push_back(Suffix.Name);
  145. }
  146. ArrayRef<Builtin::Info> HexagonTargetInfo::getTargetBuiltins() const {
  147. return llvm::makeArrayRef(BuiltinInfo, clang::Hexagon::LastTSBuiltin -
  148. Builtin::FirstTSBuiltin);
  149. }