aboutsummaryrefslogtreecommitdiff
path: root/backend/lib/Target/RISCV/RISCVSubtarget.cpp
diff options
context:
space:
mode:
authorRichard-Qin-X <richard.qin.001@gmail.com>2026-08-15 03:35:54 +0800
committerRichard-Qin-X <richard.qin.001@gmail.com>2026-08-15 03:35:54 +0800
commit2eb438cac7bdd3abb43ae1a784e8eb20d77cf7b7 (patch)
tree6a02d0aff91ccdc1ae0eca854f41aa4292321b2c /backend/lib/Target/RISCV/RISCVSubtarget.cpp
parentae9caa1af23247b75f94645c540930e2933c86e4 (diff)
downloadrcc-project-2eb438cac7bdd3abb43ae1a784e8eb20d77cf7b7.tar.gz
rcc-project-2eb438cac7bdd3abb43ae1a784e8eb20d77cf7b7.tar.xz
[RISCV] Match explicit target feature semantics
Diffstat (limited to 'backend/lib/Target/RISCV/RISCVSubtarget.cpp')
-rw-r--r--backend/lib/Target/RISCV/RISCVSubtarget.cpp19
1 files changed, 14 insertions, 5 deletions
diff --git a/backend/lib/Target/RISCV/RISCVSubtarget.cpp b/backend/lib/Target/RISCV/RISCVSubtarget.cpp
index 46e8fe6..e38a574 100644
--- a/backend/lib/Target/RISCV/RISCVSubtarget.cpp
+++ b/backend/lib/Target/RISCV/RISCVSubtarget.cpp
@@ -99,6 +99,7 @@ constexpr std::array OptionNames{
Expected<RISCVSubtargetFeatures>
RISCVSubtargetFeatures::fromFeatureList(std::span<const std::string> Features) {
std::uint16_t Enabled = extensionBit(RISCVExtension::I);
+ std::uint16_t ExplicitlyDisabled = 0;
std::uint32_t Options = 0;
for (const std::string &Feature : Features) {
if (Feature.size() < 2 || (Feature.front() != '+' && Feature.front() != '-')) {
@@ -113,10 +114,13 @@ RISCVSubtargetFeatures::fromFeatureList(std::span<const std::string> Features) {
"RISC-V backend does not support target feature '" + Feature + "'");
}
if (Extension != nullptr) {
- if (Feature.front() == '+')
+ if (Feature.front() == '+') {
Enabled |= extensionBit(Extension->Extension);
- else
+ ExplicitlyDisabled &= static_cast<std::uint16_t>(~extensionBit(Extension->Extension));
+ } else {
Enabled &= static_cast<std::uint16_t>(~extensionBit(Extension->Extension));
+ ExplicitlyDisabled |= extensionBit(Extension->Extension);
+ }
} else if (Feature.front() == '+') {
Options |= optionBit(Option->Option);
} else {
@@ -129,16 +133,21 @@ RISCVSubtargetFeatures::fromFeatureList(std::span<const std::string> Features) {
return makeUnexpected(ErrorCode::InvalidInvocation,
"RV64 target feature configuration cannot disable the base I extension");
}
- if (Result.has(RISCVExtension::D) && !Result.has(RISCVExtension::F)) {
+ if (Result.has(RISCVExtension::D) &&
+ (ExplicitlyDisabled & extensionBit(RISCVExtension::F)) != 0) {
return makeUnexpected(ErrorCode::InvalidInvocation,
"RISC-V D extension requires the F extension");
}
+ if (Result.has(RISCVExtension::D))
+ Enabled |= extensionBit(RISCVExtension::F);
if ((Result.has(RISCVExtension::Zacas) || Result.has(RISCVExtension::Zabha)) &&
- !Result.has(RISCVExtension::A)) {
+ (ExplicitlyDisabled & extensionBit(RISCVExtension::A)) != 0) {
return makeUnexpected(ErrorCode::InvalidInvocation,
"RISC-V Zacas and Zabha extensions require the A extension");
}
- return Result;
+ if (Result.has(RISCVExtension::Zacas) || Result.has(RISCVExtension::Zabha))
+ Enabled |= extensionBit(RISCVExtension::A);
+ return RISCVSubtargetFeatures(Enabled, Options);
}
RISCVSubtargetFeatures RISCVSubtargetFeatures::rv64gc() noexcept {