aboutsummaryrefslogtreecommitdiff
path: root/backend/include/rcc/CodeGen/TargetDescription.h
diff options
context:
space:
mode:
authorRichard-Qin-X <richard.qin.001@gmail.com>2026-08-01 16:07:24 +0800
committerRichard-Qin-X <richard.qin.001@gmail.com>2026-08-01 16:07:24 +0800
commit924dcd36ebed84f04729de05ec08b311a36a04c1 (patch)
tree300af742968d4d48915ef178855741f7087fc979 /backend/include/rcc/CodeGen/TargetDescription.h
parentcfdbcc469f9691bd9dce3b0b86982a63d86ca6b7 (diff)
downloadrcc-project-924dcd36ebed84f04729de05ec08b311a36a04c1.tar.gz
rcc-project-924dcd36ebed84f04729de05ec08b311a36a04c1.tar.xz
[CodeGen] Add target register descriptions
Introduce an immutable register topology for units, subregisters, classes, banks, and preserved masks. Bind instruction descriptors to this topology through TargetDescription so builders, cloning, and verification share one target-aware contract. Add the test-only TestTarget model and positive and negative target fact coverage.
Diffstat (limited to 'backend/include/rcc/CodeGen/TargetDescription.h')
-rw-r--r--backend/include/rcc/CodeGen/TargetDescription.h98
1 files changed, 98 insertions, 0 deletions
diff --git a/backend/include/rcc/CodeGen/TargetDescription.h b/backend/include/rcc/CodeGen/TargetDescription.h
new file mode 100644
index 0000000..51a820a
--- /dev/null
+++ b/backend/include/rcc/CodeGen/TargetDescription.h
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef RCC_CODEGEN_TARGETDESCRIPTION_H
+#define RCC_CODEGEN_TARGETDESCRIPTION_H
+
+#include "rcc/CodeGen/InstructionDescriptor.h"
+#include "rcc/CodeGen/TargetRegisterInfo.h"
+#include "rcc/Support/Error.h"
+
+#include <optional>
+#include <span>
+#include <utility>
+#include <vector>
+
+namespace rcc {
+
+class MachineBasicBlock;
+class MachineInstr;
+class MachineMemOperand;
+class MachineRegisterInfo;
+struct VirtualRegisterInfo;
+
+class TargetDescription final {
+public:
+ TargetDescription(const TargetDescription &) = delete;
+ TargetDescription &operator=(const TargetDescription &) = delete;
+ TargetDescription(TargetDescription &&) noexcept = default;
+ TargetDescription &operator=(TargetDescription &&) noexcept = default;
+ ~TargetDescription() = default;
+
+ [[nodiscard]] static Expected<TargetDescription> create(InstructionSet Instructions,
+ TargetRegisterInfo Registers);
+
+ [[nodiscard]] const InstructionSet &instructions() const noexcept {
+ return Instructions;
+ }
+
+ [[nodiscard]] const TargetRegisterInfo &registers() const noexcept {
+ return Registers;
+ }
+
+ [[nodiscard]] const InstructionDescriptor *
+ instructionDescriptor(Opcode InstructionOpcode) const noexcept {
+ return Instructions.descriptor(InstructionOpcode);
+ }
+
+ [[nodiscard]] Expected<void> validateExplicitOperands(Opcode InstructionOpcode,
+ std::span<const MachineOperand> Operands,
+ const MachineRegisterInfo &RegInfo) const;
+ [[nodiscard]] Expected<void> validateOperandTies(Opcode InstructionOpcode,
+ std::span<const MachineOperand> ExplicitOperands,
+ std::span<const MachineOperandTie> Ties,
+ const MachineRegisterInfo &RegInfo) const;
+ [[nodiscard]] Expected<void>
+ validateImplicitOperands(Opcode InstructionOpcode,
+ std::span<const MachineOperand *const> ImplicitOperands,
+ const MachineRegisterInfo &RegInfo) const;
+ [[nodiscard]] Expected<void>
+ validateEarlyClobber(std::span<const MachineOperand> ExplicitOperands,
+ std::span<const MachineOperand *const> ImplicitOperands,
+ std::span<const MachineOperandTie> Ties) const;
+ [[nodiscard]] Expected<void>
+ validateMemOperands(Opcode InstructionOpcode,
+ std::span<const MachineMemOperand *const> MemOperands) const {
+ return Instructions.validateMemOperands(InstructionOpcode, MemOperands);
+ }
+ [[nodiscard]] Expected<void> validateInstruction(const MachineInstr &Instruction,
+ const MachineRegisterInfo &RegInfo) const;
+ [[nodiscard]] Expected<void> validateRegisterInfo(const MachineRegisterInfo &RegInfo) const;
+ [[nodiscard]] Expected<void> validateBlockLiveIns(const MachineBasicBlock &Block) const;
+
+ [[nodiscard]] Expected<std::vector<MachineOperand>>
+ createDefaultImplicitOperands(const InstructionDescriptor &Descriptor) const {
+ return Instructions.createDefaultImplicitOperands(Descriptor);
+ }
+
+private:
+ TargetDescription(InstructionSet Instructions, TargetRegisterInfo Registers)
+ : Instructions(std::move(Instructions)), Registers(std::move(Registers)) {}
+
+ [[nodiscard]] Expected<void> validateTargetOperand(const OperandDescriptor *Descriptor,
+ const MachineOperand &Operand,
+ const MachineRegisterInfo &RegInfo) const;
+ [[nodiscard]] Expected<void> validateVirtualRegister(Register Reg,
+ const VirtualRegisterInfo &Info) const;
+ [[nodiscard]] std::optional<RegisterClassID>
+ effectiveRegisterClass(const MachineOperand &Operand, const MachineRegisterInfo &RegInfo) const;
+ [[nodiscard]] Expected<void> validateTieCompatibility(const MachineOperand &Def,
+ const MachineOperand &Use,
+ const MachineRegisterInfo &RegInfo) const;
+
+ InstructionSet Instructions;
+ TargetRegisterInfo Registers;
+};
+
+} // namespace rcc
+
+#endif // RCC_CODEGEN_TARGETDESCRIPTION_H