Skip to content

Commit 8a1f988

Browse files
committed
Added prefetch extensions for MIPS RV64 P8700 and enable with xmipscbop option.
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 948cc91 commit 8a1f988

File tree

17 files changed

+198
-7
lines changed

17 files changed

+198
-7
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)

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: 5 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>(); }
@@ -1523,6 +1524,10 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
15231524
return generateImmOutOfRangeError(
15241525
Operands, ErrorInfo, 0, (1 << 8) - 8,
15251526
"immediate must be a multiple of 8 bytes in the range");
1527+
case Match_InvalidUImm9:
1528+
return generateImmOutOfRangeError(
1529+
Operands, ErrorInfo, 0, (1 << 9) - 1,
1530+
"immediate must be a multiple of 9 bytes in the range");
15261531
case Match_InvalidBareSImm9Lsb0:
15271532
return generateImmOutOfRangeError(
15281533
Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2,

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,19 @@ static DecodeStatus decodeRTZArg(MCInst &Inst, uint32_t Imm, int64_t Address,
535535
Inst.addOperand(MCOperand::createImm(Imm));
536536
return MCDisassembler::Success;
537537
}
538+
template <int Bits>
539+
static DecodeStatus DecodeSImm(MCInst &Inst, uint64_t Imm, uint64_t Address,
540+
const MCDisassembler *Decoder) {
541+
if (Imm & ~((1LL << Bits) - 1))
542+
return MCDisassembler::Fail;
543+
544+
// Imm is a signed immediate, so sign extend it.
545+
if (Imm & (1 << (Bits - 1)))
546+
Imm |= ~((1LL << Bits) - 1);
547+
548+
Inst.addOperand(MCOperand::createImm(Imm));
549+
return MCDisassembler::Success;
550+
}
538551

539552
static DecodeStatus decodeRVCInstrRdRs1ImmZero(MCInst &Inst, uint32_t Insn,
540553
uint64_t Address,
@@ -576,6 +589,9 @@ static DecodeStatus decodeXqccmpRlistS0(MCInst &Inst, uint32_t Imm,
576589
static DecodeStatus decodeCSSPushPopchk(MCInst &Inst, uint32_t Insn,
577590
uint64_t Address,
578591
const MCDisassembler *Decoder);
592+
template <int Bits>
593+
static DecodeStatus DecodeSImm(MCInst &Inst, uint64_t Imm, uint64_t Address,
594+
const MCDisassembler *Decoder);
579595

580596
#include "RISCVGenDisassemblerTables.inc"
581597

@@ -790,6 +806,8 @@ static constexpr DecoderListEntry DecoderList32[]{
790806
{DecoderTableXmipscmov32,
791807
{RISCV::FeatureVendorXMIPSCMov},
792808
"MIPS mips.ccmov"},
809+
{DecoderTableXmipscbop32, {RISCV::FeatureVendorXMIPSCBOP},
810+
"MIPS mips.pref"},
793811
{DecoderTableXAndes32, XAndesGroup, "Andes extensions"},
794812
// Standard Extensions
795813
{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
@@ -1411,6 +1411,13 @@ def HasVendorXMIPSLSP
14111411
: Predicate<"Subtarget->hasVendorXMIPSLSP()">,
14121412
AssemblerPredicate<(all_of FeatureVendorXMIPSLSP),
14131413
"'Xmipslsp' (load and store pair instructions)">;
1414+
def FeatureVendorXMIPSCBOP
1415+
: RISCVExtension<1, 0, "MIPS Software Prefetch">;
1416+
def HasVendorXMIPSCBOP
1417+
: Predicate<"Subtarget->hasVendorXMIPSCBOP()">,
1418+
AssemblerPredicate<(all_of FeatureVendorXMIPSCBOP),
1419+
"'Xmipscbop' (MIPS hardware prefetch)">;
1420+
def NotHasVendorXMIPSCBOP : Predicate<"!Subtarget->hasVendorXMIPSCBOP()">;
14141421

14151422
// WCH / Nanjing Qinheng Microelectronics Extension(s)
14161423

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2925,6 +2925,54 @@ bool RISCVDAGToDAGISel::SelectAddrRegImm(SDValue Addr, SDValue &Base,
29252925
return true;
29262926
}
29272927

2928+
/// Similar to SelectAddrRegImm, except that the offset restricted for
2929+
/// nine bits.
2930+
bool RISCVDAGToDAGISel::SelectAddrRegImm9(SDValue Addr, SDValue &Base,
2931+
SDValue &Offset) {
2932+
if (SelectAddrFrameIndex(Addr, Base, Offset))
2933+
return true;
2934+
2935+
SDLoc DL(Addr);
2936+
MVT VT = Addr.getSimpleValueType();
2937+
2938+
if (CurDAG->isBaseWithConstantOffset(Addr)) {
2939+
2940+
int64_t CVal = cast<ConstantSDNode>(Addr.getOperand(1))->getSExtValue();
2941+
if (isUInt<9>(CVal)) {
2942+
Base = Addr.getOperand(0);
2943+
2944+
if (auto *FIN = dyn_cast<FrameIndexSDNode>(Base))
2945+
Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), VT);
2946+
Offset = CurDAG->getSignedTargetConstant(CVal, DL, VT);
2947+
return true;
2948+
}
2949+
2950+
// Handle with 12 bit ofset immediates with ADDI.
2951+
else if (Addr.getOpcode() == ISD::ADD &&
2952+
isa<ConstantSDNode>(Addr.getOperand(1))) {
2953+
int64_t CVal = cast<ConstantSDNode>(Addr.getOperand(1))->getSExtValue();
2954+
assert(!isUInt<9>(CVal) && "uimm9 not already handled?");
2955+
2956+
if (isUInt<12>(CVal)) {
2957+
Base = SDValue(CurDAG->getMachineNode(
2958+
RISCV::ADDI, DL, VT, Addr.getOperand(0),
2959+
CurDAG->getSignedTargetConstant(CVal, DL, VT)),
2960+
0);
2961+
Offset = CurDAG->getTargetConstant(0, DL, VT);
2962+
return true;
2963+
}
2964+
}
2965+
}
2966+
// Immediates more than 12 bits i.e LUI,ADDI,ADD
2967+
if (selectConstantAddr(CurDAG, DL, VT, Subtarget, Addr, Base, Offset,
2968+
/*IsPrefetch=*/true))
2969+
return true;
2970+
2971+
Base = Addr;
2972+
Offset = CurDAG->getTargetConstant(0, DL, VT);
2973+
return true;
2974+
}
2975+
29282976
/// Similar to SelectAddrRegImm, except that the least significant 5 bits of
29292977
/// Offset should be all zeros.
29302978
bool RISCVDAGToDAGISel::SelectAddrRegImmLsb00000(SDValue Addr, SDValue &Base,

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,12 @@ class RISCVDAGToDAGISel : public SelectionDAGISel {
4545
InlineAsm::ConstraintCode ConstraintID,
4646
std::vector<SDValue> &OutOps) override;
4747

48+
bool SelectAddrFrameIndexOffset(SDValue Addr, SDValue &Base, SDValue &Offset,
49+
unsigned OffsetBits,
50+
unsigned ShiftAmount);
4851
bool SelectAddrFrameIndex(SDValue Addr, SDValue &Base, SDValue &Offset);
4952
bool SelectAddrRegImm(SDValue Addr, SDValue &Base, SDValue &Offset);
53+
bool SelectAddrRegImm9(SDValue Addr, SDValue &Base, SDValue &Offset);
5054
bool SelectAddrRegImmLsb00000(SDValue Addr, SDValue &Base, SDValue &Offset);
5155

5256
bool SelectAddrRegRegScale(SDValue Addr, unsigned MaxShiftAmount,

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -682,7 +682,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
682682
if (Subtarget.is64Bit())
683683
setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i32, Custom);
684684

685-
if (Subtarget.hasStdExtZicbop()) {
685+
if (Subtarget.hasStdExtZicbop() || Subtarget.hasVendorXMIPSCBOP()) {
686686
setOperationAction(ISD::PREFETCH, MVT::Other, Legal);
687687
}
688688

llvm/lib/Target/RISCV/RISCVInstrInfo.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2742,6 +2742,9 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI,
27422742
case RISCVOp::OPERAND_UIMM9_LSB000:
27432743
Ok = isShiftedUInt<6, 3>(Imm);
27442744
break;
2745+
case RISCVOp::OPERAND_UIMM9:
2746+
Ok = isUInt<9>(Imm);
2747+
break;
27452748
case RISCVOp::OPERAND_SIMM10_LSB0000_NONZERO:
27462749
Ok = isShiftedInt<6, 4>(Imm) && (Imm != 0);
27472750
break;

0 commit comments

Comments
 (0)