aboutsummaryrefslogtreecommitdiff
path: root/backend/lib/CodeGen/Register.cpp
diff options
context:
space:
mode:
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