[PATCH] D154357: [Driver] Recognize powerpc-unknown-eabi as a bare-metal toolchain

Christian Walther via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Jul 3 08:27:21 PDT 2023


cwalther created this revision.
cwalther added reviewers: MaskRay, jroelofs.
cwalther added projects: clang, PowerPC.
Herald added subscribers: luismarques, steven.zhang, s.egerton, shchenz, abidh, PkmX, simoncook, asb, kristof.beyls, arichardson, nemanjai.
Herald added a project: All.
cwalther requested review of this revision.
Herald added subscribers: cfe-commits, wangpc.

At Indel, we have been building bare-metal embedded applications that run on custom PowerPC and ARM systems with Clang and LLD for a couple of years now, using target triples `powerpc-indel-eabi`, `powerpc-indel-eabi750`, `arm-indel-eabi`, `aarch64-indel-eabi` (which I just learned from D153430 <https://reviews.llvm.org/D153430> is wrong and should be `aarch64-indel-elf` instead, but that’s a different matter). This has worked fine for ARM, but for PowerPC we have been unable to call the linker (LLD) through the Clang driver, because it would insist on calling GCC as the linker, even when told `-fuse-ld=lld`. That does not work for us, there is no GCC around. Instead we had to call `ld.lld` directly, introducing some special cases in our build system to translate between linker-via-driver and linker-called-directly command line arguments. I have now dug into why that is, and found that the difference between ARM and PowerPC is that `arm-indel-eabi` hits a special case that causes the Clang driver to instantiate a `BareMetal` toolchain that is able to call LLD and works the way we need, whereas `powerpc-indel-eabi` lands in the default case of a `Generic_ELF` (subclass of `Generic_GCC`) toolchain which expects GCC.

It seems to me that maybe anything with OS `none` (although that doesn’t seem to be distinguished from `unknown`) or with environment `eabi` should be treated as bare-metal, but I don’t have a lot of experience in this regard. Since this seems to have been handled on a case-by-case basis in the past (arm <https://reviews.llvm.org/D33259>, riscv <https://reviews.llvm.org/D91442>, aarch64 <https://reviews.llvm.org/D111134>), what I am proposing here is to add another case to the list to also handle `powerpc[64][le]-unknown-unknown-eabi` using the `BareMetal` toolchain, following the example of the existing cases. (We don’t care about powerpc64 and powerpc[64]le, but it seemed appropriate to lump them in.)

I have run the `check-clang` tests and the patch didn’t break any of them, which makes me hopeful. Or do you think that this may break anyone’s usage? Should we additionally check for the presence of a `--gcc-toolchain` argument like in the RISC-V case? I am new here, so any guidance is appreciated.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D154357

Files:
  clang/lib/Driver/ToolChains/BareMetal.cpp
  clang/test/Driver/baremetal.cpp


Index: clang/test/Driver/baremetal.cpp
===================================================================
--- clang/test/Driver/baremetal.cpp
+++ clang/test/Driver/baremetal.cpp
@@ -345,6 +345,58 @@
 // CHECK-RV32IMAFC-SAME: "-L[[SYSROOT:[^"]+]]{{[/\\]+}}rv32imafc{{[/\\]+}}ilp32f{{[/\\]+}}lib"
 // CHECK-RV32IMAFC-SAME: "-L[[RESOURCE_DIR:[^"]+]]{{[/\\]+}}lib{{[/\\]+}}baremetal{{[/\\]+}}rv32imafc{{[/\\]+}}ilp32f"
 
+// RUN: %clang %s -### --target=powerpc-unknown-eabi 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-PPCEABI %s
+// CHECK-PPCEABI: InstalledDir: [[INSTALLEDDIR:.+]]
+// CHECK-PPCEABI: "-nostdsysteminc"
+// CHECK-PPCEABI-SAME: "-resource-dir" "[[RESOURCE:[^"]+]]"
+// CHECK-PPCEABI-SAME: "-internal-isystem" "[[INSTALLEDDIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}clang-runtimes{{[/\\]+[^"]*}}include{{[/\\]+}}c++{{[/\\]+}}v1"
+// CHECK-PPCEABI-SAME: "-internal-isystem" "[[RESOURCE]]{{[/\\]+}}include"
+// CHECK-PPCEABI-SAME: "-internal-isystem" "[[INSTALLEDDIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}clang-runtimes{{[/\\]+[^"]*}}include"
+// CHECK-PPCEABI-NEXT: ld{{(.exe)?}}" "{{.*}}.o" "-Bstatic"
+// CHECK-PPCEABI-SAME: "-L[[INSTALLEDDIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}clang-runtimes{{[/\\]+[^"]*}}lib"
+// CHECK-PPCEABI-SAME: "-L[[RESOURCE]]{{[/\\]+}}lib{{[/\\]+}}baremetal"
+// CHECK-PPCEABI-SAME: "-lc" "-lm" "-lclang_rt.builtins-powerpc" "-o" "a.out"
+
+// RUN: %clang %s -### --target=powerpc64-unknown-eabi 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-PPC64EABI %s
+// CHECK-PPC64EABI: InstalledDir: [[INSTALLEDDIR:.+]]
+// CHECK-PPC64EABI: "-nostdsysteminc"
+// CHECK-PPC64EABI-SAME: "-resource-dir" "[[RESOURCE:[^"]+]]"
+// CHECK-PPC64EABI-SAME: "-internal-isystem" "[[INSTALLEDDIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}clang-runtimes{{[/\\]+[^"]*}}include{{[/\\]+}}c++{{[/\\]+}}v1"
+// CHECK-PPC64EABI-SAME: "-internal-isystem" "[[RESOURCE]]{{[/\\]+}}include"
+// CHECK-PPC64EABI-SAME: "-internal-isystem" "[[INSTALLEDDIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}clang-runtimes{{[/\\]+[^"]*}}include"
+// CHECK-PPC64EABI-NEXT: ld{{(.exe)?}}" "{{.*}}.o" "-Bstatic"
+// CHECK-PPC64EABI-SAME: "-L[[INSTALLEDDIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}clang-runtimes{{[/\\]+[^"]*}}lib"
+// CHECK-PPC64EABI-SAME: "-L[[RESOURCE]]{{[/\\]+}}lib{{[/\\]+}}baremetal"
+// CHECK-PPC64EABI-SAME: "-lc" "-lm" "-lclang_rt.builtins-powerpc64" "-o" "a.out"
+
+// RUN: %clang %s -### --target=powerpcle-unknown-eabi 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-PPCLEEABI %s
+// CHECK-PPCLEEABI: InstalledDir: [[INSTALLEDDIR:.+]]
+// CHECK-PPCLEEABI: "-nostdsysteminc"
+// CHECK-PPCLEEABI-SAME: "-resource-dir" "[[RESOURCE:[^"]+]]"
+// CHECK-PPCLEEABI-SAME: "-internal-isystem" "[[INSTALLEDDIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}clang-runtimes{{[/\\]+[^"]*}}include{{[/\\]+}}c++{{[/\\]+}}v1"
+// CHECK-PPCLEEABI-SAME: "-internal-isystem" "[[RESOURCE]]{{[/\\]+}}include"
+// CHECK-PPCLEEABI-SAME: "-internal-isystem" "[[INSTALLEDDIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}clang-runtimes{{[/\\]+[^"]*}}include"
+// CHECK-PPCLEEABI-NEXT: ld{{(.exe)?}}" "{{.*}}.o" "-Bstatic"
+// CHECK-PPCLEEABI-SAME: "-L[[INSTALLEDDIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}clang-runtimes{{[/\\]+[^"]*}}lib"
+// CHECK-PPCLEEABI-SAME: "-L[[RESOURCE]]{{[/\\]+}}lib{{[/\\]+}}baremetal"
+// CHECK-PPCLEEABI-SAME: "-lc" "-lm" "-lclang_rt.builtins-powerpcle" "-o" "a.out"
+
+// RUN: %clang %s -### --target=powerpc64le-unknown-eabi 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-PPC64LEEABI %s
+// CHECK-PPC64LEEABI: InstalledDir: [[INSTALLEDDIR:.+]]
+// CHECK-PPC64LEEABI: "-nostdsysteminc"
+// CHECK-PPC64LEEABI-SAME: "-resource-dir" "[[RESOURCE:[^"]+]]"
+// CHECK-PPC64LEEABI-SAME: "-internal-isystem" "[[INSTALLEDDIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}clang-runtimes{{[/\\]+[^"]*}}include{{[/\\]+}}c++{{[/\\]+}}v1"
+// CHECK-PPC64LEEABI-SAME: "-internal-isystem" "[[RESOURCE]]{{[/\\]+}}include"
+// CHECK-PPC64LEEABI-SAME: "-internal-isystem" "[[INSTALLEDDIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}clang-runtimes{{[/\\]+[^"]*}}include"
+// CHECK-PPC64LEEABI-NEXT: ld{{(.exe)?}}" "{{.*}}.o" "-Bstatic"
+// CHECK-PPC64LEEABI-SAME: "-L[[INSTALLEDDIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}clang-runtimes{{[/\\]+[^"]*}}lib"
+// CHECK-PPC64LEEABI-SAME: "-L[[RESOURCE]]{{[/\\]+}}lib{{[/\\]+}}baremetal"
+// CHECK-PPC64LEEABI-SAME: "-lc" "-lm" "-lclang_rt.builtins-powerpc64le" "-o" "a.out"
+
 // Check that compiler-rt library without the arch filename suffix will
 // be used if present.
 // RUN: rm -rf %T/baremetal_clang_rt_noarch
Index: clang/lib/Driver/ToolChains/BareMetal.cpp
===================================================================
--- clang/lib/Driver/ToolChains/BareMetal.cpp
+++ clang/lib/Driver/ToolChains/BareMetal.cpp
@@ -160,6 +160,23 @@
   return Triple.getEnvironmentName() == "elf";
 }
 
+/// Is the triple powerpc[64][le]-none-none-eabi?
+static bool isPPCBareMetal(const llvm::Triple &Triple) {
+  if (!Triple.isPPC())
+    return false;
+
+  if (Triple.getVendor() != llvm::Triple::UnknownVendor)
+    return false;
+
+  if (Triple.getOS() != llvm::Triple::UnknownOS)
+    return false;
+
+  if (Triple.getEnvironment() != llvm::Triple::EABI)
+    return false;
+
+  return true;
+}
+
 static void findMultilibsFromYAML(const ToolChain &TC, const Driver &D,
                                   StringRef MultilibPath, const ArgList &Args,
                                   DetectedMultilibs &Result) {
@@ -225,7 +242,7 @@
 
 bool BareMetal::handlesTarget(const llvm::Triple &Triple) {
   return isARMBareMetal(Triple) || isAArch64BareMetal(Triple) ||
-         isRISCVBareMetal(Triple);
+         isRISCVBareMetal(Triple) || isPPCBareMetal(Triple);
 }
 
 Tool *BareMetal::buildLinker() const {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D154357.536740.patch
Type: text/x-patch
Size: 5708 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230703/9f3bebf7/attachment-0001.bin>


More information about the cfe-commits mailing list