[clang] [llvm] Added the MIPS prefetch extensions for MIPS RV64 P8700. (PR #145647)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 25 06:46:29 PDT 2025
https://github.com/ukalappa-mips updated https://github.com/llvm/llvm-project/pull/145647
>From 8a1f98820b280b02f0662c7129a078680d67497f Mon Sep 17 00:00:00 2001
From: Umesh Kalappa <ukalappa.mips at gmail.com>
Date: Wed, 25 Jun 2025 06:58:37 +0000
Subject: [PATCH 1/2] Added prefetch extensions for MIPS RV64 P8700 and enable
with xmipscbop option.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Please refer "MIPS RV64 P8700/P8700-F Multiprocessing System Programmer’s Guide" for more info on the extension
at https://mips.com/wp-content/uploads/2025/06/P8700_Programmers_Reference_Manual_Rev1.84_5-31-2025.pdf
---
.../Driver/print-supported-extensions-riscv.c | 1 +
llvm/docs/RISCVUsage.rst | 3 ++
.../Target/RISCV/AsmParser/RISCVAsmParser.cpp | 5 ++
.../RISCV/Disassembler/RISCVDisassembler.cpp | 18 +++++++
.../Target/RISCV/MCTargetDesc/RISCVBaseInfo.h | 1 +
llvm/lib/Target/RISCV/RISCVFeatures.td | 7 +++
llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | 48 +++++++++++++++++++
llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h | 4 ++
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 2 +-
llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 3 ++
llvm/lib/Target/RISCV/RISCVInstrInfoXMips.td | 38 +++++++++++++++
llvm/lib/Target/RISCV/RISCVInstrInfoZicbo.td | 4 +-
llvm/test/CodeGen/RISCV/features-info.ll | 1 +
llvm/test/CodeGen/RISCV/xmips-cbop.ll | 40 ++++++++++++++++
llvm/test/MC/RISCV/xmips-invalid.s | 11 ++++-
llvm/test/MC/RISCV/xmips-valid.s | 18 +++++--
.../TargetParser/RISCVISAInfoTest.cpp | 1 +
17 files changed, 198 insertions(+), 7 deletions(-)
create mode 100644 llvm/test/CodeGen/RISCV/xmips-cbop.ll
diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c
index 5008c2b7f789d..204e6860b6d67 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -169,6 +169,7 @@
// CHECK-NEXT: xcvmac 1.0 'XCVmac' (CORE-V Multiply-Accumulate)
// CHECK-NEXT: xcvmem 1.0 'XCVmem' (CORE-V Post-incrementing Load & Store)
// CHECK-NEXT: xcvsimd 1.0 'XCVsimd' (CORE-V SIMD ALU)
+// CHECK-NEXT: xmipscbop 1.0 'XMIPSCBOP' (MIPS Software Prefetch)
// CHECK-NEXT: xmipscmov 1.0 'XMIPSCMov' (MIPS conditional move instruction (mips.ccmov))
// CHECK-NEXT: xmipslsp 1.0 'XMIPSLSP' (MIPS optimization for hardware load-store bonding)
// CHECK-NEXT: xsfcease 1.0 'XSfcease' (SiFive sf.cease Instruction)
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 81684ba30f12c..82114791b3c0c 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -498,6 +498,9 @@ The current vendor extensions supported are:
``experimental-Xqcisync``
LLVM implements `version 0.3 of the Qualcomm uC Sync Delay extension specification <https://github.com/quic/riscv-unified-db/releases/tag/Xqci-0.13.0>`__ by Qualcomm. These instructions are only available for riscv32.
+``Xmipscbop``
+ LLVM implements MIPS prefetch extension `p8700 processor <https://mips.com/products/hardware/p8700/>`__ by MIPS.
+
``Xmipscmov``
LLVM implements conditional move for the `p8700 processor <https://mips.com/products/hardware/p8700/>`__ by MIPS.
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index e5d8ab07891ac..edb319e460e35 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -732,6 +732,7 @@ struct RISCVOperand final : public MCParsedAsmOperand {
bool isUImm6() const { return isUImm<6>(); }
bool isUImm7() const { return isUImm<7>(); }
bool isUImm8() const { return isUImm<8>(); }
+ bool isUImm9() const { return isUImm<9>(); }
bool isUImm10() const { return isUImm<10>(); }
bool isUImm11() const { return isUImm<11>(); }
bool isUImm16() const { return isUImm<16>(); }
@@ -1523,6 +1524,10 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 8) - 8,
"immediate must be a multiple of 8 bytes in the range");
+ case Match_InvalidUImm9:
+ return generateImmOutOfRangeError(
+ Operands, ErrorInfo, 0, (1 << 9) - 1,
+ "immediate must be a multiple of 9 bytes in the range");
case Match_InvalidBareSImm9Lsb0:
return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2,
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index 27e04c0cb1f8b..043aaec11e8c5 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -535,6 +535,19 @@ static DecodeStatus decodeRTZArg(MCInst &Inst, uint32_t Imm, int64_t Address,
Inst.addOperand(MCOperand::createImm(Imm));
return MCDisassembler::Success;
}
+template <int Bits>
+static DecodeStatus DecodeSImm(MCInst &Inst, uint64_t Imm, uint64_t Address,
+ const MCDisassembler *Decoder) {
+ if (Imm & ~((1LL << Bits) - 1))
+ return MCDisassembler::Fail;
+
+ // Imm is a signed immediate, so sign extend it.
+ if (Imm & (1 << (Bits - 1)))
+ Imm |= ~((1LL << Bits) - 1);
+
+ Inst.addOperand(MCOperand::createImm(Imm));
+ return MCDisassembler::Success;
+}
static DecodeStatus decodeRVCInstrRdRs1ImmZero(MCInst &Inst, uint32_t Insn,
uint64_t Address,
@@ -576,6 +589,9 @@ static DecodeStatus decodeXqccmpRlistS0(MCInst &Inst, uint32_t Imm,
static DecodeStatus decodeCSSPushPopchk(MCInst &Inst, uint32_t Insn,
uint64_t Address,
const MCDisassembler *Decoder);
+template <int Bits>
+static DecodeStatus DecodeSImm(MCInst &Inst, uint64_t Imm, uint64_t Address,
+ const MCDisassembler *Decoder);
#include "RISCVGenDisassemblerTables.inc"
@@ -790,6 +806,8 @@ static constexpr DecoderListEntry DecoderList32[]{
{DecoderTableXmipscmov32,
{RISCV::FeatureVendorXMIPSCMov},
"MIPS mips.ccmov"},
+ {DecoderTableXmipscbop32, {RISCV::FeatureVendorXMIPSCBOP},
+ "MIPS mips.pref"},
{DecoderTableXAndes32, XAndesGroup, "Andes extensions"},
// Standard Extensions
{DecoderTableXCV32, XCVFeatureGroup, "CORE-V extensions"},
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index 3d304842fac13..55ce315879439 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -316,6 +316,7 @@ enum OperandType : unsigned {
OPERAND_UIMM8_LSB000,
OPERAND_UIMM8_GE32,
OPERAND_UIMM9_LSB000,
+ OPERAND_UIMM9,
OPERAND_UIMM10,
OPERAND_UIMM10_LSB00_NONZERO,
OPERAND_UIMM11,
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 36b3aff51cda9..022def899e9e5 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1411,6 +1411,13 @@ def HasVendorXMIPSLSP
: Predicate<"Subtarget->hasVendorXMIPSLSP()">,
AssemblerPredicate<(all_of FeatureVendorXMIPSLSP),
"'Xmipslsp' (load and store pair instructions)">;
+def FeatureVendorXMIPSCBOP
+ : RISCVExtension<1, 0, "MIPS Software Prefetch">;
+def HasVendorXMIPSCBOP
+ : Predicate<"Subtarget->hasVendorXMIPSCBOP()">,
+ AssemblerPredicate<(all_of FeatureVendorXMIPSCBOP),
+ "'Xmipscbop' (MIPS hardware prefetch)">;
+def NotHasVendorXMIPSCBOP : Predicate<"!Subtarget->hasVendorXMIPSCBOP()">;
// WCH / Nanjing Qinheng Microelectronics Extension(s)
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index 4539efd591c8b..3036b32f706f2 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -2925,6 +2925,54 @@ bool RISCVDAGToDAGISel::SelectAddrRegImm(SDValue Addr, SDValue &Base,
return true;
}
+/// Similar to SelectAddrRegImm, except that the offset restricted for
+/// nine bits.
+bool RISCVDAGToDAGISel::SelectAddrRegImm9(SDValue Addr, SDValue &Base,
+ SDValue &Offset) {
+ if (SelectAddrFrameIndex(Addr, Base, Offset))
+ return true;
+
+ SDLoc DL(Addr);
+ MVT VT = Addr.getSimpleValueType();
+
+ if (CurDAG->isBaseWithConstantOffset(Addr)) {
+
+ int64_t CVal = cast<ConstantSDNode>(Addr.getOperand(1))->getSExtValue();
+ if (isUInt<9>(CVal)) {
+ Base = Addr.getOperand(0);
+
+ if (auto *FIN = dyn_cast<FrameIndexSDNode>(Base))
+ Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), VT);
+ Offset = CurDAG->getSignedTargetConstant(CVal, DL, VT);
+ return true;
+ }
+
+ // Handle with 12 bit ofset immediates with ADDI.
+ else if (Addr.getOpcode() == ISD::ADD &&
+ isa<ConstantSDNode>(Addr.getOperand(1))) {
+ int64_t CVal = cast<ConstantSDNode>(Addr.getOperand(1))->getSExtValue();
+ assert(!isUInt<9>(CVal) && "uimm9 not already handled?");
+
+ if (isUInt<12>(CVal)) {
+ Base = SDValue(CurDAG->getMachineNode(
+ RISCV::ADDI, DL, VT, Addr.getOperand(0),
+ CurDAG->getSignedTargetConstant(CVal, DL, VT)),
+ 0);
+ Offset = CurDAG->getTargetConstant(0, DL, VT);
+ return true;
+ }
+ }
+ }
+ // Immediates more than 12 bits i.e LUI,ADDI,ADD
+ if (selectConstantAddr(CurDAG, DL, VT, Subtarget, Addr, Base, Offset,
+ /*IsPrefetch=*/true))
+ return true;
+
+ Base = Addr;
+ Offset = CurDAG->getTargetConstant(0, DL, VT);
+ return true;
+}
+
/// Similar to SelectAddrRegImm, except that the least significant 5 bits of
/// Offset should be all zeros.
bool RISCVDAGToDAGISel::SelectAddrRegImmLsb00000(SDValue Addr, SDValue &Base,
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
index cb63c21fd8fc9..bd28d51b4caef 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
@@ -45,8 +45,12 @@ class RISCVDAGToDAGISel : public SelectionDAGISel {
InlineAsm::ConstraintCode ConstraintID,
std::vector<SDValue> &OutOps) override;
+ bool SelectAddrFrameIndexOffset(SDValue Addr, SDValue &Base, SDValue &Offset,
+ unsigned OffsetBits,
+ unsigned ShiftAmount);
bool SelectAddrFrameIndex(SDValue Addr, SDValue &Base, SDValue &Offset);
bool SelectAddrRegImm(SDValue Addr, SDValue &Base, SDValue &Offset);
+ bool SelectAddrRegImm9(SDValue Addr, SDValue &Base, SDValue &Offset);
bool SelectAddrRegImmLsb00000(SDValue Addr, SDValue &Base, SDValue &Offset);
bool SelectAddrRegRegScale(SDValue Addr, unsigned MaxShiftAmount,
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 712f6154732a2..2b4fa9ec3760f 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -682,7 +682,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
if (Subtarget.is64Bit())
setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i32, Custom);
- if (Subtarget.hasStdExtZicbop()) {
+ if (Subtarget.hasStdExtZicbop() || Subtarget.hasVendorXMIPSCBOP()) {
setOperationAction(ISD::PREFETCH, MVT::Other, Legal);
}
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index 5711f0077b12d..d29e9c020e79f 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -2742,6 +2742,9 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI,
case RISCVOp::OPERAND_UIMM9_LSB000:
Ok = isShiftedUInt<6, 3>(Imm);
break;
+ case RISCVOp::OPERAND_UIMM9:
+ Ok = isUInt<9>(Imm);
+ break;
case RISCVOp::OPERAND_SIMM10_LSB0000_NONZERO:
Ok = isShiftedInt<6, 4>(Imm) && (Imm != 0);
break;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXMips.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXMips.td
index ff751994b89b9..3dcefee9404b4 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXMips.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXMips.td
@@ -29,6 +29,12 @@ def uimm7_lsb000 : RISCVOp,
}];
}
+// A 9-bit unsigned offset
+def uimm9 : RISCVUImmOp<9>;
+
+// Custom prefetch ADDR selector
+def AddrRegImm9 : ComplexPattern<iPTR, 2, "SelectAddrRegImm9">;
+
//===----------------------------------------------------------------------===//
// MIPS custom instruction formats
//===----------------------------------------------------------------------===//
@@ -103,9 +109,41 @@ class SWPFormat<dag outs, dag ins, string opcodestr, string argstr>
let Inst{6-0} = OPC_CUSTOM_0.Value;
}
+// Prefetch format.
+let hasSideEffects = 0, mayLoad = 1,mayStore = 1 in
+class Mips_prefetch_ri<dag outs, dag ins, string opcodestr, string argstr>
+ : RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> {
+ bits<9> imm9;
+ bits<5> rs1;
+ bits<5> hint;
+
+ let Inst{31 - 29} = 0b000;
+ let Inst{28 - 20} = imm9{8 - 0};
+ let Inst{19 - 15} = rs1;
+ let Inst{14 - 12} = 0b000;
+ let Inst{11 - 7} = hint;
+ let Inst{6 - 0} = OPC_CUSTOM_0.Value;
+}
+
//===----------------------------------------------------------------------===//
// MIPS extensions
//===----------------------------------------------------------------------===//
+let Predicates = [HasVendorXMIPSCBOP] ,DecoderNamespace = "Xmipscbop" in {
+ def MIPSPREFETCH : Mips_prefetch_ri<(outs),(ins GPR:$rs1, uimm9:$imm9, uimm5:$hint),
+ "mips.perf", "$hint, ${imm9}(${rs1})">,
+ Sched<[]>;
+}
+
+let Predicates = [HasVendorXMIPSCBOP] in {
+ // Prefetch Data Write.
+ def : Pat<(prefetch(AddrRegImm9(XLenVT GPR:$rs1),uimm9:$imm9),
+ (i32 1), timm, (i32 1)),
+ (MIPSPREFETCH GPR:$rs1, uimm9:$imm9, 9)>;
+ // Prefetch Data Read.
+ def : Pat<(prefetch(AddrRegImm9(XLenVT GPR:$rs1),uimm9:$imm9),
+ (i32 0), timm, (i32 1)),
+ (MIPSPREFETCH GPR:$rs1, uimm9:$imm9, 8)>;
+}
let Predicates = [HasVendorXMIPSCMov], hasSideEffects = 0, mayLoad = 0, mayStore = 0,
DecoderNamespace = "Xmipscmov" in {
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZicbo.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZicbo.td
index e44bdcb4e2f0f..878b85b141578 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoZicbo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZicbo.td
@@ -57,7 +57,7 @@ let Predicates = [HasStdExtZicboz] in {
def CBO_ZERO : CBO_r<0b000000000100, "cbo.zero">, Sched<[]>;
} // Predicates = [HasStdExtZicboz]
-let Predicates = [HasStdExtZicbop] in {
+let Predicates = [HasStdExtZicbop, NotHasVendorXMIPSCBOP] in {
def PREFETCH_I : Prefetch_ri<0b00000, "prefetch.i">, Sched<[]>;
def PREFETCH_R : Prefetch_ri<0b00001, "prefetch.r">, Sched<[]>;
def PREFETCH_W : Prefetch_ri<0b00011, "prefetch.w">, Sched<[]>;
@@ -69,7 +69,7 @@ def PREFETCH_W : Prefetch_ri<0b00011, "prefetch.w">, Sched<[]>;
def AddrRegImmLsb00000 : ComplexPattern<iPTR, 2, "SelectAddrRegImmLsb00000">;
-let Predicates = [HasStdExtZicbop] in {
+let Predicates = [HasStdExtZicbop, NotHasVendorXMIPSCBOP] in {
def : Pat<(prefetch (AddrRegImmLsb00000 (XLenVT GPR:$rs1), simm12_lsb00000:$imm12),
timm, timm, (i32 0)),
(PREFETCH_I GPR:$rs1, simm12_lsb00000:$imm12)>;
diff --git a/llvm/test/CodeGen/RISCV/features-info.ll b/llvm/test/CodeGen/RISCV/features-info.ll
index 8b931f70aa5cc..64e719ed8de41 100644
--- a/llvm/test/CodeGen/RISCV/features-info.ll
+++ b/llvm/test/CodeGen/RISCV/features-info.ll
@@ -184,6 +184,7 @@
; CHECK-NEXT: xcvmac - 'XCVmac' (CORE-V Multiply-Accumulate).
; CHECK-NEXT: xcvmem - 'XCVmem' (CORE-V Post-incrementing Load & Store).
; CHECK-NEXT: xcvsimd - 'XCVsimd' (CORE-V SIMD ALU).
+; CHECK-NEXT: xmipscbop - 'XMIPSCBOP' (MIPS Software Prefetch).
; CHECK-NEXT: xmipscmov - 'XMIPSCMov' (MIPS conditional move instruction (mips.ccmov)).
; CHECK-NEXT: xmipslsp - 'XMIPSLSP' (MIPS optimization for hardware load-store bonding).
; CHECK-NEXT: xsfcease - 'XSfcease' (SiFive sf.cease Instruction).
diff --git a/llvm/test/CodeGen/RISCV/xmips-cbop.ll b/llvm/test/CodeGen/RISCV/xmips-cbop.ll
new file mode 100644
index 0000000000000..ba95fc9082fa4
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/xmips-cbop.ll
@@ -0,0 +1,40 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=riscv32 -mattr=+xmipscbop -mattr=+m -verify-machineinstrs < %s \
+; RUN: | FileCheck %s -check-prefix=RV32XMIPSPREFETCH
+; RUN: llc -mtriple=riscv64 -mattr=+xmipscbop -mattr=+m -verify-machineinstrs < %s \
+; RUN: | FileCheck %s -check-prefix=RV64XMIPSPREFETCH
+
+define dso_local void @prefetch_read(ptr noundef %a) {
+; RV32XMIPSPREFETCH-LABEL: prefetch_read:
+; RV32XMIPSPREFETCH: mips.perf 8, 511(a0)
+;
+; RV64XMIPSPREFETCH-LABEL: prefetch_read:
+; RV64XMIPSPREFETCH: mips.perf 8, 511(a0)
+entry:
+ %a.addr = alloca ptr, align 8
+ store ptr %a, ptr %a.addr, align 8
+ %0 = load ptr, ptr %a.addr, align 8
+ %arrayidx = getelementptr inbounds i8, ptr %0, i64 511
+ call void @llvm.prefetch.p0(ptr %arrayidx, i32 0, i32 0, i32 1)
+ ret void
+}
+
+declare void @llvm.prefetch.p0(ptr readonly captures(none), i32 immarg, i32 immarg, i32 immarg)
+
+define dso_local void @prefetch_write(ptr noundef %a) {
+entry:
+; RV32XMIPSPREFETCH-LABEL: prefetch_write:
+; RV32XMIPSPREFETCH: addi a1, a0, 512
+; RV32XMIPSPREFETCH-NEXT: mips.perf 9, 0(a1)
+;
+; RV64XMIPSPREFETCH-LABEL: prefetch_write:
+; RV64XMIPSPREFETCH: addi a1, a0, 512
+; RV64XMIPSPREFETCH-NEXT: mips.perf 9, 0(a1)
+ %a.addr = alloca ptr, align 8
+ store ptr %a, ptr %a.addr, align 8
+ %0 = load ptr, ptr %a.addr, align 8
+ %arrayidx = getelementptr inbounds i8, ptr %0, i64 512
+ call void @llvm.prefetch.p0(ptr %arrayidx, i32 1, i32 0, i32 1)
+ ret void
+}
+
diff --git a/llvm/test/MC/RISCV/xmips-invalid.s b/llvm/test/MC/RISCV/xmips-invalid.s
index b3834e7b3407f..fc7febf115f36 100644
--- a/llvm/test/MC/RISCV/xmips-invalid.s
+++ b/llvm/test/MC/RISCV/xmips-invalid.s
@@ -1,5 +1,14 @@
# RUN: not llvm-mc -triple=riscv64 < %s 2>&1 | FileCheck %s -check-prefixes=CHECK-FEATURE
-# RUN: not llvm-mc -triple=riscv64 -mattr=+xmipslsp,+xmipscmov < %s 2>&1 | FileCheck %s
+# RUN: not llvm-mc -triple=riscv64 -mattr=+xmipslsp,+xmipscmov,+xmipsbcop < %s 2>&1 | FileCheck %s
+
+mips.perf 8, 512(a0)
+# CHECK: error: invalid operand for instruction
+
+mips.perf 8
+# CHECK: error: too few operands for instruction
+
+mips.perf 8, 511(a0)
+# CHECK-FEATURE: error: instruction requires the following: 'Xmipscbop' (MIPS hardware prefetch)
mips.ccmov x0, x1, 0x10
# CHECK: error: invalid operand for instruction
diff --git a/llvm/test/MC/RISCV/xmips-valid.s b/llvm/test/MC/RISCV/xmips-valid.s
index 9f31e4fa2038c..5ced037752cab 100644
--- a/llvm/test/MC/RISCV/xmips-valid.s
+++ b/llvm/test/MC/RISCV/xmips-valid.s
@@ -1,9 +1,21 @@
-# RUN: llvm-mc %s -triple=riscv64 -mattr=+xmipslsp,+xmipscmov -M no-aliases -show-encoding \
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+xmipslsp,+xmipscmov,+xmipscbop -M no-aliases -show-encoding \
# RUN: | FileCheck -check-prefixes=CHECK-INST,CHECK-ENC %s
-# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+xmipslsp,+xmipscmov < %s \
-# RUN: | llvm-objdump --mattr=+xmipslsp,+xmipscmov -M no-aliases -d - \
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+xmipslsp,+xmipscmov,+xmipscbop < %s \
+# RUN: | llvm-objdump --mattr=+xmipslsp,+xmipscmov,+xmipscbop -M no-aliases -d - \
# RUN: | FileCheck -check-prefix=CHECK-DIS %s
+# CHECK-INST: mips.perf 8, 511(a0)
+# CHECK-ENC: encoding: [0x0b,0x04,0xf5,0x1f]
+mips.perf 8, 511(a0)
+
+# CHECK-DIS: mips.perf 0x8, 0x1ff(a0)
+
+# CHECK-INST: mips.perf 9, 0(a0)
+# CHECK-ENC: encoding: [0x8b,0x04,0x05,0x00]
+mips.perf 9, 0(a0)
+
+# CHECK-DIS: mips.perf 0x9, 0x0(a0)
+
# CHECK-INST: mips.ccmov s0, s1, s2, s3
# CHECK-ENC: encoding: [0x0b,0x34,0x99,0x9e]
mips.ccmov s0, s1, s2, s3
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index 66e335a33a3f7..b1b4a910650a9 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -1142,6 +1142,7 @@ R"(All available -march extensions for RISC-V
xcvsimd 1.0
xmipscmov 1.0
xmipslsp 1.0
+ xmipscbop 1.0
xsfcease 1.0
xsfmm128t 0.6
xsfmm16t 0.6
>From f14dc2030e560b10f7986ccdcfbd7ca887f8080b Mon Sep 17 00:00:00 2001
From: Umesh Kalappa <ukalappa.mips at gmail.com>
Date: Wed, 25 Jun 2025 13:41:11 +0000
Subject: [PATCH 2/2] Updated mcpu for mips-p8700 and related testcase for
xmipscbop extension.
---
clang/test/Driver/riscv-cpus.c | 11 +++--------
llvm/lib/Target/RISCV/RISCVProcessors.td | 21 +++------------------
2 files changed, 6 insertions(+), 26 deletions(-)
diff --git a/clang/test/Driver/riscv-cpus.c b/clang/test/Driver/riscv-cpus.c
index 3736e76ed06dd..88552a9b306ed 100644
--- a/clang/test/Driver/riscv-cpus.c
+++ b/clang/test/Driver/riscv-cpus.c
@@ -186,6 +186,9 @@
// MCPU-MIPS-P8700-SAME: "-target-feature" "+zalrsc"
// MCPU-MIPS-P8700-SAME: "-target-feature" "+zba"
// MCPU-MIPS-P8700-SAME: "-target-feature" "+zbb"
+// MCPU-MIPS-P8700-SAME: "-target-feature" "+xmipscbop"
+// MCPU-MIPS-P8700-SAME: "-target-feature" "+xmipscmov"
+// MCPU-MIPS-P8700-SAME: "-target-feature" "+xmipslsp"
// RUN: %clang --target=riscv32 -### -c %s 2>&1 -mtune=syntacore-scr1-base | FileCheck -check-prefix=MTUNE-SYNTACORE-SCR1-BASE %s
// MTUNE-SYNTACORE-SCR1-BASE: "-tune-cpu" "syntacore-scr1-base"
@@ -751,11 +754,3 @@
// RUN: %clang --target=riscv64 -### -c %s 2>&1 -mtune=andes-ax45 | FileCheck -check-prefix=MTUNE-ANDES-AX45 %s
// MTUNE-ANDES-AX45: "-tune-cpu" "andes-ax45"
-
-// RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=andes-ax45mpv | FileCheck -check-prefix=MCPU-ANDES-AX45MPV %s
-// COM: The list of extensions are tested in `test/Driver/print-enabled-extensions/riscv-andes-ax45mpv.c`
-// MCPU-ANDES-AX45MPV: "-target-cpu" "andes-ax45mpv"
-// MCPU-ANDES-AX45MPV-SAME: "-target-abi" "lp64d"
-
-// RUN: %clang --target=riscv64 -### -c %s 2>&1 -mtune=andes-ax45mpv | FileCheck -check-prefix=MTUNE-ANDES-AX45MPV %s
-// MTUNE-ANDES-AX45MPV: "-tune-cpu" "andes-ax45mpv"
diff --git a/llvm/lib/Target/RISCV/RISCVProcessors.td b/llvm/lib/Target/RISCV/RISCVProcessors.td
index 57b415dc713ac..95e592c5b2429 100644
--- a/llvm/lib/Target/RISCV/RISCVProcessors.td
+++ b/llvm/lib/Target/RISCV/RISCVProcessors.td
@@ -120,7 +120,8 @@ def MIPS_P8700 : RISCVProcessorModel<"mips-p8700",
FeatureStdExtZifencei,
FeatureStdExtZicsr,
FeatureVendorXMIPSCMov,
- FeatureVendorXMIPSLSP],
+ FeatureVendorXMIPSLSP,
+ FeatureVendorXMIPSCBOP],
[TuneMIPSP8700]>;
def ROCKET_RV32 : RISCVProcessorModel<"rocket-rv32",
@@ -292,8 +293,7 @@ def SIFIVE_X280 : RISCVProcessorModel<"sifive-x280", SiFive7Model,
FeatureStdExtZbb],
SiFiveIntelligenceTuneFeatures>;
-def SIFIVE_X390 : RISCVProcessorModel<"sifive-x390",
- SiFiveX390Model,
+def SIFIVE_X390 : RISCVProcessorModel<"sifive-x390", NoSchedModel,
[Feature64Bit,
FeatureStdExtI,
FeatureStdExtM,
@@ -782,18 +782,3 @@ def ANDES_AX45 : RISCVProcessorModel<"andes-ax45",
FeatureStdExtC,
FeatureVendorXAndesPerf],
Andes45TuneFeatures>;
-
-def ANDES_AX45MPV : RISCVProcessorModel<"andes-ax45mpv",
- Andes45Model,
- [Feature64Bit,
- FeatureStdExtI,
- FeatureStdExtZicsr,
- FeatureStdExtZifencei,
- FeatureStdExtM,
- FeatureStdExtA,
- FeatureStdExtF,
- FeatureStdExtD,
- FeatureStdExtC,
- FeatureStdExtV,
- FeatureVendorXAndesPerf],
- Andes45TuneFeatures>;
More information about the cfe-commits
mailing list