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/RISCVInstPrinter.cpp | 51 +++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'backend/lib/Target/RISCV/RISCVInstPrinter.cpp') diff --git a/backend/lib/Target/RISCV/RISCVInstPrinter.cpp b/backend/lib/Target/RISCV/RISCVInstPrinter.cpp index 723628f..b66d909 100644 --- a/backend/lib/Target/RISCV/RISCVInstPrinter.cpp +++ b/backend/lib/Target/RISCV/RISCVInstPrinter.cpp @@ -165,6 +165,46 @@ constexpr std::array LinearFormats{ return Result; } +[[nodiscard]] Expected formatZcmpRegisterList(const mc::MCOperand &Operand) { + const std::int64_t *Encoding = Operand.immediateValue(); + if (Encoding == nullptr || *Encoding < 4 || *Encoding > 15) { + return makeUnexpected(ErrorCode::AssemblyLoweringFailed, + "Zcmp register list encoding is out of range"); + } + std::string Result = "{ra"; + if (*Encoding > 4) { + Result += ", s0"; + if (*Encoding == 15) + Result += "-s11"; + else if (*Encoding > 5) + Result += "-s" + std::to_string(*Encoding - 5); + } + Result += "}"; + return Result; +} + +[[nodiscard]] Expected formatZcmpStackAdjustment(const mc::MCInst &Instruction, + bool Negate) { + if (Instruction.operands().size() != 2) { + return makeUnexpected(ErrorCode::AssemblyLoweringFailed, + "Zcmp stack instruction requires two operands"); + } + const std::int64_t *RegisterList = Instruction.operands()[0].immediateValue(); + const std::int64_t *ExtraAdjustment = Instruction.operands()[1].immediateValue(); + if (RegisterList == nullptr || ExtraAdjustment == nullptr || *RegisterList < 4 || + *RegisterList > 15 || *ExtraAdjustment < 0 || *ExtraAdjustment > 48 || + *ExtraAdjustment % 16 != 0) { + return makeUnexpected(ErrorCode::AssemblyLoweringFailed, + "Zcmp stack instruction has invalid encoded operands"); + } + std::int64_t RegisterCount = *RegisterList - 3; + if (*RegisterList == 15) + ++RegisterCount; + const std::int64_t BaseAdjustment = ((RegisterCount * 8 + 15) / 16) * 16; + const std::int64_t Adjustment = BaseAdjustment + *ExtraAdjustment; + return std::to_string(Negate ? -Adjustment : Adjustment); +} + } // namespace Expected RISCVInstPrinter::printInstruction(const mc::MCInst &Instruction) const { @@ -254,6 +294,17 @@ Expected RISCVInstPrinter::printInstruction(const mc::MCInst &Instr if (!Offset) return std::unexpected(Offset.error()); Operands = *First + ", " + *Offset + "(sp)"; + } else if (Format->Name == "rlist-stackadj") { + auto Count = requireOperandCount(Instruction, 2); + if (!Count) + return std::unexpected(Count.error()); + auto RegisterList = formatZcmpRegisterList(Instruction.operands()[0]); + if (!RegisterList) + return std::unexpected(RegisterList.error()); + auto StackAdjustment = formatZcmpStackAdjustment(Instruction, Assembly->Mnemonic == "cm.push"); + if (!StackAdjustment) + return std::unexpected(StackAdjustment.error()); + Operands = *RegisterList + ", " + *StackAdjustment; } else { return makeUnexpected(ErrorCode::AssemblyLoweringFailed, "RISC-V assembly printer does not support generated format '" + -- cgit v1.2.3