diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index ab19166f18c2dc..c0f97f1dd38bcb 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -9,6 +9,7 @@ #include "clang/Driver/ToolChain.h" #include "ToolChains/Arch/AArch64.h" #include "ToolChains/Arch/ARM.h" +#include "ToolChains/Arch/RISCV.h" #include "ToolChains/Clang.h" #include "ToolChains/CommonArgs.h" #include "ToolChains/Flang.h" @@ -240,6 +241,30 @@ static void getARMMultilibFlags(const Driver &D, } } + +static void getRISCVMultilibFlags(const Driver &D, + const llvm::Triple &Triple, + const llvm::opt::ArgList &Args, + Multilib::flags_list &Result) { + std::vector Features; + tools::riscv::getRISCVTargetFeatures(D, Triple, Args, Features); + const auto UnifiedFeatures = tools::unifyTargetFeatures(Features); + llvm::DenseSet FeatureSet(UnifiedFeatures.begin(), + UnifiedFeatures.end()); + llvm::dbgs() << "Getting RISCV multilib flags!\n"; + // std::vector MArch; + for (const auto &F : UnifiedFeatures) + Result.push_back(F.str()); + + Result.push_back(("-march=" + Triple.getArchName()).str()); + + bool Exceptions = + Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions, true); + if (!Exceptions) + Result.push_back("+no-except"); +} + + Multilib::flags_list ToolChain::getMultilibFlags(const llvm::opt::ArgList &Args) const { using namespace clang::driver::options; @@ -260,6 +285,10 @@ ToolChain::getMultilibFlags(const llvm::opt::ArgList &Args) const { case llvm::Triple::thumbeb: getARMMultilibFlags(D, Triple, Args, Result); break; + case llvm::Triple::riscv32: + case llvm::Triple::riscv64: + getRISCVMultilibFlags(D, Triple, Args, Result); + break; default: break; } diff --git a/clang/lib/Driver/ToolChains/BareMetal.cpp b/clang/lib/Driver/ToolChains/BareMetal.cpp index 42c8336e626c7b..7f922778fdd823 100644 --- a/clang/lib/Driver/ToolChains/BareMetal.cpp +++ b/clang/lib/Driver/ToolChains/BareMetal.cpp @@ -33,7 +33,7 @@ using namespace clang::driver; using namespace clang::driver::tools; using namespace clang::driver::toolchains; -static bool findRISCVMultilibs(const Driver &D, +[[maybe_unused]] static bool findRISCVMultilibs(const Driver &D, const llvm::Triple &TargetTriple, const ArgList &Args, DetectedMultilibs &Result) { Multilib::flags_list Flags; @@ -220,18 +220,11 @@ static std::string computeBaseSysRoot(const Driver &D, void BareMetal::findMultilibs(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) { DetectedMultilibs Result; - if (isRISCVBareMetal(Triple)) { - if (findRISCVMultilibs(D, Triple, Args, Result)) { - SelectedMultilibs = Result.SelectedMultilibs; - Multilibs = Result.Multilibs; - } - } else { - llvm::SmallString<128> MultilibPath(computeBaseSysRoot(D, Triple)); - llvm::sys::path::append(MultilibPath, MultilibFilename); - findMultilibsFromYAML(*this, D, MultilibPath, Args, Result); - SelectedMultilibs = Result.SelectedMultilibs; - Multilibs = Result.Multilibs; - } + llvm::SmallString<128> MultilibPath(computeBaseSysRoot(D, Triple)); + llvm::sys::path::append(MultilibPath, MultilibFilename); + findMultilibsFromYAML(*this, D, MultilibPath, Args, Result); + SelectedMultilibs = Result.SelectedMultilibs; + Multilibs = Result.Multilibs; } bool BareMetal::handlesTarget(const llvm::Triple &Triple) { diff --git a/clang/test/Driver/baremetal-multilib.yaml b/clang/test/Driver/baremetal-multilib.yaml index af26e82621c91e..92bd434b45601d 100644 --- a/clang/test/Driver/baremetal-multilib.yaml +++ b/clang/test/Driver/baremetal-multilib.yaml @@ -119,6 +119,18 @@ Variants: Flags: [--target=thumbv8.1m.main-none-unknown-eabihf, -march=thumbv8.1m.main+mve, -mfpu=none] +- Dir: rv32imafc/except + Flags: [--target=riscv32-unknown-unknown-elf, +m, +a, +f, +c] +- Dir: rv32imafc/noexcept + Flags: [--target=riscv32-unknown-unknown-elf, +m, +a, +f, +c, +no-except] + +- Dir: rv32imafdc/except + Flags: [--target=riscv32-unknown-unknown-elf, +m, +a, +f, +d, +c] +- Dir: rv32imafdc/noexcept + Flags: [--target=riscv32-unknown-unknown-elf, +m, +a, +f, +d, +c, +no-except] + + + # The second section of the file is a map from auto-detected flags # to custom flags. The auto-detected flags can be printed out # by running clang with `-print-multi-flags-experimental`.