Path: blob/main/contrib/llvm-project/clang/lib/Basic/Targets/Hexagon.cpp
35269 views
//===--- Hexagon.cpp - Implement Hexagon target feature support -----------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements Hexagon TargetInfo objects.9//10//===----------------------------------------------------------------------===//1112#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"1718using namespace clang;19using namespace clang::targets;2021void HexagonTargetInfo::getTargetDefines(const LangOptions &Opts,22MacroBuilder &Builder) const {23Builder.defineMacro("__qdsp6__", "1");24Builder.defineMacro("__hexagon__", "1");2526// The macro __HVXDBL__ is deprecated.27bool DefineHvxDbl = false;2829if (CPU == "hexagonv5") {30Builder.defineMacro("__HEXAGON_V5__");31Builder.defineMacro("__HEXAGON_ARCH__", "5");32if (Opts.HexagonQdsp6Compat) {33Builder.defineMacro("__QDSP6_V5__");34Builder.defineMacro("__QDSP6_ARCH__", "5");35}36} else if (CPU == "hexagonv55") {37Builder.defineMacro("__HEXAGON_V55__");38Builder.defineMacro("__HEXAGON_ARCH__", "55");39Builder.defineMacro("__QDSP6_V55__");40Builder.defineMacro("__QDSP6_ARCH__", "55");41} else if (CPU == "hexagonv60") {42DefineHvxDbl = true;43Builder.defineMacro("__HEXAGON_V60__");44Builder.defineMacro("__HEXAGON_ARCH__", "60");45Builder.defineMacro("__QDSP6_V60__");46Builder.defineMacro("__QDSP6_ARCH__", "60");47} else if (CPU == "hexagonv62") {48DefineHvxDbl = true;49Builder.defineMacro("__HEXAGON_V62__");50Builder.defineMacro("__HEXAGON_ARCH__", "62");51} else if (CPU == "hexagonv65") {52DefineHvxDbl = true;53Builder.defineMacro("__HEXAGON_V65__");54Builder.defineMacro("__HEXAGON_ARCH__", "65");55} else if (CPU == "hexagonv66") {56DefineHvxDbl = true;57Builder.defineMacro("__HEXAGON_V66__");58Builder.defineMacro("__HEXAGON_ARCH__", "66");59} else if (CPU == "hexagonv67") {60Builder.defineMacro("__HEXAGON_V67__");61Builder.defineMacro("__HEXAGON_ARCH__", "67");62} else if (CPU == "hexagonv67t") {63Builder.defineMacro("__HEXAGON_V67T__");64Builder.defineMacro("__HEXAGON_ARCH__", "67");65} else if (CPU == "hexagonv68") {66Builder.defineMacro("__HEXAGON_V68__");67Builder.defineMacro("__HEXAGON_ARCH__", "68");68} else if (CPU == "hexagonv69") {69Builder.defineMacro("__HEXAGON_V69__");70Builder.defineMacro("__HEXAGON_ARCH__", "69");71} else if (CPU == "hexagonv71") {72Builder.defineMacro("__HEXAGON_V71__");73Builder.defineMacro("__HEXAGON_ARCH__", "71");74} else if (CPU == "hexagonv71t") {75Builder.defineMacro("__HEXAGON_V71T__");76Builder.defineMacro("__HEXAGON_ARCH__", "71");77} else if (CPU == "hexagonv73") {78Builder.defineMacro("__HEXAGON_V73__");79Builder.defineMacro("__HEXAGON_ARCH__", "73");80}8182if (hasFeature("hvx-length64b")) {83Builder.defineMacro("__HVX__");84Builder.defineMacro("__HVX_ARCH__", HVXVersion);85Builder.defineMacro("__HVX_LENGTH__", "64");86}8788if (hasFeature("hvx-length128b")) {89Builder.defineMacro("__HVX__");90Builder.defineMacro("__HVX_ARCH__", HVXVersion);91Builder.defineMacro("__HVX_LENGTH__", "128");92if (DefineHvxDbl)93Builder.defineMacro("__HVXDBL__");94}9596if (hasFeature("audio")) {97Builder.defineMacro("__HEXAGON_AUDIO__");98}99100std::string NumPhySlots = isTinyCore() ? "3" : "4";101Builder.defineMacro("__HEXAGON_PHYSICAL_SLOTS__", NumPhySlots);102103Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");104Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");105Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");106Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");107}108109bool HexagonTargetInfo::initFeatureMap(110llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,111const std::vector<std::string> &FeaturesVec) const {112if (isTinyCore())113Features["audio"] = true;114115StringRef CPUFeature = CPU;116CPUFeature.consume_front("hexagon");117CPUFeature.consume_back("t");118if (!CPUFeature.empty())119Features[CPUFeature] = true;120121Features["long-calls"] = false;122123return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);124}125126bool HexagonTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,127DiagnosticsEngine &Diags) {128for (auto &F : Features) {129if (F == "+hvx-length64b")130HasHVX = HasHVX64B = true;131else if (F == "+hvx-length128b")132HasHVX = HasHVX128B = true;133else if (F.find("+hvxv") != std::string::npos) {134HasHVX = true;135HVXVersion = F.substr(std::string("+hvxv").length());136} else if (F == "-hvx")137HasHVX = HasHVX64B = HasHVX128B = false;138else if (F == "+long-calls")139UseLongCalls = true;140else if (F == "-long-calls")141UseLongCalls = false;142else if (F == "+audio")143HasAudio = true;144}145if (CPU.compare("hexagonv68") >= 0) {146HasLegalHalfType = true;147HasFloat16 = true;148}149return true;150}151152const char *const HexagonTargetInfo::GCCRegNames[] = {153// Scalar registers:154"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",155"r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21",156"r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",157"r1:0", "r3:2", "r5:4", "r7:6", "r9:8", "r11:10", "r13:12", "r15:14",158"r17:16", "r19:18", "r21:20", "r23:22", "r25:24", "r27:26", "r29:28",159"r31:30",160// Predicate registers:161"p0", "p1", "p2", "p3",162// Control registers:163"c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "c10", "c11",164"c12", "c13", "c14", "c15", "c16", "c17", "c18", "c19", "c20", "c21",165"c22", "c23", "c24", "c25", "c26", "c27", "c28", "c29", "c30", "c31",166"c1:0", "c3:2", "c5:4", "c7:6", "c9:8", "c11:10", "c13:12", "c15:14",167"c17:16", "c19:18", "c21:20", "c23:22", "c25:24", "c27:26", "c29:28",168"c31:30",169// Control register aliases:170"sa0", "lc0", "sa1", "lc1", "p3:0", "m0", "m1", "usr", "pc", "ugp",171"gp", "cs0", "cs1", "upcyclelo", "upcyclehi", "framelimit", "framekey",172"pktcountlo", "pktcounthi", "utimerlo", "utimerhi",173"upcycle", "pktcount", "utimer",174// HVX vector registers:175"v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11",176"v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21",177"v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",178"v1:0", "v3:2", "v5:4", "v7:6", "v9:8", "v11:10", "v13:12", "v15:14",179"v17:16", "v19:18", "v21:20", "v23:22", "v25:24", "v27:26", "v29:28",180"v31:30",181"v3:0", "v7:4", "v11:8", "v15:12", "v19:16", "v23:20", "v27:24", "v31:28",182// HVX vector predicates:183"q0", "q1", "q2", "q3",184};185186ArrayRef<const char *> HexagonTargetInfo::getGCCRegNames() const {187return llvm::ArrayRef(GCCRegNames);188}189190const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = {191{{"sp"}, "r29"},192{{"fp"}, "r30"},193{{"lr"}, "r31"},194};195196ArrayRef<TargetInfo::GCCRegAlias> HexagonTargetInfo::getGCCRegAliases() const {197return llvm::ArrayRef(GCCRegAliases);198}199200static constexpr Builtin::Info BuiltinInfo[] = {201#define BUILTIN(ID, TYPE, ATTRS) \202{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},203#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \204{#ID, TYPE, ATTRS, nullptr, HEADER, ALL_LANGUAGES},205#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \206{#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},207#include "clang/Basic/BuiltinsHexagon.def"208};209210bool HexagonTargetInfo::hasFeature(StringRef Feature) const {211std::string VS = "hvxv" + HVXVersion;212if (Feature == VS)213return true;214215return llvm::StringSwitch<bool>(Feature)216.Case("hexagon", true)217.Case("hvx", HasHVX)218.Case("hvx-length64b", HasHVX64B)219.Case("hvx-length128b", HasHVX128B)220.Case("long-calls", UseLongCalls)221.Case("audio", HasAudio)222.Default(false);223}224225struct CPUSuffix {226llvm::StringLiteral Name;227llvm::StringLiteral Suffix;228};229230static constexpr CPUSuffix Suffixes[] = {231{{"hexagonv5"}, {"5"}}, {{"hexagonv55"}, {"55"}},232{{"hexagonv60"}, {"60"}}, {{"hexagonv62"}, {"62"}},233{{"hexagonv65"}, {"65"}}, {{"hexagonv66"}, {"66"}},234{{"hexagonv67"}, {"67"}}, {{"hexagonv67t"}, {"67t"}},235{{"hexagonv68"}, {"68"}}, {{"hexagonv69"}, {"69"}},236{{"hexagonv71"}, {"71"}}, {{"hexagonv71t"}, {"71t"}},237{{"hexagonv73"}, {"73"}},238};239240std::optional<unsigned> HexagonTargetInfo::getHexagonCPURev(StringRef Name) {241StringRef Arch = Name;242Arch.consume_front("hexagonv");243Arch.consume_back("t");244245unsigned Val;246if (!Arch.getAsInteger(0, Val))247return Val;248249return std::nullopt;250}251252const char *HexagonTargetInfo::getHexagonCPUSuffix(StringRef Name) {253const CPUSuffix *Item = llvm::find_if(254Suffixes, [Name](const CPUSuffix &S) { return S.Name == Name; });255if (Item == std::end(Suffixes))256return nullptr;257return Item->Suffix.data();258}259260void HexagonTargetInfo::fillValidCPUList(261SmallVectorImpl<StringRef> &Values) const {262for (const CPUSuffix &Suffix : Suffixes)263Values.push_back(Suffix.Name);264}265266ArrayRef<Builtin::Info> HexagonTargetInfo::getTargetBuiltins() const {267return llvm::ArrayRef(BuiltinInfo, clang::Hexagon::LastTSBuiltin -268Builtin::FirstTSBuiltin);269}270271272