aboutsummaryrefslogtreecommitdiff
path: root/backend/lib/CodeGen/Register.cpp
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/lib/CodeGen/Register.cpp
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/lib/CodeGen/Register.cpp')
-rw-r--r--backend/lib/CodeGen/Register.cpp56
1 files changed, 56 insertions, 0 deletions
diff --git a/backend/lib/CodeGen/Register.cpp b/backend/lib/CodeGen/Register.cpp
new file mode 100644
index 0000000..0af26c7
--- /dev/null
+++ b/backend/lib/CodeGen/Register.cpp
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "rcc/CodeGen/Register.h"
+
+#include <string>
+
+namespace rcc {
+namespace {
+
+constexpr std::uint64_t MaximumRegisterIndex = (std::uint64_t{1} << 31) - 1;
+
+} // namespace
+
+Expected<PhysicalRegister> PhysicalRegister::create(std::uint64_t Number) {
+ if (Number == 0 || Number > MaximumRegisterIndex) {
+ return makeUnexpected(ErrorCode::InvalidArgument,
+ "physical register number must be in the range [1, 2147483647]");
+ }
+ return PhysicalRegister(static_cast<std::uint32_t>(Number));
+}
+
+Expected<Register> Register::makePhysical(std::uint64_t Number) {
+ auto PhysReg = PhysicalRegister::create(Number);
+ if (!PhysReg)
+ return std::unexpected(PhysReg.error());
+ return fromPhysical(*PhysReg);
+}
+
+Expected<Register> Register::makeVirtual(std::uint64_t Index) {
+ if (Index > MaximumRegisterIndex) {
+ return makeUnexpected(ErrorCode::InvalidArgument, "virtual register index must fit in 31 bits");
+ }
+ return Register(VirtualBit | static_cast<std::uint32_t>(Index));
+}
+
+std::optional<PhysicalRegister> Register::physicalRegister() const noexcept {
+ if (!isPhysical())
+ return std::nullopt;
+ return PhysicalRegister(OpaqueValue);
+}
+
+std::optional<std::uint32_t> Register::virtualIndex() const noexcept {
+ if (!isVirtual())
+ return std::nullopt;
+ return OpaqueValue & IndexMask;
+}
+
+std::string Register::toString() const {
+ if (isNoRegister())
+ return "noreg";
+ if (isVirtual())
+ return "%" + std::to_string(OpaqueValue & IndexMask);
+ return "$physreg" + std::to_string(OpaqueValue);
+}
+
+} // namespace rcc