aboutsummaryrefslogtreecommitdiff
path: root/backend/include
diff options
context:
space:
mode:
authorRichard-Qin-X <richard.qin.001@gmail.com>2026-08-07 22:03:11 +0800
committerRichard-Qin-X <richard.qin.001@gmail.com>2026-08-07 22:03:11 +0800
commit3e15bfd7b075209ec3b65d30d0611e060f6fbb77 (patch)
tree9a55310fddbb48a87f32bd964ff94374593f3f4c /backend/include
parente16de95dce32f077361577377d5c52fc4ad78339 (diff)
downloadrcc-project-3e15bfd7b075209ec3b65d30d0611e060f6fbb77.tar.gz
rcc-project-3e15bfd7b075209ec3b65d30d0611e060f6fbb77.tar.xz
[RISCV] Complete RV64GC instruction description
Diffstat (limited to 'backend/include')
-rw-r--r--backend/include/rcc/CodeGen/InstructionDescriptor.h49
-rw-r--r--backend/include/rcc/Target/RISCV/RISCVTarget.h55
2 files changed, 102 insertions, 2 deletions
diff --git a/backend/include/rcc/CodeGen/InstructionDescriptor.h b/backend/include/rcc/CodeGen/InstructionDescriptor.h
index 06e37d3..7cf598d 100644
--- a/backend/include/rcc/CodeGen/InstructionDescriptor.h
+++ b/backend/include/rcc/CodeGen/InstructionDescriptor.h
@@ -3,6 +3,7 @@
#ifndef RCC_CODEGEN_INSTRUCTIONDESCRIPTOR_H
#define RCC_CODEGEN_INSTRUCTIONDESCRIPTOR_H
+#include "rcc/CodeGen/LowLevelType.h"
#include "rcc/CodeGen/MachineIRTypes.h"
#include "rcc/CodeGen/MachineOperand.h"
#include "rcc/CodeGen/Register.h"
@@ -26,6 +27,11 @@ class MachineInstr;
class MachineMemOperand;
class MachineRegisterInfo;
+using ExplicitOperandVerifier = Expected<void> (*)(Opcode, std::span<const MachineOperand>,
+ const MachineRegisterInfo &);
+using InstructionSemanticVerifier = Expected<void> (*)(const MachineInstr &,
+ const MachineRegisterInfo &);
+
class OperandKindSet final {
public:
static_assert(static_cast<std::uint32_t>(MachineOperand::Kind::Count) <= 32);
@@ -61,11 +67,45 @@ private:
std::uint32_t Mask = 0;
};
+class LLTKindSet final {
+public:
+ static_assert(static_cast<std::uint32_t>(LLT::Kind::VectorPointer) < 16);
+
+ constexpr LLTKindSet() noexcept = default;
+
+ LLTKindSet(std::initializer_list<LLT::Kind> Kinds) noexcept;
+
+ [[nodiscard]] constexpr bool empty() const noexcept {
+ return Mask == 0;
+ }
+
+ [[nodiscard]] constexpr bool contains(LLT::Kind Kind) const noexcept {
+ const auto Index = static_cast<std::uint32_t>(Kind);
+ return Index < 16 && (Mask & (std::uint16_t{1} << Index)) != 0;
+ }
+
+ constexpr void add(LLT::Kind Kind) noexcept {
+ const auto Index = static_cast<std::uint32_t>(Kind);
+ if (Index < 16)
+ Mask |= std::uint16_t{1} << Index;
+ }
+
+ [[nodiscard]] constexpr std::uint16_t rawValue() const noexcept {
+ return Mask;
+ }
+
+ friend constexpr bool operator==(LLTKindSet Left, LLTKindSet Right) noexcept = default;
+
+private:
+ std::uint16_t Mask = 0;
+};
+
enum class RegisterOperandRole : std::uint8_t {
None,
Def,
Use,
DefUse,
+ Any,
};
enum class MemoryOperandRole : std::uint8_t {
@@ -76,6 +116,11 @@ enum class MemoryOperandRole : std::uint8_t {
Ordering,
};
+struct OperandTypeConstraint final {
+ LLTKindSet Kinds;
+ std::optional<std::uint16_t> EqualityGroup;
+};
+
enum class InstructionFlag : std::uint8_t {
Terminator,
Branch,
@@ -184,6 +229,7 @@ struct OperandDescriptor final {
std::optional<NamedOperandID> Name;
std::optional<TargetOperandTypeID> TargetOperandType;
std::uint32_t AllowedTargetFlags = 0;
+ std::optional<OperandTypeConstraint> TypeConstraint;
};
struct ImplicitRegisterDescriptor final {
@@ -201,6 +247,7 @@ struct InstructionDescriptor final {
std::vector<OperandDescriptor> Operands;
std::size_t NumExplicitDefs = 0;
bool Variadic = false;
+ std::size_t MinimumVariadicRepetitions = 0;
std::vector<ImplicitRegisterDescriptor> ImplicitDefs;
std::vector<ImplicitRegisterDescriptor> ImplicitUses;
bool AllowExtraImplicitOperands = false;
@@ -211,6 +258,8 @@ struct InstructionDescriptor final {
bool RequiresMemoryOperands = false;
PseudoOwner Owner = PseudoOwner::None;
PipelineStage Deadline = PipelineStage::Emission;
+ ExplicitOperandVerifier VerifyExplicitOperands = nullptr;
+ InstructionSemanticVerifier VerifyInstructionSemantics = nullptr;
};
struct ImmediatePredicate final {
diff --git a/backend/include/rcc/Target/RISCV/RISCVTarget.h b/backend/include/rcc/Target/RISCV/RISCVTarget.h
index 948e22d..ca0849d 100644
--- a/backend/include/rcc/Target/RISCV/RISCVTarget.h
+++ b/backend/include/rcc/Target/RISCV/RISCVTarget.h
@@ -3,20 +3,71 @@
#ifndef RCC_TARGET_RISCV_RISCVTARGET_H
#define RCC_TARGET_RISCV_RISCVTARGET_H
-#include "rcc/CodeGen/TargetMIRTextInfo.h"
-#include "rcc/CodeGen/TargetRegisterInfo.h"
+#include "rcc/CodeGen/TargetDescription.h"
#include "rcc/Support/Error.h"
+#include "rcc/Target/RISCV/RISCVInstructions.h"
#include "rcc/Target/RISCV/RISCVRegisters.h"
#include <cstdint>
#include <memory>
+#include <span>
+#include <string_view>
namespace rcc::riscv {
+struct SchedulingClassInfo final {
+ SchedulingClassID ID;
+ std::string_view Name;
+ std::uint32_t MicroOps = 0;
+ std::uint32_t Latency = 0;
+};
+
+struct EncodingCategoryInfo final {
+ EncodingCategoryID ID;
+ std::string_view Name;
+ std::uint32_t SizeInBytes = 0;
+};
+
+struct AssemblyFormatInfo final {
+ AssemblyFormatID ID;
+ std::string_view Name;
+};
+
+struct AssemblyInstructionInfo final {
+ Opcode InstructionOpcode;
+ std::string_view Mnemonic;
+ AssemblyFormatID Format;
+};
+
+struct CallingConventionInfo final {
+ CallingConvention ID;
+ std::string_view Name;
+ RegisterClassID IntegerRegisterClass;
+ RegisterClassID FloatingRegisterClass;
+ std::span<const PhysicalRegister> IntegerArgumentRegisters;
+ std::span<const PhysicalRegister> FloatingArgumentRegisters;
+ std::span<const PhysicalRegister> IntegerReturnRegisters;
+ std::span<const PhysicalRegister> FloatingReturnRegisters;
+ std::string_view PreservedMaskName;
+ std::uint32_t StackAlignmentBytes = 0;
+ std::uint32_t StackArgumentAlignmentBytes = 0;
+ std::uint32_t ShadowSpaceBytes = 0;
+ bool SupportsVarArgs = false;
+ bool SupportsTailCalls = false;
+};
+
[[nodiscard]] Expected<PhysicalRegister> physicalRegister(PhysicalRegisterID ID);
[[nodiscard]] Expected<TargetRegisterInfo> createRegisterInfo();
[[nodiscard]] Expected<TargetMIRTextInfo> createMIRTextInfo();
+[[nodiscard]] Expected<TargetDescription> createTargetDescription();
[[nodiscard]] std::shared_ptr<const RegisterMask> createCallPreservedMask();
+[[nodiscard]] std::span<const SchedulingClassInfo> schedulingClasses() noexcept;
+[[nodiscard]] std::span<const EncodingCategoryInfo> encodingCategories() noexcept;
+[[nodiscard]] std::span<const AssemblyFormatInfo> assemblyFormats() noexcept;
+[[nodiscard]] std::span<const AssemblyInstructionInfo> assemblyInstructions() noexcept;
+[[nodiscard]] const AssemblyInstructionInfo *assemblyInstruction(Opcode InstructionOpcode) noexcept;
+[[nodiscard]] std::span<const CallingConventionInfo> callingConventions() noexcept;
+[[nodiscard]] const CallingConventionInfo *callingConvention(CallingConvention ID) noexcept;
} // namespace rcc::riscv