diff options
Diffstat (limited to 'backend/unittests')
| -rw-r--r-- | backend/unittests/Target/RISCVMCEncodingCoverageTest.cpp | 12 | ||||
| -rw-r--r-- | backend/unittests/Target/RISCVMCTest.cpp | 11 | ||||
| -rw-r--r-- | backend/unittests/Target/RISCVTargetTest.cpp | 22 |
3 files changed, 39 insertions, 6 deletions
diff --git a/backend/unittests/Target/RISCVMCEncodingCoverageTest.cpp b/backend/unittests/Target/RISCVMCEncodingCoverageTest.cpp index d66d19d..1a7157a 100644 --- a/backend/unittests/Target/RISCVMCEncodingCoverageTest.cpp +++ b/backend/unittests/Target/RISCVMCEncodingCoverageTest.cpp @@ -117,6 +117,7 @@ createStandardFixture(const rcc::InstructionDescriptor &Descriptor, addRegister(Result, Descriptor, Source1Encoding); addImmediate(Result, (Encoding >> 12U) & 7U); return Result; + case RD_RS1: case RD_FRS1: addRegister(Result, Descriptor, DestinationEncoding); addRegister(Result, Descriptor, Source1Encoding); @@ -138,12 +139,17 @@ createStandardFixture(const rcc::InstructionDescriptor &Descriptor, addImmediate(Result, (Encoding >> 20U) & 0xfU); return Result; } + if (Format == RD_RS1) { + addRegister(Result, Descriptor, DestinationEncoding); + addRegister(Result, Descriptor, Source1Encoding); + return Result; + } const bool FloatingDestination = Format == FRD_OFFSET_RS1; if (Format != RD_RS1_IMM && Format != RD_OFFSET_RS1 && !FloatingDestination) return fixtureError("unsupported I-type reference fixture format"); addRegister(Result, Descriptor, DestinationEncoding); addRegister(Result, Descriptor, Source1Encoding); - const bool Shift64 = Opcode == SLLI || Opcode == SRLI || Opcode == SRAI; + const bool Shift64 = Opcode == SLLI || Opcode == SLLI_UW || Opcode == SRLI || Opcode == SRAI; const bool Shift32 = Opcode == SLLIW || Opcode == SRLIW || Opcode == SRAIW; if (Shift64) addImmediate(Result, (Encoding >> 20U) & 0x3fU); @@ -387,8 +393,8 @@ int main() { } const std::span<const rcc::riscv::AssemblyInstructionInfo> Instructions = rcc::riscv::assemblyInstructions(); - if (Instructions.size() != 195) { - std::cerr << "RV64GC encoding coverage does not contain all 195 instructions\n"; + if (Instructions.size() != 211) { + std::cerr << "RISC-V encoding coverage does not contain all 211 instructions\n"; return 1; } diff --git a/backend/unittests/Target/RISCVMCTest.cpp b/backend/unittests/Target/RISCVMCTest.cpp index 1064cf3..d77899a 100644 --- a/backend/unittests/Target/RISCVMCTest.cpp +++ b/backend/unittests/Target/RISCVMCTest.cpp @@ -90,6 +90,12 @@ symbolExpression(rcc::mc::MCContext &Context, std::string_view Name, std::uint32 {0x13, 0x86, 0xf6, 0xfe}, "ADDI") && expectEncoding(Emitter, instruction(SRAI, {reg(X14), reg(X15), imm(63)}), {0x13, 0xd7, 0xf7, 0x43}, "SRAI") && + expectEncoding(Emitter, instruction(SH1ADD, {reg(X8), reg(X9), reg(X10)}), + {0x33, 0xa4, 0xa4, 0x20}, "SH1ADD") && + expectEncoding(Emitter, instruction(SEXT_B, {reg(X8), reg(X9)}), {0x13, 0x94, 0x44, 0x60}, + "SEXT.B") && + expectEncoding(Emitter, instruction(ZEXT_H_RV64, {reg(X8), reg(X9)}), + {0x3b, 0xc4, 0x04, 0x08}, "ZEXT.H") && expectEncoding(Emitter, instruction(SD, {reg(X16), reg(X17), imm(-32)}), {0x23, 0xb0, 0x08, 0xff}, "SD") && expectEncoding(Emitter, instruction(BGE, {reg(X18), reg(X19), imm(18)}), @@ -297,6 +303,11 @@ int main() { static_cast<std::uint32_t>(rcc::riscv::RISCVMCExprKind::AbsoluteLow), "symbol"); if (!PrintedHigh || *PrintedHigh != "%hi(symbol)" || !PrintedLow || *PrintedLow != "%lo(symbol)") return fail("RISC-V absolute address modifiers do not print canonically"); + auto PrintedUnary = Printer.printInstruction(instruction( + rcc::riscv::InstructionOpcode::SEXT_B, + {reg(rcc::riscv::PhysicalRegisterID::X8), reg(rcc::riscv::PhysicalRegisterID::X9)})); + if (!PrintedUnary || *PrintedUnary != "sext.b x8, x9") + return fail("RISC-V unary integer instructions do not print canonically"); if (!testEncodings(Emitter)) return fail("RISC-V MC encodings differ from the RV64GC reference encodings"); if (!testFixups(Emitter, Backend)) diff --git a/backend/unittests/Target/RISCVTargetTest.cpp b/backend/unittests/Target/RISCVTargetTest.cpp index 555db4c..40f5f76 100644 --- a/backend/unittests/Target/RISCVTargetTest.cpp +++ b/backend/unittests/Target/RISCVTargetTest.cpp @@ -164,7 +164,7 @@ void testABIAndDebugFacts(TestContext &Context) { void testInstructionFacts(TestContext &Context) { constexpr std::size_t TargetInstructionCount = - static_cast<std::uint32_t>(rcc::riscv::InstructionOpcode::WriteFFLAGS) - + static_cast<std::uint32_t>(rcc::riscv::InstructionOpcode::MAXU) - 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"); @@ -183,6 +183,14 @@ void testInstructionFacts(TestContext &Context) { rcc::Opcode::fromValue(static_cast<std::uint32_t>(rcc::riscv::InstructionOpcode::FADD_S))); const auto *Atomic = Target->instructionDescriptor( rcc::Opcode::fromValue(static_cast<std::uint32_t>(rcc::riscv::InstructionOpcode::LR_W))); + const auto *ShiftAdd = Target->instructionDescriptor( + rcc::Opcode::fromValue(static_cast<std::uint32_t>(rcc::riscv::InstructionOpcode::SH1ADD))); + const auto *ShiftLeftUnsignedWord = Target->instructionDescriptor( + rcc::Opcode::fromValue(static_cast<std::uint32_t>(rcc::riscv::InstructionOpcode::SLLI_UW))); + const auto *SignExtendByte = Target->instructionDescriptor( + rcc::Opcode::fromValue(static_cast<std::uint32_t>(rcc::riscv::InstructionOpcode::SEXT_B))); + const auto *SignedMinimum = Target->instructionDescriptor( + rcc::Opcode::fromValue(static_cast<std::uint32_t>(rcc::riscv::InstructionOpcode::MIN))); const auto *Compressed = Target->instructionDescriptor(rcc::Opcode::fromValue( static_cast<std::uint32_t>(rcc::riscv::InstructionOpcode::C_ADDI16SP))); const auto *GenericAdd = Target->instructionDescriptor(rcc::opcode(rcc::GenericOpcode::G_ADD)); @@ -260,12 +268,20 @@ void testInstructionFacts(TestContext &Context) { rcc::opcode(rcc::GenericOpcode::G_LOAD), std::span<const rcc::MachineMemOperand *const>{}), "target memory operands must be optional while generic memory operands remain required"); + Context.expect(ShiftAdd != nullptr && ShiftAdd->Operands.size() == 3 && + ShiftLeftUnsignedWord != nullptr && + ShiftLeftUnsignedWord->Operands.size() == 3 && + ShiftLeftUnsignedWord->Operands.back().ImmediatePredicate && + SignExtendByte != nullptr && SignExtendByte->Operands.size() == 2 && + SignedMinimum != nullptr && SignedMinimum->Operands.size() == 3 && + SignedMinimum->Flags.has(rcc::InstructionFlag::Commutable), + "RISC-V Zba and Zbb instructions must expose complete generated constraints"); const auto Schedules = rcc::riscv::schedulingClasses(); const auto Encodings = rcc::riscv::encodingCategories(); const auto Formats = rcc::riscv::assemblyFormats(); - Context.expect(Schedules.size() == 15 && Encodings.size() == 10 && Formats.size() == 34 && - rcc::riscv::assemblyInstructions().size() == 195 && FenceAssembly != nullptr && + Context.expect(Schedules.size() == 15 && Encodings.size() == 10 && Formats.size() == 35 && + rcc::riscv::assemblyInstructions().size() == 211 && FenceAssembly != nullptr && FenceAssembly->Mnemonic == "fence.i" && std::ranges::any_of(Schedules, [](const rcc::riscv::SchedulingClassInfo &Class) { |
