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