aboutsummaryrefslogtreecommitdiff
path: root/backend/lib/Target/RISCV/RISCVMCCodeEmitter.cpp
diff options
context:
space:
mode:
authorRichard-Qin-X <richard.qin.001@gmail.com>2026-08-25 01:43:04 +0800
committerRichard-Qin-X <richard.qin.001@gmail.com>2026-08-25 01:43:04 +0800
commit9e89d1d718977749ca798b27b7ad45e1781602c2 (patch)
treee4ab1a06bb0f742792474153071bad94ff279f06 /backend/lib/Target/RISCV/RISCVMCCodeEmitter.cpp
parentb8fb9248e77e492c630ca135d1bfd58b74f9752a (diff)
downloadrcc-project-9e89d1d718977749ca798b27b7ad45e1781602c2.tar.gz
rcc-project-9e89d1d718977749ca798b27b7ad45e1781602c2.tar.xz
[RISCV] Implement Zcmp move merging
Diffstat (limited to 'backend/lib/Target/RISCV/RISCVMCCodeEmitter.cpp')
-rw-r--r--backend/lib/Target/RISCV/RISCVMCCodeEmitter.cpp28
1 files changed, 28 insertions, 0 deletions
diff --git a/backend/lib/Target/RISCV/RISCVMCCodeEmitter.cpp b/backend/lib/Target/RISCV/RISCVMCCodeEmitter.cpp
index 15a0c2d..339d817 100644
--- a/backend/lib/Target/RISCV/RISCVMCCodeEmitter.cpp
+++ b/backend/lib/Target/RISCV/RISCVMCCodeEmitter.cpp
@@ -88,6 +88,20 @@ namespace {
return *Encoding - 8U;
}
+[[nodiscard]] Expected<std::uint32_t> savedRegisterEncoding(const mc::MCInst &Instruction,
+ std::size_t Index,
+ const TargetDescription &Target) {
+ auto Encoding = registerEncoding(Instruction, Index, Target);
+ if (!Encoding)
+ return std::unexpected(Encoding.error());
+ if (*Encoding == 8 || *Encoding == 9)
+ return *Encoding - 8U;
+ if (*Encoding >= 18 && *Encoding <= 23)
+ return *Encoding - 16U;
+ return makeUnexpected(ErrorCode::InstructionEncodingFailed,
+ "Zcmp move requires an s0-s7 register");
+}
+
[[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;
@@ -649,6 +663,20 @@ 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<std::uint16_t>((Encoding & ~std::uint16_t{0x039c}) | *First << 7U |
+ *Second << 2U);
+ }
+
if (Opcode == InstructionOpcode::C_ADDI4SPN) {
auto Count = requireOperandCount(Instruction, 2);
if (!Count)