aboutsummaryrefslogtreecommitdiff
path: root/backend/lib
diff options
context:
space:
mode:
authorRichard-Qin-X <richard.qin.001@gmail.com>2026-08-13 19:09:51 +0800
committerRichard-Qin-X <richard.qin.001@gmail.com>2026-08-13 19:09:51 +0800
commitafce8c3e93059df6f9aab1bc57f72c83674d6d92 (patch)
treed32fdff80c90d2e643c9133a5cf5db0e3a7ea067 /backend/lib
parent86caf2db80050b857fac77269708263a1826c5a2 (diff)
downloadrcc-project-afce8c3e93059df6f9aab1bc57f72c83674d6d92.tar.gz
rcc-project-afce8c3e93059df6f9aab1bc57f72c83674d6d92.tar.xz
[RISCV] Model non-ISA subtarget features
Diffstat (limited to 'backend/lib')
-rw-r--r--backend/lib/Target/RISCV/RISCVSubtarget.cpp77
1 files changed, 70 insertions, 7 deletions
diff --git a/backend/lib/Target/RISCV/RISCVSubtarget.cpp b/backend/lib/Target/RISCV/RISCVSubtarget.cpp
index 89f6c61..a4986e4 100644
--- a/backend/lib/Target/RISCV/RISCVSubtarget.cpp
+++ b/backend/lib/Target/RISCV/RISCVSubtarget.cpp
@@ -20,6 +20,11 @@ struct ExtensionName final {
RISCVExtension Extension;
};
+struct OptionName final {
+ std::string_view Name;
+ RISCVSubtargetOption Option;
+};
+
constexpr std::array ExtensionNames{
ExtensionName{"i", RISCVExtension::I},
ExtensionName{"m", RISCVExtension::M},
@@ -33,10 +38,45 @@ constexpr std::array ExtensionNames{
ExtensionName{"zabha", RISCVExtension::Zabha},
};
+constexpr std::array OptionNames{
+ OptionName{"disable-postmisched-load-clustering",
+ RISCVSubtargetOption::DisablePostMISchedLoadClustering},
+ OptionName{"disable-postmisched-store-clustering",
+ RISCVSubtargetOption::DisablePostMISchedStoreClustering},
+ OptionName{"fusion-add-load", RISCVSubtargetOption::FusionAddLoad},
+ OptionName{"fusion-add-mem", RISCVSubtargetOption::FusionAddMemory},
+ OptionName{"fusion-addi-load", RISCVSubtargetOption::FusionAddImmediateLoad},
+ OptionName{"fusion-auipc-addi", RISCVSubtargetOption::FusionAUIPCAddImmediate},
+ OptionName{"fusion-auipc-load", RISCVSubtargetOption::FusionAUIPCLoad},
+ OptionName{"fusion-ld-add", RISCVSubtargetOption::FusionLoadDoubleAdd},
+ OptionName{"fusion-logic-imm-reg", RISCVSubtargetOption::FusionLogicImmediateRegister},
+ OptionName{"fusion-logic-reg-imm", RISCVSubtargetOption::FusionLogicRegisterImmediate},
+ OptionName{"fusion-logic-reg-reg", RISCVSubtargetOption::FusionLogicRegisterRegister},
+ OptionName{"fusion-lui-addi", RISCVSubtargetOption::FusionLUIAddImmediate},
+ OptionName{"fusion-lui-load", RISCVSubtargetOption::FusionLUILoad},
+ OptionName{"fusion-mul-add", RISCVSubtargetOption::FusionMultiplyAdd},
+ OptionName{"fusion-shift-bit-extract", RISCVSubtargetOption::FusionShiftBitExtract},
+ OptionName{"fusion-shifted-zextw", RISCVSubtargetOption::FusionShiftedZeroExtendWord},
+ OptionName{"fusion-zexth", RISCVSubtargetOption::FusionZeroExtendHalf},
+ OptionName{"fusion-zextw", RISCVSubtargetOption::FusionZeroExtendWord},
+ OptionName{"prefer-w-inst", RISCVSubtargetOption::PreferWordInstructions},
+ OptionName{"reserve-x6", RISCVSubtargetOption::ReserveX6},
+ OptionName{"reserve-x7", RISCVSubtargetOption::ReserveX7},
+ OptionName{"save-restore", RISCVSubtargetOption::SaveRestore},
+ OptionName{"tagged-globals", RISCVSubtargetOption::TaggedGlobals},
+ OptionName{"unaligned-scalar-mem", RISCVSubtargetOption::UnalignedScalarMemory},
+ OptionName{"use-postra-scheduler", RISCVSubtargetOption::UsePostRAScheduler},
+};
+
[[nodiscard]] constexpr std::uint16_t extensionBit(RISCVExtension Extension) noexcept {
return static_cast<std::uint16_t>(std::uint16_t{1} << static_cast<std::uint8_t>(Extension));
}
+[[nodiscard]] constexpr std::uint32_t optionBit(RISCVSubtargetOption Option) noexcept {
+ static_assert(static_cast<std::uint8_t>(RISCVSubtargetOption::Count) <= 32);
+ return std::uint32_t{1} << static_cast<std::uint8_t>(Option);
+}
+
[[nodiscard]] const ExtensionName *findExtension(std::string_view Name) noexcept {
for (const ExtensionName &Entry : ExtensionNames) {
if (Entry.Name == Name)
@@ -45,28 +85,45 @@ constexpr std::array ExtensionNames{
return nullptr;
}
+[[nodiscard]] const OptionName *findOption(std::string_view Name) noexcept {
+ for (const OptionName &Entry : OptionNames) {
+ if (Entry.Name == Name)
+ return &Entry;
+ }
+ return nullptr;
+}
+
} // namespace
Expected<RISCVSubtargetFeatures>
RISCVSubtargetFeatures::fromFeatureList(std::span<const std::string> Features) {
std::uint16_t Enabled = extensionBit(RISCVExtension::I);
+ std::uint32_t Options = 0;
for (const std::string &Feature : Features) {
if (Feature.size() < 2 || (Feature.front() != '+' && Feature.front() != '-')) {
return makeUnexpected(ErrorCode::InvalidInvocation,
"RISC-V target feature must use canonical +/- spelling");
}
- const ExtensionName *Extension = findExtension(std::string_view(Feature).substr(1));
- if (Extension == nullptr) {
+ const std::string_view Name = std::string_view(Feature).substr(1);
+ const ExtensionName *Extension = findExtension(Name);
+ const OptionName *Option = findOption(Name);
+ if (Extension == nullptr && Option == nullptr) {
return makeUnexpected(ErrorCode::InvalidInvocation,
"RISC-V backend does not support target feature '" + Feature + "'");
}
- if (Feature.front() == '+')
- Enabled |= extensionBit(Extension->Extension);
- else
- Enabled &= static_cast<std::uint16_t>(~extensionBit(Extension->Extension));
+ if (Extension != nullptr) {
+ if (Feature.front() == '+')
+ Enabled |= extensionBit(Extension->Extension);
+ else
+ Enabled &= static_cast<std::uint16_t>(~extensionBit(Extension->Extension));
+ } else if (Feature.front() == '+') {
+ Options |= optionBit(Option->Option);
+ } else {
+ Options &= ~optionBit(Option->Option);
+ }
}
- RISCVSubtargetFeatures Result(Enabled);
+ RISCVSubtargetFeatures Result(Enabled, Options);
if (!Result.has(RISCVExtension::I)) {
return makeUnexpected(ErrorCode::InvalidInvocation,
"RV64 target feature configuration cannot disable the base I extension");
@@ -97,6 +154,12 @@ bool RISCVSubtargetFeatures::has(RISCVExtension Extension) const noexcept {
return (Enabled & extensionBit(Extension)) != 0;
}
+bool RISCVSubtargetFeatures::has(RISCVSubtargetOption Option) const noexcept {
+ if (Option >= RISCVSubtargetOption::Count)
+ return false;
+ return (Options & optionBit(Option)) != 0;
+}
+
RISCVSubtarget::RISCVSubtarget(RISCVSubtargetFeatures Features) : Features(Features) {}
RISCVSubtarget::~RISCVSubtarget() = default;