From 379ff50dcc7ccf977379aee68fa9d10f69065d23 Mon Sep 17 00:00:00 2001 From: Richard-Qin-X Date: Sun, 9 Aug 2026 18:31:49 +0800 Subject: [MC] Implement RV64GC assembly emission --- backend/include/rcc/CodeGen/GlobalObject.h | 196 +++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 backend/include/rcc/CodeGen/GlobalObject.h (limited to 'backend/include/rcc/CodeGen/GlobalObject.h') diff --git a/backend/include/rcc/CodeGen/GlobalObject.h b/backend/include/rcc/CodeGen/GlobalObject.h new file mode 100644 index 0000000..49f1f42 --- /dev/null +++ b/backend/include/rcc/CodeGen/GlobalObject.h @@ -0,0 +1,196 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef RCC_CODEGEN_GLOBALOBJECT_H +#define RCC_CODEGEN_GLOBALOBJECT_H + +#include "rcc/CodeGen/GenericConstant.h" +#include "rcc/CodeGen/MachineIRTypes.h" +#include "rcc/CodeGen/TargetConstant.h" +#include "rcc/Support/Error.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rcc { + +class GlobalInitializer; +using GlobalInitializerRef = std::shared_ptr; + +struct GlobalZeroFill final { + std::uint64_t Size = 0; +}; + +struct GlobalRepeatedInitializer final { + std::uint64_t Count = 0; + GlobalInitializerRef Value; +}; + +struct GlobalAggregateInitializer final { + std::vector Elements; +}; + +struct GlobalSymbolAddress final { + std::string Symbol; + std::int64_t Addend = 0; + std::uint8_t Size = 8; + std::uint32_t TargetFlags = 0; +}; + +struct GlobalSymbolDifference final { + std::string Minuend; + std::string Subtrahend; + std::int64_t Addend = 0; + std::uint8_t Size = 8; +}; + +struct GlobalAlignmentPadding final { + std::uint64_t Size = 0; + std::uint8_t Fill = 0; +}; + +struct GlobalUndefinedStorage final { + std::uint64_t Size = 0; +}; + +class GlobalInitializer final { +public: + enum class Kind : std::uint8_t { + Invalid, + Integer, + Floating, + Bytes, + ZeroFill, + Repeated, + Aggregate, + SymbolAddress, + SymbolDifference, + Target, + AlignmentPadding, + UndefinedStorage, + }; + + GlobalInitializer() = default; + GlobalInitializer(const GlobalInitializer &) = delete; + GlobalInitializer &operator=(const GlobalInitializer &) = delete; + GlobalInitializer(GlobalInitializer &&) noexcept = default; + GlobalInitializer &operator=(GlobalInitializer &&) noexcept = default; + ~GlobalInitializer() = default; + + [[nodiscard]] static GlobalInitializer integer(IntegerImmediate Value); + [[nodiscard]] static GlobalInitializer floating(FloatingPointBits Value); + [[nodiscard]] static Expected bytes(std::vector Value); + [[nodiscard]] static Expected zeroFill(std::uint64_t Size); + [[nodiscard]] static Expected repeated(std::uint64_t Count, + GlobalInitializer Value); + [[nodiscard]] static Expected + aggregate(std::vector Elements); + [[nodiscard]] static Expected symbolAddress(GlobalSymbolAddress Value); + [[nodiscard]] static Expected symbolDifference(GlobalSymbolDifference Value); + [[nodiscard]] static Expected target(TargetConstant Value); + [[nodiscard]] static Expected alignmentPadding(std::uint64_t Size, + std::uint8_t Fill = 0); + [[nodiscard]] static Expected undefinedStorage(std::uint64_t Size); + + [[nodiscard]] Kind kind() const noexcept; + + template [[nodiscard]] const ValueT *getIf() const noexcept { + return std::get_if(&Storage); + } + + [[nodiscard]] Expected verify(std::size_t MaximumDepth = 1024) const; + [[nodiscard]] Expected storageSize(std::size_t MaximumDepth = 1024) const; + +private: + using StorageT = + std::variant, + GlobalZeroFill, GlobalRepeatedInitializer, GlobalAggregateInitializer, + GlobalSymbolAddress, GlobalSymbolDifference, TargetConstant, + GlobalAlignmentPadding, GlobalUndefinedStorage>; + + explicit GlobalInitializer(StorageT Storage) : Storage(std::move(Storage)) {} + + StorageT Storage; +}; + +enum class GlobalLinkage : std::uint8_t { + External, + AvailableExternally, + LinkOnceAny, + LinkOnceODR, + WeakAny, + WeakODR, + Appending, + Internal, + Private, + ExternalWeak, + Common, + Count, +}; + +enum class GlobalVisibility : std::uint8_t { + Default, + Hidden, + Protected, + Count, +}; + +enum class GlobalTLSModel : std::uint8_t { + None, + GeneralDynamic, + LocalDynamic, + InitialExec, + LocalExec, + Count, +}; + +enum class GlobalUnnamedAddress : std::uint8_t { + None, + Local, + Global, + Count, +}; + +struct GlobalObjectDesc final { + std::string Symbol; + GenericConstantType ObjectType; + GlobalLinkage Linkage = GlobalLinkage::External; + GlobalVisibility Visibility = GlobalVisibility::Default; + bool DSOLocal = false; + std::optional Section; + Alignment Align; + std::uint64_t Size = 0; + std::uint32_t AddressSpace = 0; + GlobalTLSModel TLSModel = GlobalTLSModel::None; + bool ExternallyInitialized = false; + std::optional COMDAT; + bool IsConstant = false; + GlobalUnnamedAddress UnnamedAddress = GlobalUnnamedAddress::None; + std::optional Initializer; + std::vector DebugExpressions; + std::optional StableOrigin; + std::uint64_t TargetFlags = 0; + std::vector> TargetAttributes; + + GlobalObjectDesc() = default; + GlobalObjectDesc(const GlobalObjectDesc &) = delete; + GlobalObjectDesc &operator=(const GlobalObjectDesc &) = delete; + GlobalObjectDesc(GlobalObjectDesc &&) noexcept = default; + GlobalObjectDesc &operator=(GlobalObjectDesc &&) noexcept = default; + ~GlobalObjectDesc() = default; + + [[nodiscard]] bool isDeclaration() const noexcept { + return !Initializer.has_value() && Linkage != GlobalLinkage::Common; + } + + [[nodiscard]] Expected verify() const; +}; + +} // namespace rcc + +#endif // RCC_CODEGEN_GLOBALOBJECT_H -- cgit v1.2.3