From b1c08d57f1637f5ee813d1409dacdfa88c1509a0 Mon Sep 17 00:00:00 2001 From: Richard-Qin-X Date: Fri, 28 Aug 2026 19:15:07 +0800 Subject: [RISCV] Generate complete Zcmp instruction definitions --- backend/lib/Target/RISCV/RISCVMCCodeEmitter.cpp | 71 ++++++++++++++++++++----- 1 file changed, 57 insertions(+), 14 deletions(-) (limited to 'backend/lib/Target/RISCV/RISCVMCCodeEmitter.cpp') diff --git a/backend/lib/Target/RISCV/RISCVMCCodeEmitter.cpp b/backend/lib/Target/RISCV/RISCVMCCodeEmitter.cpp index 339d817..48de3e4 100644 --- a/backend/lib/Target/RISCV/RISCVMCCodeEmitter.cpp +++ b/backend/lib/Target/RISCV/RISCVMCCodeEmitter.cpp @@ -102,6 +102,23 @@ namespace { "Zcmp move requires an s0-s7 register"); } +[[nodiscard]] Expected encodeZcmpMove(const mc::MCInst &Instruction, + const TargetDescription &Target, + const AssemblyInstructionInfo &Assembly) { + auto Count = requireOperandCount(Instruction, 2); + if (!Count) + return std::unexpected(Count.error()); + auto First = savedRegisterEncoding(Instruction, 0, Target); + auto Second = savedRegisterEncoding(Instruction, 1, Target); + if (!First) + return std::unexpected(First.error()); + if (!Second) + return std::unexpected(Second.error()); + const auto Encoding = static_cast(Assembly.Encoding); + return static_cast((Encoding & ~std::uint16_t{0x039c}) | *First << 7U | + *Second << 2U); +} + [[nodiscard]] bool fitsSigned(std::int64_t Value, unsigned Bits) noexcept { const std::int64_t Minimum = -(std::int64_t{1} << (Bits - 1U)); const std::int64_t Maximum = (std::int64_t{1} << (Bits - 1U)) - 1; @@ -190,6 +207,32 @@ namespace { return 0; } +[[nodiscard]] Expected encodeZcmpStack(const mc::MCInst &Instruction, + const AssemblyInstructionInfo &Assembly, + mc::MCEncodedInstruction &Result) { + auto Count = requireOperandCount(Instruction, 2); + if (!Count) + return std::unexpected(Count.error()); + auto RegisterList = immediateOrFixup(Instruction, 0, mc::fixup_kind::None, false, Result); + auto StackAdjustment = immediateOrFixup(Instruction, 1, mc::fixup_kind::None, false, Result); + if (!RegisterList) + return std::unexpected(RegisterList.error()); + if (!StackAdjustment) + return std::unexpected(StackAdjustment.error()); + if (*RegisterList < 4 || *RegisterList > 15) { + return makeUnexpected(ErrorCode::InstructionEncodingFailed, + "Zcmp register list encoding is out of range"); + } + if (*StackAdjustment < 0 || *StackAdjustment > 48 || *StackAdjustment % 16 != 0) { + return makeUnexpected(ErrorCode::InstructionEncodingFailed, + "Zcmp stack adjustment must be 0, 16, 32, or 48"); + } + const auto Encoding = static_cast(Assembly.Encoding); + return static_cast((Encoding & ~std::uint16_t{0x00fc}) | + static_cast(*RegisterList) << 4U | + static_cast(*StackAdjustment >> 4U) << 2U); +} + [[nodiscard]] Expected uFixupKind(const mc::MCOperand &Operand) { auto Kind = expressionTargetKind(Operand); if (!Kind) @@ -663,20 +706,6 @@ namespace { return immediateOrFixup(Instruction, Index, Kind, PCRelative, Result); }; - if (Opcode == InstructionOpcode::CM_MVA01S || Opcode == InstructionOpcode::CM_MVSA01) { - auto Count = requireOperandCount(Instruction, 2); - if (!Count) - return std::unexpected(Count.error()); - auto First = savedRegisterEncoding(Instruction, 0, Target); - auto Second = savedRegisterEncoding(Instruction, 1, Target); - if (!First) - return std::unexpected(First.error()); - if (!Second) - return std::unexpected(Second.error()); - return static_cast((Encoding & ~std::uint16_t{0x039c}) | *First << 7U | - *Second << 2U); - } - if (Opcode == InstructionOpcode::C_ADDI4SPN) { auto Count = requireOperandCount(Instruction, 2); if (!Count) @@ -1020,6 +1049,20 @@ RISCVMCCodeEmitter::encodeInstruction(const mc::MCInst &Instruction) const { appendLittleEndian(Result, *Compressed, 2); return Result; } + case EncodingCategory::ZCMP_MOVE: { + auto ZcmpMove = encodeZcmpMove(Instruction, *Target, *Assembly); + if (!ZcmpMove) + return std::unexpected(ZcmpMove.error()); + appendLittleEndian(Result, *ZcmpMove, 2); + return Result; + } + case EncodingCategory::ZCMP_STACK: { + auto ZcmpStack = encodeZcmpStack(Instruction, *Assembly, Result); + if (!ZcmpStack) + return std::unexpected(ZcmpStack.error()); + appendLittleEndian(Result, *ZcmpStack, 2); + return Result; + } case EncodingCategory::None: break; } -- cgit v1.2.3