Skip to content

Commit e5a7dc0

Browse files
authored
Merge pull request #4474 from kinke/rv64
Default to rv64gc on riscv64 [slightly revised]
2 parents d719e70 + a2c63b6 commit e5a7dc0

File tree

6 files changed

+86
-57
lines changed

6 files changed

+86
-57
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#### Platform support
99
- Supports LLVM 11.0 - 16.0.
10+
- 64-bit RISC-V: Now defaults to `-mattr=+m,+a,+f,+d,+c` ('rv64gc' ABI) for non-bare-metal targets, i.e., if the target triple includes a valid operating system. (#4390)
1011

1112
#### Bug fixes
1213
- Fix function pointers/delegates on Harvard architectures (e.g., AVR). (#4432, #4465)

driver/targetmachine.cpp

+29-2
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,20 @@ static llvm::cl::opt<bool, true> preserveDwarfLineSection(
5757
llvm::cl::init(false));
5858
#endif
5959

60-
const char *getABI(const llvm::Triple &triple) {
60+
// Returns true if 'feature' is enabled and false otherwise. Handles the
61+
// case where the feature is specified multiple times ('+m,-m'), and
62+
// takes the last occurrence.
63+
bool isFeatureEnabled(const llvm::SmallVectorImpl<llvm::StringRef> &features,
64+
llvm::StringRef feature) {
65+
for (auto it = features.rbegin(), end = features.rend(); it != end; ++it) {
66+
if (it->substr(1) == feature) {
67+
return (*it)[0] == '+';
68+
}
69+
}
70+
return false;
71+
};
72+
73+
const char *getABI(const llvm::Triple &triple, const llvm::SmallVectorImpl<llvm::StringRef> &features) {
6174
llvm::StringRef ABIName(opts::mABI);
6275
if (ABIName != "") {
6376
switch (triple.getArch()) {
@@ -120,6 +133,10 @@ const char *getABI(const llvm::Triple &triple) {
120133
case llvm::Triple::ppc64le:
121134
return "elfv2";
122135
case llvm::Triple::riscv64:
136+
if (isFeatureEnabled(features, "d"))
137+
return "lp64d";
138+
if (isFeatureEnabled(features, "f"))
139+
return "lp64f";
123140
return "lp64";
124141
case llvm::Triple::riscv32:
125142
return "ilp32";
@@ -441,6 +458,16 @@ createTargetMachine(const std::string targetTriple, const std::string arch,
441458
features.push_back("+cx16");
442459
}
443460

461+
// For a hosted RISC-V 64-bit target default to rv64gc if nothing has
462+
// been selected
463+
if (triple.getArch() == llvm::Triple::riscv64 && features.empty()) {
464+
const llvm::StringRef os = triple.getOSName();
465+
const bool isFreeStanding = os.empty() || os == "unknown" || os == "none";
466+
if (!isFreeStanding) {
467+
features = {"+m", "+a", "+f", "+d", "+c"};
468+
}
469+
}
470+
444471
// Handle cases where LLVM picks wrong default relocModel
445472
#if LDC_LLVM_VER >= 1600
446473
if (relocModel.has_value()) {}
@@ -478,7 +505,7 @@ createTargetMachine(const std::string targetTriple, const std::string arch,
478505
opts::InitTargetOptionsFromCodeGenFlags(triple);
479506

480507
if (targetOptions.MCOptions.ABIName.empty())
481-
targetOptions.MCOptions.ABIName = getABI(triple);
508+
targetOptions.MCOptions.ABIName = getABI(triple, features);
482509

483510
if (floatABI == FloatABI::Default) {
484511
switch (triple.getArch()) {

driver/targetmachine.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
#pragma once
1616

1717
#include "llvm/ADT/Optional.h"
18+
#include "llvm/ADT/SmallVector.h"
19+
#include "llvm/ADT/StringRef.h"
1820
#include "llvm/Support/CodeGen.h"
1921
#include <string>
2022
#include <vector>
@@ -73,4 +75,8 @@ MipsABI::Type getMipsABI();
7375
const llvm::Target *lookupTarget(const std::string &arch, llvm::Triple &triple,
7476
std::string &errorMsg);
7577

76-
const char *getABI(const llvm::Triple &triple);
78+
const char *getABI(const llvm::Triple &triple,
79+
const llvm::SmallVectorImpl<llvm::StringRef> &features);
80+
81+
bool isFeatureEnabled(const llvm::SmallVectorImpl<llvm::StringRef> &features,
82+
llvm::StringRef feature);

driver/tool.cpp

+37-54
Original file line numberDiff line numberDiff line change
@@ -121,62 +121,45 @@ void appendTargetArgsForGcc(std::vector<std::string> &args) {
121121
}
122122
return;
123123

124-
case Triple::riscv64:
125-
{
126-
std::string mabi = getABI(triple);
127-
args.push_back("-mabi=" + mabi);
128-
129-
extern llvm::TargetMachine* gTargetMachine;
130-
auto featuresStr = gTargetMachine->getTargetFeatureString();
131-
llvm::SmallVector<llvm::StringRef, 8> features;
132-
featuresStr.split(features, ",", -1, false);
133-
134-
// Returns true if 'feature' is enabled and false otherwise. Handles the
135-
// case where the feature is specified multiple times ('+m,-m'), and
136-
// takes the last occurrence.
137-
auto hasFeature = [&features](llvm::StringRef feature) {
138-
for (int i = features.size() - 1; i >= 0; i--) {
139-
auto f = features[i];
140-
if (f.substr(1) == feature) {
141-
return f[0] == '+';
142-
}
143-
}
144-
return false;
145-
};
146-
147-
std::string march;
148-
if (triple.isArch64Bit())
149-
march = "rv64";
150-
else
151-
march = "rv32";
152-
bool m = hasFeature("m");
153-
bool a = hasFeature("a");
154-
bool f = hasFeature("f");
155-
bool d = hasFeature("d");
156-
bool c = hasFeature("c");
157-
bool g = false;
158-
159-
if (m && a && f && d) {
160-
march += "g";
161-
g = true;
162-
} else {
163-
march += "i";
164-
if (m)
165-
march += "m";
166-
if (a)
167-
march += "a";
168-
if (f)
169-
march += "f";
170-
if (d)
171-
march += "d";
172-
}
173-
if (c)
174-
march += "c";
175-
if (!g)
176-
march += "_zicsr_zifencei";
177-
args.push_back("-march=" + march);
124+
case Triple::riscv64: {
125+
extern llvm::TargetMachine* gTargetMachine;
126+
const auto featuresStr = gTargetMachine->getTargetFeatureString();
127+
llvm::SmallVector<llvm::StringRef, 8> features;
128+
featuresStr.split(features, ",", -1, false);
129+
130+
const std::string mabi = getABI(triple, features);
131+
args.push_back("-mabi=" + mabi);
132+
133+
std::string march = triple.isArch64Bit() ? "rv64" : "rv32";
134+
const bool m = isFeatureEnabled(features, "m");
135+
const bool a = isFeatureEnabled(features, "a");
136+
const bool f = isFeatureEnabled(features, "f");
137+
const bool d = isFeatureEnabled(features, "d");
138+
const bool c = isFeatureEnabled(features, "c");
139+
bool g = false;
140+
141+
if (m && a && f && d) {
142+
march += "g";
143+
g = true;
144+
} else {
145+
march += "i";
146+
if (m)
147+
march += "m";
148+
if (a)
149+
march += "a";
150+
if (f)
151+
march += "f";
152+
if (d)
153+
march += "d";
178154
}
155+
if (c)
156+
march += "c";
157+
if (!g)
158+
march += "_zicsr_zifencei";
159+
args.push_back("-march=" + march);
179160
return;
161+
}
162+
180163
default:
181164
break;
182165
}

tests/driver/riscv_abi4.d

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// REQUIRES: target_RISCV
2+
3+
// RUN: %ldc %s -mtriple=riscv64-unknown-linux --gcc=echo > %t && FileCheck %s < %t
4+
// CHECK: -mabi=lp64d -march=rv64gc
5+
6+
void main() {}

tests/driver/riscv_abi5.d

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// REQUIRES: target_RISCV
2+
3+
// RUN: %ldc %s -mtriple=riscv64-unknown-linux -mattr=+m,+a,+f,-d --gcc=echo > %t && FileCheck %s < %t
4+
// CHECK: -mabi=lp64f -march=rv64imaf_zicsr_zifencei
5+
6+
void main() {}

0 commit comments

Comments
 (0)