aboutsummaryrefslogtreecommitdiff
path: root/backend/lib/Target/RISCV/RISCVFunctionInfo.cpp
diff options
context:
space:
mode:
authorRichard-Qin-X <richard.qin.001@gmail.com>2026-08-11 17:38:11 +0800
committerRichard-Qin-X <richard.qin.001@gmail.com>2026-08-11 17:38:11 +0800
commit4fe5ee649927d54d6fb74904d7b97ad0f63fd587 (patch)
tree75f85f5e6cae3a871fe42d025dca04eeb7c31cfd /backend/lib/Target/RISCV/RISCVFunctionInfo.cpp
parent6a7b083f322f4ac47e58cbf9d4d5fd4d1f6fecd0 (diff)
downloadrcc-project-4fe5ee649927d54d6fb74904d7b97ad0f63fd587.tar.gz
rcc-project-4fe5ee649927d54d6fb74904d7b97ad0f63fd587.tar.xz
[RISCV] Legalize fixed-baseline RV64 MachineIR
Diffstat (limited to 'backend/lib/Target/RISCV/RISCVFunctionInfo.cpp')
-rw-r--r--backend/lib/Target/RISCV/RISCVFunctionInfo.cpp137
1 files changed, 137 insertions, 0 deletions
diff --git a/backend/lib/Target/RISCV/RISCVFunctionInfo.cpp b/backend/lib/Target/RISCV/RISCVFunctionInfo.cpp
new file mode 100644
index 0000000..f25bb8c
--- /dev/null
+++ b/backend/lib/Target/RISCV/RISCVFunctionInfo.cpp
@@ -0,0 +1,137 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "rcc/Target/RISCV/RISCVFunctionInfo.h"
+
+#include "rcc/CodeGen/TargetMIRTextInfo.h"
+
+#include <bit>
+#include <charconv>
+#include <cstddef>
+#include <cstdint>
+#include <span>
+#include <string>
+#include <string_view>
+#include <system_error>
+#include <utility>
+#include <vector>
+
+namespace rcc::riscv {
+namespace {
+
+[[nodiscard]] Expected<std::int32_t> parseSignedField(const MIRTargetNode &Node,
+ std::string_view Name) {
+ if (Node.Kind != MIRTargetNodeKind::Scalar)
+ return makeUnexpected(ErrorCode::ParseError,
+ "RISC-V machineFunctionInfo field '" + std::string(Name) +
+ "' must be a scalar");
+ std::int32_t Value = 0;
+ const auto Result =
+ std::from_chars(Node.Scalar.data(), Node.Scalar.data() + Node.Scalar.size(), Value, 10);
+ if (Result.ec != std::errc{} || Result.ptr != Node.Scalar.data() + Node.Scalar.size()) {
+ return makeUnexpected(ErrorCode::ParseError,
+ "RISC-V machineFunctionInfo field '" + std::string(Name) +
+ "' must be a 32-bit signed integer");
+ }
+ return Value;
+}
+
+[[nodiscard]] Expected<TargetFunctionState> parseFunctionInfo(const MIRTargetNode &Node) {
+ if (Node.Kind != MIRTargetNodeKind::Mapping)
+ return makeUnexpected(ErrorCode::ParseError,
+ "RISC-V machineFunctionInfo must be a mapping");
+
+ std::int32_t VarArgsFrameIndex = 0;
+ std::int32_t VarArgsSaveSize = 0;
+ for (const MIRTargetMappingEntry &Entry : Node.Mapping) {
+ if (Entry.Key == "varArgsFrameIndex") {
+ auto Value = parseSignedField(Entry.Value, Entry.Key);
+ if (!Value)
+ return std::unexpected(Value.error());
+ VarArgsFrameIndex = *Value;
+ continue;
+ }
+ if (Entry.Key == "varArgsSaveSize") {
+ auto Value = parseSignedField(Entry.Value, Entry.Key);
+ if (!Value)
+ return std::unexpected(Value.error());
+ VarArgsSaveSize = *Value;
+ continue;
+ }
+ return makeUnexpected(ErrorCode::ParseError,
+ "unknown RISC-V machineFunctionInfo field '" + Entry.Key + "'");
+ }
+ return TargetFunctionState::create(
+ RISCVFunctionInfo(VarArgsFrameIndex, VarArgsSaveSize));
+}
+
+[[nodiscard]] Expected<MIRTargetNode>
+printFunctionInfo(const TargetFunctionState &State) {
+ const auto *Info = State.getIf<RISCVFunctionInfo>();
+ if (Info == nullptr)
+ return makeUnexpected(ErrorCode::InvalidArgument,
+ "target function state is not RISC-V function information");
+ std::vector<MIRTargetMappingEntry> Entries;
+ Entries.push_back({"varArgsFrameIndex",
+ MIRTargetNode::scalar(std::to_string(Info->varArgsFrameIndex()))});
+ Entries.push_back({"varArgsSaveSize",
+ MIRTargetNode::scalar(std::to_string(Info->varArgsSaveSize()))});
+ return MIRTargetNode::mapping(std::move(Entries));
+}
+
+void appendWord(std::vector<std::byte> &Payload, std::int32_t Value) {
+ const std::uint32_t Bits = std::bit_cast<std::uint32_t>(Value);
+ for (std::uint32_t Shift = 0; Shift != 32; Shift += 8)
+ Payload.push_back(static_cast<std::byte>((Bits >> Shift) & 0xFFU));
+}
+
+[[nodiscard]] std::int32_t readWord(std::span<const std::byte> Payload,
+ std::size_t Offset) noexcept {
+ std::uint32_t Bits = 0;
+ for (std::uint32_t Byte = 0; Byte != 4; ++Byte) {
+ Bits |= std::to_integer<std::uint32_t>(Payload[Offset + Byte]) << (Byte * 8U);
+ }
+ return std::bit_cast<std::int32_t>(Bits);
+}
+
+} // namespace
+
+Expected<void> RISCVFunctionInfo::verify() const {
+ return {};
+}
+
+Expected<RISCVFunctionInfo>
+RISCVFunctionInfo::clone(const MachineFunctionCloneContext &) const {
+ return RISCVFunctionInfo(VarArgsFrameIndex, VarArgsSaveSize);
+}
+
+std::string RISCVFunctionInfo::print() const {
+ return "riscv-varargs:" + std::to_string(VarArgsFrameIndex) + ":" +
+ std::to_string(VarArgsSaveSize);
+}
+
+Expected<std::vector<std::byte>> RISCVFunctionInfo::encode() const {
+ std::vector<std::byte> Payload;
+ Payload.reserve(8);
+ appendWord(Payload, VarArgsFrameIndex);
+ appendWord(Payload, VarArgsSaveSize);
+ return Payload;
+}
+
+Expected<RISCVFunctionInfo>
+RISCVFunctionInfo::decode(std::uint32_t Version, std::span<const std::byte> Payload) {
+ if (Version != schemaVersion())
+ return makeUnexpected(ErrorCode::ParseError,
+ "unsupported RISC-V function-info schema version");
+ if (Payload.size() != 8)
+ return makeUnexpected(ErrorCode::ParseError,
+ "RISC-V function-info payload must contain eight bytes");
+ return RISCVFunctionInfo(readWord(Payload, 0), readWord(Payload, 4));
+}
+
+void configureFunctionInfoMIRSchema(TargetMIRTextInfoDesc &Description) {
+ Description.FunctionStateType = RISCVFunctionInfo::stableTypeID();
+ Description.ParseFunctionState = parseFunctionInfo;
+ Description.PrintFunctionState = printFunctionInfo;
+}
+
+} // namespace rcc::riscv