From 432efe39315ed5ad0162f9c08dbf10941bc21dc1 Mon Sep 17 00:00:00 2001 From: Richard-Qin-X Date: Mon, 3 Aug 2026 19:24:30 +0800 Subject: [CodeGen] Add target MIR text schema --- backend/lib/CodeGen/TargetDescription.cpp | 134 +++++++++++++++++++++++++++++- 1 file changed, 132 insertions(+), 2 deletions(-) (limited to 'backend/lib/CodeGen/TargetDescription.cpp') 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::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::create(InstructionSet Instruction } } - return TargetDescription(std::move(Instructions), std::move(Registers)); + return TargetDescription(std::move(Instructions), std::move(Registers), std::move(*MIRText)); } Expected TargetDescription::validateVirtualRegister(Register Reg, @@ -113,6 +126,10 @@ Expected 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 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(); + 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(); + Intrinsic != nullptr && !MIRText.intrinsicName(Intrinsic->ID)) { + return makeUnexpected(ErrorCode::VerificationError, + "intrinsic operand is not registered for MIR serialization"); + } + if (const auto *Mask = Operand.getIf(); Mask != nullptr) { if (!Mask->Mask) { return makeUnexpected(ErrorCode::VerificationError, @@ -301,6 +333,104 @@ Expected TargetDescription::validateTargetOperand(const OperandDescriptor return {}; } +Expected TargetDescription::validateMemOperands( + Opcode InstructionOpcode, std::span 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 TargetDescription::validateCFIInfo(const MachineCFIInfo &Info) const { + auto ValidateRegister = [this](DwarfRegisterNumber Register) -> Expected { + 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()) { + auto Result = ValidateRegister(Rule->Register); + if (!Result) + return Result; + } + if (const auto *Rule = Instruction.getIf()) { + auto Result = ValidateRegister(Rule->Register); + if (!Result) + return Result; + } + if (const auto *Rule = Instruction.getIf()) { + auto RegisterResult = ValidateRegister(Rule->Register); + if (!RegisterResult) + return RegisterResult; + auto SourceResult = ValidateRegister(Rule->SourceRegister); + if (!SourceResult) + return SourceResult; + } + if (const auto *Rule = Instruction.getIf()) { + auto Result = ValidateRegister(Rule->Register); + if (!Result) + return Result; + } + if (const auto *Rule = Instruction.getIf()) { + for (const DwarfRegisterNumber Register : + {Rule->Register, Rule->FirstRegister, Rule->SecondRegister}) { + auto Result = ValidateRegister(Register); + if (!Result) + return Result; + } + } + if (const auto *Rule = Instruction.getIf()) { + 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()) { + auto RegisterResult = ValidateRegister(Rule->Register); + if (!RegisterResult) + return RegisterResult; + auto MaskResult = ValidateRegister(Rule->MaskRegister); + if (!MaskResult) + return MaskResult; + } + if (const auto *Rule = Instruction.getIf()) { + for (const DwarfRegisterNumber Register : + {Rule->Register, Rule->SpillRegister, Rule->MaskRegister}) { + auto Result = ValidateRegister(Register); + if (!Result) + return Result; + } + } + } + return {}; +} + +Expected 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 TargetDescription::validateExplicitOperands(Opcode InstructionOpcode, std::span Operands, -- cgit v1.2.3