aboutsummaryrefslogtreecommitdiff
path: root/backend/include/rcc/Target/RISCV
diff options
context:
space:
mode:
Diffstat (limited to 'backend/include/rcc/Target/RISCV')
-rw-r--r--backend/include/rcc/Target/RISCV/RISCVAsmBackend.h30
-rw-r--r--backend/include/rcc/Target/RISCV/RISCVAssemblyPrinter.h35
-rw-r--r--backend/include/rcc/Target/RISCV/RISCVFixupKinds.h33
-rw-r--r--backend/include/rcc/Target/RISCV/RISCVFunctionInfo.h60
-rw-r--r--backend/include/rcc/Target/RISCV/RISCVInstPrinter.h39
-rw-r--r--backend/include/rcc/Target/RISCV/RISCVMCCodeEmitter.h24
-rw-r--r--backend/include/rcc/Target/RISCV/RISCVMCTargetLowering.h35
-rw-r--r--backend/include/rcc/Target/RISCV/RISCVObjectFile.h35
-rw-r--r--backend/include/rcc/Target/RISCV/RISCVPipeline.h38
-rw-r--r--backend/include/rcc/Target/RISCV/RISCVSubtarget.h156
-rw-r--r--backend/include/rcc/Target/RISCV/RISCVTarget.h76
-rw-r--r--backend/include/rcc/Target/RISCV/RISCVTargetConstant.h73
-rw-r--r--backend/include/rcc/Target/RISCV/RISCVTargetRelocationKinds.h24
13 files changed, 658 insertions, 0 deletions
diff --git a/backend/include/rcc/Target/RISCV/RISCVAsmBackend.h b/backend/include/rcc/Target/RISCV/RISCVAsmBackend.h
new file mode 100644
index 0000000..11dcb77
--- /dev/null
+++ b/backend/include/rcc/Target/RISCV/RISCVAsmBackend.h
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef RCC_TARGET_RISCV_RISCVASMBACKEND_H
+#define RCC_TARGET_RISCV_RISCVASMBACKEND_H
+
+#include "rcc/MC/MCAsmBackend.h"
+
+namespace rcc::riscv {
+
+class RISCVAsmBackend final : public mc::MCAsmBackend {
+public:
+ [[nodiscard]] Expected<mc::MCFixupKindInfo> fixupKindInfo(mc::MCFixupKind Kind) const override;
+ [[nodiscard]] Expected<void> applyFixup(mc::MCFixupKind Kind, std::span<std::uint8_t> Data,
+ std::uint64_t Offset, std::int64_t Value) const override;
+ [[nodiscard]] Expected<std::uint32_t> relocationType(const mc::MCFixup &Fixup,
+ const mc::MCValue &Value) const override;
+ [[nodiscard]] Expected<std::vector<mc::MCFixupRelocation>>
+ relocationsForFixup(const mc::MCFixup &Fixup, const mc::MCValue &Value) const override;
+
+ [[nodiscard]] bool mayNeedRelaxation(const mc::MCInst &Instruction) const noexcept override;
+ [[nodiscard]] Expected<bool> fixupNeedsRelaxation(const mc::MCFixup &Fixup,
+ std::int64_t Value) const override;
+ [[nodiscard]] Expected<mc::MCInst> relaxInstruction(const mc::MCInst &Instruction) const override;
+
+ [[nodiscard]] std::uint32_t objectFlags() const noexcept override;
+};
+
+} // namespace rcc::riscv
+
+#endif // RCC_TARGET_RISCV_RISCVASMBACKEND_H
diff --git a/backend/include/rcc/Target/RISCV/RISCVAssemblyPrinter.h b/backend/include/rcc/Target/RISCV/RISCVAssemblyPrinter.h
new file mode 100644
index 0000000..5c8dca5
--- /dev/null
+++ b/backend/include/rcc/Target/RISCV/RISCVAssemblyPrinter.h
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef RCC_TARGET_RISCV_RISCVASSEMBLYPRINTER_H
+#define RCC_TARGET_RISCV_RISCVASSEMBLYPRINTER_H
+
+#include "rcc/CodeGen/AsmPrinter.h"
+#include "rcc/CodeGen/TargetDescription.h"
+#include "rcc/Support/Error.h"
+
+#include <string>
+
+namespace rcc {
+class CompilationUnit;
+class MachineFunction;
+} // namespace rcc
+
+namespace rcc::riscv {
+
+struct AssemblyEmissionOptions final {
+ bool EmitFunctionDirectives = true;
+ bool EmitCFI = true;
+ bool EmitBlockLabels = true;
+ bool VerifyInput = true;
+};
+
+[[nodiscard]] Expected<std::string> emitAssembly(const CompilationUnit &Unit,
+ const TargetDescription &Target,
+ AssemblyEmissionOptions Options = {});
+[[nodiscard]] Expected<std::string> emitAssembly(const MachineFunction &Function,
+ const TargetDescription &Target,
+ AssemblyEmissionOptions Options = {});
+
+} // namespace rcc::riscv
+
+#endif // RCC_TARGET_RISCV_RISCVASSEMBLYPRINTER_H
diff --git a/backend/include/rcc/Target/RISCV/RISCVFixupKinds.h b/backend/include/rcc/Target/RISCV/RISCVFixupKinds.h
new file mode 100644
index 0000000..e030bfc
--- /dev/null
+++ b/backend/include/rcc/Target/RISCV/RISCVFixupKinds.h
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef RCC_TARGET_RISCV_RISCVFIXUPKINDS_H
+#define RCC_TARGET_RISCV_RISCVFIXUPKINDS_H
+
+#include "rcc/MC/MCFixup.h"
+
+#include <cstdint>
+
+namespace rcc::riscv {
+
+enum class RISCVFixupKind : mc::MCFixupKind {
+ High20 = mc::fixup_kind::FirstTarget,
+ Low12I,
+ Low12S,
+ PCRelativeHigh20,
+ GOTPCRelativeHigh20,
+ PCRelativeLow12I,
+ PCRelativeLow12S,
+ JAL,
+ Branch,
+ RVCJump,
+ RVCBranch,
+ CallPLT,
+};
+
+[[nodiscard]] constexpr mc::MCFixupKind fixupKind(RISCVFixupKind Kind) noexcept {
+ return static_cast<mc::MCFixupKind>(Kind);
+}
+
+} // namespace rcc::riscv
+
+#endif // RCC_TARGET_RISCV_RISCVFIXUPKINDS_H
diff --git a/backend/include/rcc/Target/RISCV/RISCVFunctionInfo.h b/backend/include/rcc/Target/RISCV/RISCVFunctionInfo.h
new file mode 100644
index 0000000..6a05096
--- /dev/null
+++ b/backend/include/rcc/Target/RISCV/RISCVFunctionInfo.h
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef RCC_TARGET_RISCV_RISCVFUNCTIONINFO_H
+#define RCC_TARGET_RISCV_RISCVFUNCTIONINFO_H
+
+#include "rcc/CodeGen/TargetFunctionState.h"
+
+#include <cstddef>
+#include <cstdint>
+#include <span>
+#include <string>
+#include <vector>
+
+namespace rcc {
+
+struct TargetMIRTextInfoDesc;
+
+namespace riscv {
+
+class RISCVFunctionInfo final {
+public:
+ RISCVFunctionInfo(std::int32_t VarArgsFrameIndex = 0, std::int32_t VarArgsSaveSize = 0) noexcept
+ : VarArgsFrameIndex(VarArgsFrameIndex), VarArgsSaveSize(VarArgsSaveSize) {}
+
+ [[nodiscard]] static constexpr TargetFunctionStateTypeID stableTypeID() noexcept {
+ return TargetFunctionStateTypeID::fromValue(0x5243435256460001ULL);
+ }
+
+ [[nodiscard]] static constexpr std::uint32_t schemaVersion() noexcept {
+ return 1;
+ }
+
+ [[nodiscard]] Expected<void> verify() const;
+ [[nodiscard]] Expected<RISCVFunctionInfo> clone(const MachineFunctionCloneContext &Context) const;
+ [[nodiscard]] std::string print() const;
+ [[nodiscard]] Expected<std::vector<std::byte>> encode() const;
+ [[nodiscard]] static Expected<RISCVFunctionInfo> decode(std::uint32_t Version,
+ std::span<const std::byte> Payload);
+
+ [[nodiscard]] std::int32_t varArgsFrameIndex() const noexcept {
+ return VarArgsFrameIndex;
+ }
+
+ [[nodiscard]] std::int32_t varArgsSaveSize() const noexcept {
+ return VarArgsSaveSize;
+ }
+
+ friend bool operator==(const RISCVFunctionInfo &Left, const RISCVFunctionInfo &Right) = default;
+
+private:
+ std::int32_t VarArgsFrameIndex = 0;
+ std::int32_t VarArgsSaveSize = 0;
+};
+
+void configureFunctionInfoMIRSchema(TargetMIRTextInfoDesc &Description);
+
+} // namespace riscv
+} // namespace rcc
+
+#endif // RCC_TARGET_RISCV_RISCVFUNCTIONINFO_H
diff --git a/backend/include/rcc/Target/RISCV/RISCVInstPrinter.h b/backend/include/rcc/Target/RISCV/RISCVInstPrinter.h
new file mode 100644
index 0000000..7e74ab2
--- /dev/null
+++ b/backend/include/rcc/Target/RISCV/RISCVInstPrinter.h
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef RCC_TARGET_RISCV_RISCVINSTPRINTER_H
+#define RCC_TARGET_RISCV_RISCVINSTPRINTER_H
+
+#include "rcc/CodeGen/TargetDescription.h"
+#include "rcc/MC/MCInstPrinter.h"
+
+#include <cstdint>
+#include <string>
+#include <string_view>
+
+namespace rcc::riscv {
+
+enum class RISCVMCExprKind : std::uint32_t {
+ CallPLT = 1,
+ PCRelativeHigh = 2,
+ PCRelativeLow = 3,
+ AbsoluteHigh = 4,
+ AbsoluteLow = 5,
+ GOTPCRelativeHigh = 6,
+};
+
+class RISCVInstPrinter final : public mc::MCInstPrinter {
+public:
+ explicit RISCVInstPrinter(const TargetDescription &Target) noexcept : Target(&Target) {}
+
+ [[nodiscard]] Expected<std::string>
+ printInstruction(const mc::MCInst &Instruction) const override;
+ [[nodiscard]] Expected<std::string>
+ printTargetExpression(std::uint32_t Kind, std::string_view Operand) const override;
+
+private:
+ const TargetDescription *Target;
+};
+
+} // namespace rcc::riscv
+
+#endif // RCC_TARGET_RISCV_RISCVINSTPRINTER_H
diff --git a/backend/include/rcc/Target/RISCV/RISCVMCCodeEmitter.h b/backend/include/rcc/Target/RISCV/RISCVMCCodeEmitter.h
new file mode 100644
index 0000000..700cdc2
--- /dev/null
+++ b/backend/include/rcc/Target/RISCV/RISCVMCCodeEmitter.h
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef RCC_TARGET_RISCV_RISCVMCCODEEMITTER_H
+#define RCC_TARGET_RISCV_RISCVMCCODEEMITTER_H
+
+#include "rcc/CodeGen/TargetDescription.h"
+#include "rcc/MC/MCCodeEmitter.h"
+
+namespace rcc::riscv {
+
+class RISCVMCCodeEmitter final : public mc::MCCodeEmitter {
+public:
+ explicit RISCVMCCodeEmitter(const TargetDescription &Target) noexcept : Target(&Target) {}
+
+ [[nodiscard]] Expected<mc::MCEncodedInstruction>
+ encodeInstruction(const mc::MCInst &Instruction) const override;
+
+private:
+ const TargetDescription *Target;
+};
+
+} // namespace rcc::riscv
+
+#endif // RCC_TARGET_RISCV_RISCVMCCODEEMITTER_H
diff --git a/backend/include/rcc/Target/RISCV/RISCVMCTargetLowering.h b/backend/include/rcc/Target/RISCV/RISCVMCTargetLowering.h
new file mode 100644
index 0000000..3713bb5
--- /dev/null
+++ b/backend/include/rcc/Target/RISCV/RISCVMCTargetLowering.h
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef RCC_TARGET_RISCV_RISCVMCTARGETLOWERING_H
+#define RCC_TARGET_RISCV_RISCVMCTARGETLOWERING_H
+
+#include "rcc/CodeGen/TargetMCInstLowering.h"
+#include "rcc/Target/RISCV/RISCVInstPrinter.h"
+
+namespace rcc::riscv {
+
+class RISCVMCTargetLowering final : public TargetMCInstLowering {
+public:
+ explicit RISCVMCTargetLowering(const TargetDescription &Target) noexcept
+ : Target(&Target), Printer(Target) {}
+
+ [[nodiscard]] const mc::MCInstPrinter &instructionPrinter() const noexcept override {
+ return Printer;
+ }
+
+ [[nodiscard]] Expected<mc::MCInst> lowerInstruction(const MachineInstr &Instruction,
+ MachineMCContext &Context) const override;
+ [[nodiscard]] Expected<mc::MCExprRef>
+ lowerSymbolExpression(mc::MCExprRef Expression, std::uint32_t TargetFlags) const override;
+ [[nodiscard]] Expected<void> emitTerminalInstruction(const MachineInstr &Instruction,
+ MachineMCContext &Context,
+ mc::MCStreamer &Streamer) const override;
+
+private:
+ const TargetDescription *Target;
+ RISCVInstPrinter Printer;
+};
+
+} // namespace rcc::riscv
+
+#endif // RCC_TARGET_RISCV_RISCVMCTARGETLOWERING_H
diff --git a/backend/include/rcc/Target/RISCV/RISCVObjectFile.h b/backend/include/rcc/Target/RISCV/RISCVObjectFile.h
new file mode 100644
index 0000000..fd25012
--- /dev/null
+++ b/backend/include/rcc/Target/RISCV/RISCVObjectFile.h
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef RCC_TARGET_RISCV_RISCVOBJECTFILE_H
+#define RCC_TARGET_RISCV_RISCVOBJECTFILE_H
+
+#include "rcc/CodeGen/TargetDescription.h"
+#include "rcc/Support/Error.h"
+
+#include <cstdint>
+#include <vector>
+
+namespace rcc {
+class CompilationUnit;
+class MachineFunction;
+} // namespace rcc
+
+namespace rcc::riscv {
+
+struct ObjectEmissionOptions final {
+ bool EmitFunctionDirectives = true;
+ bool EmitCFI = true;
+ bool EmitBlockLabels = true;
+ bool VerifyInput = true;
+};
+
+[[nodiscard]] Expected<std::vector<std::uint8_t>> emitObject(const CompilationUnit &Unit,
+ const TargetDescription &Target,
+ ObjectEmissionOptions Options = {});
+[[nodiscard]] Expected<std::vector<std::uint8_t>> emitObject(const MachineFunction &Function,
+ const TargetDescription &Target,
+ ObjectEmissionOptions Options = {});
+
+} // namespace rcc::riscv
+
+#endif // RCC_TARGET_RISCV_RISCVOBJECTFILE_H
diff --git a/backend/include/rcc/Target/RISCV/RISCVPipeline.h b/backend/include/rcc/Target/RISCV/RISCVPipeline.h
new file mode 100644
index 0000000..f556ded
--- /dev/null
+++ b/backend/include/rcc/Target/RISCV/RISCVPipeline.h
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef RCC_TARGET_RISCV_RISCVPIPELINE_H
+#define RCC_TARGET_RISCV_RISCVPIPELINE_H
+
+#include "rcc/CodeGen/MachinePassManager.h"
+#include "rcc/Support/Error.h"
+#include "rcc/Target/RISCV/RISCVSubtarget.h"
+#include "rcc/Target/TargetMachine.h"
+
+#include <memory>
+#include <string>
+#include <string_view>
+#include <vector>
+
+namespace rcc {
+
+class MachineFunction;
+class TargetDescription;
+class TargetMachineOutlinerInfo;
+
+namespace riscv {
+
+[[nodiscard]] Expected<void> addCanonicalPipeline(MachineFunctionPassManager &Pipeline,
+ const MachineFunction &Function,
+ const RISCVSubtarget &Subtarget,
+ TargetPipelineOptions Options = {});
+[[nodiscard]] Expected<std::unique_ptr<MachineFunctionPass>>
+createCanonicalPipelinePass(std::string_view Name, const RISCVSubtarget &Subtarget,
+ TargetPipelineOptions Options = {});
+[[nodiscard]] Expected<std::vector<std::string>>
+canonicalPipelinePassNames(const MachineFunction &Function, const RISCVSubtarget &Subtarget);
+[[nodiscard]] Expected<std::unique_ptr<TargetMachineOutlinerInfo>>
+createMachineOutlinerInfo(bool FunctionSections, bool EnableRegisterSave);
+} // namespace riscv
+} // namespace rcc
+
+#endif // RCC_TARGET_RISCV_RISCVPIPELINE_H
diff --git a/backend/include/rcc/Target/RISCV/RISCVSubtarget.h b/backend/include/rcc/Target/RISCV/RISCVSubtarget.h
new file mode 100644
index 0000000..a5ba01a
--- /dev/null
+++ b/backend/include/rcc/Target/RISCV/RISCVSubtarget.h
@@ -0,0 +1,156 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef RCC_TARGET_RISCV_RISCVSUBTARGET_H
+#define RCC_TARGET_RISCV_RISCVSUBTARGET_H
+
+#include "rcc/CodeGen/CommandFlags.h"
+#include "rcc/Support/Error.h"
+
+#include <cstdint>
+#include <memory>
+#include <span>
+#include <string>
+#include <string_view>
+
+namespace rcc {
+
+class InstructionSelector;
+class LegalizerInfo;
+class TargetCallLowering;
+class TargetFrameLowering;
+class TargetSchedulingHooks;
+class TargetSchedulingModel;
+
+namespace riscv {
+
+class RISCVRegisterBankInfo;
+
+enum class RISCVExtension : std::uint8_t {
+ I,
+ M,
+ A,
+ F,
+ D,
+ C,
+ Zba,
+ Zbb,
+ Zicsr,
+ Zifencei,
+ Zacas,
+ Zabha,
+ Zcmp,
+ Count,
+};
+
+enum class RISCVSubtargetOption : std::uint8_t {
+ DisablePostMISchedLoadClustering,
+ DisablePostMISchedStoreClustering,
+ FusionAddLoad,
+ FusionAddMemory,
+ FusionAddImmediateLoad,
+ FusionAUIPCAddImmediate,
+ FusionAUIPCLoad,
+ FusionBitfieldExtract,
+ FusionLoadDoubleAdd,
+ FusionLogicImmediateRegister,
+ FusionLogicRegisterImmediate,
+ FusionLogicRegisterRegister,
+ FusionLUIAddImmediate,
+ FusionLUILoad,
+ FusionMultiplyAdd,
+ FusionShiftBitExtract,
+ FusionShiftedAddLoad,
+ FusionShiftedZeroExtendWord,
+ FusionZeroExtendHalf,
+ FusionZeroExtendWord,
+ PreferWordInstructions,
+ ReserveX6,
+ ReserveX7,
+ SaveRestore,
+ TaggedGlobals,
+ UnalignedScalarMemory,
+ UsePostRAScheduler,
+ Count,
+};
+
+enum class RISCVABI : std::uint8_t {
+ LP64,
+ LP64D,
+};
+
+[[nodiscard]] Expected<RISCVABI> parseRISCVABI(std::string_view Name);
+
+class RISCVSubtargetFeatures final {
+public:
+ [[nodiscard]] static Expected<RISCVSubtargetFeatures>
+ fromFeatureList(std::span<const std::string> Features);
+ [[nodiscard]] static RISCVSubtargetFeatures rv64gc() noexcept;
+
+ [[nodiscard]] bool has(RISCVExtension Extension) const noexcept;
+ [[nodiscard]] bool has(RISCVSubtargetOption Option) const noexcept;
+ [[nodiscard]] bool hasFeature(std::string_view Feature) const noexcept;
+
+ friend bool operator==(const RISCVSubtargetFeatures &Left,
+ const RISCVSubtargetFeatures &Right) = default;
+
+private:
+ explicit constexpr RISCVSubtargetFeatures(std::uint16_t Enabled,
+ std::uint32_t Options = 0) noexcept
+ : Enabled(Enabled), Options(Options) {}
+
+ std::uint16_t Enabled = 0;
+ std::uint32_t Options = 0;
+};
+
+class RISCVSubtarget final {
+public:
+ explicit RISCVSubtarget(RISCVSubtargetFeatures Features,
+ RelocationModel Relocation = RelocationModel::Static,
+ CodeModel Code = CodeModel::Small, RISCVABI ABI = RISCVABI::LP64D);
+ RISCVSubtarget(const RISCVSubtarget &) = delete;
+ RISCVSubtarget &operator=(const RISCVSubtarget &) = delete;
+ RISCVSubtarget(RISCVSubtarget &&) = delete;
+ RISCVSubtarget &operator=(RISCVSubtarget &&) = delete;
+ ~RISCVSubtarget();
+
+ [[nodiscard]] const RISCVSubtargetFeatures &features() const noexcept {
+ return Features;
+ }
+
+ [[nodiscard]] RelocationModel relocationModel() const noexcept {
+ return Relocation;
+ }
+
+ [[nodiscard]] CodeModel codeModel() const noexcept {
+ return Code;
+ }
+
+ [[nodiscard]] RISCVABI targetABI() const noexcept {
+ return ABI;
+ }
+
+ [[nodiscard]] const TargetCallLowering *getCallLowering() const;
+ [[nodiscard]] InstructionSelector *getInstructionSelector() const;
+ [[nodiscard]] const LegalizerInfo *getLegalizerInfo() const;
+ [[nodiscard]] const RISCVRegisterBankInfo *getRegBankInfo() const;
+ [[nodiscard]] const TargetFrameLowering &frameLowering() const noexcept;
+ [[nodiscard]] const TargetSchedulingModel &schedulingModel() const noexcept;
+
+private:
+ RISCVSubtargetFeatures Features;
+ RelocationModel Relocation;
+ CodeModel Code;
+ RISCVABI ABI;
+ std::unique_ptr<TargetFrameLowering> FrameLoweringInfo;
+ std::unique_ptr<TargetCallLowering> CallLoweringInfo;
+ std::unique_ptr<InstructionSelector> InstSelector;
+ std::unique_ptr<LegalizerInfo> Legalizer;
+ std::unique_ptr<RISCVRegisterBankInfo> RegBankInfo;
+ std::unique_ptr<TargetSchedulingHooks> SchedulingHooks;
+ std::unique_ptr<TargetSchedulingModel> SchedulingModel;
+};
+
+} // namespace riscv
+} // namespace rcc
+
+#endif // RCC_TARGET_RISCV_RISCVSUBTARGET_H
diff --git a/backend/include/rcc/Target/RISCV/RISCVTarget.h b/backend/include/rcc/Target/RISCV/RISCVTarget.h
new file mode 100644
index 0000000..6d6b806
--- /dev/null
+++ b/backend/include/rcc/Target/RISCV/RISCVTarget.h
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef RCC_TARGET_RISCV_RISCVTARGET_H
+#define RCC_TARGET_RISCV_RISCVTARGET_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;
+ std::uint32_t Encoding = 0;
+};
+
+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(CallingConvention Convention);
+[[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
+
+#endif // RCC_TARGET_RISCV_RISCVTARGET_H
diff --git a/backend/include/rcc/Target/RISCV/RISCVTargetConstant.h b/backend/include/rcc/Target/RISCV/RISCVTargetConstant.h
new file mode 100644
index 0000000..2244117
--- /dev/null
+++ b/backend/include/rcc/Target/RISCV/RISCVTargetConstant.h
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef RCC_TARGET_RISCV_RISCVTARGETCONSTANT_H
+#define RCC_TARGET_RISCV_RISCVTARGETCONSTANT_H
+
+#include "rcc/CodeGen/TargetConstant.h"
+
+#include <cstddef>
+#include <cstdint>
+#include <optional>
+#include <span>
+#include <string>
+#include <string_view>
+#include <utility>
+#include <vector>
+
+namespace rcc::riscv {
+
+enum class RISCVSymbolConstantKind : std::uint8_t {
+ GlobalValue,
+ ExternalSymbol,
+};
+
+class RISCVSymbolConstant final {
+public:
+ RISCVSymbolConstant(RISCVSymbolConstantKind Kind, std::string Symbol, std::int64_t Addend = 0)
+ : ConstantKind(Kind), SymbolName(std::move(Symbol)), SymbolAddend(Addend) {}
+
+ [[nodiscard]] static constexpr TargetConstantTypeID stableTypeID() noexcept {
+ return TargetConstantTypeID::fromValue(0x5243435256435001ULL);
+ }
+
+ [[nodiscard]] static constexpr std::uint32_t schemaVersion() noexcept {
+ return 1;
+ }
+
+ [[nodiscard]] Expected<void> verify() const;
+ [[nodiscard]] Expected<RISCVSymbolConstant> clone() const;
+ [[nodiscard]] std::uint64_t stableHash() const noexcept;
+ [[nodiscard]] std::string print() const;
+ [[nodiscard]] Expected<std::vector<std::byte>> encode() const;
+ [[nodiscard]] Expected<TargetConstantEmission> emit() const;
+ [[nodiscard]] Alignment requiredAlignment() const noexcept;
+ [[nodiscard]] std::optional<TargetRelocationKindID> relocationKind() const noexcept;
+
+ [[nodiscard]] static Expected<RISCVSymbolConstant> parse(std::string_view Text);
+ [[nodiscard]] static Expected<RISCVSymbolConstant> decode(std::uint32_t Version,
+ std::span<const std::byte> Payload);
+
+ [[nodiscard]] RISCVSymbolConstantKind kind() const noexcept {
+ return ConstantKind;
+ }
+
+ [[nodiscard]] std::string_view symbol() const noexcept {
+ return SymbolName;
+ }
+
+ [[nodiscard]] std::int64_t addend() const noexcept {
+ return SymbolAddend;
+ }
+
+ friend bool operator==(const RISCVSymbolConstant &Left,
+ const RISCVSymbolConstant &Right) = default;
+
+private:
+ RISCVSymbolConstantKind ConstantKind;
+ std::string SymbolName;
+ std::int64_t SymbolAddend = 0;
+};
+
+} // namespace rcc::riscv
+
+#endif // RCC_TARGET_RISCV_RISCVTARGETCONSTANT_H
diff --git a/backend/include/rcc/Target/RISCV/RISCVTargetRelocationKinds.h b/backend/include/rcc/Target/RISCV/RISCVTargetRelocationKinds.h
new file mode 100644
index 0000000..08bc73f
--- /dev/null
+++ b/backend/include/rcc/Target/RISCV/RISCVTargetRelocationKinds.h
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef RCC_TARGET_RISCV_RISCVTARGETRELOCATIONKINDS_H
+#define RCC_TARGET_RISCV_RISCVTARGETRELOCATIONKINDS_H
+
+#include "rcc/CodeGen/MachineIRTypes.h"
+
+#include <cstdint>
+
+namespace rcc::riscv {
+
+enum class RISCVTargetRelocationKind : std::uint32_t {
+ Absolute32 = 1,
+ Absolute64,
+};
+
+[[nodiscard]] constexpr TargetRelocationKindID
+targetRelocationKind(RISCVTargetRelocationKind Kind) noexcept {
+ return TargetRelocationKindID::fromValue(static_cast<std::uint32_t>(Kind));
+}
+
+} // namespace rcc::riscv
+
+#endif // RCC_TARGET_RISCV_RISCVTARGETRELOCATIONKINDS_H