Author: Hafiz Abid Qadeer Date: 2020-12-14T20:49:45Z New Revision: 670686ad8ecc80158a6ff87fff55e0ffa6fdff5d
URL: https://github.com/llvm/llvm-project/commit/670686ad8ecc80158a6ff87fff55e0ffa6fdff5d DIFF: https://github.com/llvm/llvm-project/commit/670686ad8ecc80158a6ff87fff55e0ffa6fdff5d.diff LOG: Add initial support for multilibs in Baremetal toolchain. This patch add support of riscv multilibs in the Baremetal toolchain. It is a bit different to what is done in GNU.cpp as we are not iterating a GNU sysroot to find the multilibs. This is intended for an llvm only toolchain. We are not checking for the presence of any runtime bits to enable a specific multilib. I have structured the patch so that other targets for which there is no multilibs support yet in Baremetal.cpp (e.g. arm-none-eabi) will not be affected. Patch also allows some multilibs reuse. Long term, I would like to go in the direction of data-driven specification of multilib directories and flags. Reviewed By: jroelofs Differential Revision: https://reviews.llvm.org/D93138 Added: Modified: clang/lib/Driver/ToolChains/BareMetal.cpp clang/lib/Driver/ToolChains/BareMetal.h clang/test/Driver/baremetal.cpp Removed: ################################################################################ diff --git a/clang/lib/Driver/ToolChains/BareMetal.cpp b/clang/lib/Driver/ToolChains/BareMetal.cpp index 7429c822b7e9..7619dd30da5a 100644 --- a/clang/lib/Driver/ToolChains/BareMetal.cpp +++ b/clang/lib/Driver/ToolChains/BareMetal.cpp @@ -12,6 +12,7 @@ #include "InputInfo.h" #include "Gnu.h" +#include "Arch/RISCV.h" #include "clang/Driver/Compilation.h" #include "clang/Driver/Driver.h" #include "clang/Driver/DriverDiagnostic.h" @@ -27,12 +28,77 @@ using namespace clang::driver; using namespace clang::driver::tools; using namespace clang::driver::toolchains; +static Multilib makeMultilib(StringRef commonSuffix) { + return Multilib(commonSuffix, commonSuffix, commonSuffix); +} + +static bool findRISCVMultilibs(const Driver &D, + const llvm::Triple &TargetTriple, + const ArgList &Args, DetectedMultilibs &Result) { + Multilib::flags_list Flags; + StringRef Arch = riscv::getRISCVArch(Args, TargetTriple); + StringRef Abi = tools::riscv::getRISCVABI(Args, TargetTriple); + + if (TargetTriple.getArch() == llvm::Triple::riscv64) { + Multilib Imac = makeMultilib("").flag("+march=rv64imac").flag("+mabi=lp64"); + Multilib Imafdc = makeMultilib("/rv64imafdc/lp64d") + .flag("+march=rv64imafdc") + .flag("+mabi=lp64d"); + + // Multilib reuse + bool UseImafdc = + (Arch == "rv64imafdc") || (Arch == "rv64gc"); // gc => imafdc + + addMultilibFlag((Arch == "rv64imac"), "march=rv64imac", Flags); + addMultilibFlag(UseImafdc, "march=rv64imafdc", Flags); + addMultilibFlag(Abi == "lp64", "mabi=lp64", Flags); + addMultilibFlag(Abi == "lp64d", "mabi=lp64d", Flags); + + Result.Multilibs = MultilibSet().Either(Imac, Imafdc); + return Result.Multilibs.select(Flags, Result.SelectedMultilib); + } + if (TargetTriple.getArch() == llvm::Triple::riscv32) { + Multilib Imac = + makeMultilib("").flag("+march=rv32imac").flag("+mabi=ilp32"); + Multilib I = + makeMultilib("/rv32i/ilp32").flag("+march=rv32i").flag("+mabi=ilp32"); + Multilib Im = + makeMultilib("/rv32im/ilp32").flag("+march=rv32im").flag("+mabi=ilp32"); + Multilib Iac = makeMultilib("/rv32iac/ilp32") + .flag("+march=rv32iac") + .flag("+mabi=ilp32"); + Multilib Imafc = makeMultilib("/rv32imafc/ilp32f") + .flag("+march=rv32imafc") + .flag("+mabi=ilp32f"); + + // Multilib reuse + bool UseI = (Arch == "rv32i") || (Arch == "rv32ic"); // ic => i + bool UseIm = (Arch == "rv32im") || (Arch == "rv32imc"); // imc => im + bool UseImafc = (Arch == "rv32imafc") || (Arch == "rv32imafdc") || + (Arch == "rv32gc"); // imafdc,gc => imafc + + addMultilibFlag(UseI, "march=rv32i", Flags); + addMultilibFlag(UseIm, "march=rv32im", Flags); + addMultilibFlag((Arch == "rv32iac"), "march=rv32iac", Flags); + addMultilibFlag((Arch == "rv32imac"), "march=rv32imac", Flags); + addMultilibFlag(UseImafc, "march=rv32imafc", Flags); + addMultilibFlag(Abi == "ilp32", "mabi=ilp32", Flags); + addMultilibFlag(Abi == "ilp32f", "mabi=ilp32f", Flags); + + Result.Multilibs = MultilibSet().Either(I, Im, Iac, Imac, Imafc); + return Result.Multilibs.select(Flags, Result.SelectedMultilib); + } + return false; +} + BareMetal::BareMetal(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) : ToolChain(D, Triple, Args) { getProgramPaths().push_back(getDriver().getInstalledDir()); if (getDriver().getInstalledDir() != getDriver().Dir) getProgramPaths().push_back(getDriver().Dir); + + findMultilibs(D, Triple, Args); SmallString<128> SysRoot(computeSysRoot()); if (!SysRoot.empty()) { llvm::sys::path::append(SysRoot, "lib"); @@ -73,6 +139,17 @@ static bool isRISCVBareMetal(const llvm::Triple &Triple) { return Triple.getEnvironmentName() == "elf"; } +void BareMetal::findMultilibs(const Driver &D, const llvm::Triple &Triple, + const ArgList &Args) { + DetectedMultilibs Result; + if (isRISCVBareMetal(Triple)) { + if (findRISCVMultilibs(D, Triple, Args, Result)) { + SelectedMultilib = Result.SelectedMultilib; + Multilibs = Result.Multilibs; + } + } +} + bool BareMetal::handlesTarget(const llvm::Triple &Triple) { return isARMBareMetal(Triple) || isRISCVBareMetal(Triple); } @@ -91,17 +168,19 @@ std::string BareMetal::getCompilerRTBasename(const llvm::opt::ArgList &, std::string BareMetal::getRuntimesDir() const { SmallString<128> Dir(getDriver().ResourceDir); llvm::sys::path::append(Dir, "lib", "baremetal"); + Dir += SelectedMultilib.gccSuffix(); return std::string(Dir.str()); } std::string BareMetal::computeSysRoot() const { if (!getDriver().SysRoot.empty()) - return getDriver().SysRoot; + return getDriver().SysRoot + SelectedMultilib.osSuffix(); SmallString<128> SysRootDir; llvm::sys::path::append(SysRootDir, getDriver().Dir, "../lib/clang-runtimes", getDriver().getTargetTriple()); + SysRootDir += SelectedMultilib.osSuffix(); return std::string(SysRootDir); } diff --git a/clang/lib/Driver/ToolChains/BareMetal.h b/clang/lib/Driver/ToolChains/BareMetal.h index 3f4fadf8a7c3..a6d4922a380f 100644 --- a/clang/lib/Driver/ToolChains/BareMetal.h +++ b/clang/lib/Driver/ToolChains/BareMetal.h @@ -26,6 +26,10 @@ class LLVM_LIBRARY_VISIBILITY BareMetal : public ToolChain { ~BareMetal() override = default; static bool handlesTarget(const llvm::Triple &Triple); + + void findMultilibs(const Driver &D, const llvm::Triple &Triple, + const llvm::opt::ArgList &Args); + protected: Tool *buildLinker() const override; diff --git a/clang/test/Driver/baremetal.cpp b/clang/test/Driver/baremetal.cpp index addf09f00e14..7bbdbac66754 100644 --- a/clang/test/Driver/baremetal.cpp +++ b/clang/test/Driver/baremetal.cpp @@ -233,3 +233,113 @@ // CHECK-RV64-NDL-SAME: "-L{{[^"]*}}{{[/\\]+}}lib{{(64)?}}{{[/\\]+}}clang{{[/\\]+}}{{.*}}{{[/\\]+}}lib{{[/\\]+}}baremetal" // CHECK-RV64-NDL-SAME: "-L{{[^"]*}}{{[/\\]+}}Inputs{{[/\\]+}}basic_riscv64_tree{{[/\\]+}}riscv64-unknown-elf{{[/\\]+}}lib" // CHECK-RV64-NDL-SAME: "-o" "{{.*}}.o" + +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -target riscv64-unknown-elf \ +// RUN: -march=rv64imafdc -mabi=lp64d \ +// RUN: --sysroot=%S/Inputs/basic_riscv64_tree/riscv64-unknown-elf \ +// RUN: | FileCheck --check-prefix=CHECK-RV64FD %s + +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -target riscv64-unknown-elf \ +// RUN: -march=rv64gc -mabi=lp64d \ +// RUN: --sysroot=%S/Inputs/basic_riscv64_tree/riscv64-unknown-elf \ +// RUN: | FileCheck --check-prefix=CHECK-RV64FD %s + +// CHECK-RV64FD: "[[PREFIX_DIR:.*]]{{[/\\]+}}{{[^/^\\]+}}{{[/\\]+}}clang{{.*}}" "-cc1" "-triple" "riscv64-unknown-unknown-elf" +// CHECK-RV64FD-SAME: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-RV64FD-SAME: "-isysroot" "[[SYSROOT:[^"]*]]" +// CHECK-RV64FD-SAME: "-internal-isystem" "[[SYSROOT]]{{[/\\]+}}rv64imafdc{{[/\\]+}}lp64d{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}v1" +// CHECk-RV64FD-SAME: "-internal-isystem" "[[SYSROOT]]{{[/\\]+}}rv64imafdc{{[/\\]+}}lp64d{{[/\\]+}}include" +// CHECK-RV64FD-SAME: "-x" "c++" "{{.*}}baremetal.cpp" +// CHECK-RV64FD-NEXT: "{{[^"]*}}ld{{(\.(lld|bfd|gold))?}}{{(\.exe)?}}" "{{.*}}.o" "-Bstatic" +// CHECK-RV64FD-SAME: "-L[[RESOURCE_DIR:[^"]+]]{{[/\\]+}}lib{{[/\\]+}}baremetal{{[/\\]+}}rv64imafdc{{[/\\]+}}lp64d" +// CHECK-RV64FD-SAME: "-L[[SYSROOT:[^"]+]]{{[/\\]+}}rv64imafdc{{[/\\]+}}lp64d{{[/\\]+}}lib" + +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -target riscv32-unknown-elf \ +// RUN: -march=rv32i -mabi=ilp32 \ +// RUN: --sysroot=%S/Inputs/basic_riscv32_tree/riscv32-unknown-elf \ +// RUN: | FileCheck --check-prefix=CHECK-RV32I %s + +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -target riscv32-unknown-elf \ +// RUN: -march=rv32ic -mabi=ilp32 \ +// RUN: --sysroot=%S/Inputs/basic_riscv32_tree/riscv32-unknown-elf \ +// RUN: | FileCheck --check-prefix=CHECK-RV32I %s + +// CHECK-RV32I: "[[PREFIX_DIR:.*]]{{[/\\]+}}{{[^/^\\]+}}{{[/\\]+}}clang{{.*}}" "-cc1" "-triple" "riscv32-unknown-unknown-elf" +// CHECK-RV32I-SAME: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-RV32I-SAME: "-isysroot" "[[SYSROOT:[^"]*]]" +// CHECK-RV32I-SAME: "-internal-isystem" "[[SYSROOT]]{{[/\\]+}}rv32i{{[/\\]+}}ilp32{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}v1" +// CHECK-RV32I-SAME: "-internal-isystem" "[[SYSROOT]]{{[/\\]+}}rv32i{{[/\\]+}}ilp32{{[/\\]+}}include" +// CHECK-RV32I-SAME: "-x" "c++" "{{.*}}baremetal.cpp" +// CHECK-RV32I-NEXT: "{{[^"]*}}ld{{(\.(lld|bfd|gold))?}}{{(\.exe)?}}" "{{.*}}.o" "-Bstatic" +// CHECK-RV32I-SAME: "-L[[RESOURCE_DIR:[^"]+]]{{[/\\]+}}lib{{[/\\]+}}baremetal{{[/\\]+}}rv32i{{[/\\]+}}ilp32" +// CHECK-RV32I-SAME: "-L[[SYSROOT:[^"]+]]{{[/\\]+}}rv32i{{[/\\]+}}ilp32{{[/\\]+}}lib" + +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -target riscv32-unknown-elf \ +// RUN: -march=rv32im -mabi=ilp32 \ +// RUN: --sysroot=%S/Inputs/basic_riscv32_tree/riscv32-unknown-elf \ +// RUN: | FileCheck --check-prefix=CHECK-RV32IM %s + +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -target riscv32-unknown-elf \ +// RUN: -march=rv32imc -mabi=ilp32 \ +// RUN: --sysroot=%S/Inputs/basic_riscv32_tree/riscv32-unknown-elf \ +// RUN: | FileCheck --check-prefix=CHECK-RV32IM %s + +// CHECK-RV32IM: "[[PREFIX_DIR:.*]]{{[/\\]+}}{{[^/^\\]+}}{{[/\\]+}}clang{{.*}}" "-cc1" "-triple" "riscv32-unknown-unknown-elf" +// CHECK-RV32IM-SAME: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-RV32IM-SAME: "-isysroot" "[[SYSROOT:[^"]*]]" +// CHECK-RV32IM-SAME: "-internal-isystem" "[[SYSROOT]]{{[/\\]+}}rv32im{{[/\\]+}}ilp32{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}v1" +// CHECK-RV32IM-SAME: "-internal-isystem" "[[SYSROOT]]{{[/\\]+}}rv32im{{[/\\]+}}ilp32{{[/\\]+}}include" +// CHECK-RV32IM-SAME: "-x" "c++" "{{.*}}baremetal.cpp" +// CHECK-RV32IM-NEXT: "{{[^"]*}}ld{{(\.(lld|bfd|gold))?}}{{(\.exe)?}}" "{{.*}}.o" "-Bstatic" +// CHECK-RV32IM-SAME: "-L[[RESOURCE_DIR:[^"]+]]{{[/\\]+}}lib{{[/\\]+}}baremetal{{[/\\]+}}rv32im{{[/\\]+}}ilp32" +// CHECK-RV32IM-SAME: "-L[[SYSROOT:[^"]+]]{{[/\\]+}}rv32im{{[/\\]+}}ilp32{{[/\\]+}}lib" + +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -target riscv32-unknown-elf \ +// RUN: -march=rv32iac -mabi=ilp32 \ +// RUN: --sysroot=%S/Inputs/basic_riscv32_tree/riscv32-unknown-elf \ +// RUN: | FileCheck --check-prefix=CHECK-RV32IAC %s + +// CHECK-RV32IAC: "[[PREFIX_DIR:.*]]{{[/\\]+}}{{[^/^\\]+}}{{[/\\]+}}clang{{.*}}" "-cc1" "-triple" "riscv32-unknown-unknown-elf" +// CHECK-RV32IAC-SAME: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-RV32IAC-SAME: "-isysroot" "[[SYSROOT:[^"]*]]" +// CHECK-RV32IAC-SAME: "-internal-isystem" "[[SYSROOT]]{{[/\\]+}}rv32iac{{[/\\]+}}ilp32{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}v1" +// CHECK-RV32IAC-SAME: "-internal-isystem" "[[SYSROOT]]{{[/\\]+}}rv32iac{{[/\\]+}}ilp32{{[/\\]+}}include" +// CHECK-RV32IAC-SAME: "-x" "c++" "{{.*}}baremetal.cpp" +// CHECK-RV32IAC-NEXT: "{{[^"]*}}ld{{(\.(lld|bfd|gold))?}}{{(\.exe)?}}" "{{.*}}.o" "-Bstatic" +// CHECK-RV32IAC-SAME: "-L[[RESOURCE_DIR:[^"]+]]{{[/\\]+}}lib{{[/\\]+}}baremetal{{[/\\]+}}rv32iac{{[/\\]+}}ilp32" +// CHECK-RV32IAC-SAME: "-L[[SYSROOT:[^"]+]]{{[/\\]+}}rv32iac{{[/\\]+}}ilp32{{[/\\]+}}lib" + +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -target riscv32-unknown-elf \ +// RUN: -march=rv32imafc -mabi=ilp32f \ +// RUN: --sysroot=%S/Inputs/basic_riscv32_tree/riscv32-unknown-elf \ +// RUN: | FileCheck --check-prefix=CHECK-RV32IMAFC %s + +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -target riscv32-unknown-elf \ +// RUN: -march=rv32imafdc -mabi=ilp32f \ +// RUN: --sysroot=%S/Inputs/basic_riscv32_tree/riscv32-unknown-elf \ +// RUN: | FileCheck --check-prefix=CHECK-RV32IMAFC %s + +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -target riscv32-unknown-elf \ +// RUN: -march=rv32gc -mabi=ilp32f \ +// RUN: --sysroot=%S/Inputs/basic_riscv32_tree/riscv32-unknown-elf \ +// RUN: | FileCheck --check-prefix=CHECK-RV32IMAFC %s + +// CHECK-RV32IMAFC: "[[PREFIX_DIR:.*]]{{[/\\]+}}{{[^/^\\]+}}{{[/\\]+}}clang{{.*}}" "-cc1" "-triple" "riscv32-unknown-unknown-elf" +// CHECK-RV32IMAFC-SAME: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-RV32IMAFC-SAME: "-isysroot" "[[SYSROOT:[^"]*]]" +// CHECK-RV32IMAFC-SAME: "-internal-isystem" "[[SYSROOT]]{{[/\\]+}}rv32imafc{{[/\\]+}}ilp32f{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}v1" +// CHECK-RV32IMAFC-SAME: "-internal-isystem" "[[SYSROOT]]{{[/\\]+}}rv32imafc{{[/\\]+}}ilp32f{{[/\\]+}}include" +// CHECK-RV32IMAFC-SAME: "-x" "c++" "{{.*}}baremetal.cpp" +// CHECK-RV32IMAFC-NEXT: "{{[^"]*}}ld{{(\.(lld|bfd|gold))?}}{{(\.exe)?}}" "{{.*}}.o" "-Bstatic" +// CHECK-RV32IMAFC-SAME: "-L[[RESOURCE_DIR:[^"]+]]{{[/\\]+}}lib{{[/\\]+}}baremetal{{[/\\]+}}rv32imafc{{[/\\]+}}ilp32f" +// CHECK-RV32IMAFC-SAME: "-L[[SYSROOT:[^"]+]]{{[/\\]+}}rv32imafc{{[/\\]+}}ilp32f{{[/\\]+}}lib" _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits