296 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements Hexagon TargetInfo objects.10//11//===----------------------------------------------------------------------===//12 13#include "Hexagon.h"14#include "clang/Basic/MacroBuilder.h"15#include "clang/Basic/TargetBuiltins.h"16#include "llvm/ADT/StringSwitch.h"17 18using namespace clang;19using namespace clang::targets;20 21void HexagonTargetInfo::getTargetDefines(const LangOptions &Opts,22 MacroBuilder &Builder) const {23 Builder.defineMacro("__qdsp6__", "1");24 Builder.defineMacro("__hexagon__", "1");25 26 // The macro __HVXDBL__ is deprecated.27 bool DefineHvxDbl = false;28 29 if (CPU == "hexagonv5") {30 Builder.defineMacro("__HEXAGON_V5__");31 Builder.defineMacro("__HEXAGON_ARCH__", "5");32 if (Opts.HexagonQdsp6Compat) {33 Builder.defineMacro("__QDSP6_V5__");34 Builder.defineMacro("__QDSP6_ARCH__", "5");35 }36 } else if (CPU == "hexagonv55") {37 Builder.defineMacro("__HEXAGON_V55__");38 Builder.defineMacro("__HEXAGON_ARCH__", "55");39 Builder.defineMacro("__QDSP6_V55__");40 Builder.defineMacro("__QDSP6_ARCH__", "55");41 } else if (CPU == "hexagonv60") {42 DefineHvxDbl = true;43 Builder.defineMacro("__HEXAGON_V60__");44 Builder.defineMacro("__HEXAGON_ARCH__", "60");45 Builder.defineMacro("__QDSP6_V60__");46 Builder.defineMacro("__QDSP6_ARCH__", "60");47 } else if (CPU == "hexagonv62") {48 DefineHvxDbl = true;49 Builder.defineMacro("__HEXAGON_V62__");50 Builder.defineMacro("__HEXAGON_ARCH__", "62");51 } else if (CPU == "hexagonv65") {52 DefineHvxDbl = true;53 Builder.defineMacro("__HEXAGON_V65__");54 Builder.defineMacro("__HEXAGON_ARCH__", "65");55 } else if (CPU == "hexagonv66") {56 DefineHvxDbl = true;57 Builder.defineMacro("__HEXAGON_V66__");58 Builder.defineMacro("__HEXAGON_ARCH__", "66");59 } else if (CPU == "hexagonv67") {60 Builder.defineMacro("__HEXAGON_V67__");61 Builder.defineMacro("__HEXAGON_ARCH__", "67");62 } else if (CPU == "hexagonv67t") {63 Builder.defineMacro("__HEXAGON_V67T__");64 Builder.defineMacro("__HEXAGON_ARCH__", "67");65 } else if (CPU == "hexagonv68") {66 Builder.defineMacro("__HEXAGON_V68__");67 Builder.defineMacro("__HEXAGON_ARCH__", "68");68 } else if (CPU == "hexagonv69") {69 Builder.defineMacro("__HEXAGON_V69__");70 Builder.defineMacro("__HEXAGON_ARCH__", "69");71 } else if (CPU == "hexagonv71") {72 Builder.defineMacro("__HEXAGON_V71__");73 Builder.defineMacro("__HEXAGON_ARCH__", "71");74 } else if (CPU == "hexagonv71t") {75 Builder.defineMacro("__HEXAGON_V71T__");76 Builder.defineMacro("__HEXAGON_ARCH__", "71");77 } else if (CPU == "hexagonv73") {78 Builder.defineMacro("__HEXAGON_V73__");79 Builder.defineMacro("__HEXAGON_ARCH__", "73");80 } else if (CPU == "hexagonv75") {81 Builder.defineMacro("__HEXAGON_V75__");82 Builder.defineMacro("__HEXAGON_ARCH__", "75");83 } else if (CPU == "hexagonv79") {84 Builder.defineMacro("__HEXAGON_V79__");85 Builder.defineMacro("__HEXAGON_ARCH__", "79");86 } else if (CPU == "hexagonv81") {87 Builder.defineMacro("__HEXAGON_V81__");88 Builder.defineMacro("__HEXAGON_ARCH__", "81");89 }90 91 if (hasFeature("hvx-length64b")) {92 Builder.defineMacro("__HVX__");93 Builder.defineMacro("__HVX_ARCH__", HVXVersion);94 Builder.defineMacro("__HVX_LENGTH__", "64");95 }96 97 if (hasFeature("hvx-length128b")) {98 Builder.defineMacro("__HVX__");99 Builder.defineMacro("__HVX_ARCH__", HVXVersion);100 Builder.defineMacro("__HVX_LENGTH__", "128");101 if (DefineHvxDbl)102 Builder.defineMacro("__HVXDBL__");103 }104 105 if (hasFeature("audio")) {106 Builder.defineMacro("__HEXAGON_AUDIO__");107 }108 109 std::string NumPhySlots = isTinyCore() ? "3" : "4";110 Builder.defineMacro("__HEXAGON_PHYSICAL_SLOTS__", NumPhySlots);111 112 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");113 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");114 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");115 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");116}117 118bool HexagonTargetInfo::initFeatureMap(119 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,120 const std::vector<std::string> &FeaturesVec) const {121 if (isTinyCore())122 Features["audio"] = true;123 124 StringRef CPUFeature = CPU;125 CPUFeature.consume_front("hexagon");126 CPUFeature.consume_back("t");127 if (!CPUFeature.empty())128 Features[CPUFeature] = true;129 130 Features["long-calls"] = false;131 132 return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);133}134 135bool HexagonTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,136 DiagnosticsEngine &Diags) {137 for (auto &F : Features) {138 if (F == "+hvx-length64b")139 HasHVX = HasHVX64B = true;140 else if (F == "+hvx-length128b")141 HasHVX = HasHVX128B = true;142 else if (F.find("+hvxv") != std::string::npos) {143 HasHVX = true;144 HVXVersion = F.substr(std::string("+hvxv").length());145 } else if (F == "-hvx")146 HasHVX = HasHVX64B = HasHVX128B = false;147 else if (F == "+long-calls")148 UseLongCalls = true;149 else if (F == "-long-calls")150 UseLongCalls = false;151 else if (F == "+audio")152 HasAudio = true;153 }154 if (CPU.compare("hexagonv68") >= 0) {155 HasFastHalfType = true;156 HasFloat16 = true;157 }158 if (CPU.compare("hexagonv81") >= 0)159 HasBFloat16 = true;160 161 return true;162}163 164bool HexagonTargetInfo::hasBFloat16Type() const { return HasBFloat16; }165 166const char *const HexagonTargetInfo::GCCRegNames[] = {167 // Scalar registers:168 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",169 "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21",170 "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",171 "r1:0", "r3:2", "r5:4", "r7:6", "r9:8", "r11:10", "r13:12", "r15:14",172 "r17:16", "r19:18", "r21:20", "r23:22", "r25:24", "r27:26", "r29:28",173 "r31:30",174 // Predicate registers:175 "p0", "p1", "p2", "p3",176 // Control registers:177 "c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "c10", "c11",178 "c12", "c13", "c14", "c15", "c16", "c17", "c18", "c19", "c20", "c21",179 "c22", "c23", "c24", "c25", "c26", "c27", "c28", "c29", "c30", "c31",180 "c1:0", "c3:2", "c5:4", "c7:6", "c9:8", "c11:10", "c13:12", "c15:14",181 "c17:16", "c19:18", "c21:20", "c23:22", "c25:24", "c27:26", "c29:28",182 "c31:30",183 // Control register aliases:184 "sa0", "lc0", "sa1", "lc1", "p3:0", "m0", "m1", "usr", "pc", "ugp",185 "gp", "cs0", "cs1", "upcyclelo", "upcyclehi", "framelimit", "framekey",186 "pktcountlo", "pktcounthi", "utimerlo", "utimerhi",187 "upcycle", "pktcount", "utimer",188 // HVX vector registers:189 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11",190 "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21",191 "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",192 "v1:0", "v3:2", "v5:4", "v7:6", "v9:8", "v11:10", "v13:12", "v15:14",193 "v17:16", "v19:18", "v21:20", "v23:22", "v25:24", "v27:26", "v29:28",194 "v31:30",195 "v3:0", "v7:4", "v11:8", "v15:12", "v19:16", "v23:20", "v27:24", "v31:28",196 // HVX vector predicates:197 "q0", "q1", "q2", "q3",198};199 200ArrayRef<const char *> HexagonTargetInfo::getGCCRegNames() const {201 return llvm::ArrayRef(GCCRegNames);202}203 204const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = {205 {{"sp"}, "r29"},206 {{"fp"}, "r30"},207 {{"lr"}, "r31"},208};209 210ArrayRef<TargetInfo::GCCRegAlias> HexagonTargetInfo::getGCCRegAliases() const {211 return llvm::ArrayRef(GCCRegAliases);212}213 214static constexpr int NumBuiltins =215 clang::Hexagon::LastTSBuiltin - Builtin::FirstTSBuiltin;216 217#define GET_BUILTIN_STR_TABLE218#include "clang/Basic/BuiltinsHexagon.inc"219#undef GET_BUILTIN_STR_TABLE220 221static constexpr Builtin::Info BuiltinInfos[] = {222#define GET_BUILTIN_INFOS223#include "clang/Basic/BuiltinsHexagon.inc"224#undef GET_BUILTIN_INFOS225};226 227static constexpr Builtin::Info PrefixedBuiltinInfos[] = {228#define GET_BUILTIN_PREFIXED_INFOS229#include "clang/Basic/BuiltinsHexagon.inc"230#undef GET_BUILTIN_PREFIXED_INFOS231};232static_assert((std::size(BuiltinInfos) + std::size(PrefixedBuiltinInfos)) ==233 NumBuiltins);234 235bool HexagonTargetInfo::hasFeature(StringRef Feature) const {236 std::string VS = "hvxv" + HVXVersion;237 if (Feature == VS)238 return true;239 240 return llvm::StringSwitch<bool>(Feature)241 .Case("hexagon", true)242 .Case("hvx", HasHVX)243 .Case("hvx-length64b", HasHVX64B)244 .Case("hvx-length128b", HasHVX128B)245 .Case("long-calls", UseLongCalls)246 .Case("audio", HasAudio)247 .Default(false);248}249 250struct CPUSuffix {251 llvm::StringLiteral Name;252 llvm::StringLiteral Suffix;253};254 255static constexpr CPUSuffix Suffixes[] = {256 {{"hexagonv5"}, {"5"}}, {{"hexagonv55"}, {"55"}},257 {{"hexagonv60"}, {"60"}}, {{"hexagonv62"}, {"62"}},258 {{"hexagonv65"}, {"65"}}, {{"hexagonv66"}, {"66"}},259 {{"hexagonv67"}, {"67"}}, {{"hexagonv67t"}, {"67t"}},260 {{"hexagonv68"}, {"68"}}, {{"hexagonv69"}, {"69"}},261 {{"hexagonv71"}, {"71"}}, {{"hexagonv71t"}, {"71t"}},262 {{"hexagonv73"}, {"73"}}, {{"hexagonv75"}, {"75"}},263 {{"hexagonv79"}, {"79"}}, {{"hexagonv81"}, {"81"}}};264 265std::optional<unsigned> HexagonTargetInfo::getHexagonCPURev(StringRef Name) {266 StringRef Arch = Name;267 Arch.consume_front("hexagonv");268 Arch.consume_back("t");269 270 unsigned Val;271 if (!Arch.getAsInteger(0, Val))272 return Val;273 274 return std::nullopt;275}276 277const char *HexagonTargetInfo::getHexagonCPUSuffix(StringRef Name) {278 const CPUSuffix *Item = llvm::find_if(279 Suffixes, [Name](const CPUSuffix &S) { return S.Name == Name; });280 if (Item == std::end(Suffixes))281 return nullptr;282 return Item->Suffix.data();283}284 285void HexagonTargetInfo::fillValidCPUList(286 SmallVectorImpl<StringRef> &Values) const {287 for (const CPUSuffix &Suffix : Suffixes)288 Values.push_back(Suffix.Name);289}290 291llvm::SmallVector<Builtin::InfosShard>292HexagonTargetInfo::getTargetBuiltins() const {293 return {{&BuiltinStrings, BuiltinInfos},294 {&BuiltinStrings, PrefixedBuiltinInfos, "__builtin_HEXAGON_"}};295}296