Hexagon.cpp 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  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. Builder.defineMacro("__ELF__");
  24. // The macro __HVXDBL__ is deprecated.
  25. bool DefineHvxDbl = false;
  26. if (CPU == "hexagonv5") {
  27. Builder.defineMacro("__HEXAGON_V5__");
  28. Builder.defineMacro("__HEXAGON_ARCH__", "5");
  29. if (Opts.HexagonQdsp6Compat) {
  30. Builder.defineMacro("__QDSP6_V5__");
  31. Builder.defineMacro("__QDSP6_ARCH__", "5");
  32. }
  33. } else if (CPU == "hexagonv55") {
  34. Builder.defineMacro("__HEXAGON_V55__");
  35. Builder.defineMacro("__HEXAGON_ARCH__", "55");
  36. Builder.defineMacro("__QDSP6_V55__");
  37. Builder.defineMacro("__QDSP6_ARCH__", "55");
  38. } else if (CPU == "hexagonv60") {
  39. DefineHvxDbl = true;
  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. DefineHvxDbl = true;
  46. Builder.defineMacro("__HEXAGON_V62__");
  47. Builder.defineMacro("__HEXAGON_ARCH__", "62");
  48. } else if (CPU == "hexagonv65") {
  49. DefineHvxDbl = true;
  50. Builder.defineMacro("__HEXAGON_V65__");
  51. Builder.defineMacro("__HEXAGON_ARCH__", "65");
  52. } else if (CPU == "hexagonv66") {
  53. DefineHvxDbl = true;
  54. Builder.defineMacro("__HEXAGON_V66__");
  55. Builder.defineMacro("__HEXAGON_ARCH__", "66");
  56. } else if (CPU == "hexagonv67") {
  57. Builder.defineMacro("__HEXAGON_V67__");
  58. Builder.defineMacro("__HEXAGON_ARCH__", "67");
  59. } else if (CPU == "hexagonv67t") {
  60. Builder.defineMacro("__HEXAGON_V67T__");
  61. Builder.defineMacro("__HEXAGON_ARCH__", "67");
  62. } else if (CPU == "hexagonv68") {
  63. Builder.defineMacro("__HEXAGON_V68__");
  64. Builder.defineMacro("__HEXAGON_ARCH__", "68");
  65. } else if (CPU == "hexagonv69") {
  66. Builder.defineMacro("__HEXAGON_V69__");
  67. Builder.defineMacro("__HEXAGON_ARCH__", "69");
  68. } else if (CPU == "hexagonv71") {
  69. Builder.defineMacro("__HEXAGON_V71__");
  70. Builder.defineMacro("__HEXAGON_ARCH__", "71");
  71. } else if (CPU == "hexagonv71t") {
  72. Builder.defineMacro("__HEXAGON_V71T__");
  73. Builder.defineMacro("__HEXAGON_ARCH__", "71");
  74. } else if (CPU == "hexagonv73") {
  75. Builder.defineMacro("__HEXAGON_V73__");
  76. Builder.defineMacro("__HEXAGON_ARCH__", "73");
  77. }
  78. if (hasFeature("hvx-length64b")) {
  79. Builder.defineMacro("__HVX__");
  80. Builder.defineMacro("__HVX_ARCH__", HVXVersion);
  81. Builder.defineMacro("__HVX_LENGTH__", "64");
  82. }
  83. if (hasFeature("hvx-length128b")) {
  84. Builder.defineMacro("__HVX__");
  85. Builder.defineMacro("__HVX_ARCH__", HVXVersion);
  86. Builder.defineMacro("__HVX_LENGTH__", "128");
  87. if (DefineHvxDbl)
  88. Builder.defineMacro("__HVXDBL__");
  89. }
  90. if (hasFeature("audio")) {
  91. Builder.defineMacro("__HEXAGON_AUDIO__");
  92. }
  93. std::string NumPhySlots = isTinyCore() ? "3" : "4";
  94. Builder.defineMacro("__HEXAGON_PHYSICAL_SLOTS__", NumPhySlots);
  95. Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
  96. Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
  97. Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
  98. Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
  99. }
  100. bool HexagonTargetInfo::initFeatureMap(
  101. llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
  102. const std::vector<std::string> &FeaturesVec) const {
  103. if (isTinyCore())
  104. Features["audio"] = true;
  105. StringRef CPUFeature = CPU;
  106. CPUFeature.consume_front("hexagon");
  107. CPUFeature.consume_back("t");
  108. if (!CPUFeature.empty())
  109. Features[CPUFeature] = true;
  110. Features["long-calls"] = false;
  111. return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
  112. }
  113. bool HexagonTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
  114. DiagnosticsEngine &Diags) {
  115. for (auto &F : Features) {
  116. if (F == "+hvx-length64b")
  117. HasHVX = HasHVX64B = true;
  118. else if (F == "+hvx-length128b")
  119. HasHVX = HasHVX128B = true;
  120. else if (F.find("+hvxv") != std::string::npos) {
  121. HasHVX = true;
  122. HVXVersion = F.substr(std::string("+hvxv").length());
  123. } else if (F == "-hvx")
  124. HasHVX = HasHVX64B = HasHVX128B = false;
  125. else if (F == "+long-calls")
  126. UseLongCalls = true;
  127. else if (F == "-long-calls")
  128. UseLongCalls = false;
  129. else if (F == "+audio")
  130. HasAudio = true;
  131. }
  132. if (CPU.compare("hexagonv68") >= 0) {
  133. HasLegalHalfType = true;
  134. HasFloat16 = true;
  135. }
  136. return true;
  137. }
  138. const char *const HexagonTargetInfo::GCCRegNames[] = {
  139. // Scalar registers:
  140. "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
  141. "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21",
  142. "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
  143. "r1:0", "r3:2", "r5:4", "r7:6", "r9:8", "r11:10", "r13:12", "r15:14",
  144. "r17:16", "r19:18", "r21:20", "r23:22", "r25:24", "r27:26", "r29:28",
  145. "r31:30",
  146. // Predicate registers:
  147. "p0", "p1", "p2", "p3",
  148. // Control registers:
  149. "c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "c10", "c11",
  150. "c12", "c13", "c14", "c15", "c16", "c17", "c18", "c19", "c20", "c21",
  151. "c22", "c23", "c24", "c25", "c26", "c27", "c28", "c29", "c30", "c31",
  152. "c1:0", "c3:2", "c5:4", "c7:6", "c9:8", "c11:10", "c13:12", "c15:14",
  153. "c17:16", "c19:18", "c21:20", "c23:22", "c25:24", "c27:26", "c29:28",
  154. "c31:30",
  155. // Control register aliases:
  156. "sa0", "lc0", "sa1", "lc1", "p3:0", "m0", "m1", "usr", "pc", "ugp",
  157. "gp", "cs0", "cs1", "upcyclelo", "upcyclehi", "framelimit", "framekey",
  158. "pktcountlo", "pktcounthi", "utimerlo", "utimerhi",
  159. "upcycle", "pktcount", "utimer",
  160. // HVX vector registers:
  161. "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11",
  162. "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21",
  163. "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
  164. "v1:0", "v3:2", "v5:4", "v7:6", "v9:8", "v11:10", "v13:12", "v15:14",
  165. "v17:16", "v19:18", "v21:20", "v23:22", "v25:24", "v27:26", "v29:28",
  166. "v31:30",
  167. "v3:0", "v7:4", "v11:8", "v15:12", "v19:16", "v23:20", "v27:24", "v31:28",
  168. // HVX vector predicates:
  169. "q0", "q1", "q2", "q3",
  170. };
  171. ArrayRef<const char *> HexagonTargetInfo::getGCCRegNames() const {
  172. return llvm::ArrayRef(GCCRegNames);
  173. }
  174. const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = {
  175. {{"sp"}, "r29"},
  176. {{"fp"}, "r30"},
  177. {{"lr"}, "r31"},
  178. };
  179. ArrayRef<TargetInfo::GCCRegAlias> HexagonTargetInfo::getGCCRegAliases() const {
  180. return llvm::ArrayRef(GCCRegAliases);
  181. }
  182. static constexpr Builtin::Info BuiltinInfo[] = {
  183. #define BUILTIN(ID, TYPE, ATTRS) \
  184. {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
  185. #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
  186. {#ID, TYPE, ATTRS, nullptr, HEADER, ALL_LANGUAGES},
  187. #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
  188. {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
  189. #include "clang/Basic/BuiltinsHexagon.def"
  190. };
  191. bool HexagonTargetInfo::hasFeature(StringRef Feature) const {
  192. std::string VS = "hvxv" + HVXVersion;
  193. if (Feature == VS)
  194. return true;
  195. return llvm::StringSwitch<bool>(Feature)
  196. .Case("hexagon", true)
  197. .Case("hvx", HasHVX)
  198. .Case("hvx-length64b", HasHVX64B)
  199. .Case("hvx-length128b", HasHVX128B)
  200. .Case("long-calls", UseLongCalls)
  201. .Case("audio", HasAudio)
  202. .Default(false);
  203. }
  204. struct CPUSuffix {
  205. llvm::StringLiteral Name;
  206. llvm::StringLiteral Suffix;
  207. };
  208. static constexpr CPUSuffix Suffixes[] = {
  209. {{"hexagonv5"}, {"5"}}, {{"hexagonv55"}, {"55"}},
  210. {{"hexagonv60"}, {"60"}}, {{"hexagonv62"}, {"62"}},
  211. {{"hexagonv65"}, {"65"}}, {{"hexagonv66"}, {"66"}},
  212. {{"hexagonv67"}, {"67"}}, {{"hexagonv67t"}, {"67t"}},
  213. {{"hexagonv68"}, {"68"}}, {{"hexagonv69"}, {"69"}},
  214. {{"hexagonv71"}, {"71"}}, {{"hexagonv71t"}, {"71t"}},
  215. {{"hexagonv73"}, {"73"}},
  216. };
  217. const char *HexagonTargetInfo::getHexagonCPUSuffix(StringRef Name) {
  218. const CPUSuffix *Item = llvm::find_if(
  219. Suffixes, [Name](const CPUSuffix &S) { return S.Name == Name; });
  220. if (Item == std::end(Suffixes))
  221. return nullptr;
  222. return Item->Suffix.data();
  223. }
  224. void HexagonTargetInfo::fillValidCPUList(
  225. SmallVectorImpl<StringRef> &Values) const {
  226. for (const CPUSuffix &Suffix : Suffixes)
  227. Values.push_back(Suffix.Name);
  228. }
  229. ArrayRef<Builtin::Info> HexagonTargetInfo::getTargetBuiltins() const {
  230. return llvm::ArrayRef(BuiltinInfo, clang::Hexagon::LastTSBuiltin -
  231. Builtin::FirstTSBuiltin);
  232. }