Skip to content

Commit 032966f

Browse files
[RISCV] Added the MIPS prefetch extensions for MIPS RV64 P8700. (#145647)
the extension enabled with xmipscbop. 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
1 parent bd6cd92 commit 032966f

19 files changed

+188
-10
lines changed

clang/test/Driver/print-supported-extensions-riscv.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@
169169
// CHECK-NEXT: xcvmac 1.0 'XCVmac' (CORE-V Multiply-Accumulate)
170170
// CHECK-NEXT: xcvmem 1.0 'XCVmem' (CORE-V Post-incrementing Load & Store)
171171
// CHECK-NEXT: xcvsimd 1.0 'XCVsimd' (CORE-V SIMD ALU)
172+
// CHECK-NEXT: xmipscbop 1.0 'XMIPSCBOP' (MIPS Software Prefetch)
172173
// CHECK-NEXT: xmipscmov 1.0 'XMIPSCMov' (MIPS conditional move instruction (mips.ccmov))
173174
// CHECK-NEXT: xmipslsp 1.0 'XMIPSLSP' (MIPS optimization for hardware load-store bonding)
174175
// CHECK-NEXT: xsfcease 1.0 'XSfcease' (SiFive sf.cease Instruction)

clang/test/Driver/riscv-cpus.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,9 @@
186186
// MCPU-MIPS-P8700-SAME: "-target-feature" "+zalrsc"
187187
// MCPU-MIPS-P8700-SAME: "-target-feature" "+zba"
188188
// MCPU-MIPS-P8700-SAME: "-target-feature" "+zbb"
189+
// MCPU-MIPS-P8700-SAME: "-target-feature" "+xmipscbop"
190+
// MCPU-MIPS-P8700-SAME: "-target-feature" "+xmipscmov"
191+
// MCPU-MIPS-P8700-SAME: "-target-feature" "+xmipslsp"
189192

190193
// RUN: %clang --target=riscv32 -### -c %s 2>&1 -mtune=syntacore-scr1-base | FileCheck -check-prefix=MTUNE-SYNTACORE-SCR1-BASE %s
191194
// MTUNE-SYNTACORE-SCR1-BASE: "-tune-cpu" "syntacore-scr1-base"

llvm/docs/RISCVUsage.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,9 @@ The current vendor extensions supported are:
498498
``experimental-Xqcisync``
499499
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.
500500

501+
``Xmipscbop``
502+
LLVM implements MIPS prefetch extension `p8700 processor <https://mips.com/products/hardware/p8700/>`__ by MIPS.
503+
501504
``Xmipscmov``
502505
LLVM implements conditional move for the `p8700 processor <https://mips.com/products/hardware/p8700/>`__ by MIPS.
503506

llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -732,6 +732,7 @@ struct RISCVOperand final : public MCParsedAsmOperand {
732732
bool isUImm6() const { return isUImm<6>(); }
733733
bool isUImm7() const { return isUImm<7>(); }
734734
bool isUImm8() const { return isUImm<8>(); }
735+
bool isUImm9() const { return isUImm<9>(); }
735736
bool isUImm10() const { return isUImm<10>(); }
736737
bool isUImm11() const { return isUImm<11>(); }
737738
bool isUImm16() const { return isUImm<16>(); }
@@ -1527,6 +1528,9 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
15271528
return generateImmOutOfRangeError(
15281529
Operands, ErrorInfo, 0, (1 << 8) - 8,
15291530
"immediate must be a multiple of 8 bytes in the range");
1531+
case Match_InvalidUImm9:
1532+
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 9) - 1,
1533+
"immediate offset must be in the range");
15301534
case Match_InvalidBareSImm9Lsb0:
15311535
return generateImmOutOfRangeError(
15321536
Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2,

llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -790,6 +790,9 @@ static constexpr DecoderListEntry DecoderList32[]{
790790
{DecoderTableXmipscmov32,
791791
{RISCV::FeatureVendorXMIPSCMov},
792792
"MIPS mips.ccmov"},
793+
{DecoderTableXmipscbop32,
794+
{RISCV::FeatureVendorXMIPSCBOP},
795+
"MIPS mips.pref"},
793796
{DecoderTableXAndes32, XAndesGroup, "Andes extensions"},
794797
// Standard Extensions
795798
{DecoderTableXCV32, XCVFeatureGroup, "CORE-V extensions"},

llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,7 @@ enum OperandType : unsigned {
316316
OPERAND_UIMM8_LSB000,
317317
OPERAND_UIMM8_GE32,
318318
OPERAND_UIMM9_LSB000,
319+
OPERAND_UIMM9,
319320
OPERAND_UIMM10,
320321
OPERAND_UIMM10_LSB00_NONZERO,
321322
OPERAND_UIMM11,

llvm/lib/Target/RISCV/RISCVFeatures.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1404,6 +1404,13 @@ def HasVendorXMIPSLSP
14041404
: Predicate<"Subtarget->hasVendorXMIPSLSP()">,
14051405
AssemblerPredicate<(all_of FeatureVendorXMIPSLSP),
14061406
"'Xmipslsp' (load and store pair instructions)">;
1407+
def FeatureVendorXMIPSCBOP
1408+
: RISCVExtension<1, 0, "MIPS Software Prefetch">;
1409+
def HasVendorXMIPSCBOP
1410+
: Predicate<"Subtarget->hasVendorXMIPSCBOP()">,
1411+
AssemblerPredicate<(all_of FeatureVendorXMIPSCBOP),
1412+
"'Xmipscbop' (MIPS hardware prefetch)">;
1413+
def NotHasVendorXMIPSCBOP : Predicate<"!Subtarget->hasVendorXMIPSCBOP()">;
14071414

14081415
// WCH / Nanjing Qinheng Microelectronics Extension(s)
14091416

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2921,6 +2921,33 @@ bool RISCVDAGToDAGISel::SelectAddrRegImm(SDValue Addr, SDValue &Base,
29212921
return true;
29222922
}
29232923

2924+
/// Similar to SelectAddrRegImm, except that the offset restricted for
2925+
/// unsinged nine bits.
2926+
bool RISCVDAGToDAGISel::SelectAddrRegImm9(SDValue Addr, SDValue &Base,
2927+
SDValue &Offset) {
2928+
if (SelectAddrFrameIndex(Addr, Base, Offset))
2929+
return true;
2930+
2931+
SDLoc DL(Addr);
2932+
MVT VT = Addr.getSimpleValueType();
2933+
2934+
if (CurDAG->isBaseWithConstantOffset(Addr)) {
2935+
int64_t CVal = cast<ConstantSDNode>(Addr.getOperand(1))->getSExtValue();
2936+
if (isUInt<9>(CVal)) {
2937+
Base = Addr.getOperand(0);
2938+
2939+
if (auto *FIN = dyn_cast<FrameIndexSDNode>(Base))
2940+
Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), VT);
2941+
Offset = CurDAG->getSignedTargetConstant(CVal, DL, VT);
2942+
return true;
2943+
}
2944+
}
2945+
2946+
Base = Addr;
2947+
Offset = CurDAG->getTargetConstant(0, DL, VT);
2948+
return true;
2949+
}
2950+
29242951
/// Similar to SelectAddrRegImm, except that the least significant 5 bits of
29252952
/// Offset should be all zeros.
29262953
bool RISCVDAGToDAGISel::SelectAddrRegImmLsb00000(SDValue Addr, SDValue &Base,

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ class RISCVDAGToDAGISel : public SelectionDAGISel {
4747

4848
bool SelectAddrFrameIndex(SDValue Addr, SDValue &Base, SDValue &Offset);
4949
bool SelectAddrRegImm(SDValue Addr, SDValue &Base, SDValue &Offset);
50+
bool SelectAddrRegImm9(SDValue Addr, SDValue &Base, SDValue &Offset);
5051
bool SelectAddrRegImmLsb00000(SDValue Addr, SDValue &Base, SDValue &Offset);
5152

5253
bool SelectAddrRegRegScale(SDValue Addr, unsigned MaxShiftAmount,

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -683,9 +683,10 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
683683
if (Subtarget.is64Bit())
684684
setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i32, Custom);
685685

686-
if (Subtarget.hasStdExtZicbop()) {
686+
if (Subtarget.hasVendorXMIPSCBOP())
687+
setOperationAction(ISD::PREFETCH, MVT::Other, Custom);
688+
else if (Subtarget.hasStdExtZicbop())
687689
setOperationAction(ISD::PREFETCH, MVT::Other, Legal);
688-
}
689690

690691
if (Subtarget.hasStdExtA()) {
691692
setMaxAtomicSizeInBitsSupported(Subtarget.getXLen());
@@ -6613,6 +6614,17 @@ SDValue RISCVTargetLowering::lowerConstantFP(SDValue Op,
66136614
return DAG.getNode(ISD::FNEG, DL, VT, Const);
66146615
}
66156616

6617+
static SDValue LowerPREFETCH(SDValue Op, const RISCVSubtarget &Subtarget,
6618+
SelectionDAG &DAG) {
6619+
6620+
unsigned IsData = Op.getConstantOperandVal(4);
6621+
6622+
// mips-p8700 we support data prefetch for now.
6623+
if (Subtarget.hasVendorXMIPSCBOP() && !IsData)
6624+
return Op.getOperand(0);
6625+
return Op;
6626+
}
6627+
66166628
static SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG,
66176629
const RISCVSubtarget &Subtarget) {
66186630
SDLoc dl(Op);
@@ -7178,6 +7190,8 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
71787190
switch (Op.getOpcode()) {
71797191
default:
71807192
report_fatal_error("unimplemented operand");
7193+
case ISD::PREFETCH:
7194+
return LowerPREFETCH(Op, Subtarget, DAG);
71817195
case ISD::ATOMIC_FENCE:
71827196
return LowerATOMIC_FENCE(Op, DAG, Subtarget);
71837197
case ISD::GlobalAddress:

0 commit comments

Comments
 (0)