From cb33ca6ddcbd4cbcde04fd987cf1965d70ed4f51 Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Sun, 16 Apr 2023 22:28:41 +0200 Subject: [PATCH] Default to rv64gc for hosted riscv64 target Also select the correct ABI by default matching the enabled features (double, float or no floating point). Fixes #4375 --- CHANGELOG.md | 1 + driver/targetmachine.cpp | 41 ++++++++++++++++++++++++++++++++++----- driver/targetmachine.h | 5 ++++- driver/tool.cpp | 6 +++--- tests/driver/riscv_abi4.d | 6 ++++++ tests/driver/riscv_abi5.d | 6 ++++++ 6 files changed, 56 insertions(+), 9 deletions(-) create mode 100644 tests/driver/riscv_abi4.d create mode 100644 tests/driver/riscv_abi5.d diff --git a/driver/targetmachine.cpp b/driver/targetmachine.cpp index 3f16e20813..74f9efbc06 100644 --- a/driver/targetmachine.cpp +++ b/driver/targetmachine.cpp @@ -57,7 +57,7 @@ static llvm::cl::opt preserveDwarfLineSection( llvm::cl::init(false)); #endif -const char *getABI(const llvm::Triple &triple) { +const char *getABI(const llvm::Triple &triple, const llvm::SmallVector &features) { llvm::StringRef ABIName(opts::mABI); if (ABIName != "") { switch (triple.getArch()) { @@ -111,6 +111,17 @@ const char *getABI(const llvm::Triple &triple) { ABIName.str().c_str()); } + // checks if the features include ± + auto hasFeature = [&features](llvm::StringRef feature) { + for (int i = features.size() - 1; i >= 0; i--) { + auto f = features[i]; + if (f.substr(1) == feature) { + return f[0] == '+'; + } + } + return false; + }; + switch (triple.getArch()) { case llvm::Triple::mips64: case llvm::Triple::mips64el: @@ -120,6 +131,10 @@ const char *getABI(const llvm::Triple &triple) { case llvm::Triple::ppc64le: return "elfv2"; case llvm::Triple::riscv64: + if (hasFeature("d")) + return "lp64d"; + if (hasFeature("f")) + return "lp64f"; return "lp64"; case llvm::Triple::riscv32: return "ilp32"; @@ -430,9 +445,13 @@ createTargetMachine(const std::string targetTriple, const std::string arch, // checks if the features include ± auto hasFeature = [&features](llvm::StringRef feature) { - return std::any_of( - features.begin(), features.end(), - [feature](llvm::StringRef f) { return f.substr(1) == feature; }); + for (int i = features.size() - 1; i >= 0; i--) { + auto f = features[i]; + if (f.substr(1) == feature) { + return f[0] == '+'; + } + } + return false; }; // cmpxchg16b is not available on old 64bit CPUs. Enable code generation @@ -441,6 +460,18 @@ createTargetMachine(const std::string targetTriple, const std::string arch, features.push_back("+cx16"); } + // For a hosted RISC-V 64-bit target default to rv64gc if nothing has + // been selected + if (triple.getArch() == llvm::Triple::riscv64 && + triple.getOS() != llvm::Triple::UnknownOS && + features.empty()) { + features.push_back("+m"); + features.push_back("+a"); + features.push_back("+f"); + features.push_back("+d"); + features.push_back("+c"); + } + // Handle cases where LLVM picks wrong default relocModel #if LDC_LLVM_VER >= 1600 if (relocModel.has_value()) {} @@ -478,7 +509,7 @@ createTargetMachine(const std::string targetTriple, const std::string arch, opts::InitTargetOptionsFromCodeGenFlags(triple); if (targetOptions.MCOptions.ABIName.empty()) - targetOptions.MCOptions.ABIName = getABI(triple); + targetOptions.MCOptions.ABIName = getABI(triple, features); if (floatABI == FloatABI::Default) { switch (triple.getArch()) { diff --git a/driver/targetmachine.h b/driver/targetmachine.h index 17e664a2bf..66a84cfd82 100644 --- a/driver/targetmachine.h +++ b/driver/targetmachine.h @@ -15,6 +15,8 @@ #pragma once #include "llvm/ADT/Optional.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/CodeGen.h" #include #include @@ -73,4 +75,5 @@ MipsABI::Type getMipsABI(); const llvm::Target *lookupTarget(const std::string &arch, llvm::Triple &triple, std::string &errorMsg); -const char *getABI(const llvm::Triple &triple); +const char *getABI(const llvm::Triple &triple, + const llvm::SmallVector &features); diff --git a/driver/tool.cpp b/driver/tool.cpp index 806e365996..cf633499a8 100644 --- a/driver/tool.cpp +++ b/driver/tool.cpp @@ -123,14 +123,14 @@ void appendTargetArgsForGcc(std::vector &args) { case Triple::riscv64: { - std::string mabi = getABI(triple); - args.push_back("-mabi=" + mabi); - extern llvm::TargetMachine* gTargetMachine; auto featuresStr = gTargetMachine->getTargetFeatureString(); llvm::SmallVector features; featuresStr.split(features, ",", -1, false); + std::string mabi = getABI(triple, features); + args.push_back("-mabi=" + mabi); + // Returns true if 'feature' is enabled and false otherwise. Handles the // case where the feature is specified multiple times ('+m,-m'), and // takes the last occurrence. diff --git a/tests/driver/riscv_abi4.d b/tests/driver/riscv_abi4.d new file mode 100644 index 0000000000..a5c93bab61 --- /dev/null +++ b/tests/driver/riscv_abi4.d @@ -0,0 +1,6 @@ +// REQUIRES: target_RISCV + +// RUN: %ldc %s -mtriple=riscv64-unknown-linux --gcc=echo > %t && FileCheck %s < %t +// CHECK: -mabi=lp64d -march=rv64gc + +void main() {} diff --git a/tests/driver/riscv_abi5.d b/tests/driver/riscv_abi5.d new file mode 100644 index 0000000000..11cd97c41c --- /dev/null +++ b/tests/driver/riscv_abi5.d @@ -0,0 +1,6 @@ +// REQUIRES: target_RISCV + +// RUN: %ldc %s -mtriple=riscv64-unknown-linux -mattr=+m,+a,+f,-d --gcc=echo > %t && FileCheck %s < %t +// CHECK: -mabi=lp64f -march=rv64imaf_zicsr_zifencei + +void main() {} -- 2.43.0