aboutsummaryrefslogtreecommitdiff
path: root/backend/unittests/Target
diff options
context:
space:
mode:
authorRichard-Qin-X <richard.qin.001@gmail.com>2026-08-12 01:07:48 +0800
committerRichard-Qin-X <richard.qin.001@gmail.com>2026-08-12 01:07:48 +0800
commit7819df7189a54fa5b8df657d10285f1873628d25 (patch)
treed2f3d851aa00656e20df861a6f29e6423eeca944 /backend/unittests/Target
parentdeb6a9e08397083a8d23cac4cfba94345419b443 (diff)
downloadrcc-project-7819df7189a54fa5b8df657d10285f1873628d25.tar.gz
rcc-project-7819df7189a54fa5b8df657d10285f1873628d25.tar.xz
[RISCV] Model FFLAGS accesses
Diffstat (limited to 'backend/unittests/Target')
-rw-r--r--backend/unittests/Target/RISCVLateCodeGenTest.cpp20
-rw-r--r--backend/unittests/Target/RISCVTargetTest.cpp15
2 files changed, 29 insertions, 6 deletions
diff --git a/backend/unittests/Target/RISCVLateCodeGenTest.cpp b/backend/unittests/Target/RISCVLateCodeGenTest.cpp
index e8ac9de..4b11140 100644
--- a/backend/unittests/Target/RISCVLateCodeGenTest.cpp
+++ b/backend/unittests/Target/RISCVLateCodeGenTest.cpp
@@ -1129,6 +1129,18 @@ void testPostRAPseudoExpansionAndFinalization(TestContext &Context,
Context.expect(false, "post-RA cross-bank copy construction must succeed");
return;
}
+ auto ReadFFLAGS = Builder.buildInstr(opcode(rcc::riscv::InstructionOpcode::ReadFFLAGS));
+ if (!ReadFFLAGS || !ReadFFLAGS->addDef(physical(rcc::riscv::PhysicalRegisterID::X12)) ||
+ !ReadFFLAGS->build()) {
+ Context.expect(false, "ReadFFLAGS pseudo construction must succeed");
+ return;
+ }
+ auto WriteFFLAGS = Builder.buildInstr(opcode(rcc::riscv::InstructionOpcode::WriteFFLAGS));
+ if (!WriteFFLAGS || !WriteFFLAGS->addUse(physical(rcc::riscv::PhysicalRegisterID::X12)) ||
+ !WriteFFLAGS->build()) {
+ Context.expect(false, "WriteFFLAGS pseudo construction must succeed");
+ return;
+ }
auto Call = Builder.buildInstr(opcode(rcc::riscv::InstructionOpcode::PseudoCALL));
auto Preserved = rcc::riscv::createCallPreservedMask(rcc::riscv::CallingConvention::LP64D);
if (!Call || !Call->addExternalSymbol("callee", 0, 1) || !Call->addRegisterMask(Preserved) ||
@@ -1154,16 +1166,20 @@ void testPostRAPseudoExpansionAndFinalization(TestContext &Context,
std::size_t CrossMoveCount = 0;
std::size_t CallCount = 0;
std::size_t ReturnCount = 0;
+ std::size_t CSRRSCount = 0;
+ std::size_t CSRRWCount = 0;
for (rcc::MachineInstr *Instruction = Block->firstInstruction(); Instruction != nullptr;
Instruction = Instruction->next()) {
ADDICount += Instruction->opcode() == opcode(rcc::riscv::InstructionOpcode::ADDI);
CrossMoveCount += Instruction->opcode() == opcode(rcc::riscv::InstructionOpcode::FMV_D_X);
CallCount += Instruction->opcode() == opcode(rcc::riscv::InstructionOpcode::JALR_CALL);
ReturnCount += Instruction->opcode() == opcode(rcc::riscv::InstructionOpcode::JALR_RET);
+ CSRRSCount += Instruction->opcode() == opcode(rcc::riscv::InstructionOpcode::CSRRS);
+ CSRRWCount += Instruction->opcode() == opcode(rcc::riscv::InstructionOpcode::CSRRW);
}
Context.expect(Expanded && Expanded->Changed && ADDICount == 1 && CrossMoveCount == 1 &&
- CallCount == 1 && ReturnCount == 1,
- "post-RA expansion must lower copies, calls, and returns to real RV64GC code");
+ CallCount == 1 && ReturnCount == 1 && CSRRSCount == 1 && CSRRWCount == 1,
+ "post-RA expansion must lower copies, calls, returns, and FFLAGS accesses");
if (!Expanded)
return;
diff --git a/backend/unittests/Target/RISCVTargetTest.cpp b/backend/unittests/Target/RISCVTargetTest.cpp
index 680d606..b4b3648 100644
--- a/backend/unittests/Target/RISCVTargetTest.cpp
+++ b/backend/unittests/Target/RISCVTargetTest.cpp
@@ -49,11 +49,12 @@ void testRegisterFacts(TestContext &Context) {
const rcc::PhysicalRegister X8 = registerID(rcc::riscv::PhysicalRegisterID::X8);
const rcc::PhysicalRegister F31D = registerID(rcc::riscv::PhysicalRegisterID::F31_D);
const rcc::PhysicalRegister F31F = registerID(rcc::riscv::PhysicalRegisterID::F31_F);
+ const rcc::PhysicalRegister FFLAGS = registerID(rcc::riscv::PhysicalRegisterID::FFLAGS);
Context.expect(
- Registers->physicalRegisters().size() == 96 && Registers->registerUnits().size() == 64 &&
- Registers->registerClasses().size() == 8 && Registers->registerBanks().size() == 2,
- "RV64GC must expose the complete scalar, compressed, and restricted register classes");
+ Registers->physicalRegisters().size() == 97 && Registers->registerUnits().size() == 65 &&
+ Registers->registerClasses().size() == 9 && Registers->registerBanks().size() == 3,
+ "RV64GC must expose scalar, compressed, restricted, and status register classes");
Context.expect(Registers->physicalRegister("x0") != nullptr &&
Registers->physicalRegister("zero") == nullptr &&
Registers->physicalRegisterByAlternativeName("ZERO") != nullptr &&
@@ -77,6 +78,12 @@ void testRegisterFacts(TestContext &Context) {
Registers->regsOverlap(F31D, F31F) &&
Registers->subRegister(F31D, rcc::SubRegIndex::fromValue(1)) == F31F,
"FPR32 and FPR64 MIR views must retain encoding, overlap, and subregister facts");
+ Context.expect(Registers->physicalRegister("fflags") != nullptr &&
+ Registers->physicalRegister("fflags")->Reg == FFLAGS &&
+ Registers->isReservedRegister(FFLAGS) &&
+ Registers->registerClass("fflags") != nullptr &&
+ !Registers->registerClass("fflags")->Allocatable,
+ "FFLAGS must be a reserved nonallocatable status register");
const auto *GPR = Registers->registerClass("gpr");
Context.expect(
@@ -149,7 +156,7 @@ void testABIAndDebugFacts(TestContext &Context) {
void testInstructionFacts(TestContext &Context) {
constexpr std::size_t TargetInstructionCount =
- static_cast<std::uint32_t>(rcc::riscv::InstructionOpcode::Select_GPR_Using_CC_GPR) -
+ static_cast<std::uint32_t>(rcc::riscv::InstructionOpcode::WriteFFLAGS) -
static_cast<std::uint32_t>(rcc::riscv::InstructionOpcode::LUI) + 1U;
auto Target = rcc::riscv::createTargetDescription();
Context.expect(Target.has_value(), "RV64GC target description must be structurally valid");