aboutsummaryrefslogtreecommitdiff
path: root/backend/lib/Target/RISCV/RISCVInstPrinter.cpp
diff options
context:
space:
mode:
authorRichard-Qin-X <richard.qin.001@gmail.com>2026-08-28 19:15:07 +0800
committerRichard-Qin-X <richard.qin.001@gmail.com>2026-08-28 19:15:07 +0800
commitb1c08d57f1637f5ee813d1409dacdfa88c1509a0 (patch)
treed1c8d3f9ba3da70628e356dcd97f878ea7124b62 /backend/lib/Target/RISCV/RISCVInstPrinter.cpp
parentf89d528efc0228c049c2867dcba886a56bac8619 (diff)
downloadrcc-project-b1c08d57f1637f5ee813d1409dacdfa88c1509a0.tar.gz
rcc-project-b1c08d57f1637f5ee813d1409dacdfa88c1509a0.tar.xz
[RISCV] Generate complete Zcmp instruction definitions
Diffstat (limited to 'backend/lib/Target/RISCV/RISCVInstPrinter.cpp')
-rw-r--r--backend/lib/Target/RISCV/RISCVInstPrinter.cpp51
1 files changed, 51 insertions, 0 deletions
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<std::string> 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<std::string> 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<std::string> RISCVInstPrinter::printInstruction(const mc::MCInst &Instruction) const {
@@ -254,6 +294,17 @@ Expected<std::string> 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 '" +