diff options
| author | Richard-Qin-X <richard.qin.001@gmail.com> | 2026-08-07 02:15:09 +0800 |
|---|---|---|
| committer | Richard-Qin-X <richard.qin.001@gmail.com> | 2026-08-07 02:15:09 +0800 |
| commit | e16de95dce32f077361577377d5c52fc4ad78339 (patch) | |
| tree | ea563652a95e6e32eb86ce68845a2005d83a85d5 /backend/lib/CodeGen | |
| parent | 76d89700953ddd81cf31ab8f260eddf67e93aa85 (diff) | |
| download | rcc-project-e16de95dce32f077361577377d5c52fc4ad78339.tar.gz rcc-project-e16de95dce32f077361577377d5c52fc4ad78339.tar.xz | |
[RISCV] Add generated RV64GC register description
Add an RCC-owned build-time target description generator and the initial RV64GC register model. Keep ABI aliases separate from canonical MIR register spelling.
Diffstat (limited to 'backend/lib/CodeGen')
| -rw-r--r-- | backend/lib/CodeGen/TargetDescription.cpp | 17 | ||||
| -rw-r--r-- | backend/lib/CodeGen/TargetRegisterInfo.cpp | 30 |
2 files changed, 40 insertions, 7 deletions
diff --git a/backend/lib/CodeGen/TargetDescription.cpp b/backend/lib/CodeGen/TargetDescription.cpp index b9f7606..e2bbe8a 100644 --- a/backend/lib/CodeGen/TargetDescription.cpp +++ b/backend/lib/CodeGen/TargetDescription.cpp @@ -175,10 +175,10 @@ Expected<void> TargetDescription::validateVirtualRegister(Register Reg, return makeUnexpected(ErrorCode::VerificationError, "virtual register allocation hint names an unknown physical register"); } - if (HintDesc->IsConstant || HintDesc->IsArtificial) { + if (HintDesc->IsConstant || HintDesc->IsArtificial || HintDesc->IsReserved) { return makeUnexpected( ErrorCode::VerificationError, - "virtual register allocation hint names a constant or artificial register"); + "virtual register allocation hint names a constant, artificial, or reserved register"); } if (Info.RegClass && !Registers.registerClassContains(*Info.RegClass, Hint)) { return makeUnexpected(ErrorCode::VerificationError, @@ -283,7 +283,8 @@ Expected<void> TargetDescription::validateTargetOperand(const OperandDescriptor return Registers.regsOverlap(Reserved, PhysRegValue); }); if (Operand.registerFlags().has(RegisterOperandFlag::Renamable) && - (IsReservedOrAlias || PhysRegDesc->IsConstant || PhysRegDesc->IsArtificial)) { + (IsReservedOrAlias || PhysRegDesc->IsConstant || PhysRegDesc->IsArtificial || + PhysRegDesc->IsReserved)) { return makeUnexpected(ErrorCode::VerificationError, "fixed physical register operand cannot be renamable"); } @@ -718,9 +719,15 @@ Expected<void> TargetDescription::validateRegisterInfo(const MachineRegisterInfo if (!Validation) return std::unexpected(Validation.error()); for (const PhysicalRegister Hint : Info.AllocationHints) { - if (std::ranges::any_of(RegInfo.reservedRegisters(), [this, Hint](PhysicalRegister Reserved) { + const bool IsStaticReservedOrAlias = std::ranges::any_of( + Registers.physicalRegisters(), [this, Hint](const PhysicalRegisterDesc &Register) { + return Register.IsReserved && Registers.regsOverlap(Register.Reg, Hint); + }); + const bool IsFunctionReservedOrAlias = + std::ranges::any_of(RegInfo.reservedRegisters(), [this, Hint](PhysicalRegister Reserved) { return Registers.regsOverlap(Reserved, Hint); - })) { + }); + if (IsStaticReservedOrAlias || IsFunctionReservedOrAlias) { return makeUnexpected( ErrorCode::VerificationError, "virtual register allocation hint overlaps a reserved physical register"); diff --git a/backend/lib/CodeGen/TargetRegisterInfo.cpp b/backend/lib/CodeGen/TargetRegisterInfo.cpp index 3ece639..42ae935 100644 --- a/backend/lib/CodeGen/TargetRegisterInfo.cpp +++ b/backend/lib/CodeGen/TargetRegisterInfo.cpp @@ -75,10 +75,19 @@ Expected<TargetRegisterInfo> TargetRegisterInfo::create(TargetRegisterInfoDesc D } std::string MIRName = lowerASCII(Register.Name); if (!Result.RegisterToIndex.emplace(Register.Reg, Index).second || + Result.AlternativeRegisterNameToIndex.contains(MIRName) || !Result.RegisterNameToIndex.emplace(MIRName, Index).second) { return invalidDescription( "physical register numbers and names must be unique case-insensitively"); } + for (const std::string &AlternativeName : Register.AlternativeNames) { + const std::string NormalizedName = lowerASCII(AlternativeName); + if (AlternativeName.empty() || Result.RegisterNameToIndex.contains(NormalizedName) || + !Result.AlternativeRegisterNameToIndex.emplace(NormalizedName, Index).second) { + return invalidDescription( + "physical register alternative names must be nonempty and unique case-insensitively"); + } + } Result.RegisterMIRNames.push_back(std::move(MIRName)); } @@ -275,9 +284,13 @@ Expected<TargetRegisterInfo> TargetRegisterInfo::create(TargetRegisterInfoDesc D std::unordered_set<PhysicalRegister> AllocationRegisters; for (const PhysicalRegister Reg : Class.AllocationOrder) { - if (!Members.contains(Reg) || !AllocationRegisters.insert(Reg).second) { + const PhysicalRegisterDesc *Register = Result.physicalRegister(Reg); + const bool IsUnavailable = + Register != nullptr && + (Register->IsConstant || Register->IsArtificial || Register->IsReserved); + if (!Members.contains(Reg) || IsUnavailable || !AllocationRegisters.insert(Reg).second) { return invalidDescription( - "register class allocation order must contain unique class members"); + "register class allocation order must contain unique allocatable class members"); } } if ((Class.Allocatable && Class.AllocationOrder.empty()) || @@ -453,6 +466,19 @@ TargetRegisterInfo::physicalRegister(std::string_view Name) const noexcept { : &Description.PhysicalRegisters[Position->second]; } +const PhysicalRegisterDesc * +TargetRegisterInfo::physicalRegisterByAlternativeName(std::string_view Name) const noexcept { + const auto Position = AlternativeRegisterNameToIndex.find(lowerASCII(Name)); + return Position == AlternativeRegisterNameToIndex.end() + ? nullptr + : &Description.PhysicalRegisters[Position->second]; +} + +bool TargetRegisterInfo::isReservedRegister(PhysicalRegister Reg) const noexcept { + const PhysicalRegisterDesc *Register = physicalRegister(Reg); + return Register != nullptr && Register->IsReserved; +} + const SubRegIndexDesc *TargetRegisterInfo::subRegIndex(SubRegIndex Index) const noexcept { const auto Position = SubRegIndexToIndex.find(Index); return Position == SubRegIndexToIndex.end() ? nullptr |
