diff options
| author | Richard-Qin-X <richard.qin.001@gmail.com> | 2026-08-03 19:24:30 +0800 |
|---|---|---|
| committer | Richard-Qin-X <richard.qin.001@gmail.com> | 2026-08-03 19:24:30 +0800 |
| commit | 432efe39315ed5ad0162f9c08dbf10941bc21dc1 (patch) | |
| tree | 46622290cabfaeb8f4db1729aca6f0725739e08c /backend/lib/CodeGen/TargetDescription.cpp | |
| parent | 6580ac1c05bd1cbccd2dcd71fd9c2a384ae3db56 (diff) | |
| download | rcc-project-432efe39315ed5ad0162f9c08dbf10941bc21dc1.tar.gz rcc-project-432efe39315ed5ad0162f9c08dbf10941bc21dc1.tar.xz | |
[CodeGen] Add target MIR text schema
Diffstat (limited to 'backend/lib/CodeGen/TargetDescription.cpp')
| -rw-r--r-- | backend/lib/CodeGen/TargetDescription.cpp | 134 |
1 files changed, 132 insertions, 2 deletions
diff --git a/backend/lib/CodeGen/TargetDescription.cpp b/backend/lib/CodeGen/TargetDescription.cpp index a32534d..b9f7606 100644 --- a/backend/lib/CodeGen/TargetDescription.cpp +++ b/backend/lib/CodeGen/TargetDescription.cpp @@ -4,7 +4,10 @@ #include "rcc/CodeGen/LowLevelType.h" #include "rcc/CodeGen/MachineBasicBlock.h" +#include "rcc/CodeGen/MachineCFIInfo.h" +#include "rcc/CodeGen/MachineFrameInfo.h" #include "rcc/CodeGen/MachineInstr.h" +#include "rcc/CodeGen/MachineMemOperand.h" #include "rcc/CodeGen/MachineOperand.h" #include "rcc/CodeGen/MachineRegisterInfo.h" @@ -47,9 +50,19 @@ namespace { } // namespace Expected<TargetDescription> TargetDescription::create(InstructionSet Instructions, - TargetRegisterInfo Registers) { + TargetRegisterInfo Registers, + TargetMIRTextInfoDesc MIRTextDescription) { + auto MIRText = TargetMIRTextInfo::create(std::move(MIRTextDescription), Registers); + if (!MIRText) + return std::unexpected(MIRText.error()); + for (const InstructionDescriptor &Instruction : Instructions.descriptors()) { for (const OperandDescriptor &Operand : Instruction.Operands) { + if ((Operand.AllowedTargetFlags & ~MIRText->serializableOperandFlagMask()) != 0) { + return makeUnexpected( + ErrorCode::InvalidArgument, + "instruction operand allows a target flag outside the MIR text schema"); + } if (Operand.RegClass && Registers.registerClass(*Operand.RegClass) == nullptr) { return makeUnexpected(ErrorCode::InvalidArgument, "instruction operand references an unknown target register class"); @@ -103,7 +116,7 @@ Expected<TargetDescription> TargetDescription::create(InstructionSet Instruction } } - return TargetDescription(std::move(Instructions), std::move(Registers)); + return TargetDescription(std::move(Instructions), std::move(Registers), std::move(*MIRText)); } Expected<void> TargetDescription::validateVirtualRegister(Register Reg, @@ -113,6 +126,10 @@ Expected<void> TargetDescription::validateVirtualRegister(Register Reg, "target virtual-register validation received a non-virtual register"); } + auto TargetFlagValidation = MIRText.validateVirtualRegisterFlags(Info.TargetFlags); + if (!TargetFlagValidation) + return std::unexpected(TargetFlagValidation.error()); + const RegisterBankDesc *Bank = nullptr; if (Info.Bank) { Bank = Registers.registerBank(*Info.Bank); @@ -196,6 +213,21 @@ TargetDescription::effectiveRegisterClass(const MachineOperand &Operand, Expected<void> TargetDescription::validateTargetOperand(const OperandDescriptor *Descriptor, const MachineOperand &Operand, const MachineRegisterInfo &RegInfo) const { + auto TargetFlagValidation = MIRText.validateOperandFlags(Operand.targetFlags()); + if (!TargetFlagValidation) + return std::unexpected(TargetFlagValidation.error()); + + if (const auto *Index = Operand.getIf<TargetIndexOperand>(); + Index != nullptr && !MIRText.targetIndexName(Index->Index)) { + return makeUnexpected(ErrorCode::VerificationError, + "target-index operand is not registered for MIR serialization"); + } + if (const auto *Intrinsic = Operand.getIf<IntrinsicOperand>(); + Intrinsic != nullptr && !MIRText.intrinsicName(Intrinsic->ID)) { + return makeUnexpected(ErrorCode::VerificationError, + "intrinsic operand is not registered for MIR serialization"); + } + if (const auto *Mask = Operand.getIf<RegisterMaskOperand>(); Mask != nullptr) { if (!Mask->Mask) { return makeUnexpected(ErrorCode::VerificationError, @@ -301,6 +333,104 @@ Expected<void> TargetDescription::validateTargetOperand(const OperandDescriptor return {}; } +Expected<void> TargetDescription::validateMemOperands( + Opcode InstructionOpcode, std::span<const MachineMemOperand *const> MemOperands) const { + auto DescriptorValidation = Instructions.validateMemOperands(InstructionOpcode, MemOperands); + if (!DescriptorValidation) + return std::unexpected(DescriptorValidation.error()); + for (const MachineMemOperand *MemOperand : MemOperands) { + if (MemOperand == nullptr) + continue; + auto TargetFlagValidation = + MIRText.validateMachineMemOperandFlags(MemOperand->description().TargetFlags); + if (!TargetFlagValidation) + return std::unexpected(TargetFlagValidation.error()); + } + return {}; +} + +Expected<void> TargetDescription::validateCFIInfo(const MachineCFIInfo &Info) const { + auto ValidateRegister = [this](DwarfRegisterNumber Register) -> Expected<void> { + if (!MIRText.physicalRegister(Register.value())) { + return makeUnexpected(ErrorCode::VerificationError, + "CFI instruction references an unmapped DWARF register"); + } + return {}; + }; + + for (const MachineCFIInstruction &Instruction : Info.instructions()) { + if (const auto *Rule = Instruction.getIf<MachineCFIRegisterRule>()) { + auto Result = ValidateRegister(Rule->Register); + if (!Result) + return Result; + } + if (const auto *Rule = Instruction.getIf<MachineCFIRegisterOffsetRule>()) { + auto Result = ValidateRegister(Rule->Register); + if (!Result) + return Result; + } + if (const auto *Rule = Instruction.getIf<MachineCFIRegisterRegisterRule>()) { + auto RegisterResult = ValidateRegister(Rule->Register); + if (!RegisterResult) + return RegisterResult; + auto SourceResult = ValidateRegister(Rule->SourceRegister); + if (!SourceResult) + return SourceResult; + } + if (const auto *Rule = Instruction.getIf<MachineCFIAddressSpaceCFARule>()) { + auto Result = ValidateRegister(Rule->Register); + if (!Result) + return Result; + } + if (const auto *Rule = Instruction.getIf<MachineCFIRegisterPairRule>()) { + for (const DwarfRegisterNumber Register : + {Rule->Register, Rule->FirstRegister, Rule->SecondRegister}) { + auto Result = ValidateRegister(Register); + if (!Result) + return Result; + } + } + if (const auto *Rule = Instruction.getIf<MachineCFIVectorRegistersRule>()) { + auto Result = ValidateRegister(Rule->Register); + if (!Result) + return Result; + for (const MachineCFIVectorRegisterLane &Lane : Rule->VectorRegisters) { + Result = ValidateRegister(Lane.Register); + if (!Result) + return Result; + } + } + if (const auto *Rule = Instruction.getIf<MachineCFIVectorOffsetRule>()) { + auto RegisterResult = ValidateRegister(Rule->Register); + if (!RegisterResult) + return RegisterResult; + auto MaskResult = ValidateRegister(Rule->MaskRegister); + if (!MaskResult) + return MaskResult; + } + if (const auto *Rule = Instruction.getIf<MachineCFIVectorRegisterMaskRule>()) { + for (const DwarfRegisterNumber Register : + {Rule->Register, Rule->SpillRegister, Rule->MaskRegister}) { + auto Result = ValidateRegister(Register); + if (!Result) + return Result; + } + } + } + return {}; +} + +Expected<void> TargetDescription::validateFrameInfo(const MachineFrameInfo &Info) const { + for (const StackObject &Object : Info.objects()) { + const StackObjectDesc *Description = Object.description(); + if (Description != nullptr && !MIRText.supportsStackID(Description->Stack)) { + return makeUnexpected(ErrorCode::VerificationError, + "stack object uses a stack ID unsupported by the target"); + } + } + return {}; +} + Expected<void> TargetDescription::validateExplicitOperands(Opcode InstructionOpcode, std::span<const MachineOperand> Operands, |
