aboutsummaryrefslogtreecommitdiff
path: root/backend/include/rcc/CodeGen/Register.h
diff options
context:
space:
mode:
authorRichard-Qin-X <richard.qin.001@gmail.com>2026-08-01 04:50:21 +0800
committerRichard-Qin-X <richard.qin.001@gmail.com>2026-08-01 04:50:21 +0800
commit916b05ee8d79b22147c098cf52bba7fe86858f3f (patch)
treed798384e44ccdce3ffe34d5d5171034ba36d13e2 /backend/include/rcc/CodeGen/Register.h
parent81cf8b68eca2636574f3d0a9fa1cf0b428c163e9 (diff)
downloadrcc-project-916b05ee8d79b22147c098cf52bba7fe86858f3f.tar.gz
rcc-project-916b05ee8d79b22147c098cf52bba7fe86858f3f.tar.xz
[CodeGen] Add core machine type primitives
Introduce an independent 64-bit extended LLT representation that preserves exact floating-point semantics and supports fixed and scalable vectors. Add opaque physical and virtual registers, strongly typed monotonic stable IDs, and atomic MachineFunctionProperties transitions. Export the primitives through RCCBackend::CodeGen, cover their boundary and failure cases, record the frozen invariants, and normalize the architecture document permissions.
Diffstat (limited to 'backend/include/rcc/CodeGen/Register.h')
-rw-r--r--backend/include/rcc/CodeGen/Register.h103
1 files changed, 103 insertions, 0 deletions
diff --git a/backend/include/rcc/CodeGen/Register.h b/backend/include/rcc/CodeGen/Register.h
new file mode 100644
index 0000000..7d98a21
--- /dev/null
+++ b/backend/include/rcc/CodeGen/Register.h
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef RCC_CODEGEN_REGISTER_H
+#define RCC_CODEGEN_REGISTER_H
+
+#include "rcc/Support/Error.h"
+
+#include <cstddef>
+#include <cstdint>
+#include <functional>
+#include <optional>
+#include <string>
+#include <type_traits>
+
+namespace rcc {
+
+class PhysicalRegister final {
+public:
+ constexpr PhysicalRegister() noexcept = default;
+
+ [[nodiscard]] static Expected<PhysicalRegister> create(std::uint64_t Number);
+
+ [[nodiscard]] constexpr bool isValid() const noexcept {
+ return Number != 0;
+ }
+
+ [[nodiscard]] constexpr std::uint32_t number() const noexcept {
+ return Number;
+ }
+
+ friend constexpr bool operator==(PhysicalRegister Left,
+ PhysicalRegister Right) noexcept = default;
+
+private:
+ explicit constexpr PhysicalRegister(std::uint32_t Number) noexcept : Number(Number) {}
+
+ std::uint32_t Number = 0;
+
+ friend class Register;
+};
+
+class Register final {
+public:
+ constexpr Register() noexcept = default;
+ explicit constexpr Register(std::uint32_t OpaqueValue) noexcept : OpaqueValue(OpaqueValue) {}
+
+ [[nodiscard]] static Expected<Register> makePhysical(std::uint64_t Number);
+ [[nodiscard]] static Expected<Register> makeVirtual(std::uint64_t Index);
+
+ [[nodiscard]] static constexpr Register fromPhysical(PhysicalRegister PhysReg) noexcept {
+ return Register(PhysReg.Number);
+ }
+
+ [[nodiscard]] constexpr bool isNoRegister() const noexcept {
+ return OpaqueValue == 0;
+ }
+
+ [[nodiscard]] constexpr bool isPhysical() const noexcept {
+ return OpaqueValue != 0 && (OpaqueValue & VirtualBit) == 0;
+ }
+
+ [[nodiscard]] constexpr bool isVirtual() const noexcept {
+ return (OpaqueValue & VirtualBit) != 0;
+ }
+
+ [[nodiscard]] std::optional<PhysicalRegister> physicalRegister() const noexcept;
+ [[nodiscard]] std::optional<std::uint32_t> virtualIndex() const noexcept;
+
+ [[nodiscard]] constexpr std::uint32_t opaqueValue() const noexcept {
+ return OpaqueValue;
+ }
+
+ [[nodiscard]] std::string toString() const;
+
+ friend constexpr bool operator==(Register Left, Register Right) noexcept = default;
+
+private:
+ static constexpr std::uint32_t VirtualBit = std::uint32_t{1} << 31;
+ static constexpr std::uint32_t IndexMask = VirtualBit - 1;
+
+ std::uint32_t OpaqueValue = 0;
+};
+
+static_assert(sizeof(PhysicalRegister) == sizeof(std::uint32_t));
+static_assert(sizeof(Register) == sizeof(std::uint32_t));
+static_assert(std::is_trivially_copyable_v<PhysicalRegister>);
+static_assert(std::is_trivially_copyable_v<Register>);
+
+} // namespace rcc
+
+template <> struct std::hash<rcc::PhysicalRegister> {
+ [[nodiscard]] std::size_t operator()(rcc::PhysicalRegister PhysReg) const noexcept {
+ return std::hash<std::uint32_t>{}(PhysReg.number());
+ }
+};
+
+template <> struct std::hash<rcc::Register> {
+ [[nodiscard]] std::size_t operator()(rcc::Register Reg) const noexcept {
+ return std::hash<std::uint32_t>{}(Reg.opaqueValue());
+ }
+};
+
+#endif // RCC_CODEGEN_REGISTER_H