simoll updated this revision to Diff 233336.
simoll added a comment.

Trimmed to Clang changes only


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D71339/new/

https://reviews.llvm.org/D71339

Files:
  clang/lib/Basic/CMakeLists.txt
  clang/lib/Basic/Targets.cpp
  clang/lib/Basic/Targets/VE.cpp
  clang/lib/Basic/Targets/VE.h
  clang/lib/CodeGen/TargetInfo.cpp
  clang/lib/Driver/CMakeLists.txt
  clang/lib/Driver/Driver.cpp
  clang/lib/Driver/ToolChains/Arch/VE.cpp
  clang/lib/Driver/ToolChains/Arch/VE.h
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Driver/ToolChains/Clang.h
  clang/lib/Driver/ToolChains/CommonArgs.cpp
  clang/lib/Driver/ToolChains/Gnu.cpp
  clang/lib/Driver/ToolChains/Linux.cpp
  clang/lib/Driver/ToolChains/VE.cpp
  clang/lib/Driver/ToolChains/VE.h
  clang/lib/Frontend/CompilerInvocation.cpp

Index: clang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -2980,7 +2980,8 @@
                      Arch != llvm::Triple::x86;
     emitError |= (DefaultCC == LangOptions::DCC_VectorCall ||
                   DefaultCC == LangOptions::DCC_RegCall) &&
-                 !(Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64);
+                 !(Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64 ||
+                   Arch == llvm::Triple::ve);
     if (emitError)
       Diags.Report(diag::err_drv_argument_not_allowed_with)
           << A->getSpelling() << T.getTriple();
Index: clang/lib/Driver/ToolChains/VE.h
===================================================================
--- /dev/null
+++ clang/lib/Driver/ToolChains/VE.h
@@ -0,0 +1,66 @@
+//===--- VE.h - VE ToolChain Implementations --------------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_VE_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_VE_H
+
+#include "Linux.h"
+#include "clang/Driver/ToolChain.h"
+
+namespace clang {
+namespace driver {
+namespace toolchains {
+
+class LLVM_LIBRARY_VISIBILITY VEToolChain : public Linux {
+public:
+  VEToolChain(const Driver &D, const llvm::Triple &Triple,
+              const llvm::opt::ArgList &Args);
+
+protected:
+  Tool *buildAssembler() const override;
+  Tool *buildLinker() const override;
+
+public:
+  bool isPICDefault() const override;
+  bool isPIEDefault() const override;
+  bool isPICDefaultForced() const override;
+  bool SupportsProfiling() const override;
+  bool hasBlocksRuntime() const override;
+  void
+  AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+                            llvm::opt::ArgStringList &CC1Args) const override;
+  void
+  addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
+                        llvm::opt::ArgStringList &CC1Args,
+                        Action::OffloadKind DeviceOffloadKind) const override;
+  void AddClangCXXStdlibIncludeArgs(
+      const llvm::opt::ArgList &DriverArgs,
+      llvm::opt::ArgStringList &CC1Args) const override;
+  void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
+                           llvm::opt::ArgStringList &CmdArgs) const override;
+
+  llvm::ExceptionHandling
+  GetExceptionModel(const llvm::opt::ArgList &Args) const override;
+
+  CXXStdlibType
+  GetCXXStdlibType(const llvm::opt::ArgList &Args) const override {
+    return ToolChain::CST_Libcxx;
+  }
+
+  RuntimeLibType GetDefaultRuntimeLibType() const override {
+    return ToolChain::RLT_CompilerRT;
+  }
+
+  const char *getDefaultLinker() const override { return "nld"; }
+};
+
+} // end namespace toolchains
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_VE_H
Index: clang/lib/Driver/ToolChains/VE.cpp
===================================================================
--- /dev/null
+++ clang/lib/Driver/ToolChains/VE.cpp
@@ -0,0 +1,151 @@
+//===--- VE.cpp - VE ToolChain Implementations ------------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "VE.h"
+#include "CommonArgs.h"
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/Options.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include <cstdlib> // ::getenv
+
+using namespace clang::driver;
+using namespace clang::driver::toolchains;
+using namespace clang;
+using namespace llvm::opt;
+
+/// VE tool chain
+VEToolChain::VEToolChain(const Driver &D, const llvm::Triple &Triple,
+                         const ArgList &Args)
+    : Linux(D, Triple, Args) {
+  getProgramPaths().push_back("/opt/nec/ve/bin");
+  // ProgramPaths are found via 'PATH' environment variable.
+
+  // default file paths are:
+  //   ${RESOURCEDIR}/lib/linux/ve (== getArchSpecificLibPath)
+  //   /lib/../lib64
+  //   /usr/lib/../lib64
+  //   ${BINPATH}/../lib
+  //   /lib
+  //   /usr/lib
+  //
+  // These are OK for host, but no go for VE.  So, defines them all
+  // from scratch here.
+  getFilePaths().clear();
+  getFilePaths().push_back(getArchSpecificLibPath());
+  if (getTriple().isMusl())
+    getFilePaths().push_back(computeSysRoot() + "/opt/nec/ve/musl/lib");
+  else
+    getFilePaths().push_back(computeSysRoot() + "/opt/nec/ve/lib");
+}
+
+Tool *VEToolChain::buildAssembler() const {
+  return new tools::gnutools::Assembler(*this);
+}
+
+Tool *VEToolChain::buildLinker() const {
+  return new tools::gnutools::Linker(*this);
+}
+
+bool VEToolChain::isPICDefault() const { return false; }
+
+bool VEToolChain::isPIEDefault() const { return false; }
+
+bool VEToolChain::isPICDefaultForced() const { return false; }
+
+bool VEToolChain::SupportsProfiling() const { return false; }
+
+bool VEToolChain::hasBlocksRuntime() const { return false; }
+
+void VEToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
+                                            ArgStringList &CC1Args) const {
+  if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc))
+    return;
+
+  if (DriverArgs.hasArg(options::OPT_nobuiltininc) &&
+      DriverArgs.hasArg(options::OPT_nostdlibinc))
+    return;
+
+  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
+    SmallString<128> P(getDriver().ResourceDir);
+    llvm::sys::path::append(P, "include");
+    addSystemInclude(DriverArgs, CC1Args, P);
+  }
+
+  if (!DriverArgs.hasArg(options::OPT_nostdlibinc)) {
+    if (const char *cl_include_dir = getenv("NCC_C_INCLUDE_PATH")) {
+      SmallVector<StringRef, 4> Dirs;
+      const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
+      StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr));
+      ArrayRef<StringRef> DirVec(Dirs);
+      addSystemIncludes(DriverArgs, CC1Args, DirVec);
+    } else {
+      if (getTriple().isMusl())
+        addSystemInclude(DriverArgs, CC1Args,
+                         getDriver().SysRoot + "/opt/nec/ve/musl/include");
+      else
+        addSystemInclude(DriverArgs, CC1Args,
+                         getDriver().SysRoot + "/opt/nec/ve/include");
+    }
+  }
+}
+
+void VEToolChain::addClangTargetOptions(const ArgList &DriverArgs,
+                                        ArgStringList &CC1Args,
+                                        Action::OffloadKind) const {
+  CC1Args.push_back("-nostdsysteminc");
+  bool UseInitArrayDefault = true;
+  if (DriverArgs.hasFlag(options::OPT_fuse_init_array,
+                         options::OPT_fno_use_init_array, UseInitArrayDefault))
+    CC1Args.push_back("-fuse-init-array");
+}
+
+void VEToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
+                                               ArgStringList &CC1Args) const {
+  if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc) ||
+      DriverArgs.hasArg(options::OPT_nostdlibinc) ||
+      DriverArgs.hasArg(options::OPT_nostdincxx))
+    return;
+  if (const char *cl_include_dir = getenv("NCC_CPLUS_INCLUDE_PATH")) {
+    SmallVector<StringRef, 4> Dirs;
+    const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
+    StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr));
+    ArrayRef<StringRef> DirVec(Dirs);
+    addSystemIncludes(DriverArgs, CC1Args, DirVec);
+  } else {
+    SmallString<128> P(getDriver().ResourceDir);
+    llvm::sys::path::append(P, "include/c++/v1");
+    addSystemInclude(DriverArgs, CC1Args, P);
+  }
+}
+
+void VEToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
+                                      ArgStringList &CmdArgs) const {
+  assert((GetCXXStdlibType(Args) == ToolChain::CST_Libcxx) &&
+         "Only -lc++ (aka libxx) is supported in this toolchain.");
+
+  tools::addArchSpecificRPath(*this, Args, CmdArgs);
+
+  CmdArgs.push_back("-lc++");
+  CmdArgs.push_back("-lc++abi");
+  CmdArgs.push_back("-lunwind");
+  // libc++ requires -lpthread under glibc environment
+  // libunwind requires -ldl under glibc environment
+  if (!getTriple().isMusl()) {
+    CmdArgs.push_back("-lpthread");
+    CmdArgs.push_back("-ldl");
+  }
+}
+
+llvm::ExceptionHandling
+VEToolChain::GetExceptionModel(const ArgList &Args) const {
+  // VE uses SjLj exceptions.
+  return llvm::ExceptionHandling::SjLj;
+}
Index: clang/lib/Driver/ToolChains/Linux.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Linux.cpp
+++ clang/lib/Driver/ToolChains/Linux.cpp
@@ -518,6 +518,7 @@
 
   if (Triple.isMusl()) {
     std::string ArchName;
+    std::string Path = "/lib/";
     bool IsArm = false;
 
     switch (Arch) {
@@ -531,6 +532,10 @@
       ArchName = "armeb";
       IsArm = true;
       break;
+    case llvm::Triple::ve:
+      Path = "/opt/nec/ve/musl/lib/";
+      ArchName = "ve";
+      break;
     default:
       ArchName = Triple.getArchName().str();
     }
@@ -539,7 +544,7 @@
          tools::arm::getARMFloatABI(*this, Args) == tools::arm::FloatABI::Hard))
       ArchName += "hf";
 
-    return "/lib/ld-musl-" + ArchName + ".so.1";
+    return Path + "ld-musl-" + ArchName + ".so.1";
   }
 
   std::string LibDir;
@@ -638,6 +643,9 @@
     Loader = X32 ? "ld-linux-x32.so.2" : "ld-linux-x86-64.so.2";
     break;
   }
+  case llvm::Triple::ve:
+    return "/opt/nec/ve/lib/ld-linux-ve.so.1";
+    break;
   }
 
   if (Distro == Distro::Exherbo &&
Index: clang/lib/Driver/ToolChains/Gnu.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Gnu.cpp
+++ clang/lib/Driver/ToolChains/Gnu.cpp
@@ -304,6 +304,8 @@
     if (T.getEnvironment() == llvm::Triple::GNUX32)
       return "elf32_x86_64";
     return "elf_x86_64";
+  case llvm::Triple::ve:
+    return "elf64ve";
   default:
     return nullptr;
   }
@@ -355,6 +357,8 @@
   const llvm::Triple::ArchType Arch = ToolChain.getArch();
   const bool isAndroid = ToolChain.getTriple().isAndroid();
   const bool IsIAMCU = ToolChain.getTriple().isOSIAMCU();
+  const bool IsVE = ToolChain.getTriple().isVE();
+  const bool IsMusl = ToolChain.getTriple().isMusl();
   const bool IsPIE = getPIE(Args, ToolChain);
   const bool IsStaticPIE = getStaticPIE(Args, ToolChain);
   const bool IsStatic = getStatic(Args);
@@ -475,6 +479,11 @@
       CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
     }
 
+    if (IsVE) {
+      CmdArgs.push_back("-z");
+      CmdArgs.push_back("max-page-size=0x4000000");
+    }
+
     if (IsIAMCU)
       CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt0.o")));
     else if (HasCRTBeginEndFiles) {
@@ -570,7 +579,7 @@
 
       AddRunTimeLibs(ToolChain, D, CmdArgs, Args);
 
-      if (WantPthread && !isAndroid)
+      if (WantPthread && !isAndroid && !(IsVE && IsMusl))
         CmdArgs.push_back("-lpthread");
 
       if (Args.hasArg(options::OPT_fsplit_stack))
@@ -646,6 +655,7 @@
   llvm::Reloc::Model RelocationModel;
   unsigned PICLevel;
   bool IsPIE;
+  const char *DefaultAssembler = "as";
   std::tie(RelocationModel, PICLevel, IsPIE) =
       ParsePICArgs(getToolChain(), Args);
 
@@ -866,6 +876,8 @@
     CmdArgs.push_back(Args.MakeArgString("-march=" + CPUName));
     break;
   }
+  case llvm::Triple::ve:
+    DefaultAssembler = "nas";
   }
 
   for (const Arg *A : Args.filtered(options::OPT_ffile_prefix_map_EQ,
@@ -890,7 +902,8 @@
   for (const auto &II : Inputs)
     CmdArgs.push_back(II.getFilename());
 
-  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
+  const char *Exec =
+      Args.MakeArgString(getToolChain().GetProgramPath(DefaultAssembler));
   C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
 
   // Handle the debug info splitting at object creation time if we're
Index: clang/lib/Driver/ToolChains/CommonArgs.cpp
===================================================================
--- clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -489,8 +489,11 @@
 
 void tools::addArchSpecificRPath(const ToolChain &TC, const ArgList &Args,
                                  ArgStringList &CmdArgs) {
+  // Enable -frtlib-add-rpath by default for the case of VE.
+  const bool IsVE = TC.getTriple().isVE();
+  bool DefaultValue = IsVE;
   if (!Args.hasFlag(options::OPT_frtlib_add_rpath,
-                    options::OPT_fno_rtlib_add_rpath, false))
+                    options::OPT_fno_rtlib_add_rpath, DefaultValue))
     return;
 
   std::string CandidateRPath = TC.getArchSpecificLibPath();
Index: clang/lib/Driver/ToolChains/Clang.h
===================================================================
--- clang/lib/Driver/ToolChains/Clang.h
+++ clang/lib/Driver/ToolChains/Clang.h
@@ -73,6 +73,8 @@
                           llvm::opt::ArgStringList &CmdArgs) const;
   void AddWebAssemblyTargetArgs(const llvm::opt::ArgList &Args,
                                 llvm::opt::ArgStringList &CmdArgs) const;
+  void AddVETargetArgs(const llvm::opt::ArgList &Args,
+                       llvm::opt::ArgStringList &CmdArgs) const;
 
   enum RewriteKind { RK_None, RK_Fragile, RK_NonFragile };
 
Index: clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -15,6 +15,7 @@
 #include "Arch/Sparc.h"
 #include "Arch/SystemZ.h"
 #include "Arch/X86.h"
+#include "Arch/VE.h"
 #include "AMDGPU.h"
 #include "CommonArgs.h"
 #include "Hexagon.h"
@@ -368,6 +369,9 @@
     break;
   case llvm::Triple::msp430:
     msp430::getMSP430TargetFeatures(D, Args, Features);
+    break;
+  case llvm::Triple::ve:
+    ve::getVETargetFeatures(D, Args, Features);
   }
 
   // Find the last of each feature.
@@ -1675,6 +1679,10 @@
   case llvm::Triple::wasm64:
     AddWebAssemblyTargetArgs(Args, CmdArgs);
     break;
+
+  case llvm::Triple::ve:
+    AddVETargetArgs(Args, CmdArgs);
+    break;
   }
 }
 
@@ -2112,6 +2120,24 @@
   }
 }
 
+void Clang::AddVETargetArgs(const ArgList &Args,
+                            ArgStringList &CmdArgs) const {
+  ve::FloatABI FloatABI =
+      ve::getVEFloatABI(getToolChain().getDriver(), Args);
+
+  if (FloatABI == ve::FloatABI::Soft) {
+    // Floating point operations and argument passing are soft.
+    CmdArgs.push_back("-msoft-float");
+    CmdArgs.push_back("-mfloat-abi");
+    CmdArgs.push_back("soft");
+  } else {
+    // Floating point operations and argument passing are hard.
+    assert(FloatABI == ve::FloatABI::Hard && "Invalid float abi!");
+    CmdArgs.push_back("-mfloat-abi");
+    CmdArgs.push_back("hard");
+  }
+}
+
 void Clang::DumpCompilationDatabase(Compilation &C, StringRef Filename,
                                     StringRef Target, const InputInfo &Output,
                                     const InputInfo &Input, const ArgList &Args) const {
Index: clang/lib/Driver/ToolChains/Arch/VE.h
===================================================================
--- /dev/null
+++ clang/lib/Driver/ToolChains/Arch/VE.h
@@ -0,0 +1,41 @@
+//===--- VE.h - VE-specific Tool Helpers ------------------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_VE_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_VE_H
+
+#include "clang/Driver/Driver.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Option/Option.h"
+#include <string>
+#include <vector>
+
+namespace clang {
+namespace driver {
+namespace tools {
+namespace ve {
+
+enum class FloatABI {
+  Invalid,
+  Soft,
+  Hard,
+};
+
+FloatABI getVEFloatABI(const Driver &D, const llvm::opt::ArgList &Args);
+
+void getVETargetFeatures(const Driver &D, const llvm::opt::ArgList &Args,
+                            std::vector<llvm::StringRef> &Features);
+const char *getVEAsmModeForCPU(llvm::StringRef Name,
+                                  const llvm::Triple &Triple);
+
+} // end namespace ve
+} // end namespace target
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_VE_H
Index: clang/lib/Driver/ToolChains/Arch/VE.cpp
===================================================================
--- /dev/null
+++ clang/lib/Driver/ToolChains/Arch/VE.cpp
@@ -0,0 +1,67 @@
+//===--- VE.cpp - Tools Implementations -------------------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "VE.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Options.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Option/ArgList.h"
+
+using namespace clang::driver;
+using namespace clang::driver::tools;
+using namespace clang;
+using namespace llvm::opt;
+
+const char *ve::getVEAsmModeForCPU(StringRef Name,
+                                         const llvm::Triple &Triple) {
+  return llvm::StringSwitch<const char *>(Name)
+      .Default("");
+}
+
+ve::FloatABI ve::getVEFloatABI(const Driver &D,
+                                        const ArgList &Args) {
+  ve::FloatABI ABI = ve::FloatABI::Invalid;
+  if (Arg *A = Args.getLastArg(clang::driver::options::OPT_msoft_float,
+                               options::OPT_mhard_float,
+                               options::OPT_mfloat_abi_EQ)) {
+    if (A->getOption().matches(clang::driver::options::OPT_msoft_float))
+      ABI = ve::FloatABI::Soft;
+    else if (A->getOption().matches(options::OPT_mhard_float))
+      ABI = ve::FloatABI::Hard;
+    else {
+      ABI = llvm::StringSwitch<ve::FloatABI>(A->getValue())
+                .Case("soft", ve::FloatABI::Soft)
+                .Case("hard", ve::FloatABI::Hard)
+                .Default(ve::FloatABI::Invalid);
+      if (ABI == ve::FloatABI::Invalid &&
+          !StringRef(A->getValue()).empty()) {
+        D.Diag(clang::diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
+        ABI = ve::FloatABI::Hard;
+      }
+    }
+  }
+
+  // If unspecified, choose the default based on the platform.
+  // Only the hard-float ABI on VE is standardized, and it is the
+  // default. GCC also supports a nonstandard soft-float ABI mode, also
+  // implemented in LLVM. However as this is not standard we set the default
+  // to be hard-float.
+  if (ABI == ve::FloatABI::Invalid) {
+    ABI = ve::FloatABI::Hard;
+  }
+
+  return ABI;
+}
+
+void ve::getVETargetFeatures(const Driver &D, const ArgList &Args,
+                                   std::vector<StringRef> &Features) {
+  ve::FloatABI FloatABI = ve::getVEFloatABI(D, Args);
+  if (FloatABI == ve::FloatABI::Soft)
+    Features.push_back("+soft-float");
+}
Index: clang/lib/Driver/Driver.cpp
===================================================================
--- clang/lib/Driver/Driver.cpp
+++ clang/lib/Driver/Driver.cpp
@@ -45,6 +45,7 @@
 #include "ToolChains/TCE.h"
 #include "ToolChains/WebAssembly.h"
 #include "ToolChains/XCore.h"
+#include "ToolChains/VE.h"
 #include "clang/Basic/Version.h"
 #include "clang/Config/config.h"
 #include "clang/Driver/Action.h"
@@ -4823,17 +4824,19 @@
     case llvm::Triple::Linux:
     case llvm::Triple::ELFIAMCU:
       if (Target.getArch() == llvm::Triple::hexagon)
-        TC = std::make_unique<toolchains::HexagonToolChain>(*this, Target,
-                                                             Args);
+        TC =
+            std::make_unique<toolchains::HexagonToolChain>(*this, Target, Args);
+      else if (Target.getArch() == llvm::Triple::ve)
+        TC = std::make_unique<toolchains::VEToolChain>(*this, Target, Args);
       else if ((Target.getVendor() == llvm::Triple::MipsTechnologies) &&
                !Target.hasEnvironment())
         TC = std::make_unique<toolchains::MipsLLVMToolChain>(*this, Target,
-                                                              Args);
+                                                             Args);
       else if (Target.getArch() == llvm::Triple::ppc ||
                Target.getArch() == llvm::Triple::ppc64 ||
                Target.getArch() == llvm::Triple::ppc64le)
         TC = std::make_unique<toolchains::PPCLinuxToolChain>(*this, Target,
-                                                              Args);
+                                                             Args);
       else
         TC = std::make_unique<toolchains::Linux>(*this, Target, Args);
       break;
@@ -4924,6 +4927,9 @@
       case llvm::Triple::riscv64:
         TC = std::make_unique<toolchains::RISCVToolChain>(*this, Target, Args);
         break;
+      case llvm::Triple::ve:
+        TC = std::make_unique<toolchains::VEToolChain>(*this, Target, Args);
+        break;
       default:
         if (Target.getVendor() == llvm::Triple::Myriad)
           TC = std::make_unique<toolchains::MyriadToolChain>(*this, Target,
Index: clang/lib/Driver/CMakeLists.txt
===================================================================
--- clang/lib/Driver/CMakeLists.txt
+++ clang/lib/Driver/CMakeLists.txt
@@ -31,6 +31,7 @@
   ToolChains/Arch/Sparc.cpp
   ToolChains/Arch/SystemZ.cpp
   ToolChains/Arch/X86.cpp
+  ToolChains/Arch/VE.cpp
   ToolChains/AIX.cpp
   ToolChains/Ananas.cpp
   ToolChains/AMDGPU.cpp
@@ -70,6 +71,7 @@
   ToolChains/XCore.cpp
   ToolChains/PPCLinux.cpp
   ToolChains/InterfaceStubs.cpp
+  ToolChains/VE.cpp
   Types.cpp
   XRayArgs.cpp
 
Index: clang/lib/CodeGen/TargetInfo.cpp
===================================================================
--- clang/lib/CodeGen/TargetInfo.cpp
+++ clang/lib/CodeGen/TargetInfo.cpp
@@ -9763,6 +9763,46 @@
 };
 } // namespace
 
+//===----------------------------------------------------------------------===//
+// VE ABI Implementation.
+// Copied from SPARC V8 ABI.
+//
+// Ensures that complex values are passed in registers.
+//
+namespace {
+class VEABIInfo : public DefaultABIInfo {
+public:
+  VEABIInfo(CodeGenTypes &CGT) : DefaultABIInfo(CGT) {}
+
+private:
+  ABIArgInfo classifyReturnType(QualType RetTy) const;
+  void computeInfo(CGFunctionInfo &FI) const override;
+};
+} // end anonymous namespace
+
+ABIArgInfo VEABIInfo::classifyReturnType(QualType Ty) const {
+  if (Ty->isAnyComplexType()) {
+    return ABIArgInfo::getDirect();
+  } else {
+    return DefaultABIInfo::classifyReturnType(Ty);
+  }
+}
+
+void VEABIInfo::computeInfo(CGFunctionInfo &FI) const {
+
+  FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
+  for (auto &Arg : FI.arguments())
+    Arg.info = classifyArgumentType(Arg.type);
+}
+
+namespace {
+class VETargetCodeGenInfo : public TargetCodeGenInfo {
+public:
+  VETargetCodeGenInfo(CodeGenTypes &CGT)
+      : TargetCodeGenInfo(new VEABIInfo(CGT)) {}
+};
+} // end anonymous namespace
+
 //===----------------------------------------------------------------------===//
 // Driver code
 //===----------------------------------------------------------------------===//
@@ -9950,6 +9990,8 @@
   case llvm::Triple::spir:
   case llvm::Triple::spir64:
     return SetCGInfo(new SPIRTargetCodeGenInfo(Types));
+  case llvm::Triple::ve:
+    return SetCGInfo(new VETargetCodeGenInfo(Types));
   }
 }
 
Index: clang/lib/Basic/Targets/VE.h
===================================================================
--- /dev/null
+++ clang/lib/Basic/Targets/VE.h
@@ -0,0 +1,155 @@
+//===--- VE.h - Declare VE target feature support ---------------*- C++ -*-===//
+//
+// 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 declares VE TargetInfo objects.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_VE_H
+#define LLVM_CLANG_LIB_BASIC_TARGETS_VE_H
+
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/TargetOptions.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/Compiler.h"
+
+namespace clang {
+namespace targets {
+
+class LLVM_LIBRARY_VISIBILITY VETargetInfo : public TargetInfo {
+
+public:
+  VETargetInfo(const llvm::Triple &Triple, const TargetOptions &)
+      : TargetInfo(Triple) {
+    NoAsmVariants = true;
+    LongDoubleWidth = 128;
+    LongDoubleAlign = 128;
+    LongDoubleFormat = &llvm::APFloat::IEEEquad();
+    DoubleAlign = LongLongAlign = 64;
+    SuitableAlign = 64;
+    LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
+    SizeType = UnsignedLong;
+    PtrDiffType = SignedLong;
+    IntPtrType = SignedLong;
+    IntMaxType = SignedLong;
+    Int64Type = SignedLong;
+    RegParmMax = 8;
+    MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
+
+    WCharType = UnsignedInt;
+    WIntType = UnsignedInt;
+    UseZeroLengthBitfieldAlignment = true;
+    resetDataLayout("e-m:e-i64:64-n32:64-S64");
+  }
+
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override;
+
+  bool hasSjLjLowering() const override { return true; }
+
+  ArrayRef<Builtin::Info> getTargetBuiltins() const override;
+
+  BuiltinVaListKind getBuiltinVaListKind() const override {
+    return TargetInfo::VoidPtrBuiltinVaList;
+  }
+
+  CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
+    switch (CC) {
+    default:
+      return CCCR_Warning;
+    case CC_C:
+    case CC_X86RegCall:
+      return CCCR_OK;
+    }
+  }
+
+  const char *getClobbers() const override { return ""; }
+
+  ArrayRef<const char *> getGCCRegNames() const override {
+    static const char *const GCCRegNames[] = {
+      // Regular registers
+        "sx0",  "sx1",  "sx2",  "sx3",  "sx4",  "sx5",  "sx6",  "sx7",
+        "sx8",  "sx9", "sx10", "sx11", "sx12", "sx13", "sx14", "sx15",
+       "sx16", "sx17", "sx18", "sx19", "sx20", "sx21", "sx22", "sx23",
+       "sx24", "sx25", "sx26", "sx27", "sx28", "sx29", "sx30", "sx31",
+       "sx32", "sx33", "sx34", "sx35", "sx36", "sx37", "sx38", "sx39",
+       "sx40", "sx41", "sx42", "sx43", "sx44", "sx45", "sx46", "sx47",
+       "sx48", "sx49", "sx50", "sx51", "sx52", "sx53", "sx54", "sx55",
+       "sx56", "sx57", "sx58", "sx59", "sx60", "sx61", "sx62", "sx63",
+      // Vector registers
+        "v0",  "v1",  "v2",  "v3",  "v4",  "v5",  "v6",  "v7",
+        "v8",  "v9", "v10", "v11", "v12", "v13", "v14", "v15",
+       "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
+       "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
+       "v32", "v33", "v34", "v35", "v36", "v37", "v38", "v39",
+       "v40", "v41", "v42", "v43", "v44", "v45", "v46", "v47",
+       "v48", "v49", "v50", "v51", "v52", "v53", "v54", "v55",
+       "v56", "v57", "v58", "v59", "v60", "v61", "v62", "v63",
+      // Special registers
+        "vl",  "vixr",  "ucc", "psw", "sar", "pmmr",
+        "pmcr0", "pmcr1", "pmcr2", "pmcr3",
+        "pmc0", "pmc1", "pmc2", "pmc3", "pmc4", "pmc5", "pmc6", "pmc7",
+        "pmc8", "pmc9", "pmc10", "pmc11", "pmc12", "pmc13", "pmc14",
+    };
+    return llvm::makeArrayRef(GCCRegNames);
+  }
+
+  ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
+    static const TargetInfo::GCCRegAlias GCCRegAliases[] = {
+       {{"s0"},  "sx0"},  {{"s1"},  "sx1"},
+       {{"s2"},  "sx2"},  {{"s3"},  "sx3"},
+       {{"s4"},  "sx4"},  {{"s5"},  "sx5"},
+       {{"s6"},  "sx6"},  {{"s7"},  "sx7"},
+       {{"s8", "sl"},  "sx8"},     {{"s9", "fp"},  "sx9"},
+      {{"s10", "lr"}, "sx10"},    {{"s11", "sp"}, "sx11"},
+      {{"s12", "outer"}, "sx12"}, {{"s13"}, "sx13"},
+      {{"s14", "tp"}, "sx14"},    {{"s15", "got"}, "sx15"},
+      {{"s16", "plt"}, "sx16"},   {{"s17", "info"}, "sx17"},
+      {{"s18"}, "sx18"}, {{"s19"}, "sx19"},
+      {{"s20"}, "sx20"}, {{"s21"}, "sx21"},
+      {{"s22"}, "sx22"}, {{"s23"}, "sx23"},
+      {{"s24"}, "sx24"}, {{"s25"}, "sx25"},
+      {{"s26"}, "sx26"}, {{"s27"}, "sx27"},
+      {{"s28"}, "sx28"}, {{"s29"}, "sx29"},
+      {{"s30"}, "sx30"}, {{"s31"}, "sx31"},
+      {{"s32"}, "sx32"}, {{"s33"}, "sx33"},
+      {{"s34"}, "sx34"}, {{"s35"}, "sx35"},
+      {{"s36"}, "sx36"}, {{"s37"}, "sx37"},
+      {{"s38"}, "sx38"}, {{"s39"}, "sx39"},
+      {{"s40"}, "sx40"}, {{"s41"}, "sx41"},
+      {{"s42"}, "sx42"}, {{"s43"}, "sx43"},
+      {{"s44"}, "sx44"}, {{"s45"}, "sx45"},
+      {{"s46"}, "sx46"}, {{"s47"}, "sx47"},
+      {{"s48"}, "sx48"}, {{"s49"}, "sx49"},
+      {{"s50"}, "sx50"}, {{"s51"}, "sx51"},
+      {{"s52"}, "sx52"}, {{"s53"}, "sx53"},
+      {{"s54"}, "sx54"}, {{"s55"}, "sx55"},
+      {{"s56"}, "sx56"}, {{"s57"}, "sx57"},
+      {{"s58"}, "sx58"}, {{"s59"}, "sx59"},
+      {{"s60"}, "sx60"}, {{"s61"}, "sx61"},
+      {{"s62"}, "sx62"}, {{"s63"}, "sx63"},
+      {{"vix"}, "vixr"}, {{"usrcc"}, "ucc"},
+    };
+    return llvm::makeArrayRef(GCCRegAliases);
+  }
+
+  bool validateAsmConstraint(const char *&Name,
+                             TargetInfo::ConstraintInfo &Info) const override {
+    return false;
+  }
+
+  int getEHDataRegisterNumber(unsigned RegNo) const override {
+    // S0 = ExceptionPointerRegister, S1 = ExceptionSelectorRegister
+    return (RegNo < 2) ? RegNo : -1;
+  }
+
+  bool allowsLargerPreferedTypeAlignment() const override { return false; }
+};
+} // namespace targets
+} // namespace clang
+#endif // LLVM_CLANG_LIB_BASIC_TARGETS_VE_H
Index: clang/lib/Basic/Targets/VE.cpp
===================================================================
--- /dev/null
+++ clang/lib/Basic/Targets/VE.cpp
@@ -0,0 +1,39 @@
+//===--- VE.cpp - Implement VE 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 VE TargetInfo objects.
+//
+//===----------------------------------------------------------------------===//
+
+#include "VE.h"
+#include "clang/Basic/Builtins.h"
+#include "clang/Basic/MacroBuilder.h"
+#include "clang/Basic/TargetBuiltins.h"
+
+using namespace clang;
+using namespace clang::targets;
+
+void VETargetInfo::getTargetDefines(const LangOptions &Opts,
+                                       MacroBuilder &Builder) const {
+  Builder.defineMacro("_LP64", "1");
+  Builder.defineMacro("unix", "1");
+  Builder.defineMacro("__unix__", "1");
+  Builder.defineMacro("__linux__", "1");
+  Builder.defineMacro("__ve", "1");
+  Builder.defineMacro("__ve__", "1");
+  Builder.defineMacro("__STDC_HOSTED__", "1");
+  Builder.defineMacro("__STDC__", "1");
+  Builder.defineMacro("__NEC__", "1");
+  // FIXME: define __FAST_MATH__ 1 if -ffast-math is enabled
+  // FIXME: define __OPTIMIZE__ n if -On is enabled
+  // FIXME: define __VECTOR__ n 1 if automatic vectorization is enabled
+}
+
+ArrayRef<Builtin::Info> VETargetInfo::getTargetBuiltins() const {
+  return None;
+}
Index: clang/lib/Basic/Targets.cpp
===================================================================
--- clang/lib/Basic/Targets.cpp
+++ clang/lib/Basic/Targets.cpp
@@ -33,6 +33,7 @@
 #include "Targets/Sparc.h"
 #include "Targets/SystemZ.h"
 #include "Targets/TCE.h"
+#include "Targets/VE.h"
 #include "Targets/WebAssembly.h"
 #include "Targets/X86.h"
 #include "Targets/XCore.h"
@@ -608,6 +609,9 @@
     return new LinuxTargetInfo<RenderScript32TargetInfo>(Triple, Opts);
   case llvm::Triple::renderscript64:
     return new LinuxTargetInfo<RenderScript64TargetInfo>(Triple, Opts);
+
+  case llvm::Triple::ve:
+    return new LinuxTargetInfo<VETargetInfo>(Triple, Opts);
   }
 }
 } // namespace targets
Index: clang/lib/Basic/CMakeLists.txt
===================================================================
--- clang/lib/Basic/CMakeLists.txt
+++ clang/lib/Basic/CMakeLists.txt
@@ -86,6 +86,7 @@
   Targets/WebAssembly.cpp
   Targets/X86.cpp
   Targets/XCore.cpp
+  Targets/VE.cpp
   TokenKinds.cpp
   Version.cpp
   Warnings.cpp
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to