diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td index a539e11b95006..a56b6aa2e38a4 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td @@ -563,7 +563,7 @@ def C_JR : RVInst16CR<0b1000, 0b10, (outs), (ins GPRNoX0:$rs1), } let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isMoveReg = 1, - isAsCheapAsAMove = 1 in + isAsCheapAsAMove = 1, Predicates = [HasStdExtCOrZca, NotCapMode] in def C_MV : RVInst16CR<0b1000, 0b10, (outs GPRNoX0:$rs1), (ins GPRNoX0:$rs2), "c.mv", "$rs1, $rs2">, Sched<[WriteIALU, ReadIALU]>; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td index 8b0bfd05d2778..0c6fe5abe6f71 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td @@ -1131,6 +1131,12 @@ def C_CSDCSP : CCheriStackStore<0b111, "c.sdsp", GPR, uimm9_lsb000> { } } // Predicates = [HasCheri, HasCheriRVC, HasStdExtC, IsCapMode] +let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isMoveReg = 1, + isAsCheapAsAMove = 1, + Predicates = [HasCheri, HasCheriRVC, HasStdExtCOrZca, IsCapMode] in +def C_CMove : RVInst16CR<0b1000, 0b10, (outs GPCRNoC0:$rs1), (ins GPCRNoC0:$rs2), + "c.cmove", "$rs1, $rs2">, + Sched<[WriteIALU, ReadIALU]>; } // DecoderNamespace = "CapModeOnly_" let Predicates = [HasCheri, HasCheriRVC, HasStdExtC, IsCapMode] in { @@ -1173,6 +1179,11 @@ def : InstAlias<"c.cfsdcsp $rs2, ${imm}(${rs1})", (C_CFSDCSP FPR64:$rs2, CSP:$rs def : InstAlias<"c.cj $offset", (C_J simm12_lsb0:$offset), 0>; } +let Predicates = [HasCheri, HasCheriRVC, HasStdExtCOrZca, IsCapMode] in { +def : CompressPat<(CMove GPCRNoC0:$cs1, GPCRNoC0:$cs2), + (C_CMove GPCRNoC0:$cs1, GPCRNoC0:$cs2)>; +} + //===----------------------------------------------------------------------===// // Pseudo-instructions and codegen patterns //===----------------------------------------------------------------------===// diff --git a/llvm/test/MC/RISCV/cheri/compressed-move.s b/llvm/test/MC/RISCV/cheri/compressed-move.s new file mode 100644 index 0000000000000..8eb62b29649e4 --- /dev/null +++ b/llvm/test/MC/RISCV/cheri/compressed-move.s @@ -0,0 +1,24 @@ +## Check that we don't compress addi 0 to c.mv (which is c.cmove for the RISC-V standard capmode) +# RUN: llvm-mc %s -triple=riscv64 -mattr=+c,+xcheri,-cap-mode -riscv-no-aliases \ +# RUN: -show-encoding --defsym=PURECAP=0 | FileCheck %s --check-prefix=INT-MODE +# RUN: llvm-mc %s -triple=riscv64 -mattr=+c,+xcheri,+cap-mode -riscv-no-aliases \ +# RUN: -show-encoding --defsym=PURECAP=1 | FileCheck %s --check-prefix=CAP-MODE + +# TODO-ISAV9-CAPMODE: c.mv a1, a0 # encoding: [0xaa,0x85] +# TODO-ISAV9-INTMODE: c.mv a1, a0 # encoding: [0xaa,0x85] +# CAP-MODE: addi a1, a0, 0 # encoding: [0x93,0x05,0x05,0x00] +# INT-MODE: c.mv a1, a0 # encoding: [0xaa,0x85] +## Should not be compressed to c.cmove for capability mode (only in integer mode). +addi a1, a0, 0 + +# CMove should be compressed for capmode. +# TODO-ISAV9-CAPMODE: cmove ca1, ca0 # encoding: [0xdb,0x05,0xa5,0xfe] +# TODO-ISAV9-INTMODE: cmove ca1, ca0 # encoding: [0xdb,0x05,0xa5,0xfe] +# INT-MODE: cmove ca1, ca0 # encoding: [0xdb,0x05,0xa5,0xfe] +# CAP-MODE: c.cmove ca1, ca0 # encoding: [0xaa,0x85] +cmove ca1, ca0 + +.if PURECAP +# CAP-MODE: c.cmove ca2, ca0 # encoding: [0x2a,0x86] +c.cmove ca2, ca0 +.endif