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 == "hexagonv4") { 29 Builder.defineMacro("__HEXAGON_V4__"); 30 Builder.defineMacro("__HEXAGON_ARCH__", "4"); 31 if (Opts.HexagonQdsp6Compat) { 32 Builder.defineMacro("__QDSP6_V4__"); 33 Builder.defineMacro("__QDSP6_ARCH__", "4"); 34 } 35 } else if (CPU == "hexagonv5") { 36 Builder.defineMacro("__HEXAGON_V5__"); 37 Builder.defineMacro("__HEXAGON_ARCH__", "5"); 38 if (Opts.HexagonQdsp6Compat) { 39 Builder.defineMacro("__QDSP6_V5__"); 40 Builder.defineMacro("__QDSP6_ARCH__", "5"); 41 } 42 } else if (CPU == "hexagonv55") { 43 Builder.defineMacro("__HEXAGON_V55__"); 44 Builder.defineMacro("__HEXAGON_ARCH__", "55"); 45 Builder.defineMacro("__QDSP6_V55__"); 46 Builder.defineMacro("__QDSP6_ARCH__", "55"); 47 } else if (CPU == "hexagonv60") { 48 Builder.defineMacro("__HEXAGON_V60__"); 49 Builder.defineMacro("__HEXAGON_ARCH__", "60"); 50 Builder.defineMacro("__QDSP6_V60__"); 51 Builder.defineMacro("__QDSP6_ARCH__", "60"); 52 } else if (CPU == "hexagonv62") { 53 Builder.defineMacro("__HEXAGON_V62__"); 54 Builder.defineMacro("__HEXAGON_ARCH__", "62"); 55 } 56 57 if (hasFeature("hvx")) { 58 Builder.defineMacro("__HVX__"); 59 if (hasFeature("hvx-double")) 60 Builder.defineMacro("__HVXDBL__"); 61 } 62 } 63 64 bool HexagonTargetInfo::initFeatureMap( 65 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU, 66 const std::vector<std::string> &FeaturesVec) const { 67 // Default for v60: -hvx, -hvx-double. 68 Features["hvx"] = false; 69 Features["hvx-double"] = false; 70 Features["long-calls"] = false; 71 72 return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); 73 } 74 75 bool HexagonTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, 76 DiagnosticsEngine &Diags) { 77 for (auto &F : Features) { 78 if (F == "+hvx") 79 HasHVX = true; 80 else if (F == "-hvx") 81 HasHVX = HasHVXDouble = false; 82 else if (F == "+hvx-double") 83 HasHVX = HasHVXDouble = true; 84 else if (F == "-hvx-double") 85 HasHVXDouble = false; 86 87 if (F == "+long-calls") 88 UseLongCalls = true; 89 else if (F == "-long-calls") 90 UseLongCalls = false; 91 } 92 return true; 93 } 94 95 void HexagonTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, 96 StringRef Name, bool Enabled) const { 97 if (Enabled) { 98 if (Name == "hvx-double") 99 Features["hvx"] = true; 100 } else { 101 if (Name == "hvx") 102 Features["hvx-double"] = false; 103 } 104 Features[Name] = Enabled; 105 } 106 107 const char *const HexagonTargetInfo::GCCRegNames[] = { 108 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", 109 "r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", 110 "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", 111 "r27", "r28", "r29", "r30", "r31", "p0", "p1", "p2", "p3", 112 "sa0", "lc0", "sa1", "lc1", "m0", "m1", "usr", "ugp" 113 }; 114 115 ArrayRef<const char *> HexagonTargetInfo::getGCCRegNames() const { 116 return llvm::makeArrayRef(GCCRegNames); 117 } 118 119 const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = { 120 {{"sp"}, "r29"}, 121 {{"fp"}, "r30"}, 122 {{"lr"}, "r31"}, 123 }; 124 125 ArrayRef<TargetInfo::GCCRegAlias> HexagonTargetInfo::getGCCRegAliases() const { 126 return llvm::makeArrayRef(GCCRegAliases); 127 } 128 129 const Builtin::Info HexagonTargetInfo::BuiltinInfo[] = { 130 #define BUILTIN(ID, TYPE, ATTRS) \ 131 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, 132 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ 133 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr}, 134 #include "clang/Basic/BuiltinsHexagon.def" 135 }; 136 137 bool HexagonTargetInfo::hasFeature(StringRef Feature) const { 138 return llvm::StringSwitch<bool>(Feature) 139 .Case("hexagon", true) 140 .Case("hvx", HasHVX) 141 .Case("hvx-double", HasHVXDouble) 142 .Case("long-calls", UseLongCalls) 143 .Default(false); 144 } 145 146 const char *HexagonTargetInfo::getHexagonCPUSuffix(StringRef Name) { 147 return llvm::StringSwitch<const char *>(Name) 148 .Case("hexagonv4", "4") 149 .Case("hexagonv5", "5") 150 .Case("hexagonv55", "55") 151 .Case("hexagonv60", "60") 152 .Case("hexagonv62", "62") 153 .Default(nullptr); 154 } 155 156 ArrayRef<Builtin::Info> HexagonTargetInfo::getTargetBuiltins() const { 157 return llvm::makeArrayRef(BuiltinInfo, clang::Hexagon::LastTSBuiltin - 158 Builtin::FirstTSBuiltin); 159 } 160