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 19 using namespace clang; 20 using namespace clang::targets; 21 22 void 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 70 bool 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 78 bool 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 98 const 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 106 ArrayRef<const char *> HexagonTargetInfo::getGCCRegNames() const { 107 return llvm::makeArrayRef(GCCRegNames); 108 } 109 110 const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = { 111 {{"sp"}, "r29"}, 112 {{"fp"}, "r30"}, 113 {{"lr"}, "r31"}, 114 }; 115 116 ArrayRef<TargetInfo::GCCRegAlias> HexagonTargetInfo::getGCCRegAliases() const { 117 return llvm::makeArrayRef(GCCRegAliases); 118 } 119 120 const 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 128 bool 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 142 struct CPUSuffix { 143 llvm::StringLiteral Name; 144 llvm::StringLiteral Suffix; 145 }; 146 147 static constexpr CPUSuffix Suffixes[] = { 148 {{"hexagonv5"}, {"5"}}, {{"hexagonv55"}, {"55"}}, 149 {{"hexagonv60"}, {"60"}}, {{"hexagonv62"}, {"62"}}, 150 {{"hexagonv65"}, {"65"}}, {{"hexagonv66"}, {"66"}}, 151 }; 152 153 const 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 161 void HexagonTargetInfo::fillValidCPUList( 162 SmallVectorImpl<StringRef> &Values) const { 163 for (const CPUSuffix &Suffix : Suffixes) 164 Values.push_back(Suffix.Name); 165 } 166 167 ArrayRef<Builtin::Info> HexagonTargetInfo::getTargetBuiltins() const { 168 return llvm::makeArrayRef(BuiltinInfo, clang::Hexagon::LastTSBuiltin - 169 Builtin::FirstTSBuiltin); 170 } 171