benshi001 created this revision.
benshi001 added reviewers: aykevl, dylanmckay.
Herald added subscribers: Jim, dberris.
Herald added a project: All.
benshi001 requested review of this revision.
Herald added subscribers: cfe-commits, jacquesguan, MaskRay.
Herald added a project: clang.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D126299

Files:
  clang/lib/Driver/ToolChains/AVR.cpp
  clang/lib/Driver/ToolChains/AVR.h
  clang/test/Driver/Inputs/basic_avr_tree/usr/lib/gcc/avr/5.4.0/avr5/libgcc.a
  
clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/avr/libclang_rt.builtins-avr5.a
  clang/test/Driver/avr-toolchain.c

Index: clang/test/Driver/avr-toolchain.c
===================================================================
--- clang/test/Driver/avr-toolchain.c
+++ clang/test/Driver/avr-toolchain.c
@@ -69,3 +69,17 @@
 // LLD-SAME: "--defsym=__EEPROM_REGION_LENGTH__=1024"
 // LLD-NOT: "avr-ld"
 // LLD-NOT: "-mavr5"
+
+// RUN: %clang %s -### --target=avr -mmcu=atmega328 --sysroot=%S/Inputs/basic_avr_tree/ -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir 2>&1 | FileCheck --check-prefix=LIBGCC %s
+// RUN: %clang %s -### --target=avr -mmcu=atmega328 --sysroot=%S/Inputs/basic_avr_tree/ -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir --rtlib=libgcc 2>&1 | FileCheck --check-prefix=LIBGCC %s
+// LIBGCC: "-lgcc"
+// LIBGCC-NOT: libclang_rt
+
+// RUN: %clang %s -### --target=avr -mmcu=atmega328 --sysroot=%S/Inputs/basic_avr_tree/ -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir --rtlib=compiler-rt 2>&1 | FileCheck --check-prefix=COMRT %s
+// COMRT: libclang_rt.builtins-avr5.a
+// COMRT-NOT: "-lgcc"
+
+// RUN: %clang %s -### --target=avr --sysroot=%S/Inputs/basic_avr_tree/ -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir --rtlib=compiler-rt 2>&1 | FileCheck --check-prefix=NOMCU %s
+// RUN: %clang %s -### --target=avr --sysroot=%S/Inputs/basic_avr_tree/ -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir --rtlib=libgcc 2>&1 | FileCheck --check-prefix=NOMCU %s
+// NOMCU-NOT: libclang_rt
+// NOMCU-NOT: "-lgcc"
Index: clang/lib/Driver/ToolChains/AVR.h
===================================================================
--- clang/lib/Driver/ToolChains/AVR.h
+++ clang/lib/Driver/ToolChains/AVR.h
@@ -34,11 +34,20 @@
   llvm::Optional<std::string> findAVRLibcInstallation() const;
   StringRef getGCCInstallPath() const { return GCCInstallPath; }
 
+  std::string buildCompilerRTBasename(const llvm::opt::ArgList &Args,
+                                      StringRef Component, FileType Type,
+                                      bool AddArch) const override;
+
+  std::string getCompilerRTPath() const override;
+
+  ToolChain::RuntimeLibType GetDefaultRuntimeLibType() const override;
+
 protected:
   Tool *buildLinker() const override;
 
 private:
   StringRef GCCInstallPath;
+  std::string MCU;
 };
 
 } // end namespace toolchains
Index: clang/lib/Driver/ToolChains/AVR.cpp
===================================================================
--- clang/lib/Driver/ToolChains/AVR.cpp
+++ clang/lib/Driver/ToolChains/AVR.cpp
@@ -19,6 +19,7 @@
 #include "llvm/MC/SubtargetFeature.h"
 #include "llvm/Option/ArgList.h"
 #include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
 
 using namespace clang::driver;
 using namespace clang::driver::toolchains;
@@ -413,8 +414,8 @@
     : Generic_ELF(D, Triple, Args) {
   GCCInstallation.init(Triple, Args);
 
-  std::string CPU = getCPUName(D, Args, Triple);
-  if (CPU.empty())
+  MCU = getCPUName(D, Args, Triple);
+  if (MCU.empty())
     D.Diag(diag::warn_drv_avr_mcu_not_specified);
 
   // Only add default libraries if the user hasn't explicitly opted out.
@@ -458,6 +459,41 @@
     CC1Args.push_back("-fno-use-cxa-atexit");
 }
 
+std::string
+AVRToolChain::buildCompilerRTBasename(const llvm::opt::ArgList &Args,
+                                      StringRef Component, FileType Type,
+                                      bool AddArch) const {
+  std::string Arch;
+  // Each device family should has its own compiler-rt build with optimization.
+  if (AddArch) {
+    Optional<StringRef> FamilyName = GetMCUFamilyName(MCU);
+    if (FamilyName)
+      Arch = "-" + (*FamilyName).str();
+    // Neither libgcc nor compiler-rt will be linked if no '-mmcu' specified.
+    // However we still append a default "-avr" for future changes.
+    else
+      Arch = "-avr";
+  }
+  // Since the libgcc distributed with avr-gcc always named 'libgcc.a' even
+  // on windows, we should also build compiler-rt with a '.a' suffix.
+  return (Twine("libclang_rt.") + Component + Arch + ".a").str();
+}
+
+std::string AVRToolChain::getCompilerRTPath() const {
+  // Return default path appended with "/avr", if it exists.
+  SmallString<128> Path(ToolChain::getCompilerRTPath());
+  llvm::sys::path::append(Path, "avr");
+  if (llvm::sys::fs::is_directory(Path))
+    return std::string(Path.str());
+  // Fall back to default.
+  return ToolChain::getCompilerRTPath();
+}
+
+ToolChain::RuntimeLibType AVRToolChain::GetDefaultRuntimeLibType() const {
+  return GCCInstallation.isValid() ? ToolChain::RLT_Libgcc
+                                   : ToolChain::RLT_CompilerRT;
+}
+
 Tool *AVRToolChain::buildLinker() const {
   return new tools::AVR::Linker(getTriple(), *this);
 }
@@ -499,6 +535,12 @@
   Args.AddAllArgs(CmdArgs, options::OPT_L);
   getToolChain().AddFilePathLibArgs(Args, CmdArgs);
 
+  // Get the runtime library, currently we only support libgcc and compiler-rt.
+  auto RtLib = TC.GetRuntimeLibType(Args);
+  assert(
+      (RtLib == ToolChain::RLT_Libgcc || RtLib == ToolChain::RLT_CompilerRT) &&
+      "unknown runtime library");
+
   // Only add default libraries if the user hasn't explicitly opted out.
   bool LinkStdlib = false;
   if (!Args.hasArg(options::OPT_nostdlib) &&
@@ -514,10 +556,13 @@
         D.Diag(diag::warn_drv_avr_libc_not_found);
       } else {
         std::string SubPath = GetMCUSubPath(CPU);
+        // Add avr-libc path.
         CmdArgs.push_back(
             Args.MakeArgString(Twine("-L") + *AVRLibcRoot + "/lib/" + SubPath));
-        CmdArgs.push_back(
-            Args.MakeArgString("-L" + TC.getGCCInstallPath() + "/" + SubPath));
+        // Add path of libgcc.
+        if (RtLib == ToolChain::RLT_Libgcc)
+          CmdArgs.push_back(Args.MakeArgString("-L" + TC.getGCCInstallPath() +
+                                               "/" + SubPath));
         LinkStdlib = true;
       }
     }
@@ -546,7 +591,11 @@
     std::string CrtFileName = std::string("-l:crt") + CPU + std::string(".o");
     CmdArgs.push_back(Args.MakeArgString(CrtFileName));
 
-    CmdArgs.push_back("-lgcc");
+    // Link to libgcc.
+    if (RtLib == ToolChain::RLT_Libgcc)
+      CmdArgs.push_back("-lgcc");
+
+    // Link to generic libraries of avr-libc.
     CmdArgs.push_back("-lm");
     CmdArgs.push_back("-lc");
 
@@ -555,6 +604,14 @@
 
     CmdArgs.push_back("--end-group");
 
+    // Link to compiler-rt.
+    if (RtLib == ToolChain::RLT_CompilerRT) {
+      std::string RtLib =
+          getToolChain().getCompilerRT(Args, "builtins", ToolChain::FT_Static);
+      if (llvm::sys::fs::exists(RtLib))
+        CmdArgs.push_back(Args.MakeArgString(RtLib));
+    }
+
     // Add specific options for different linkers.
     if (Linker.find("avr-ld") != std::string::npos) {
       // Specify the family name as the emulation mode to use.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to