aboutsummaryrefslogtreecommitdiff
path: root/backend/unittests/Target
diff options
context:
space:
mode:
Diffstat (limited to 'backend/unittests/Target')
-rw-r--r--backend/unittests/Target/CMakeLists.txt17
-rw-r--r--backend/unittests/Target/TestTarget.cpp177
-rw-r--r--backend/unittests/Target/TestTarget.h64
3 files changed, 258 insertions, 0 deletions
diff --git a/backend/unittests/Target/CMakeLists.txt b/backend/unittests/Target/CMakeLists.txt
new file mode 100644
index 0000000..514cb97
--- /dev/null
+++ b/backend/unittests/Target/CMakeLists.txt
@@ -0,0 +1,17 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+add_library(RCCBackendTestTarget TestTarget.cpp)
+add_library(RCCBackend::TestTarget ALIAS RCCBackendTestTarget)
+
+rcc_backend_configure_target(RCCBackendTestTarget)
+target_include_directories(
+ RCCBackendTestTarget
+ PUBLIC "${RCC_BACKEND_SOURCE_DIR}/unittests"
+)
+target_link_libraries(RCCBackendTestTarget PUBLIC RCCBackend::CodeGen)
+
+rcc_backend_register_format_files(
+ "${CMAKE_CURRENT_SOURCE_DIR}/TestTarget.cpp"
+ "${CMAKE_CURRENT_SOURCE_DIR}/TestTarget.h"
+)
+rcc_backend_register_tidy_files("${CMAKE_CURRENT_SOURCE_DIR}/TestTarget.cpp")
diff --git a/backend/unittests/Target/TestTarget.cpp b/backend/unittests/Target/TestTarget.cpp
new file mode 100644
index 0000000..30fa22f
--- /dev/null
+++ b/backend/unittests/Target/TestTarget.cpp
@@ -0,0 +1,177 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "Target/TestTarget.h"
+
+#include <cstdint>
+#include <memory>
+#include <utility>
+#include <vector>
+
+namespace rcc::test {
+namespace {
+
+[[nodiscard]] PhysicalRegister phys(std::uint32_t Number) {
+ return *PhysicalRegister::create(Number);
+}
+
+[[nodiscard]] RegisterUnitDesc unit(std::uint32_t ID, const char *Name) {
+ return RegisterUnitDesc{RegisterUnitID::fromValue(ID), Name};
+}
+
+[[nodiscard]] RegisterUnitLane unitLane(std::uint32_t ID, std::uint64_t Lanes) {
+ return RegisterUnitLane{RegisterUnitID::fromValue(ID), LaneMask::fromRaw(Lanes)};
+}
+
+[[nodiscard]] PhysicalRegisterDesc physicalRegister(std::uint32_t Number, const char *Name,
+ std::uint32_t Encoding,
+ std::vector<RegisterUnitLane> Units) {
+ return PhysicalRegisterDesc{phys(Number), Name, Encoding, std::move(Units)};
+}
+
+[[nodiscard]] RegisterClassDesc
+registerClass(RegisterClassID ID, const char *Name, std::vector<PhysicalRegister> Registers,
+ std::vector<PhysicalRegister> AllocationOrder, std::uint32_t SizeInBits,
+ LaneMask Lanes, RegisterBankID DefaultBank,
+ std::vector<SubRegIndex> SupportedSubRegs = {},
+ std::vector<RegisterClassID> SuperClasses = {}, bool Allocatable = true,
+ bool CoveredBySubRegs = false) {
+ return RegisterClassDesc{
+ ID,
+ Name,
+ std::move(Registers),
+ std::move(AllocationOrder),
+ SizeInBits,
+ SizeInBits,
+ SizeInBits,
+ Lanes,
+ std::move(SupportedSubRegs),
+ std::move(SuperClasses),
+ DefaultBank,
+ Allocatable,
+ 1,
+ CoveredBySubRegs,
+ };
+}
+
+} // namespace
+
+TargetRegisterInfoDesc createTestTargetRegisterInfoDescription() {
+ TargetRegisterInfoDesc Description;
+ Description.RegisterUnits = {
+ unit(1, "g0.lo16"), unit(2, "g0.bits16_31"), unit(3, "g0.bits32_47"), unit(4, "g0.hi16"),
+ unit(5, "g1.lo16"), unit(6, "g1.bits16_31"), unit(7, "g1.bits32_47"), unit(8, "g1.hi16"),
+ unit(9, "sp"), unit(10, "f0"), unit(11, "f1"),
+ };
+
+ Description.PhysicalRegisters = {
+ physicalRegister(TestRegister::G0, "g0", 0,
+ {unitLane(1, 0x1), unitLane(2, 0x2), unitLane(3, 0x4), unitLane(4, 0x8)}),
+ physicalRegister(TestRegister::G0Low32, "g0l", 0, {unitLane(1, 0x1), unitLane(2, 0x2)}),
+ physicalRegister(TestRegister::G0High32, "g0h", 0, {unitLane(3, 0x1), unitLane(4, 0x2)}),
+ physicalRegister(TestRegister::G0Low16, "g0w", 0, {unitLane(1, 0x1)}),
+ physicalRegister(TestRegister::G1, "g1", 1,
+ {unitLane(5, 0x1), unitLane(6, 0x2), unitLane(7, 0x4), unitLane(8, 0x8)}),
+ physicalRegister(TestRegister::G1Low32, "g1l", 1, {unitLane(5, 0x1), unitLane(6, 0x2)}),
+ physicalRegister(TestRegister::G1High32, "g1h", 1, {unitLane(7, 0x1), unitLane(8, 0x2)}),
+ physicalRegister(TestRegister::G1Low16, "g1w", 1, {unitLane(5, 0x1)}),
+ physicalRegister(TestRegister::StackPointer, "sp", 2, {unitLane(9, 0xF)}),
+ physicalRegister(TestRegister::F0, "f0", 0, {unitLane(10, 0x1)}),
+ physicalRegister(TestRegister::F1, "f1", 1, {unitLane(11, 0x1)}),
+ };
+
+ Description.SubRegIndices = {
+ SubRegIndexDesc{TestSubReg::Low32, "low32", LaneMask::fromRaw(0x3), 32, 0},
+ SubRegIndexDesc{TestSubReg::High32, "high32", LaneMask::fromRaw(0xC), 32, 32},
+ SubRegIndexDesc{TestSubReg::Low16, "low16", LaneMask::fromRaw(0x1), 16, 0},
+ };
+ Description.PhysicalSubRegisters = {
+ {phys(TestRegister::G0), TestSubReg::Low32, phys(TestRegister::G0Low32)},
+ {phys(TestRegister::G0), TestSubReg::High32, phys(TestRegister::G0High32)},
+ {phys(TestRegister::G0), TestSubReg::Low16, phys(TestRegister::G0Low16)},
+ {phys(TestRegister::G0Low32), TestSubReg::Low16, phys(TestRegister::G0Low16)},
+ {phys(TestRegister::G1), TestSubReg::Low32, phys(TestRegister::G1Low32)},
+ {phys(TestRegister::G1), TestSubReg::High32, phys(TestRegister::G1High32)},
+ {phys(TestRegister::G1), TestSubReg::Low16, phys(TestRegister::G1Low16)},
+ {phys(TestRegister::G1Low32), TestSubReg::Low16, phys(TestRegister::G1Low16)},
+ };
+ Description.SubRegCompositions = {
+ {TestSubReg::Low32, TestSubReg::Low16, TestSubReg::Low16},
+ };
+
+ const auto G0 = phys(TestRegister::G0);
+ const auto G0Low32 = phys(TestRegister::G0Low32);
+ const auto G0High32 = phys(TestRegister::G0High32);
+ const auto G0Low16 = phys(TestRegister::G0Low16);
+ const auto G1 = phys(TestRegister::G1);
+ const auto G1Low32 = phys(TestRegister::G1Low32);
+ const auto G1High32 = phys(TestRegister::G1High32);
+ const auto G1Low16 = phys(TestRegister::G1Low16);
+ const auto StackPointer = phys(TestRegister::StackPointer);
+ const auto F0 = phys(TestRegister::F0);
+ const auto F1 = phys(TestRegister::F1);
+
+ Description.RegisterClasses = {
+ registerClass(TestRegisterClass::GPR64, "GPR64", {G0, G1}, {G0, G1}, 64,
+ LaneMask::fromRaw(0xF), TestRegisterBank::GPR,
+ {TestSubReg::Low32, TestSubReg::High32, TestSubReg::Low16}, {}, true, true),
+ registerClass(TestRegisterClass::GPR64Alloc, "GPR64Alloc", {G0, G1}, {G1, G0}, 64,
+ LaneMask::fromRaw(0xF), TestRegisterBank::GPR, {}, {TestRegisterClass::GPR64}),
+ registerClass(TestRegisterClass::GPR32, "GPR32", {G0Low32, G0High32, G1Low32, G1High32},
+ {G0Low32, G1Low32, G0High32, G1High32}, 32, LaneMask::fromRaw(0x3),
+ TestRegisterBank::GPR),
+ registerClass(TestRegisterClass::GPR32Low, "GPR32Low", {G0Low32, G1Low32}, {G0Low32, G1Low32},
+ 32, LaneMask::fromRaw(0x3), TestRegisterBank::GPR, {TestSubReg::Low16},
+ {TestRegisterClass::GPR32}),
+ registerClass(TestRegisterClass::GPR32High, "GPR32High", {G0High32, G1High32},
+ {G0High32, G1High32}, 32, LaneMask::fromRaw(0x3), TestRegisterBank::GPR, {},
+ {TestRegisterClass::GPR32}),
+ registerClass(TestRegisterClass::GPR16, "GPR16", {G0Low16, G1Low16}, {G0Low16, G1Low16}, 16,
+ LaneMask::fromRaw(0x1), TestRegisterBank::GPR),
+ registerClass(TestRegisterClass::FPR64, "FPR64", {F0, F1}, {F0, F1}, 64,
+ LaneMask::fromRaw(0x1), TestRegisterBank::FPR),
+ registerClass(TestRegisterClass::SpecialGPR64, "SpecialGPR64", {StackPointer}, {}, 64,
+ LaneMask::fromRaw(0xF), TestRegisterBank::GPR, {}, {}, false),
+ };
+
+ Description.SubRegClassMappings = {
+ {TestRegisterClass::GPR64, TestSubReg::Low32, TestRegisterClass::GPR32Low},
+ {TestRegisterClass::GPR64, TestSubReg::High32, TestRegisterClass::GPR32High},
+ {TestRegisterClass::GPR64, TestSubReg::Low16, TestRegisterClass::GPR16},
+ {TestRegisterClass::GPR32Low, TestSubReg::Low16, TestRegisterClass::GPR16},
+ };
+ Description.RegisterBanks = {
+ {TestRegisterBank::GPR,
+ "GPR",
+ 64,
+ {TestRegisterClass::GPR64, TestRegisterClass::GPR64Alloc, TestRegisterClass::GPR32,
+ TestRegisterClass::GPR32Low, TestRegisterClass::GPR32High, TestRegisterClass::GPR16,
+ TestRegisterClass::SpecialGPR64}},
+ {TestRegisterBank::FPR, "FPR", 64, {TestRegisterClass::FPR64}},
+ };
+
+ return Description;
+}
+
+Expected<TargetRegisterInfo> createTestTargetRegisterInfo() {
+ return TargetRegisterInfo::create(createTestTargetRegisterInfoDescription());
+}
+
+Expected<TargetDescription> createTestTargetDescription(InstructionSet Instructions) {
+ auto Registers = createTestTargetRegisterInfo();
+ if (!Registers)
+ return std::unexpected(Registers.error());
+ return TargetDescription::create(std::move(Instructions), std::move(*Registers));
+}
+
+std::shared_ptr<const RegisterMask> createTestCallPreservedMask() {
+ std::uint64_t Preserved = 0;
+ Preserved |= std::uint64_t{1} << TestRegister::G1;
+ Preserved |= std::uint64_t{1} << TestRegister::G1Low32;
+ Preserved |= std::uint64_t{1} << TestRegister::G1High32;
+ Preserved |= std::uint64_t{1} << TestRegister::G1Low16;
+ Preserved |= std::uint64_t{1} << TestRegister::StackPointer;
+ Preserved |= std::uint64_t{1} << TestRegister::F1;
+ return std::make_shared<const RegisterMask>(std::vector<std::uint64_t>{Preserved});
+}
+
+} // namespace rcc::test
diff --git a/backend/unittests/Target/TestTarget.h b/backend/unittests/Target/TestTarget.h
new file mode 100644
index 0000000..3c2aa51
--- /dev/null
+++ b/backend/unittests/Target/TestTarget.h
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef HOME_RICHARD_CODE_RCC_PROJECT_BACKEND_UNITTESTS_TARGET_TESTTARGET_H
+#define HOME_RICHARD_CODE_RCC_PROJECT_BACKEND_UNITTESTS_TARGET_TESTTARGET_H
+
+#include "rcc/CodeGen/InstructionDescriptor.h"
+#include "rcc/CodeGen/RegisterMask.h"
+#include "rcc/CodeGen/TargetDescription.h"
+#include "rcc/CodeGen/TargetRegisterInfo.h"
+#include "rcc/Support/Error.h"
+
+#include <cstdint>
+#include <memory>
+
+namespace rcc::test {
+
+struct TestRegister final {
+
+ static constexpr std::uint32_t G0 = 1;
+ static constexpr std::uint32_t G0Low32 = 2;
+ static constexpr std::uint32_t G0High32 = 3;
+ static constexpr std::uint32_t G0Low16 = 4;
+ static constexpr std::uint32_t G1 = 5;
+ static constexpr std::uint32_t G1Low32 = 6;
+ static constexpr std::uint32_t G1High32 = 7;
+ static constexpr std::uint32_t G1Low16 = 8;
+ static constexpr std::uint32_t StackPointer = 9;
+ static constexpr std::uint32_t F0 = 10;
+ static constexpr std::uint32_t F1 = 11;
+};
+
+struct TestSubReg final {
+
+ static constexpr SubRegIndex Low32 = SubRegIndex::fromValue(1);
+ static constexpr SubRegIndex High32 = SubRegIndex::fromValue(2);
+ static constexpr SubRegIndex Low16 = SubRegIndex::fromValue(3);
+};
+
+struct TestRegisterBank final {
+
+ static constexpr RegisterBankID GPR = RegisterBankID::fromValue(1);
+ static constexpr RegisterBankID FPR = RegisterBankID::fromValue(2);
+};
+
+struct TestRegisterClass final {
+
+ static constexpr RegisterClassID GPR64 = RegisterClassID::fromValue(1);
+ static constexpr RegisterClassID GPR64Alloc = RegisterClassID::fromValue(2);
+ static constexpr RegisterClassID GPR32 = RegisterClassID::fromValue(3);
+ static constexpr RegisterClassID GPR32Low = RegisterClassID::fromValue(4);
+ static constexpr RegisterClassID GPR32High = RegisterClassID::fromValue(5);
+ static constexpr RegisterClassID GPR16 = RegisterClassID::fromValue(6);
+ static constexpr RegisterClassID FPR64 = RegisterClassID::fromValue(7);
+ static constexpr RegisterClassID SpecialGPR64 = RegisterClassID::fromValue(8);
+};
+
+[[nodiscard]] TargetRegisterInfoDesc createTestTargetRegisterInfoDescription();
+[[nodiscard]] Expected<TargetRegisterInfo> createTestTargetRegisterInfo();
+[[nodiscard]] Expected<TargetDescription> createTestTargetDescription(InstructionSet Instructions);
+[[nodiscard]] std::shared_ptr<const RegisterMask> createTestCallPreservedMask();
+
+} // namespace rcc::test
+
+#endif // HOME_RICHARD_CODE_RCC_PROJECT_BACKEND_UNITTESTS_TARGET_TESTTARGET_H