diff options
Diffstat (limited to 'clang/lib/Basic/Targets/Hexagon.cpp')
| -rw-r--r-- | clang/lib/Basic/Targets/Hexagon.cpp | 170 | 
1 files changed, 170 insertions, 0 deletions
| diff --git a/clang/lib/Basic/Targets/Hexagon.cpp b/clang/lib/Basic/Targets/Hexagon.cpp new file mode 100644 index 000000000000..be23fd2536e0 --- /dev/null +++ b/clang/lib/Basic/Targets/Hexagon.cpp @@ -0,0 +1,170 @@ +//===--- Hexagon.cpp - Implement Hexagon target feature support -----------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements Hexagon TargetInfo objects. +// +//===----------------------------------------------------------------------===// + +#include "Hexagon.h" +#include "Targets.h" +#include "clang/Basic/MacroBuilder.h" +#include "clang/Basic/TargetBuiltins.h" +#include "llvm/ADT/StringSwitch.h" + +using namespace clang; +using namespace clang::targets; + +void HexagonTargetInfo::getTargetDefines(const LangOptions &Opts, +                                         MacroBuilder &Builder) const { +  Builder.defineMacro("__qdsp6__", "1"); +  Builder.defineMacro("__hexagon__", "1"); + +  if (CPU == "hexagonv5") { +    Builder.defineMacro("__HEXAGON_V5__"); +    Builder.defineMacro("__HEXAGON_ARCH__", "5"); +    if (Opts.HexagonQdsp6Compat) { +      Builder.defineMacro("__QDSP6_V5__"); +      Builder.defineMacro("__QDSP6_ARCH__", "5"); +    } +  } else if (CPU == "hexagonv55") { +    Builder.defineMacro("__HEXAGON_V55__"); +    Builder.defineMacro("__HEXAGON_ARCH__", "55"); +    Builder.defineMacro("__QDSP6_V55__"); +    Builder.defineMacro("__QDSP6_ARCH__", "55"); +  } else if (CPU == "hexagonv60") { +    Builder.defineMacro("__HEXAGON_V60__"); +    Builder.defineMacro("__HEXAGON_ARCH__", "60"); +    Builder.defineMacro("__QDSP6_V60__"); +    Builder.defineMacro("__QDSP6_ARCH__", "60"); +  } else if (CPU == "hexagonv62") { +    Builder.defineMacro("__HEXAGON_V62__"); +    Builder.defineMacro("__HEXAGON_ARCH__", "62"); +  } else if (CPU == "hexagonv65") { +    Builder.defineMacro("__HEXAGON_V65__"); +    Builder.defineMacro("__HEXAGON_ARCH__", "65"); +  } else if (CPU == "hexagonv66") { +    Builder.defineMacro("__HEXAGON_V66__"); +    Builder.defineMacro("__HEXAGON_ARCH__", "66"); +  } + +  if (hasFeature("hvx-length64b")) { +    Builder.defineMacro("__HVX__"); +    Builder.defineMacro("__HVX_ARCH__", HVXVersion); +    Builder.defineMacro("__HVX_LENGTH__", "64"); +  } + +  if (hasFeature("hvx-length128b")) { +    Builder.defineMacro("__HVX__"); +    Builder.defineMacro("__HVX_ARCH__", HVXVersion); +    Builder.defineMacro("__HVX_LENGTH__", "128"); +    // FIXME: This macro is deprecated. +    Builder.defineMacro("__HVXDBL__"); +  } +} + +bool HexagonTargetInfo::initFeatureMap( +    llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU, +    const std::vector<std::string> &FeaturesVec) const { +  Features["long-calls"] = false; + +  return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); +} + +bool HexagonTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, +                                             DiagnosticsEngine &Diags) { +  for (auto &F : Features) { +    if (F == "+hvx-length64b") +      HasHVX = HasHVX64B = true; +    else if (F == "+hvx-length128b") +      HasHVX = HasHVX128B = true; +    else if (F.find("+hvxv") != std::string::npos) { +      HasHVX = true; +      HVXVersion = F.substr(std::string("+hvxv").length()); +    } else if (F == "-hvx") +      HasHVX = HasHVX64B = HasHVX128B = false; +    else if (F == "+long-calls") +      UseLongCalls = true; +    else if (F == "-long-calls") +      UseLongCalls = false; +  } +  return true; +} + +const char *const HexagonTargetInfo::GCCRegNames[] = { +    "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",  "r8", +    "r9",  "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", +    "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", +    "r27", "r28", "r29", "r30", "r31", "p0",  "p1",  "p2",  "p3", +    "sa0", "lc0", "sa1", "lc1", "m0",  "m1",  "usr", "ugp" +}; + +ArrayRef<const char *> HexagonTargetInfo::getGCCRegNames() const { +  return llvm::makeArrayRef(GCCRegNames); +} + +const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = { +    {{"sp"}, "r29"}, +    {{"fp"}, "r30"}, +    {{"lr"}, "r31"}, +}; + +ArrayRef<TargetInfo::GCCRegAlias> HexagonTargetInfo::getGCCRegAliases() const { +  return llvm::makeArrayRef(GCCRegAliases); +} + +const Builtin::Info HexagonTargetInfo::BuiltinInfo[] = { +#define BUILTIN(ID, TYPE, ATTRS)                                               \ +  {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, +#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)                                    \ +  {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr}, +#include "clang/Basic/BuiltinsHexagon.def" +}; + +bool HexagonTargetInfo::hasFeature(StringRef Feature) const { +  std::string VS = "hvxv" + HVXVersion; +  if (Feature == VS) +    return true; + +  return llvm::StringSwitch<bool>(Feature) +      .Case("hexagon", true) +      .Case("hvx", HasHVX) +      .Case("hvx-length64b", HasHVX64B) +      .Case("hvx-length128b", HasHVX128B) +      .Case("long-calls", UseLongCalls) +      .Default(false); +} + +struct CPUSuffix { +  llvm::StringLiteral Name; +  llvm::StringLiteral Suffix; +}; + +static constexpr CPUSuffix Suffixes[] = { +    {{"hexagonv5"},  {"5"}},  {{"hexagonv55"}, {"55"}}, +    {{"hexagonv60"}, {"60"}}, {{"hexagonv62"}, {"62"}}, +    {{"hexagonv65"}, {"65"}}, {{"hexagonv66"}, {"66"}}, +}; + +const char *HexagonTargetInfo::getHexagonCPUSuffix(StringRef Name) { +  const CPUSuffix *Item = llvm::find_if( +      Suffixes, [Name](const CPUSuffix &S) { return S.Name == Name; }); +  if (Item == std::end(Suffixes)) +    return nullptr; +  return Item->Suffix.data(); +} + +void HexagonTargetInfo::fillValidCPUList( +    SmallVectorImpl<StringRef> &Values) const { +  for (const CPUSuffix &Suffix : Suffixes) +    Values.push_back(Suffix.Name); +} + +ArrayRef<Builtin::Info> HexagonTargetInfo::getTargetBuiltins() const { +  return llvm::makeArrayRef(BuiltinInfo, clang::Hexagon::LastTSBuiltin - +                                             Builtin::FirstTSBuiltin); +} | 
