aboutsummaryrefslogtreecommitdiff
path: root/backend/include/rcc
diff options
context:
space:
mode:
Diffstat (limited to 'backend/include/rcc')
-rw-r--r--backend/include/rcc/CodeGen/InstructionDescriptor.h26
-rw-r--r--backend/include/rcc/CodeGen/MachineIRBuilder.h161
-rw-r--r--backend/include/rcc/CodeGen/MachineInstr.h4
3 files changed, 189 insertions, 2 deletions
diff --git a/backend/include/rcc/CodeGen/InstructionDescriptor.h b/backend/include/rcc/CodeGen/InstructionDescriptor.h
index c6049b9..94ea374 100644
--- a/backend/include/rcc/CodeGen/InstructionDescriptor.h
+++ b/backend/include/rcc/CodeGen/InstructionDescriptor.h
@@ -23,6 +23,7 @@
namespace rcc {
class MachineInstr;
+class MachineMemOperand;
class MachineRegisterInfo;
class OperandKindSet final {
@@ -217,6 +218,13 @@ struct ImmediatePredicate final {
std::function<bool(const MachineOperand &)> Predicate;
};
+struct MachineOperandTie final {
+ std::size_t DefOperand;
+ std::size_t UseOperand;
+
+ friend bool operator==(MachineOperandTie Left, MachineOperandTie Right) noexcept = default;
+};
+
class InstructionSet final {
public:
[[nodiscard]] static Expected<InstructionSet>
@@ -232,6 +240,15 @@ public:
[[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;
+ [[nodiscard]] Expected<void>
+ validateImplicitOperands(Opcode InstructionOpcode,
+ std::span<const MachineOperand *const> ImplicitOperands) const;
+ [[nodiscard]] Expected<void>
+ validateMemOperands(Opcode InstructionOpcode,
+ std::span<const MachineMemOperand *const> MemOperands) const;
[[nodiscard]] Expected<void> validateInstruction(const MachineInstr &Instruction,
const MachineRegisterInfo &RegInfo) const;
@@ -248,6 +265,15 @@ private:
[[nodiscard]] Expected<void> validateExplicitOperands(const InstructionDescriptor &Descriptor,
std::span<const MachineOperand> Operands,
const MachineRegisterInfo &RegInfo) const;
+ [[nodiscard]] Expected<void> validateOperandTies(const InstructionDescriptor &Descriptor,
+ std::span<const MachineOperand> ExplicitOperands,
+ std::span<const MachineOperandTie> Ties) const;
+ [[nodiscard]] Expected<void>
+ validateImplicitOperands(const InstructionDescriptor &Descriptor,
+ std::span<const MachineOperand *const> ImplicitOperands) const;
+ [[nodiscard]] Expected<void>
+ validateMemOperands(const InstructionDescriptor &Descriptor,
+ std::span<const MachineMemOperand *const> MemOperands) const;
[[nodiscard]] Expected<void> validateOperand(const OperandDescriptor &Descriptor,
const MachineOperand &Operand,
const MachineRegisterInfo &RegInfo) const;
diff --git a/backend/include/rcc/CodeGen/MachineIRBuilder.h b/backend/include/rcc/CodeGen/MachineIRBuilder.h
new file mode 100644
index 0000000..02e47ff
--- /dev/null
+++ b/backend/include/rcc/CodeGen/MachineIRBuilder.h
@@ -0,0 +1,161 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef RCC_CODEGEN_MACHINEIRBUILDER_H
+#define RCC_CODEGEN_MACHINEIRBUILDER_H
+
+#include "rcc/CodeGen/InstructionDescriptor.h"
+#include "rcc/CodeGen/MachineIRTypes.h"
+#include "rcc/CodeGen/MachineOperand.h"
+#include "rcc/CodeGen/Register.h"
+#include "rcc/Support/Error.h"
+
+#include <cstddef>
+#include <cstdint>
+#include <memory>
+#include <optional>
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace rcc {
+
+class MachineBasicBlock;
+class MachineFunction;
+class MachineInstr;
+class MachineMemOperand;
+class RegisterMask;
+
+class MachineInstrBuilder final {
+public:
+ MachineInstrBuilder(const MachineInstrBuilder &) = delete;
+ MachineInstrBuilder &operator=(const MachineInstrBuilder &) = delete;
+ MachineInstrBuilder(MachineInstrBuilder &&Other) noexcept;
+ MachineInstrBuilder &operator=(MachineInstrBuilder &&Other) noexcept;
+ ~MachineInstrBuilder() = default;
+
+ [[nodiscard]] Expected<void> addOperand(MachineOperand &&Operand);
+ [[nodiscard]] Expected<void> addImplicitOperand(MachineOperand &&Operand);
+
+ [[nodiscard]] Expected<void> addDef(Register Reg, RegisterOperandFlags AdditionalFlags = {},
+ SubRegIndex SubReg = {}, std::uint32_t TargetFlags = 0);
+ [[nodiscard]] Expected<void> addUse(Register Reg, RegisterOperandFlags AdditionalFlags = {},
+ SubRegIndex SubReg = {}, std::uint32_t TargetFlags = 0);
+ [[nodiscard]] Expected<void> addDefUse(Register Reg, RegisterOperandFlags AdditionalFlags = {},
+ SubRegIndex SubReg = {}, std::uint32_t TargetFlags = 0);
+ [[nodiscard]] Expected<void> addImplicitDef(Register Reg,
+ RegisterOperandFlags AdditionalFlags = {},
+ SubRegIndex SubReg = {},
+ std::uint32_t TargetFlags = 0);
+ [[nodiscard]] Expected<void> addImplicitUse(Register Reg,
+ RegisterOperandFlags AdditionalFlags = {},
+ SubRegIndex SubReg = {},
+ std::uint32_t TargetFlags = 0);
+
+ [[nodiscard]] Expected<void> addImmediate(std::int64_t Value, std::uint32_t TargetFlags = 0);
+ [[nodiscard]] Expected<void> addFloatingImmediate(FloatingPointBits Bits,
+ std::uint32_t TargetFlags = 0);
+ [[nodiscard]] Expected<void> addBasicBlock(MachineBasicBlock &Block,
+ std::uint32_t TargetFlags = 0);
+ [[nodiscard]] Expected<void> addFrameIndex(FrameIndex Index, std::int64_t Offset = 0,
+ std::uint32_t TargetFlags = 0);
+ [[nodiscard]] Expected<void> addConstantPool(ConstantPoolIndex Index, std::int64_t Offset = 0,
+ std::uint32_t TargetFlags = 0);
+ [[nodiscard]] Expected<void> addJumpTable(JumpTableIndex Index, std::uint32_t TargetFlags = 0);
+ [[nodiscard]] Expected<void> addGlobalSymbol(std::string Name, std::int64_t Offset = 0,
+ std::uint32_t TargetFlags = 0);
+ [[nodiscard]] Expected<void> addExternalSymbol(std::string Name, std::int64_t Offset = 0,
+ std::uint32_t TargetFlags = 0);
+ [[nodiscard]] Expected<void> addBlockAddress(std::string FunctionName, std::string BlockName,
+ std::int64_t Offset = 0,
+ std::uint32_t TargetFlags = 0);
+ [[nodiscard]] Expected<void> addRegisterMask(std::shared_ptr<const RegisterMask> Mask,
+ std::uint32_t TargetFlags = 0);
+ [[nodiscard]] Expected<void> addMetadata(std::string Marker, std::uint32_t TargetFlags = 0);
+ [[nodiscard]] Expected<void> addTargetIndex(TargetIndex Index, std::int64_t Offset = 0,
+ std::uint32_t TargetFlags = 0);
+ [[nodiscard]] Expected<void> addMCSymbol(std::string Name, std::int64_t Offset = 0,
+ std::uint32_t TargetFlags = 0);
+
+ [[nodiscard]] Expected<void> tieOperands(std::size_t DefOperand, std::size_t UseOperand);
+ [[nodiscard]] Expected<void> addMemOperand(const MachineMemOperand &MemOperand);
+
+ [[nodiscard]] Expected<void> setFlags(MachineInstrFlags NewFlags);
+
+ [[nodiscard]] Expected<void> setSourceLocation(SourceLocation NewLocation);
+ [[nodiscard]] Expected<void> clearSourceLocation();
+
+ [[nodiscard]] Expected<void> setOrigin(OriginID NewOrigin);
+ [[nodiscard]] Expected<void> clearOrigin();
+
+ [[nodiscard]] Expected<MachineInstr *> build();
+
+private:
+ MachineInstrBuilder(MachineFunction &Function, const InstructionSet &Instructions,
+ const InstructionDescriptor &Descriptor, MachineBasicBlock &InsertBlock,
+ MachineInstr *InsertBefore) noexcept;
+
+ [[nodiscard]] Expected<void> ensurePending() const;
+ [[nodiscard]] Expected<void> validateInsertionPoint() const;
+ [[nodiscard]] Expected<void> validateOperandOwnership(const MachineOperand &Operand) const;
+ [[nodiscard]] std::vector<MachineOperandTie> collectOperandTies() const;
+ [[nodiscard]] Expected<void> appendRegister(Register Reg, RegisterOperandFlags Flags,
+ SubRegIndex SubReg, std::uint32_t TargetFlags,
+ bool IsImplicit);
+
+ MachineFunction *Function;
+ const InstructionSet *Instructions;
+ const InstructionDescriptor *Descriptor;
+ MachineBasicBlock *InsertBlock;
+ MachineInstr *InsertBefore;
+ std::vector<MachineOperand> ExplicitOperands;
+ std::vector<MachineOperand> ExtraImplicitOperands;
+ std::vector<MachineOperandTie> RequestedTies;
+ std::vector<const MachineMemOperand *> MemOperands;
+ MachineInstrFlags Flags;
+ std::optional<SourceLocation> Location;
+ std::optional<OriginID> Origin;
+ bool IsBuilt = false;
+
+ friend class MachineIRBuilder;
+};
+
+class MachineIRBuilder final {
+public:
+ MachineIRBuilder(MachineFunction &Function, const InstructionSet &Instructions) noexcept
+ : Function(&Function), Instructions(&Instructions) {}
+ MachineIRBuilder(const MachineIRBuilder &) = delete;
+ MachineIRBuilder &operator=(const MachineIRBuilder &) = delete;
+ MachineIRBuilder(MachineIRBuilder &&) = delete;
+ MachineIRBuilder &operator=(MachineIRBuilder &&) = delete;
+
+ [[nodiscard]] MachineFunction &function() noexcept {
+ return *Function;
+ }
+
+ [[nodiscard]] const MachineFunction &function() const noexcept {
+ return *Function;
+ }
+
+ [[nodiscard]] Expected<void> setInsertPoint(MachineBasicBlock &Block);
+ [[nodiscard]] Expected<void> setInsertPointBefore(MachineInstr &Instruction);
+ [[nodiscard]] Expected<void> setInsertPointAfter(MachineInstr &Instruction);
+ void clearInsertPoint() noexcept {
+ InsertBlock = nullptr;
+ InsertBefore = nullptr;
+ }
+
+ [[nodiscard]] Expected<MachineInstrBuilder> buildInstr(Opcode InstructionOpcode) const;
+
+private:
+ [[nodiscard]] Expected<void> validateBlock(const MachineBasicBlock &Block) const;
+ [[nodiscard]] Expected<void> validateInstruction(const MachineInstr &Instruction) const;
+
+ MachineFunction *Function;
+ const InstructionSet *Instructions;
+ MachineBasicBlock *InsertBlock = nullptr;
+ MachineInstr *InsertBefore = nullptr;
+};
+
+} // namespace rcc
+
+#endif // RCC_CODEGEN_MACHINEIRBUILDER_H
diff --git a/backend/include/rcc/CodeGen/MachineInstr.h b/backend/include/rcc/CodeGen/MachineInstr.h
index 376273f..bcae306 100644
--- a/backend/include/rcc/CodeGen/MachineInstr.h
+++ b/backend/include/rcc/CodeGen/MachineInstr.h
@@ -87,8 +87,8 @@ public:
}
void reserveOperands(std::size_t Capacity);
- [[nodiscard]] Expected<void> addOperand(MachineOperand Operand);
- [[nodiscard]] Expected<void> insertOperand(std::size_t Index, MachineOperand Operand);
+ [[nodiscard]] Expected<void> addOperand(MachineOperand &&Operand);
+ [[nodiscard]] Expected<void> insertOperand(std::size_t Index, MachineOperand &&Operand);
[[nodiscard]] Expected<void> eraseOperand(std::size_t Index);
[[nodiscard]] Expected<void> tieOperands(std::size_t DefIndex, std::size_t UseIndex);