diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4343,8 +4343,13 @@ HelpText<"Print supported cpu models for the given target (if target is not specified," " it will print the supported cpus for the default target)">, MarshallingInfoFlag>; +def print_supported_marchs : Flag<["-", "--"], "print-supported-marchs">, + Group, Flags<[CC1Option, CoreOption]>, + HelpText<"Print supported marchs for the given target (if target is not specified," + " it will print the supported marchs for the default target)">; def : Flag<["-"], "mcpu=help">, Alias; def : Flag<["-"], "mtune=help">, Alias; +def march_EQ_QUESTION : Flag<["-"], "march=help">, Alias; def time : Flag<["-"], "time">, HelpText<"Time individual commands">; def traditional_cpp : Flag<["-", "--"], "traditional-cpp">, Flags<[CC1Option]>, diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -107,6 +107,8 @@ using namespace clang; using namespace llvm::opt; +extern void RISCVMarchHelp(); + static std::optional getOffloadTargetTriple(const Driver &D, const ArgList &Args) { auto OffloadTargets = Args.getAllArgValues(options::OPT_offload_EQ); @@ -2090,7 +2092,8 @@ if (C.getArgs().hasArg(options::OPT_v) || C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) || - C.getArgs().hasArg(options::OPT_print_supported_cpus)) { + C.getArgs().hasArg(options::OPT_print_supported_cpus) || + C.getArgs().hasArg(options::OPT_print_supported_marchs)) { PrintVersion(C, llvm::errs()); SuppressMissingInputWarning = true; } @@ -4223,6 +4226,14 @@ I.second->claim(); } + // If --print-supported-marchs or -march=help is specified, call the helper + // function RISCVMarchHelp in RISCVISAInfo.cpp that prints out supported + // marchs and quits. + if (Args.getLastArg(options::OPT_print_supported_marchs)) { + RISCVMarchHelp(); + exit(0); + } + // Call validator for dxil when -Vd not in Args. if (C.getDefaultToolChain().getTriple().isDXIL()) { // Only add action when needValidation. diff --git a/clang/test/Driver/print-supported-marchs.c b/clang/test/Driver/print-supported-marchs.c new file mode 100644 --- /dev/null +++ b/clang/test/Driver/print-supported-marchs.c @@ -0,0 +1,98 @@ +// Test that --print-supported-marchs lists supported Marchs. + +// REQUIRES: riscv-registered-target + +// RUN: %clang --target=riscv64 --print-supported-marchs 2>&1 | \ +// RUN: FileCheck %s --check-prefix=CHECK-RISCV + +// Test -march=help alias. +// RUN: %clang --target=riscv64 -march=help 2>&1 | \ +// RUN: FileCheck %s --check-prefix=CHECK-RISCV + +// CHECK-NOT: warning: argument unused during compilation +// CHECK-RISCV: Target: riscv64 +// CHECK-RISCV: All available -march extensions for RISC-V +// CHECK-RISCV: Name Version +// CHECK-RISCV: a 2.0 +// CHECK-RISCV: c 2.0 +// CHECK-RISCV: d 2.0 +// CHECK-RISCV: e 1.9 +// CHECK-RISCV: f 2.0 +// CHECK-RISCV: h 1.0 +// CHECK-RISCV: i 2.0 +// CHECK-RISCV: m 2.0 +// CHECK-RISCV: svinval 1.0 +// CHECK-RISCV: svnapot 1.0 +// CHECK-RISCV: svpbmt 1.0 +// CHECK-RISCV: v 1.0 +// CHECK-RISCV: xtheadba 1.0 +// CHECK-RISCV: xtheadbb 1.0 +// CHECK-RISCV: xtheadbs 1.0 +// CHECK-RISCV: xtheadcmo 1.0 +// CHECK-RISCV: xtheadcondmov 1.0 +// CHECK-RISCV: xtheadfmemidx 1.0 +// CHECK-RISCV: xtheadmac 1.0 +// CHECK-RISCV: xtheadmemidx 1.0 +// CHECK-RISCV: xtheadmempair 1.0 +// CHECK-RISCV: xtheadsync 1.0 +// CHECK-RISCV: xtheadvdot 1.0 +// CHECK-RISCV: xventanacondops 1.0 +// CHECK-RISCV: zawrs 1.0 +// CHECK-RISCV: zba 1.0 +// CHECK-RISCV: zbb 1.0 +// CHECK-RISCV: zbc 1.0 +// CHECK-RISCV: zbkb 1.0 +// CHECK-RISCV: zbkc 1.0 +// CHECK-RISCV: zbkx 1.0 +// CHECK-RISCV: zbs 1.0 +// CHECK-RISCV: zdinx 1.0 +// CHECK-RISCV: zfh 1.0 +// CHECK-RISCV: zfhmin 1.0 +// CHECK-RISCV: zfinx 1.0 +// CHECK-RISCV: zhinx 1.0 +// CHECK-RISCV: zhinxmin 1.0 +// CHECK-RISCV: zicbom 1.0 +// CHECK-RISCV: zicbop 1.0 +// CHECK-RISCV: zicboz 1.0 +// CHECK-RISCV: zicsr 2.0 +// CHECK-RISCV: zifencei 2.0 +// CHECK-RISCV: zihintpause 2.0 +// CHECK-RISCV: zk 1.0 +// CHECK-RISCV: zkn 1.0 +// CHECK-RISCV: zknd 1.0 +// CHECK-RISCV: zkne 1.0 +// CHECK-RISCV: zknh 1.0 +// CHECK-RISCV: zkr 1.0 +// CHECK-RISCV: zks 1.0 +// CHECK-RISCV: zksed 1.0 +// CHECK-RISCV: zksh 1.0 +// CHECK-RISCV: zkt 1.0 +// CHECK-RISCV: zmmul 1.0 +// CHECK-RISCV: zve32f 1.0 +// CHECK-RISCV: zve32x 1.0 +// CHECK-RISCV: zve64d 1.0 +// CHECK-RISCV: zve64f 1.0 +// CHECK-RISCV: zve64x 1.0 +// CHECK-RISCV: zvl1024b 1.0 +// CHECK-RISCV: zvl128b 1.0 +// CHECK-RISCV: zvl16384b 1.0 +// CHECK-RISCV: zvl2048b 1.0 +// CHECK-RISCV: zvl256b 1.0 +// CHECK-RISCV: zvl32768b 1.0 +// CHECK-RISCV: zvl32b 1.0 +// CHECK-RISCV: zvl4096b 1.0 +// CHECK-RISCV: zvl512b 1.0 +// CHECK-RISCV: zvl64b 1.0 +// CHECK-RISCV: zvl65536b 1.0 +// CHECK-RISCV: zvl8192b 1.0 +// CHECK-RISCV: Experimental extensions +// CHECK-RISCV: zca 1.0 +// CHECK-RISCV: zcb 1.0 +// CHECK-RISCV: zcd 1.0 +// CHECK-RISCV: zcf 1.0 +// CHECK-RISCV: zfa 0.1 +// CHECK-RISCV: zihintntl 0.2 +// CHECK-RISCV: ztso 0.1 +// CHECK-RISCV: zvfh 0.1 +// CHECK-RISCV: Use -march to specify the target's extension. +// CHECK-RISCV: For example, clang -march=rv32i_v1p0 diff --git a/llvm/lib/Support/RISCVISAInfo.cpp b/llvm/lib/Support/RISCVISAInfo.cpp --- a/llvm/lib/Support/RISCVISAInfo.cpp +++ b/llvm/lib/Support/RISCVISAInfo.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include @@ -139,6 +140,34 @@ {"ztso", RISCVExtensionVersion{0, 1}}, }; +void RISCVMarchHelp() { + auto Cmp = [](const RISCVSupportedExtension &a, + const RISCVSupportedExtension &b) { + StringRef aRef{a.Name}, bRef{b.Name}; + return std::tie(aRef, a.Version.Major, a.Version.Minor) < + std::tie(bRef, b.Version.Major, b.Version.Minor); }; + + errs() << "All available -march extensions for RISC-V\n\n"; + errs() << '\t' << left_justify("Name", 20) << "Version\n"; + std::set TempSet(Cmp); + for (auto E : SupportedExtensions) + TempSet.insert(E); + for (auto E : TempSet) + errs() << format("\t%-20s%d.%d\n", E.Name, E.Version.Major, E.Version.Minor); + + errs() << "\nExperimental extensions\n"; + TempSet.clear(); + for (auto E : SupportedExperimentalExtensions) + TempSet.insert(E); + for (auto E : TempSet) + errs() << format("\t%-20s%d.%d\n", + E.Name, E.Version.Major, E.Version.Minor); + errs() << '\n'; + + errs() << "Use -march to specify the target's extension.\n" + "For example, clang -march=rv32i_v1p0\n"; +} + static bool stripExperimentalPrefix(StringRef &Ext) { return Ext.consume_front("experimental-"); }