From ce691f04c3eb1a972419187884f926de9632b7cf Mon Sep 17 00:00:00 2001 From: Richard-Qin-X Date: Wed, 12 Aug 2026 03:33:45 +0800 Subject: [RISCV] Describe vector tuple registers --- backend/lib/Target/RISCV/RISCV.rccdesc | 2 +- backend/lib/Target/RISCV/RISCVTarget.cpp | 86 ++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 1 deletion(-) (limited to 'backend/lib') diff --git a/backend/lib/Target/RISCV/RISCV.rccdesc b/backend/lib/Target/RISCV/RISCV.rccdesc index f41d11b..c4a87e9 100644 --- a/backend/lib/Target/RISCV/RISCV.rccdesc +++ b/backend/lib/Target/RISCV/RISCV.rccdesc @@ -246,7 +246,7 @@ register_banks: - { id: 1, symbol: GPR, name: GPRB, maximum_size_bits: 64 } - { id: 2, symbol: FPR, name: FPRB, maximum_size_bits: 64 } - { id: 3, symbol: CSR, name: CSRB, maximum_size_bits: 32 } - - { id: 4, symbol: VR, name: VRB, maximum_size_bits: 64 } + - { id: 4, symbol: VR, name: VRB, maximum_size_bits: 512 } register_classes: - diff --git a/backend/lib/Target/RISCV/RISCVTarget.cpp b/backend/lib/Target/RISCV/RISCVTarget.cpp index 090d0bc..8bdea20 100644 --- a/backend/lib/Target/RISCV/RISCVTarget.cpp +++ b/backend/lib/Target/RISCV/RISCVTarget.cpp @@ -5,6 +5,7 @@ #include "rcc/CodeGen/GenericOpcodes.h" #include "rcc/Target/RISCV/RISCVFunctionInfo.h" +#include #include #include #include @@ -13,6 +14,7 @@ #include #include #include +#include #include #include @@ -98,6 +100,88 @@ physicalRegisters(std::initializer_list IDs) { return AddClassMapping(RegisterClass::FPR64C, RegisterClass::FPR32C); } +[[nodiscard]] Expected appendRISCVVectorTupleInfo(TargetRegisterInfoDesc &Description) { + constexpr std::uint32_t FirstVector = static_cast(PhysicalRegisterID::V0); + constexpr std::uint32_t LastVector = static_cast(PhysicalRegisterID::V31); + static_assert(LastVector - FirstVector == 31); + + const RegisterBankID VectorBankID = + RegisterBankID::fromValue(static_cast(RegisterBank::VR)); + auto VectorBank = + std::ranges::find(Description.RegisterBanks, VectorBankID, &RegisterBankDesc::ID); + if (VectorBank == Description.RegisterBanks.end()) + return makeUnexpected(ErrorCode::InternalError, "RISC-V vector register bank is missing"); + + std::uint32_t NextRegisterID = 1; + for (const PhysicalRegisterDesc &Register : Description.PhysicalRegisters) + NextRegisterID = std::max(NextRegisterID, Register.Reg.number() + 1U); + std::uint32_t NextClassID = 1; + for (const RegisterClassDesc &Class : Description.RegisterClasses) + NextClassID = std::max(NextClassID, Class.ID.value() + 1U); + + for (std::uint32_t Length = 2; Length <= 8; ++Length) { + std::vector TupleRegisters; + TupleRegisters.reserve(33U - Length); + for (std::uint32_t Start = 0; Start + Length <= 32; ++Start) { + auto Tuple = PhysicalRegister::create(NextRegisterID++); + if (!Tuple) + return makeUnexpected(ErrorCode::InternalError, "RISC-V vector tuple ID is invalid"); + + std::string Name; + std::vector Units; + Units.reserve(Length); + for (std::uint32_t Offset = 0; Offset < Length; ++Offset) { + auto Element = PhysicalRegister::create(FirstVector + Start + Offset); + if (!Element) + return makeUnexpected(ErrorCode::InternalError, + "RISC-V vector tuple element ID is invalid"); + const auto ElementDescription = + std::ranges::find(Description.PhysicalRegisters, *Element, &PhysicalRegisterDesc::Reg); + if (ElementDescription == Description.PhysicalRegisters.end() || + ElementDescription->Units.size() != 1) { + return makeUnexpected(ErrorCode::InternalError, + "RISC-V vector tuple element has invalid register units"); + } + if (!Name.empty()) + Name.push_back('_'); + Name.append(ElementDescription->Name); + Units.push_back(ElementDescription->Units.front()); + } + + Description.PhysicalRegisters.push_back({ + .Reg = *Tuple, + .Name = std::move(Name), + .Encoding = Start, + .Units = std::move(Units), + .IsConstant = false, + .IsArtificial = false, + .IsReserved = false, + .AlternativeNames = {}, + }); + TupleRegisters.push_back(*Tuple); + } + + const RegisterClassID ClassID = RegisterClassID::fromValue(NextClassID++); + Description.RegisterClasses.push_back({ + .ID = ClassID, + .Name = "VRTuple" + std::to_string(Length), + .Registers = std::move(TupleRegisters), + .AllocationOrder = {}, + .SizeInBits = Length * 64U, + .SpillSizeInBits = Length * 64U, + .SpillAlignmentInBits = 64, + .Lanes = LaneMask::fromRaw(1), + .SupportedSubRegs = {}, + .SuperClasses = {}, + .DefaultBank = VectorBankID, + .Allocatable = false, + .CopyCost = Length, + }); + VectorBank->RegisterClasses.push_back(ClassID); + } + return {}; +} + [[nodiscard]] std::shared_ptr makePreservedMask(std::initializer_list Preserved) { std::vector Words; @@ -124,6 +208,8 @@ Expected createRegisterInfo() { appendGeneratedRegisterInfo(Description); if (auto Result = appendRISCVSubRegisterInfo(Description); !Result) return std::unexpected(Result.error()); + if (auto Result = appendRISCVVectorTupleInfo(Description); !Result) + return std::unexpected(Result.error()); return TargetRegisterInfo::create(std::move(Description)); } -- cgit v1.2.3