Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:15.3
llvm9
clang-riscv64-rv64gc.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File clang-riscv64-rv64gc.diff of Package llvm9
commit 93c4d53b0a5 Author: Roger Ferrer Ibanez <rofirrim@gmail.com> Date: Tue Sep 10 08:16:24 2019 +0000 [RISCV] Make -march=rv{32,64}gc the default in RISC-V Linux This is the logical follow-up of D65634. Differential Revision: https://reviews.llvm.org/D66003 llvm-svn: 371496 Index: clang-9.0.1.src/lib/Driver/ToolChains/Arch/RISCV.cpp =================================================================== --- clang-9.0.1.src.orig/lib/Driver/ToolChains/Arch/RISCV.cpp +++ clang-9.0.1.src/lib/Driver/ToolChains/Arch/RISCV.cpp @@ -12,6 +12,7 @@ #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Options.h" #include "llvm/Option/ArgList.h" +#include "llvm/ADT/Optional.h" #include "llvm/Support/TargetParser.h" #include "llvm/Support/raw_ostream.h" #include "ToolChains/CommonArgs.h" @@ -189,168 +190,182 @@ static void getExtensionFeatures(const D } } -void riscv::getRISCVTargetFeatures(const Driver &D, const ArgList &Args, - std::vector<StringRef> &Features) { - if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) { - StringRef MArch = A->getValue(); +// Returns false if an error is diagnosed. +static bool getArchFeatures(const Driver &D, StringRef MArch, + std::vector<StringRef> &Features, + const ArgList &Args) { + // RISC-V ISA strings must be lowercase. + if (llvm::any_of(MArch, [](char c) { return isupper(c); })) { + D.Diag(diag::err_drv_invalid_riscv_arch_name) + << MArch << "string must be lowercase"; + return false; + } - // RISC-V ISA strings must be lowercase. - if (llvm::any_of(MArch, [](char c) { return isupper(c); })) { - D.Diag(diag::err_drv_invalid_riscv_arch_name) - << MArch << "string must be lowercase"; - return; - } + // ISA string must begin with rv32 or rv64. + if (!(MArch.startswith("rv32") || MArch.startswith("rv64")) || + (MArch.size() < 5)) { + D.Diag(diag::err_drv_invalid_riscv_arch_name) + << MArch << "string must begin with rv32{i,e,g} or rv64{i,g}"; + return false; + } - // ISA string must begin with rv32 or rv64. - if (!(MArch.startswith("rv32") || MArch.startswith("rv64")) || - (MArch.size() < 5)) { - D.Diag(diag::err_drv_invalid_riscv_arch_name) << MArch - << "string must begin with rv32{i,e,g} or rv64{i,g}"; - return; - } + bool HasRV64 = MArch.startswith("rv64"); - bool HasRV64 = MArch.startswith("rv64"); + // The canonical order specified in ISA manual. + // Ref: Table 22.1 in RISC-V User-Level ISA V2.2 + StringRef StdExts = "mafdqlcbjtpvn"; + bool HasF = false, HasD = false; + char Baseline = MArch[4]; + + // First letter should be 'e', 'i' or 'g'. + switch (Baseline) { + default: + D.Diag(diag::err_drv_invalid_riscv_arch_name) + << MArch << "first letter should be 'e', 'i' or 'g'"; + return false; + case 'e': { + StringRef Error; + // Currently LLVM does not support 'e'. + // Extension 'e' is not allowed in rv64. + if (HasRV64) + Error = "standard user-level extension 'e' requires 'rv32'"; + else + Error = "unsupported standard user-level extension 'e'"; + D.Diag(diag::err_drv_invalid_riscv_arch_name) << MArch << Error; + return false; + } + case 'i': + break; + case 'g': + // g = imafd + StdExts = StdExts.drop_front(4); + Features.push_back("+m"); + Features.push_back("+a"); + Features.push_back("+f"); + Features.push_back("+d"); + HasF = true; + HasD = true; + break; + } - // The canonical order specified in ISA manual. - // Ref: Table 22.1 in RISC-V User-Level ISA V2.2 - StringRef StdExts = "mafdqlcbjtpvn"; - bool HasF = false, HasD = false; - char Baseline = MArch[4]; + // Skip rvxxx + StringRef Exts = MArch.substr(5); - // First letter should be 'e', 'i' or 'g'. - switch (Baseline) { - default: - D.Diag(diag::err_drv_invalid_riscv_arch_name) << MArch - << "first letter should be 'e', 'i' or 'g'"; - return; - case 'e': { + // Remove non-standard extensions and supervisor-level extensions. + // They have 'x', 's', 'sx' prefixes. Parse them at the end. + // Find the very first occurrence of 's' or 'x'. + StringRef OtherExts; + size_t Pos = Exts.find_first_of("sx"); + if (Pos != StringRef::npos) { + OtherExts = Exts.substr(Pos); + Exts = Exts.substr(0, Pos); + } + + std::string Major, Minor; + if (!getExtensionVersion(D, MArch, std::string(1, Baseline), Exts, Major, + Minor)) + return false; + + // TODO: Use version number when setting target features + // and consume the underscore '_' that might follow. + + auto StdExtsItr = StdExts.begin(); + auto StdExtsEnd = StdExts.end(); + + for (auto I = Exts.begin(), E = Exts.end(); I != E; ++I) { + char c = *I; + + // Check ISA extensions are specified in the canonical order. + while (StdExtsItr != StdExtsEnd && *StdExtsItr != c) + ++StdExtsItr; + + if (StdExtsItr == StdExtsEnd) { + // Either c contains a valid extension but it was not given in + // canonical order or it is an invalid extension. StringRef Error; - // Currently LLVM does not support 'e'. - // Extension 'e' is not allowed in rv64. - if (HasRV64) - Error = "standard user-level extension 'e' requires 'rv32'"; + if (StdExts.contains(c)) + Error = "standard user-level extension not given in canonical order"; else - Error = "unsupported standard user-level extension 'e'"; - D.Diag(diag::err_drv_invalid_riscv_arch_name) - << MArch << Error; - return; + Error = "invalid standard user-level extension"; + D.Diag(diag::err_drv_invalid_riscv_ext_arch_name) + << MArch << Error << std::string(1, c); + return false; } - case 'i': - break; - case 'g': - // g = imafd - StdExts = StdExts.drop_front(4); + + // Move to next char to prevent repeated letter. + ++StdExtsItr; + + if (std::next(I) != E) { + // Skip c. + std::string Next = std::string(std::next(I), E); + std::string Major, Minor; + if (!getExtensionVersion(D, MArch, std::string(1, c), Next, Major, Minor)) + return false; + + // TODO: Use version number when setting target features + // and consume the underscore '_' that might follow. + } + + // The order is OK, then push it into features. + switch (c) { + default: + // Currently LLVM supports only "mafdc". + D.Diag(diag::err_drv_invalid_riscv_ext_arch_name) + << MArch << "unsupported standard user-level extension" + << std::string(1, c); + return false; + case 'm': Features.push_back("+m"); + break; + case 'a': Features.push_back("+a"); + break; + case 'f': Features.push_back("+f"); - Features.push_back("+d"); HasF = true; + break; + case 'd': + Features.push_back("+d"); HasD = true; break; + case 'c': + Features.push_back("+c"); + break; } + } - // Skip rvxxx - StringRef Exts = MArch.substr(5); - - // Remove non-standard extensions and supervisor-level extensions. - // They have 'x', 's', 'sx' prefixes. Parse them at the end. - // Find the very first occurrence of 's' or 'x'. - StringRef OtherExts; - size_t Pos = Exts.find_first_of("sx"); - if (Pos != StringRef::npos) { - OtherExts = Exts.substr(Pos); - Exts = Exts.substr(0, Pos); - } - - std::string Major, Minor; - if (!getExtensionVersion(D, MArch, std::string(1, Baseline), - Exts, Major, Minor)) - return; - - // TODO: Use version number when setting target features - // and consume the underscore '_' that might follow. - - auto StdExtsItr = StdExts.begin(); - auto StdExtsEnd = StdExts.end(); - - for (auto I = Exts.begin(), E = Exts.end(); I != E; ++I) { - char c = *I; + // Dependency check. + // It's illegal to specify the 'd' (double-precision floating point) + // extension without also specifying the 'f' (single precision + // floating-point) extension. + if (HasD && !HasF) { + D.Diag(diag::err_drv_invalid_riscv_arch_name) + << MArch << "d requires f extension to also be specified"; + return false; + } - // Check ISA extensions are specified in the canonical order. - while (StdExtsItr != StdExtsEnd && *StdExtsItr != c) - ++StdExtsItr; - - if (StdExtsItr == StdExtsEnd) { - // Either c contains a valid extension but it was not given in - // canonical order or it is an invalid extension. - StringRef Error; - if (StdExts.contains(c)) - Error = "standard user-level extension not given in canonical order"; - else - Error = "invalid standard user-level extension"; - D.Diag(diag::err_drv_invalid_riscv_ext_arch_name) - << MArch << Error << std::string(1, c); - return; - } + // Additional dependency checks. + // TODO: The 'q' extension requires rv64. + // TODO: It is illegal to specify 'e' extensions with 'f' and 'd'. - // Move to next char to prevent repeated letter. - ++StdExtsItr; + // Handle all other types of extensions. + getExtensionFeatures(D, Args, Features, MArch, OtherExts); - if (std::next(I) != E) { - // Skip c. - std::string Next = std::string(std::next(I), E); - std::string Major, Minor; - if (!getExtensionVersion(D, MArch, std::string(1, c), - Next, Major, Minor)) - return; - - // TODO: Use version number when setting target features - // and consume the underscore '_' that might follow. - } - - // The order is OK, then push it into features. - switch (c) { - default: - // Currently LLVM supports only "mafdc". - D.Diag(diag::err_drv_invalid_riscv_ext_arch_name) - << MArch << "unsupported standard user-level extension" - << std::string(1, c); - return; - case 'm': - Features.push_back("+m"); - break; - case 'a': - Features.push_back("+a"); - break; - case 'f': - Features.push_back("+f"); - HasF = true; - break; - case 'd': - Features.push_back("+d"); - HasD = true; - break; - case 'c': - Features.push_back("+c"); - break; - } - } - - // Dependency check. - // It's illegal to specify the 'd' (double-precision floating point) - // extension without also specifying the 'f' (single precision - // floating-point) extension. - if (HasD && !HasF) - D.Diag(diag::err_drv_invalid_riscv_arch_name) << MArch - << "d requires f extension to also be specified"; + return true; +} - // Additional dependency checks. - // TODO: The 'q' extension requires rv64. - // TODO: It is illegal to specify 'e' extensions with 'f' and 'd'. +void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple, + const ArgList &Args, + std::vector<StringRef> &Features) { + llvm::Optional<StringRef> MArch; + if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) + MArch = A->getValue(); + else if (Triple.getOS() == llvm::Triple::Linux) + // RISC-V Linux defaults to rv{32,64}gc. + MArch = Triple.getArch() == llvm::Triple::riscv32 ? "rv32gc" : "rv64gc"; - // Handle all other types of extensions. - getExtensionFeatures(D, Args, Features, MArch, OtherExts); - } + if (MArch.hasValue() && !getArchFeatures(D, *MArch, Features, Args)) + return; // -mrelax is default, unless -mno-relax is specified. if (Args.hasFlag(options::OPT_mrelax, options::OPT_mno_relax, true)) @@ -372,8 +387,16 @@ void riscv::getRISCVTargetFeatures(const } StringRef riscv::getRISCVABI(const ArgList &Args, const llvm::Triple &Triple) { - if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) + assert((Triple.getArch() == llvm::Triple::riscv32 || + Triple.getArch() == llvm::Triple::riscv64) && + "Unexpected triple"); + + if (const Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) return A->getValue(); - return Triple.getArch() == llvm::Triple::riscv32 ? "ilp32" : "lp64"; + // RISC-V Linux defaults to ilp32d/lp64d + if (Triple.getOS() == llvm::Triple::Linux) + return Triple.getArch() == llvm::Triple::riscv32 ? "ilp32d" : "lp64d"; + else + return Triple.getArch() == llvm::Triple::riscv32 ? "ilp32" : "lp64"; } Index: clang-9.0.1.src/lib/Driver/ToolChains/Arch/RISCV.h =================================================================== --- clang-9.0.1.src.orig/lib/Driver/ToolChains/Arch/RISCV.h +++ clang-9.0.1.src/lib/Driver/ToolChains/Arch/RISCV.h @@ -19,7 +19,8 @@ namespace clang { namespace driver { namespace tools { namespace riscv { -void getRISCVTargetFeatures(const Driver &D, const llvm::opt::ArgList &Args, +void getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple, + const llvm::opt::ArgList &Args, std::vector<llvm::StringRef> &Features); StringRef getRISCVABI(const llvm::opt::ArgList &Args, const llvm::Triple &Triple); Index: clang-9.0.1.src/lib/Driver/ToolChains/Clang.cpp =================================================================== --- clang-9.0.1.src.orig/lib/Driver/ToolChains/Clang.cpp +++ clang-9.0.1.src/lib/Driver/ToolChains/Clang.cpp @@ -335,7 +335,7 @@ static void getTargetFeatures(const Tool break; case llvm::Triple::riscv32: case llvm::Triple::riscv64: - riscv::getRISCVTargetFeatures(D, Args, Features); + riscv::getRISCVTargetFeatures(D, Triple, Args, Features); break; case llvm::Triple::systemz: systemz::getSystemZTargetFeatures(Args, Features); @@ -1853,21 +1853,11 @@ void Clang::AddPPCTargetArgs(const ArgLi void Clang::AddRISCVTargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const { - // FIXME: currently defaults to the soft-float ABIs. Will need to be - // expanded to select ilp32f, ilp32d, lp64f, lp64d when appropriate. - const char *ABIName = nullptr; const llvm::Triple &Triple = getToolChain().getTriple(); - if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) - ABIName = A->getValue(); - else if (Triple.getArch() == llvm::Triple::riscv32) - ABIName = "ilp32"; - else if (Triple.getArch() == llvm::Triple::riscv64) - ABIName = "lp64"; - else - llvm_unreachable("Unexpected triple!"); + StringRef ABIName = riscv::getRISCVABI(Args, Triple); CmdArgs.push_back("-target-abi"); - CmdArgs.push_back(ABIName); + CmdArgs.push_back(ABIName.data()); } void Clang::AddSparcTargetArgs(const ArgList &Args, Index: clang-9.0.1.src/test/Driver/riscv32-toolchain.c =================================================================== --- clang-9.0.1.src.orig/test/Driver/riscv32-toolchain.c +++ clang-9.0.1.src/test/Driver/riscv32-toolchain.c @@ -68,7 +68,7 @@ // CXX-RV32-BAREMETAL-NOSYSROOT-ILP32: "{{.*}}/Inputs/basic_riscv32_tree/lib/gcc/riscv32-unknown-elf/8.0.1{{/|\\\\}}crtend.o" // RUN: %clang %s -### -no-canonical-prefixes -fuse-ld=ld \ -// RUN: -target riscv32-unknown-linux-gnu \ +// RUN: -target riscv32-unknown-linux-gnu -mabi=ilp32 \ // RUN: --gcc-toolchain=%S/Inputs/multilib_riscv_linux_sdk \ // RUN: --sysroot=%S/Inputs/multilib_riscv_linux_sdk/sysroot 2>&1 \ // RUN: | FileCheck -check-prefix=C-RV32-LINUX-MULTI-ILP32 %s @@ -84,7 +84,7 @@ // C-RV32-LINUX-MULTI-ILP32: "-L{{.*}}/Inputs/multilib_riscv_linux_sdk/sysroot/usr/lib32/ilp32" // RUN: %clang %s -### -no-canonical-prefixes -fuse-ld=ld \ -// RUN: -target riscv32-unknown-linux-gnu -march=rv32imafd -mabi=ilp32d \ +// RUN: -target riscv32-unknown-linux-gnu -march=rv32imafd \ // RUN: --gcc-toolchain=%S/Inputs/multilib_riscv_linux_sdk \ // RUN: --sysroot=%S/Inputs/multilib_riscv_linux_sdk/sysroot 2>&1 \ // RUN: | FileCheck -check-prefix=C-RV32-LINUX-MULTI-ILP32D %s Index: clang-9.0.1.src/test/Driver/riscv64-toolchain.c =================================================================== --- clang-9.0.1.src.orig/test/Driver/riscv64-toolchain.c +++ clang-9.0.1.src/test/Driver/riscv64-toolchain.c @@ -68,7 +68,7 @@ // CXX-RV64-BAREMETAL-NOSYSROOT-LP64: "{{.*}}/Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1{{/|\\\\}}crtend.o" // RUN: %clang %s -### -no-canonical-prefixes -fuse-ld=ld \ -// RUN: -target riscv64-unknown-linux-gnu \ +// RUN: -target riscv64-unknown-linux-gnu -mabi=lp64 \ // RUN: --gcc-toolchain=%S/Inputs/multilib_riscv_linux_sdk \ // RUN: --sysroot=%S/Inputs/multilib_riscv_linux_sdk/sysroot 2>&1 \ // RUN: | FileCheck -check-prefix=C-RV64-LINUX-MULTI-LP64 %s @@ -84,7 +84,7 @@ // C-RV64-LINUX-MULTI-LP64: "-L{{.*}}/Inputs/multilib_riscv_linux_sdk/sysroot/usr/lib64/lp64" // RUN: %clang %s -### -no-canonical-prefixes -fuse-ld=ld \ -// RUN: -target riscv64-unknown-linux-gnu -march=rv64imafd -mabi=lp64d \ +// RUN: -target riscv64-unknown-linux-gnu -march=rv64imafd \ // RUN: --gcc-toolchain=%S/Inputs/multilib_riscv_linux_sdk \ // RUN: --sysroot=%S/Inputs/multilib_riscv_linux_sdk/sysroot 2>&1 \ // RUN: | FileCheck -check-prefix=C-RV64-LINUX-MULTI-LP64D %s Index: clang-9.0.1.src/test/Preprocessor/riscv-target-features.c =================================================================== --- clang-9.0.1.src.orig/test/Preprocessor/riscv-target-features.c +++ clang-9.0.1.src/test/Preprocessor/riscv-target-features.c @@ -48,9 +48,9 @@ // RUN: -o - | FileCheck --check-prefix=CHECK-C-EXT %s // CHECK-C-EXT: __riscv_compressed 1 -// RUN: %clang -target riscv32-unknown-linux-gnu -march=rv32ifd -x c -E -dM %s \ +// RUN: %clang -target riscv32-unknown-linux-gnu -march=rv32ifd -mabi=ilp32 -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-SOFT %s -// RUN: %clang -target riscv64-unknown-linux-gnu -march=rv64ifd -x c -E -dM %s \ +// RUN: %clang -target riscv64-unknown-linux-gnu -march=rv64ifd -mabi=lp64 -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-SOFT %s // CHECK-SOFT: __riscv_float_abi_soft 1 // CHECK-SOFT-NOT: __riscv_float_abi_single @@ -64,9 +64,9 @@ // CHECK-SINGLE-NOT: __riscv_float_abi_soft // CHECK-SINGLE-NOT: __riscv_float_abi_double -// RUN: %clang -target riscv32-unknown-linux-gnu -march=rv32ifd -mabi=ilp32d -x c -E -dM %s \ +// RUN: %clang -target riscv32-unknown-linux-gnu -march=rv32ifd -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-DOUBLE %s -// RUN: %clang -target riscv64-unknown-linux-gnu -march=rv64ifd -mabi=lp64d -x c -E -dM %s \ +// RUN: %clang -target riscv64-unknown-linux-gnu -march=rv64ifd -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-DOUBLE %s // CHECK-DOUBLE: __riscv_float_abi_double 1 // CHECK-DOUBLE-NOT: __riscv_float_abi_soft
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor